summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--BORINGSSL_REVISION2
-rw-r--r--android_compat_hacks.c32
-rw-r--r--err_data.c1226
-rw-r--r--linux-aarch64/crypto/aes/aesv8-armx64.S8
-rw-r--r--linux-aarch64/crypto/bn/armv8-mont.S3
-rw-r--r--linux-aarch64/crypto/chacha/chacha-armv8.S1971
-rw-r--r--linux-aarch64/crypto/modes/ghashv8-armx64.S5
-rw-r--r--linux-aarch64/crypto/sha/sha1-armv8.S3
-rw-r--r--linux-aarch64/crypto/sha/sha256-armv8.S3
-rw-r--r--linux-aarch64/crypto/sha/sha512-armv8.S3
-rw-r--r--linux-arm/crypto/aes/aes-armv4.S2
-rw-r--r--linux-arm/crypto/aes/aesv8-armx32.S8
-rw-r--r--linux-arm/crypto/aes/bsaes-armv7.S2
-rw-r--r--linux-arm/crypto/bn/armv4-mont.S4
-rw-r--r--linux-arm/crypto/chacha/chacha-armv4.S1471
-rw-r--r--linux-arm/crypto/modes/ghash-armv4.S2
-rw-r--r--linux-arm/crypto/modes/ghashv8-armx32.S5
-rw-r--r--linux-arm/crypto/sha/sha1-armv4-large.S3
-rw-r--r--linux-arm/crypto/sha/sha256-armv4.S4
-rw-r--r--linux-arm/crypto/sha/sha512-armv4.S6
-rw-r--r--linux-x86/crypto/chacha/chacha-x86.S989
-rw-r--r--linux-x86/crypto/rc4/rc4-586.S35
-rw-r--r--linux-x86_64/crypto/aes/aes-x86_64.S70
-rw-r--r--linux-x86_64/crypto/aes/aesni-x86_64.S82
-rw-r--r--linux-x86_64/crypto/aes/bsaes-x86_64.S158
-rw-r--r--linux-x86_64/crypto/aes/vpaes-x86_64.S20
-rw-r--r--linux-x86_64/crypto/bn/rsaz-x86_64.S218
-rw-r--r--linux-x86_64/crypto/bn/x86_64-mont.S108
-rw-r--r--linux-x86_64/crypto/bn/x86_64-mont5.S901
-rw-r--r--linux-x86_64/crypto/chacha/chacha-x86_64.S1585
-rw-r--r--linux-x86_64/crypto/ec/p256-x86_64-asm.S27
-rw-r--r--linux-x86_64/crypto/md5/md5-x86_64.S34
-rw-r--r--linux-x86_64/crypto/modes/ghash-x86_64.S34
-rw-r--r--mac-x86/crypto/chacha/chacha-x86.S989
-rw-r--r--mac-x86/crypto/rc4/rc4-586.S33
-rw-r--r--mac-x86_64/crypto/aes/aes-x86_64.S70
-rw-r--r--mac-x86_64/crypto/aes/aesni-x86_64.S82
-rw-r--r--mac-x86_64/crypto/aes/bsaes-x86_64.S158
-rw-r--r--mac-x86_64/crypto/aes/vpaes-x86_64.S20
-rw-r--r--mac-x86_64/crypto/bn/rsaz-x86_64.S218
-rw-r--r--mac-x86_64/crypto/bn/x86_64-mont.S108
-rw-r--r--mac-x86_64/crypto/bn/x86_64-mont5.S897
-rw-r--r--mac-x86_64/crypto/chacha/chacha-x86_64.S1584
-rw-r--r--mac-x86_64/crypto/ec/p256-x86_64-asm.S27
-rw-r--r--mac-x86_64/crypto/md5/md5-x86_64.S34
-rw-r--r--mac-x86_64/crypto/modes/ghash-x86_64.S34
-rw-r--r--sources.mk32
-rw-r--r--src/.clang-format3
-rw-r--r--src/.github/PULL_REQUEST_TEMPLATE7
-rw-r--r--src/BUILDING.md36
-rw-r--r--src/CMakeLists.txt44
-rw-r--r--src/CONTRIBUTING.md49
-rw-r--r--src/FUZZING.md45
-rw-r--r--src/INCORPORATING.md85
-rw-r--r--src/LICENSE7
-rw-r--r--src/PORTING.md23
-rw-r--r--src/README.md2
-rw-r--r--src/crypto/CMakeLists.txt46
-rw-r--r--src/crypto/aes/asm/aes-armv4.pl5
-rw-r--r--src/crypto/aes/asm/bsaes-armv7.pl8
-rw-r--r--src/crypto/aes/mode_wrappers.c8
-rw-r--r--src/crypto/asn1/CMakeLists.txt12
-rw-r--r--src/crypto/asn1/a_bitstr.c360
-rw-r--r--src/crypto/asn1/a_bool.c86
-rw-r--r--src/crypto/asn1/a_bytes.c481
-rw-r--r--src/crypto/asn1/a_d2i_fp.c380
-rw-r--r--src/crypto/asn1/a_dup.c78
-rw-r--r--src/crypto/asn1/a_enum.c216
-rw-r--r--src/crypto/asn1/a_gentm.c361
-rw-r--r--src/crypto/asn1/a_i2d_fp.c153
-rw-r--r--src/crypto/asn1/a_int.c710
-rw-r--r--src/crypto/asn1/a_mbstr.c525
-rw-r--r--src/crypto/asn1/a_object.c602
-rw-r--r--src/crypto/asn1/a_octet.c19
-rw-r--r--src/crypto/asn1/a_print.c106
-rw-r--r--src/crypto/asn1/a_strnid.c336
-rw-r--r--src/crypto/asn1/a_time.c254
-rw-r--r--src/crypto/asn1/a_type.c165
-rw-r--r--src/crypto/asn1/a_utctm.c501
-rw-r--r--src/crypto/asn1/a_utf8.c294
-rw-r--r--src/crypto/asn1/asn1_lib.c729
-rw-r--r--src/crypto/asn1/asn1_locl.h22
-rw-r--r--src/crypto/asn1/asn1_par.c669
-rw-r--r--src/crypto/asn1/asn1_test.cc81
-rw-r--r--src/crypto/asn1/asn_pack.c59
-rw-r--r--src/crypto/asn1/bio_asn1.c769
-rw-r--r--src/crypto/asn1/bio_ndef.c295
-rw-r--r--src/crypto/asn1/f_enum.c262
-rw-r--r--src/crypto/asn1/f_int.c270
-rw-r--r--src/crypto/asn1/f_string.c258
-rw-r--r--src/crypto/asn1/t_bitst.c59
-rw-r--r--src/crypto/asn1/tasn_dec.c2311
-rw-r--r--src/crypto/asn1/tasn_enc.c1148
-rw-r--r--src/crypto/asn1/tasn_fre.c368
-rw-r--r--src/crypto/asn1/tasn_new.c559
-rw-r--r--src/crypto/asn1/tasn_prn.c970
-rw-r--r--src/crypto/asn1/tasn_typ.c49
-rw-r--r--src/crypto/asn1/x_bignum.c114
-rw-r--r--src/crypto/asn1/x_long.c187
-rw-r--r--src/crypto/base64/base64_test.cc1
-rw-r--r--src/crypto/bio/bio_mem.c5
-rw-r--r--src/crypto/bio/bio_test.cc3
-rw-r--r--src/crypto/bio/buffer.c6
-rw-r--r--src/crypto/bio/connect.c5
-rw-r--r--src/crypto/bio/fd.c2
-rw-r--r--src/crypto/bio/file.c40
-rw-r--r--src/crypto/bio/internal.h3
-rw-r--r--src/crypto/bio/pair.c2
-rw-r--r--src/crypto/bio/socket.c8
-rw-r--r--src/crypto/bn/asm/armv4-mont.pl3
-rwxr-xr-x[-rw-r--r--]src/crypto/bn/asm/rsaz-avx2.pl219
-rwxr-xr-x[-rw-r--r--]src/crypto/bn/asm/rsaz-x86_64.pl375
-rw-r--r--src/crypto/bn/asm/x86_64-gcc.c84
-rwxr-xr-x[-rw-r--r--]src/crypto/bn/asm/x86_64-mont.pl227
-rwxr-xr-x[-rw-r--r--]src/crypto/bn/asm/x86_64-mont5.pl1276
-rw-r--r--src/crypto/bn/bn.c14
-rw-r--r--src/crypto/bn/bn_asn1.c31
-rw-r--r--src/crypto/bn/bn_test.cc28
-rw-r--r--src/crypto/bn/convert.c20
-rw-r--r--src/crypto/bn/div.c212
-rw-r--r--src/crypto/bn/exponentiation.c101
-rw-r--r--src/crypto/bn/generic.c328
-rw-r--r--src/crypto/bn/internal.h85
-rw-r--r--src/crypto/bn/montgomery.c115
-rw-r--r--src/crypto/bn/mul.c35
-rw-r--r--src/crypto/bn/rsaz_exp.c49
-rw-r--r--src/crypto/bytestring/CMakeLists.txt1
-rw-r--r--src/crypto/bytestring/asn1_compat.c51
-rw-r--r--src/crypto/bytestring/ber.c216
-rw-r--r--src/crypto/bytestring/bytestring_test.cc67
-rw-r--r--src/crypto/bytestring/cbs.c20
-rw-r--r--src/crypto/bytestring/internal.h49
-rw-r--r--src/crypto/chacha/CMakeLists.txt44
-rwxr-xr-xsrc/crypto/chacha/asm/chacha-armv4.pl1151
-rwxr-xr-xsrc/crypto/chacha/asm/chacha-armv8.pl1127
-rwxr-xr-xsrc/crypto/chacha/asm/chacha-x86.pl769
-rwxr-xr-xsrc/crypto/chacha/asm/chacha-x86_64.pl1767
-rw-r--r--src/crypto/chacha/chacha.c (renamed from src/crypto/chacha/chacha_generic.c)64
-rw-r--r--src/crypto/chacha/chacha_test.cc257
-rw-r--r--src/crypto/chacha/chacha_vec.c323
-rw-r--r--src/crypto/chacha/chacha_vec_arm.S1447
-rw-r--r--src/crypto/chacha/chacha_vec_arm_generate.go153
-rw-r--r--src/crypto/cipher/aead_test.cc191
-rw-r--r--src/crypto/cipher/cipher.c2
-rw-r--r--src/crypto/cipher/cipher_test.cc43
-rw-r--r--src/crypto/cipher/e_aes.c82
-rw-r--r--src/crypto/cipher/e_chacha20poly1305.c21
-rw-r--r--src/crypto/cipher/e_des.c2
-rw-r--r--src/crypto/cipher/e_null.c2
-rw-r--r--src/crypto/cipher/e_rc2.c2
-rw-r--r--src/crypto/cipher/e_rc4.c2
-rw-r--r--src/crypto/cipher/test/cipher_test.txt16
-rw-r--r--src/crypto/cipher/tls_cbc.c52
-rw-r--r--src/crypto/cmac/cmac_test.cc2
-rw-r--r--src/crypto/conf/conf.c12
-rw-r--r--src/crypto/cpu-aarch64-linux.c61
-rw-r--r--src/crypto/cpu-arm-asm.S32
-rw-r--r--src/crypto/cpu-arm-linux.c360
-rw-r--r--src/crypto/cpu-arm.c161
-rw-r--r--src/crypto/cpu-intel.c6
-rw-r--r--src/crypto/crypto.c10
-rw-r--r--src/crypto/curve25519/CMakeLists.txt10
-rw-r--r--src/crypto/curve25519/asm/x25519-asm-arm.S6
-rw-r--r--src/crypto/curve25519/asm/x25519-asm-x86_64.S6
-rw-r--r--src/crypto/curve25519/curve25519.c532
-rw-r--r--src/crypto/curve25519/internal.h64
-rw-r--r--src/crypto/curve25519/spake25519.c464
-rw-r--r--src/crypto/curve25519/spake25519_test.cc169
-rw-r--r--src/crypto/curve25519/x25519_test.cc6
-rw-r--r--src/crypto/dh/check.c42
-rw-r--r--src/crypto/dh/dh.c19
-rw-r--r--src/crypto/dh/dh_test.cc58
-rw-r--r--src/crypto/digest/digest.c6
-rw-r--r--src/crypto/digest/digest_test.cc1
-rw-r--r--src/crypto/digest/md32_common.h60
-rw-r--r--src/crypto/directory.h66
-rw-r--r--src/crypto/directory_posix.c108
-rw-r--r--src/crypto/directory_win.c144
-rw-r--r--src/crypto/dsa/dsa.c84
-rw-r--r--src/crypto/dsa/dsa_asn1.c317
-rw-r--r--src/crypto/dsa/dsa_test.c2
-rwxr-xr-x[-rw-r--r--]src/crypto/ec/asm/p256-x86_64-asm.pl11
-rw-r--r--src/crypto/ec/ec.c110
-rw-r--r--src/crypto/ec/ec_asn1.c715
-rw-r--r--src/crypto/ec/ec_key.c19
-rw-r--r--src/crypto/ec/ec_montgomery.c137
-rw-r--r--src/crypto/ec/ec_test.cc291
-rw-r--r--src/crypto/ec/example_mul.c4
-rw-r--r--src/crypto/ec/internal.h40
-rw-r--r--src/crypto/ec/oct.c34
-rw-r--r--src/crypto/ec/p224-64.c199
-rw-r--r--src/crypto/ec/p256-64.c285
-rw-r--r--src/crypto/ec/p256-x86_64-table.h7
-rw-r--r--src/crypto/ec/p256-x86_64.c61
-rw-r--r--src/crypto/ec/simple.c333
-rw-r--r--src/crypto/ec/util-64.c74
-rw-r--r--src/crypto/ecdsa/ecdsa.c11
-rw-r--r--src/crypto/ecdsa/ecdsa_asn1.c35
-rw-r--r--src/crypto/ecdsa/ecdsa_test.cc17
-rw-r--r--src/crypto/err/asn1.errordata163
-rw-r--r--src/crypto/err/dsa.errordata3
-rw-r--r--src/crypto/err/ec.errordata3
-rw-r--r--src/crypto/err/err_data_generate.go9
-rw-r--r--src/crypto/err/evp.errordata72
-rw-r--r--src/crypto/err/rsa.errordata92
-rw-r--r--src/crypto/err/ssl.errordata1
-rw-r--r--src/crypto/err/x509.errordata40
-rw-r--r--src/crypto/evp/CMakeLists.txt2
-rw-r--r--src/crypto/evp/evp.c64
-rw-r--r--src/crypto/evp/evp_asn1.c299
-rw-r--r--src/crypto/evp/evp_ctx.c78
-rw-r--r--src/crypto/evp/evp_extra_test.cc446
-rw-r--r--src/crypto/evp/evp_test.cc96
-rw-r--r--src/crypto/evp/evp_tests.txt114
-rw-r--r--src/crypto/evp/internal.h103
-rw-r--r--src/crypto/evp/p_dsa_asn1.c482
-rw-r--r--src/crypto/evp/p_ec.c87
-rw-r--r--src/crypto/evp/p_ec_asn1.c455
-rw-r--r--src/crypto/evp/p_rsa.c103
-rw-r--r--src/crypto/evp/p_rsa_asn1.c643
-rw-r--r--src/crypto/evp/pbkdf_test.cc2
-rw-r--r--src/crypto/evp/print.c527
-rw-r--r--src/crypto/hkdf/hkdf_test.c8
-rw-r--r--src/crypto/hmac/hmac.c11
-rw-r--r--src/crypto/internal.h77
-rw-r--r--src/crypto/md4/md4.c9
-rw-r--r--src/crypto/mem.c4
-rw-r--r--src/crypto/modes/asm/aesni-gcm-x86_64.pl48
-rw-r--r--src/crypto/modes/asm/ghash-armv4.pl5
-rw-r--r--src/crypto/modes/asm/ghash-x86_64.pl5
-rw-r--r--src/crypto/modes/cfb.c11
-rw-r--r--src/crypto/modes/ctr.c31
-rw-r--r--src/crypto/modes/gcm.c94
-rw-r--r--src/crypto/modes/gcm_test.c8
-rw-r--r--src/crypto/modes/internal.h38
-rw-r--r--src/crypto/modes/ofb.c6
-rw-r--r--src/crypto/newhope/CMakeLists.txt22
-rw-r--r--src/crypto/newhope/error_correction.c134
-rw-r--r--src/crypto/newhope/internal.h95
-rw-r--r--src/crypto/newhope/newhope.c160
-rw-r--r--src/crypto/newhope/newhope_test.c144
-rw-r--r--src/crypto/newhope/ntt.c148
-rw-r--r--src/crypto/newhope/poly.c183
-rw-r--r--src/crypto/newhope/precomp.c306
-rw-r--r--src/crypto/newhope/reduce.c42
-rw-r--r--src/crypto/obj/CMakeLists.txt11
-rw-r--r--src/crypto/obj/README12
-rw-r--r--src/crypto/obj/obj_dat.h14
-rw-r--r--src/crypto/obj/obj_dat.pl6
-rw-r--r--src/crypto/obj/obj_mac.num2
-rw-r--r--src/crypto/obj/obj_test.cc106
-rw-r--r--src/crypto/obj/objects.pl40
-rw-r--r--src/crypto/obj/objects.txt2
-rw-r--r--src/crypto/pem/pem_all.c175
-rw-r--r--src/crypto/pem/pem_info.c595
-rw-r--r--src/crypto/pem/pem_lib.c1371
-rw-r--r--src/crypto/pem/pem_oth.c31
-rw-r--r--src/crypto/pem/pem_pk8.c251
-rw-r--r--src/crypto/pem/pem_pkey.c359
-rw-r--r--src/crypto/pem/pem_x509.c6
-rw-r--r--src/crypto/pem/pem_xaux.c9
-rwxr-xr-xsrc/crypto/perlasm/arm-xlate.pl6
-rwxr-xr-xsrc/crypto/perlasm/x86_64-xlate.pl9
-rw-r--r--src/crypto/perlasm/x86gas.pl2
-rw-r--r--src/crypto/pkcs8/CMakeLists.txt2
-rw-r--r--src/crypto/pkcs8/p5_pbe.c1
-rw-r--r--src/crypto/pkcs8/p5_pbev2.c1
-rw-r--r--src/crypto/pkcs8/pkcs12_test.cc3
-rw-r--r--src/crypto/pkcs8/pkcs8.c296
-rwxr-xr-xsrc/crypto/poly1305/asm/poly1305-armv4.pl1216
-rwxr-xr-xsrc/crypto/poly1305/asm/poly1305-armv8.pl925
-rwxr-xr-xsrc/crypto/poly1305/asm/poly1305-x86.pl1788
-rwxr-xr-xsrc/crypto/poly1305/asm/poly1305-x86_64.pl2235
-rw-r--r--src/crypto/poly1305/internal.h40
-rw-r--r--src/crypto/poly1305/poly1305.c17
-rw-r--r--src/crypto/poly1305/poly1305_arm.c5
-rw-r--r--src/crypto/poly1305/poly1305_test.cc69
-rw-r--r--src/crypto/poly1305/poly1305_test.txt107
-rw-r--r--src/crypto/poly1305/poly1305_vec.c104
-rw-r--r--src/crypto/rand/CMakeLists.txt1
-rw-r--r--src/crypto/rand/deterministic.c49
-rw-r--r--src/crypto/rand/rand.c5
-rw-r--r--src/crypto/rand/urandom.c4
-rw-r--r--src/crypto/rand/windows.c4
-rw-r--r--src/crypto/rc4/asm/rc4-586.pl26
-rw-r--r--src/crypto/rsa/blinding.c337
-rw-r--r--src/crypto/rsa/internal.h26
-rw-r--r--src/crypto/rsa/padding.c21
-rw-r--r--src/crypto/rsa/rsa.c30
-rw-r--r--src/crypto/rsa/rsa_asn1.c78
-rw-r--r--src/crypto/rsa/rsa_impl.c279
-rw-r--r--src/crypto/rsa/rsa_test.cc62
-rw-r--r--src/crypto/sha/asm/sha512-armv4.pl2
-rw-r--r--src/crypto/sha/sha256.c4
-rw-r--r--src/crypto/sha/sha512.c4
-rw-r--r--src/crypto/stack/stack.c2
-rw-r--r--src/crypto/test/file_test.cc52
-rw-r--r--src/crypto/test/file_test.h31
-rw-r--r--src/crypto/test/scoped_types.h8
-rw-r--r--src/crypto/test/test_util.h8
-rw-r--r--src/crypto/thread_pthread.c3
-rw-r--r--src/crypto/thread_test.c21
-rw-r--r--src/crypto/thread_win.c84
-rw-r--r--src/crypto/x509/CMakeLists.txt13
-rw-r--r--src/crypto/x509/a_digest.c53
-rw-r--r--src/crypto/x509/a_sign.c129
-rw-r--r--src/crypto/x509/a_strex.c895
-rw-r--r--src/crypto/x509/a_verify.c98
-rw-r--r--src/crypto/x509/algorithm.c (renamed from src/crypto/evp/algorithm.c)90
-rw-r--r--src/crypto/x509/asn1_gen.c1483
-rw-r--r--src/crypto/x509/by_dir.c748
-rw-r--r--src/crypto/x509/by_file.c392
-rw-r--r--src/crypto/x509/charmap.h22
-rw-r--r--src/crypto/x509/i2d_pr.c43
-rw-r--r--src/crypto/x509/internal.h66
-rw-r--r--src/crypto/x509/pkcs7_test.c21
-rw-r--r--src/crypto/x509/rsa_pss.c385
-rw-r--r--src/crypto/x509/t_crl.c101
-rw-r--r--src/crypto/x509/t_x509.c820
-rw-r--r--src/crypto/x509/t_x509a.c86
-rw-r--r--src/crypto/x509/vpm_int.h26
-rw-r--r--src/crypto/x509/x509.c5
-rw-r--r--src/crypto/x509/x509_att.c460
-rw-r--r--src/crypto/x509/x509_cmp.c702
-rw-r--r--src/crypto/x509/x509_d2.c71
-rw-r--r--src/crypto/x509/x509_def.c36
-rw-r--r--src/crypto/x509/x509_ext.c150
-rw-r--r--src/crypto/x509/x509_lu.c1191
-rw-r--r--src/crypto/x509/x509_obj.c219
-rw-r--r--src/crypto/x509/x509_r2x.c80
-rw-r--r--src/crypto/x509/x509_req.c355
-rw-r--r--src/crypto/x509/x509_set.c147
-rw-r--r--src/crypto/x509/x509_test.cc472
-rw-r--r--src/crypto/x509/x509_trs.c364
-rw-r--r--src/crypto/x509/x509_txt.c273
-rw-r--r--src/crypto/x509/x509_v3.c341
-rw-r--r--src/crypto/x509/x509_vfy.c4215
-rw-r--r--src/crypto/x509/x509_vpm.c1008
-rw-r--r--src/crypto/x509/x509cset.c195
-rw-r--r--src/crypto/x509/x509name.c549
-rw-r--r--src/crypto/x509/x509rset.c29
-rw-r--r--src/crypto/x509/x509spki.c122
-rw-r--r--src/crypto/x509/x509type.c118
-rw-r--r--src/crypto/x509/x_algor.c143
-rw-r--r--src/crypto/x509/x_all.c560
-rw-r--r--src/crypto/x509/x_attrib.c78
-rw-r--r--src/crypto/x509/x_crl.c815
-rw-r--r--src/crypto/x509/x_exten.c10
-rw-r--r--src/crypto/x509/x_info.c57
-rw-r--r--src/crypto/x509/x_name.c775
-rw-r--r--src/crypto/x509/x_pkey.c61
-rw-r--r--src/crypto/x509/x_pubkey.c544
-rw-r--r--src/crypto/x509/x_req.c63
-rw-r--r--src/crypto/x509/x_sig.c4
-rw-r--r--src/crypto/x509/x_spki.c16
-rw-r--r--src/crypto/x509/x_val.c4
-rw-r--r--src/crypto/x509/x_x509.c247
-rw-r--r--src/crypto/x509/x_x509a.c190
-rw-r--r--src/crypto/x509v3/ext_dat.h108
-rw-r--r--src/crypto/x509v3/pcy_cache.c413
-rw-r--r--src/crypto/x509v3/pcy_data.c121
-rw-r--r--src/crypto/x509v3/pcy_int.h185
-rw-r--r--src/crypto/x509v3/pcy_lib.c173
-rw-r--r--src/crypto/x509v3/pcy_map.c125
-rw-r--r--src/crypto/x509v3/pcy_node.c225
-rw-r--r--src/crypto/x509v3/pcy_tree.c1400
-rw-r--r--src/crypto/x509v3/tab_test.c68
-rw-r--r--src/crypto/x509v3/v3_akey.c264
-rw-r--r--src/crypto/x509v3/v3_akeya.c13
-rw-r--r--src/crypto/x509v3/v3_alt.c1006
-rw-r--r--src/crypto/x509v3/v3_bcons.c101
-rw-r--r--src/crypto/x509v3/v3_bitst.c134
-rw-r--r--src/crypto/x509v3/v3_conf.c657
-rw-r--r--src/crypto/x509v3/v3_cpols.c697
-rw-r--r--src/crypto/x509v3/v3_crld.c937
-rw-r--r--src/crypto/x509v3/v3_enum.c68
-rw-r--r--src/crypto/x509v3/v3_extku.c129
-rw-r--r--src/crypto/x509v3/v3_genn.c316
-rw-r--r--src/crypto/x509v3/v3_ia5.c88
-rw-r--r--src/crypto/x509v3/v3_info.c236
-rw-r--r--src/crypto/x509v3/v3_int.c56
-rw-r--r--src/crypto/x509v3/v3_lib.c435
-rw-r--r--src/crypto/x509v3/v3_ncons.c734
-rw-r--r--src/crypto/x509v3/v3_pci.c522
-rw-r--r--src/crypto/x509v3/v3_pcia.c17
-rw-r--r--src/crypto/x509v3/v3_pcons.c119
-rw-r--r--src/crypto/x509v3/v3_pku.c69
-rw-r--r--src/crypto/x509v3/v3_pmaps.c146
-rw-r--r--src/crypto/x509v3/v3_prn.c267
-rw-r--r--src/crypto/x509v3/v3_purp.c1233
-rw-r--r--src/crypto/x509v3/v3_skey.c148
-rw-r--r--src/crypto/x509v3/v3_sxnet.c270
-rw-r--r--src/crypto/x509v3/v3_utl.c2141
-rw-r--r--src/crypto/x509v3/v3name_test.c636
-rw-r--r--src/decrepit/CMakeLists.txt18
-rw-r--r--src/decrepit/dh/CMakeLists.txt9
-rw-r--r--src/decrepit/dh/dh_decrepit.c103
-rw-r--r--src/decrepit/dsa/CMakeLists.txt9
-rw-r--r--src/decrepit/dsa/dsa_decrepit.c105
-rw-r--r--src/decrepit/evp/CMakeLists.txt9
-rw-r--r--src/decrepit/evp/evp_do_all.c77
-rw-r--r--src/decrepit/obj/CMakeLists.txt9
-rw-r--r--src/decrepit/obj/obj_decrepit.c71
-rw-r--r--src/decrepit/rc4/CMakeLists.txt9
-rw-r--r--src/decrepit/rc4/rc4_decrepit.c (renamed from src/crypto/dsa/internal.h)26
-rw-r--r--src/decrepit/ripemd/CMakeLists.txt21
-rw-r--r--src/decrepit/ripemd/internal.h493
-rw-r--r--src/decrepit/ripemd/ripemd.c324
-rw-r--r--src/decrepit/ripemd/ripemd_test.cc119
-rw-r--r--src/decrepit/rsa/rsa_decrepit.c17
-rw-r--r--src/decrepit/ssl/CMakeLists.txt9
-rw-r--r--src/decrepit/ssl/ssl_decrepit.c225
-rw-r--r--src/decrepit/x509/CMakeLists.txt9
-rw-r--r--src/decrepit/x509/x509_decrepit.c42
-rw-r--r--src/include/openssl/aead.h120
-rw-r--r--src/include/openssl/arm_arch.h6
-rw-r--r--src/include/openssl/asn1.h167
-rw-r--r--src/include/openssl/base.h21
-rw-r--r--src/include/openssl/bio.h52
-rw-r--r--src/include/openssl/bn.h35
-rw-r--r--src/include/openssl/buf.h2
-rw-r--r--src/include/openssl/bytestring.h12
-rw-r--r--src/include/openssl/cipher.h2
-rw-r--r--src/include/openssl/conf.h29
-rw-r--r--src/include/openssl/cpu.h35
-rw-r--r--src/include/openssl/crypto.h16
-rw-r--r--src/include/openssl/curve25519.h92
-rw-r--r--src/include/openssl/dh.h20
-rw-r--r--src/include/openssl/digest.h7
-rw-r--r--src/include/openssl/dsa.h168
-rw-r--r--src/include/openssl/ec.h96
-rw-r--r--src/include/openssl/ec_key.h129
-rw-r--r--src/include/openssl/ecdsa.h8
-rw-r--r--src/include/openssl/err.h5
-rw-r--r--src/include/openssl/evp.h260
-rw-r--r--src/include/openssl/hkdf.h11
-rw-r--r--src/include/openssl/hmac.h2
-rw-r--r--src/include/openssl/md4.h4
-rw-r--r--src/include/openssl/mem.h24
-rw-r--r--src/include/openssl/newhope.h78
-rw-r--r--src/include/openssl/nid.h4163
-rw-r--r--src/include/openssl/obj.h28
-rw-r--r--src/include/openssl/obj_mac.h4160
-rw-r--r--src/include/openssl/opensslconf.h (renamed from src/include/openssl/opensslfeatures.h)6
-rw-r--r--src/include/openssl/pem.h6
-rw-r--r--src/include/openssl/pkcs8.h8
-rw-r--r--src/include/openssl/rand.h9
-rw-r--r--src/include/openssl/rc4.h6
-rw-r--r--src/include/openssl/ripemd.h (renamed from src/crypto/asn1/t_pkey.c)95
-rw-r--r--src/include/openssl/rsa.h170
-rw-r--r--src/include/openssl/ssl.h234
-rw-r--r--src/include/openssl/thread.h4
-rw-r--r--src/include/openssl/time_support.h1
-rw-r--r--src/include/openssl/tls1.h2
-rw-r--r--src/include/openssl/x509.h52
-rw-r--r--src/include/openssl/x509_vfy.h6
-rw-r--r--src/include/openssl/x509v3.h2
-rw-r--r--src/ssl/d1_both.c8
-rw-r--r--src/ssl/d1_clnt.c23
-rw-r--r--src/ssl/d1_lib.c15
-rw-r--r--src/ssl/d1_pkt.c117
-rw-r--r--src/ssl/d1_srtp.c4
-rw-r--r--src/ssl/d1_srvr.c24
-rw-r--r--src/ssl/dtls_record.c6
-rw-r--r--src/ssl/internal.h110
-rw-r--r--src/ssl/pqueue/pqueue.c4
-rw-r--r--src/ssl/s3_both.c49
-rw-r--r--src/ssl/s3_clnt.c221
-rw-r--r--src/ssl/s3_enc.c180
-rw-r--r--src/ssl/s3_lib.c70
-rw-r--r--src/ssl/s3_pkt.c168
-rw-r--r--src/ssl/s3_srvr.c109
-rw-r--r--src/ssl/ssl_aead_ctx.c20
-rw-r--r--src/ssl/ssl_buffer.c12
-rw-r--r--src/ssl/ssl_cert.c55
-rw-r--r--src/ssl/ssl_cipher.c31
-rw-r--r--src/ssl/ssl_ecdh.c32
-rw-r--r--src/ssl/ssl_file.c48
-rw-r--r--src/ssl/ssl_lib.c295
-rw-r--r--src/ssl/ssl_rsa.c5
-rw-r--r--src/ssl/ssl_session.c40
-rw-r--r--src/ssl/ssl_test.cc649
-rw-r--r--src/ssl/t1_enc.c362
-rw-r--r--src/ssl/t1_lib.c221
-rw-r--r--src/ssl/test/bssl_shim.cc118
-rw-r--r--src/ssl/test/runner/alert.go1
-rw-r--r--src/ssl/test/runner/common.go20
-rw-r--r--src/ssl/test/runner/conn.go10
-rw-r--r--src/ssl/test/runner/handshake_client.go22
-rw-r--r--src/ssl/test/runner/handshake_messages.go2
-rw-r--r--src/ssl/test/runner/handshake_server.go25
-rw-r--r--src/ssl/test/runner/key_agreement.go9
-rw-r--r--src/ssl/test/runner/prf.go2
-rw-r--r--src/ssl/test/runner/recordingconn.go11
-rw-r--r--src/ssl/test/runner/runner.go315
-rw-r--r--src/ssl/test/test_config.cc5
-rw-r--r--src/ssl/test/test_config.h2
-rw-r--r--src/ssl/tls_record.c69
-rw-r--r--src/tool/digest.cc2
-rw-r--r--src/tool/internal.h15
-rw-r--r--src/tool/rand.cc2
-rw-r--r--src/tool/speed.cc83
-rw-r--r--src/tool/tool.cc17
-rw-r--r--src/tool/transport_common.cc15
-rw-r--r--src/util/all_tests.go62
-rw-r--r--src/util/all_tests.json9
-rw-r--r--src/util/bot/DEPS2
-rw-r--r--src/util/bot/UPDATING46
-rw-r--r--src/util/bot/cmake-linux64.tar.gz.sha12
-rw-r--r--src/util/bot/cmake-mac.tar.gz.sha12
-rw-r--r--src/util/bot/cmake-win32.zip.sha12
-rwxr-xr-xsrc/util/bot/go/bootstrap.py2
-rw-r--r--src/util/bot/perl-win32.zip.sha12
-rw-r--r--src/util/bot/update_clang.py2
-rw-r--r--src/util/bot/vs_toolchain.py2
-rw-r--r--src/util/doc.config2
-rw-r--r--src/util/doc.go21
-rwxr-xr-xsrc/util/generate-asm-lcov.py152
-rwxr-xr-xsrc/util/generate-coverage.sh60
-rw-r--r--src/util/generate_build_files.py245
-rw-r--r--src/util/run_android_tests.go211
-rw-r--r--win-x86/crypto/chacha/chacha-x86.asm997
-rw-r--r--win-x86/crypto/rc4/rc4-586.asm29
-rw-r--r--win-x86_64/crypto/bn/rsaz-x86_64.asm291
-rw-r--r--win-x86_64/crypto/bn/x86_64-mont.asm108
-rw-r--r--win-x86_64/crypto/bn/x86_64-mont5.asm933
-rw-r--r--win-x86_64/crypto/chacha/chacha-x86_64.asm1689
-rw-r--r--win-x86_64/crypto/ec/p256-x86_64-asm.asm11
528 files changed, 71965 insertions, 44309 deletions
diff --git a/BORINGSSL_REVISION b/BORINGSSL_REVISION
index 6e9fe824..87ea6cce 100644
--- a/BORINGSSL_REVISION
+++ b/BORINGSSL_REVISION
@@ -1 +1 @@
-7b8b9c17db93ea5287575b437c77fb36eeb81b31
+d18cb77864dcc4b5c7cb08c2331008c01165f34f
diff --git a/android_compat_hacks.c b/android_compat_hacks.c
index cf4863de..a3f032ec 100644
--- a/android_compat_hacks.c
+++ b/android_compat_hacks.c
@@ -18,40 +18,10 @@
* The declarations for these functions are in the main BoringSSL headers but
* the only definitions are here, in Android land. */
-#include <openssl/base.h>
-
-#include <assert.h>
-
-#include <openssl/bn.h>
-#include <openssl/cipher.h>
-#include <openssl/err.h>
#include <openssl/ssl.h>
+#include <stdlib.h>
-BIGNUM *get_rfc3526_prime_1536(BIGNUM *bn) {
- assert(bn == NULL);
-
- static const uint8_t data[] = {
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
- 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
- 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
- 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
- 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
- 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
- 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
- 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
- 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
- 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
- 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
- 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
- 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
- 0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
- 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
- 0xCA, 0x23, 0x73, 0x27, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- };
-
- return BN_bin2bn(data, sizeof(data), NULL);
-}
int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len) {
return 0;
diff --git a/err_data.c b/err_data.c
index fe7979b4..f66cb28e 100644
--- a/err_data.c
+++ b/err_data.c
@@ -54,178 +54,163 @@ OPENSSL_COMPILE_ASSERT(ERR_LIB_USER == 32, library_values_changed_32);
OPENSSL_COMPILE_ASSERT(ERR_NUM_LIBS == 33, library_values_changed_num);
const uint32_t kOpenSSLReasonValues[] = {
- 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,
+ 0xc320838,
+ 0xc328852,
+ 0xc330861,
+ 0xc338871,
+ 0xc340880,
+ 0xc348899,
+ 0xc3508a5,
+ 0xc3588c2,
+ 0xc3608d4,
+ 0xc3688e2,
+ 0xc3708f2,
+ 0xc3788ff,
+ 0xc38090f,
+ 0xc38891a,
+ 0xc390930,
+ 0xc39893f,
+ 0xc3a0953,
+ 0xc3a8845,
+ 0xc3b00ea,
+ 0x10320845,
+ 0x1032939a,
+ 0x103313a6,
+ 0x103393bf,
+ 0x103413d2,
+ 0x10348e7a,
+ 0x10350c19,
+ 0x103593e5,
+ 0x103613fa,
+ 0x1036940d,
+ 0x1037142c,
+ 0x10379445,
+ 0x1038145a,
+ 0x10389478,
+ 0x10391487,
+ 0x103994a3,
+ 0x103a14be,
+ 0x103a94cd,
+ 0x103b14e9,
+ 0x103b9504,
+ 0x103c151b,
+ 0x103c80ea,
+ 0x103d152c,
+ 0x103d9540,
+ 0x103e155f,
+ 0x103e956e,
+ 0x103f1585,
+ 0x103f9598,
+ 0x10400bea,
+ 0x104095ab,
+ 0x104115c9,
+ 0x104195dc,
+ 0x104215f6,
+ 0x10429606,
+ 0x1043161a,
+ 0x10439630,
+ 0x10441648,
+ 0x1044965d,
+ 0x10451671,
+ 0x10459683,
+ 0x104605fb,
+ 0x1046893f,
+ 0x10471698,
+ 0x104796af,
+ 0x104816c4,
+ 0x104896d2,
+ 0x14320bcd,
+ 0x14328bdb,
+ 0x14330bea,
+ 0x14338bfc,
0x18320083,
- 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,
- 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,
- 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,
+ 0x18328ed0,
+ 0x183300ac,
+ 0x18338ee6,
+ 0x18340efa,
+ 0x183480ea,
+ 0x18350f0f,
+ 0x18358f27,
+ 0x18360f3c,
+ 0x18368f50,
+ 0x18370f74,
+ 0x18378f8a,
+ 0x18380f9e,
+ 0x18388fae,
+ 0x18390a57,
+ 0x18398fbe,
+ 0x183a0fd3,
+ 0x183a8fe7,
+ 0x183b0c25,
+ 0x183b8ff4,
+ 0x183c1006,
+ 0x183c9011,
+ 0x183d1021,
+ 0x183d9032,
+ 0x183e1043,
+ 0x183e9055,
+ 0x183f107e,
+ 0x183f9097,
+ 0x184010af,
+ 0x184086d3,
+ 0x203210d6,
+ 0x243210e2,
+ 0x24328985,
+ 0x243310f4,
+ 0x24339101,
+ 0x2434110e,
+ 0x24349120,
+ 0x2435112f,
+ 0x2435914c,
+ 0x24361159,
+ 0x24369167,
+ 0x24371175,
+ 0x24379183,
+ 0x2438118c,
+ 0x24389199,
+ 0x243911ac,
+ 0x28320c0d,
+ 0x28328c25,
+ 0x28330bea,
+ 0x28338c38,
+ 0x28340c19,
+ 0x283480ac,
+ 0x283500ea,
+ 0x2c32274a,
+ 0x2c32a758,
+ 0x2c33276a,
+ 0x2c33a77c,
+ 0x2c342790,
+ 0x2c34a7a2,
+ 0x2c3527bd,
+ 0x2c35a7cf,
+ 0x2c3627e2,
+ 0x2c36832d,
+ 0x2c3727ef,
+ 0x2c37a801,
+ 0x2c382814,
+ 0x2c38a82b,
+ 0x2c392839,
+ 0x2c39a849,
+ 0x2c3a285b,
+ 0x2c3aa86f,
+ 0x2c3b2880,
+ 0x2c3ba891,
+ 0x2c3c28a5,
+ 0x2c3ca8bb,
+ 0x2c3d28d4,
+ 0x2c3da8f1,
+ 0x2c3e2902,
+ 0x2c3ea910,
+ 0x2c3f2928,
+ 0x2c3fa940,
+ 0x2c40294d,
+ 0x2c4090d6,
+ 0x2c41295e,
+ 0x2c41a971,
+ 0x2c4210af,
+ 0x2c42a982,
+ 0x2c430720,
0x30320000,
0x30328015,
0x3033001f,
@@ -235,440 +220,449 @@ const uint32_t kOpenSSLReasonValues[] = {
0x3035006b,
0x30358083,
0x30360094,
- 0x303680a1,
- 0x303700b0,
- 0x303780bd,
- 0x303800d0,
- 0x303880eb,
- 0x30390100,
- 0x30398114,
- 0x303a0128,
- 0x303a8139,
- 0x303b0152,
- 0x303b816f,
- 0x303c017d,
- 0x303c8191,
- 0x303d01a1,
- 0x303d81ba,
- 0x303e01ca,
- 0x303e81dd,
- 0x303f01ec,
- 0x303f81f8,
- 0x3040020d,
- 0x3040821d,
- 0x30410234,
- 0x30418241,
- 0x30420254,
- 0x30428263,
- 0x30430278,
- 0x30438299,
- 0x304402ac,
- 0x304482bf,
- 0x304502d8,
- 0x304582f3,
- 0x30460310,
- 0x30468329,
- 0x30470337,
- 0x30478348,
- 0x30480357,
- 0x3048836f,
- 0x30490381,
- 0x30498395,
- 0x304a03b4,
- 0x304a83c7,
- 0x304b03d2,
- 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,
- 0x305a0621,
- 0x305a8630,
- 0x305b063c,
- 0x305b865c,
- 0x305c0678,
- 0x305c8689,
- 0x305d0693,
- 0x34320aba,
- 0x34328ace,
- 0x34330aeb,
- 0x34338afe,
- 0x34340b0d,
- 0x34348b2a,
+ 0x303680ac,
+ 0x303700b9,
+ 0x303780c8,
+ 0x303800ea,
+ 0x303880f7,
+ 0x3039010a,
+ 0x30398125,
+ 0x303a013a,
+ 0x303a814e,
+ 0x303b0162,
+ 0x303b8173,
+ 0x303c018c,
+ 0x303c81a9,
+ 0x303d01b7,
+ 0x303d81cb,
+ 0x303e01db,
+ 0x303e81f4,
+ 0x303f0204,
+ 0x303f8217,
+ 0x30400226,
+ 0x30408232,
+ 0x30410247,
+ 0x30418257,
+ 0x3042026e,
+ 0x3042827b,
+ 0x3043028e,
+ 0x3043829d,
+ 0x304402b2,
+ 0x304482d3,
+ 0x304502e6,
+ 0x304582f9,
+ 0x30460312,
+ 0x3046832d,
+ 0x3047034a,
+ 0x30478363,
+ 0x30480371,
+ 0x30488382,
+ 0x30490391,
+ 0x304983a9,
+ 0x304a03bb,
+ 0x304a83cf,
+ 0x304b03ee,
+ 0x304b8401,
+ 0x304c040c,
+ 0x304c841d,
+ 0x304d0429,
+ 0x304d843f,
+ 0x304e044d,
+ 0x304e8463,
+ 0x304f0475,
+ 0x304f8487,
+ 0x3050049a,
+ 0x305084ad,
+ 0x305104be,
+ 0x305184ce,
+ 0x305204e6,
+ 0x305284fb,
+ 0x30530513,
+ 0x30538527,
+ 0x3054053f,
+ 0x30548558,
+ 0x30550571,
+ 0x3055858e,
+ 0x30560599,
+ 0x305685b1,
+ 0x305705c1,
+ 0x305785d2,
+ 0x305805e5,
+ 0x305885fb,
+ 0x30590604,
+ 0x30598619,
+ 0x305a062c,
+ 0x305a863b,
+ 0x305b065b,
+ 0x305b866a,
+ 0x305c068b,
+ 0x305c86a7,
+ 0x305d06b3,
+ 0x305d86d3,
+ 0x305e06ef,
+ 0x305e8700,
+ 0x305f0716,
+ 0x305f8720,
+ 0x34320b47,
+ 0x34328b5b,
+ 0x34330b78,
+ 0x34338b8b,
+ 0x34340b9a,
+ 0x34348bb7,
0x3c320083,
- 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,
+ 0x3c328c62,
+ 0x3c330c7b,
+ 0x3c338c96,
+ 0x3c340cb3,
+ 0x3c348cdd,
+ 0x3c350cf8,
+ 0x3c358d0d,
+ 0x3c360d26,
+ 0x3c368d3e,
+ 0x3c370d4f,
+ 0x3c378d5d,
+ 0x3c380d6a,
+ 0x3c388d7e,
+ 0x3c390c25,
+ 0x3c398d92,
+ 0x3c3a0da6,
+ 0x3c3a88ff,
+ 0x3c3b0db6,
+ 0x3c3b8dd1,
+ 0x3c3c0de3,
+ 0x3c3c8df9,
+ 0x3c3d0e03,
+ 0x3c3d8e17,
+ 0x3c3e0e25,
+ 0x3c3e8e4a,
+ 0x3c3f0c4e,
+ 0x3c3f8e33,
+ 0x3c4000ac,
+ 0x3c4080ea,
+ 0x3c410cce,
+ 0x403216e9,
+ 0x403296ff,
+ 0x4033172d,
+ 0x40339737,
+ 0x4034174e,
+ 0x4034976c,
+ 0x4035177c,
+ 0x4035978e,
+ 0x4036179b,
+ 0x403697a7,
+ 0x403717bc,
+ 0x403797ce,
+ 0x403817d9,
+ 0x403897eb,
+ 0x40390e7a,
+ 0x403997fb,
+ 0x403a180e,
+ 0x403a982f,
+ 0x403b1840,
+ 0x403b9850,
0x403c0064,
0x403c8083,
- 0x403d1937,
- 0x403d994d,
- 0x403e195c,
- 0x403e996f,
- 0x403f1989,
- 0x403f9997,
- 0x404019ac,
- 0x404099c0,
- 0x404119dd,
- 0x404199f8,
- 0x40421a11,
- 0x40429a24,
- 0x40431a38,
- 0x40439a50,
- 0x40441a67,
- 0x40448094,
- 0x40451a7c,
- 0x40459a8e,
- 0x40461ab2,
- 0x40469ad2,
- 0x40471ae0,
- 0x40479af4,
- 0x40481b09,
- 0x40489b22,
- 0x40491b39,
- 0x40499b53,
- 0x404a1b6a,
- 0x404a9b88,
- 0x404b1ba0,
- 0x404b9bb7,
- 0x404c1bcd,
- 0x404c9bdf,
- 0x404d1c00,
- 0x404d9c22,
- 0x404e1c36,
- 0x404e9c43,
- 0x404f1c5a,
- 0x404f9c6a,
- 0x40501c7a,
- 0x40509c8e,
- 0x40511ca9,
- 0x40519cb9,
- 0x40521cd0,
- 0x40529ce2,
- 0x40531cfa,
- 0x40539d0d,
- 0x40541d22,
- 0x40549d45,
- 0x40551d53,
- 0x40559d70,
- 0x40561d7d,
- 0x40569d96,
- 0x40571dae,
- 0x40579dc1,
- 0x40581dd6,
- 0x40589de8,
- 0x40591df8,
- 0x40599e11,
- 0x405a1e25,
- 0x405a9e35,
- 0x405b1e4d,
- 0x405b9e5e,
- 0x405c1e71,
- 0x405c9e82,
- 0x405d1e8f,
- 0x405d9ea6,
- 0x405e1ec6,
- 0x405e8a08,
- 0x405f1ee7,
- 0x405f9ef4,
- 0x40601f02,
- 0x40609f24,
- 0x40611f4c,
- 0x40619f61,
- 0x40621f78,
- 0x40629f89,
- 0x40631f9a,
- 0x40639faf,
- 0x40641fc6,
- 0x40649fd7,
- 0x40651ff2,
- 0x4065a009,
- 0x40662021,
- 0x4066a04b,
- 0x40672076,
- 0x4067a097,
- 0x406820aa,
- 0x4068a0cb,
- 0x406920e6,
- 0x4069a114,
- 0x406a2135,
- 0x406aa155,
- 0x406b22dd,
- 0x406ba300,
- 0x406c2316,
- 0x406ca542,
- 0x406d2571,
- 0x406da599,
- 0x406e25b2,
- 0x406ea5ca,
- 0x406f25e9,
- 0x406fa5fe,
- 0x40702611,
- 0x4070a62e,
- 0x40710773,
- 0x4071a640,
- 0x40722653,
- 0x4072a66c,
- 0x40732684,
- 0x407390ae,
- 0x40742698,
- 0x4074a6b2,
- 0x407526c3,
- 0x4075a6d7,
- 0x407626e5,
- 0x40769277,
- 0x4077270a,
- 0x4077a72c,
- 0x40782747,
- 0x4078a75c,
- 0x40792773,
- 0x4079a789,
- 0x407a2795,
- 0x407aa7a8,
- 0x407b27bd,
- 0x407ba7cf,
- 0x407c27e4,
- 0x407ca7ed,
- 0x41f42208,
- 0x41f9229a,
- 0x41fe218d,
- 0x41fea369,
- 0x41ff245a,
- 0x42032221,
- 0x42082243,
- 0x4208a27f,
- 0x42092171,
- 0x4209a2b9,
- 0x420a21c8,
- 0x420aa1a8,
- 0x420b21e8,
- 0x420ba261,
- 0x420c2476,
- 0x420ca336,
- 0x420d2350,
- 0x420da387,
- 0x421223a1,
- 0x4217243d,
- 0x4217a3e3,
- 0x421c2405,
- 0x421f23c0,
- 0x4221248d,
- 0x42262420,
- 0x422b2526,
- 0x422ba4ef,
- 0x422c250e,
- 0x422ca4c9,
- 0x422d24a8,
- 0x4432069e,
- 0x443286ad,
- 0x443306b9,
- 0x443386c7,
- 0x443406da,
- 0x443486eb,
- 0x443506f2,
- 0x443586fc,
- 0x4436070f,
- 0x44368725,
- 0x44370737,
- 0x44378744,
- 0x44380753,
- 0x4438875b,
- 0x44390773,
- 0x44398781,
- 0x443a0794,
- 0x4c3212a1,
- 0x4c3292b1,
- 0x4c3312c4,
- 0x4c3392e4,
- 0x4c340094,
- 0x4c3480b0,
- 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,
- 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,
+ 0x403d185c,
+ 0x403d9872,
+ 0x403e1881,
+ 0x403e9894,
+ 0x403f18ae,
+ 0x403f98bc,
+ 0x404018d1,
+ 0x404098e5,
+ 0x40411902,
+ 0x4041991d,
+ 0x40421936,
+ 0x40429949,
+ 0x4043195d,
+ 0x40439975,
+ 0x4044198c,
+ 0x404480ac,
+ 0x404519a1,
+ 0x404599b3,
+ 0x404619d7,
+ 0x404699f7,
+ 0x40471a05,
+ 0x40479a19,
+ 0x40481a2e,
+ 0x40489a47,
+ 0x40491a5e,
+ 0x40499a78,
+ 0x404a1a8f,
+ 0x404a9aad,
+ 0x404b1ac5,
+ 0x404b9adc,
+ 0x404c1af2,
+ 0x404c9b04,
+ 0x404d1b25,
+ 0x404d9b47,
+ 0x404e1b5b,
+ 0x404e9b68,
+ 0x404f1b7f,
+ 0x404f9b8f,
+ 0x40501b9f,
+ 0x40509bb3,
+ 0x40511bce,
+ 0x40519bde,
+ 0x40521bf5,
+ 0x40529c07,
+ 0x40531c1f,
+ 0x40539c32,
+ 0x40541c47,
+ 0x40549c6a,
+ 0x40551c78,
+ 0x40559c95,
+ 0x40561ca2,
+ 0x40569cbb,
+ 0x40571cd3,
+ 0x40579ce6,
+ 0x40581cfb,
+ 0x40589d0d,
+ 0x40591d1d,
+ 0x40599d36,
+ 0x405a1d4a,
+ 0x405a9d5a,
+ 0x405b1d72,
+ 0x405b9d83,
+ 0x405c1d96,
+ 0x405c9da7,
+ 0x405d1db4,
+ 0x405d9dcb,
+ 0x405e1deb,
+ 0x405e8a95,
+ 0x405f1e0c,
+ 0x405f9e19,
+ 0x40601e27,
+ 0x40609e49,
+ 0x40611e71,
+ 0x40619e86,
+ 0x40621e9d,
+ 0x40629eae,
+ 0x40631ebf,
+ 0x40639ed4,
+ 0x40641eeb,
+ 0x40649efc,
+ 0x40651f17,
+ 0x40659f2e,
+ 0x40661f46,
+ 0x40669f70,
+ 0x40671f9b,
+ 0x40679fbc,
+ 0x40681fcf,
+ 0x40689ff0,
+ 0x40692022,
+ 0x4069a050,
+ 0x406a2071,
+ 0x406aa091,
+ 0x406b2219,
+ 0x406ba23c,
+ 0x406c2252,
+ 0x406ca47e,
+ 0x406d24ad,
+ 0x406da4d5,
+ 0x406e24ee,
+ 0x406ea506,
+ 0x406f2525,
+ 0x406fa53a,
+ 0x4070254d,
+ 0x4070a56a,
+ 0x40710800,
+ 0x4071a57c,
+ 0x4072258f,
+ 0x4072a5a8,
+ 0x407325c0,
+ 0x4073935c,
+ 0x407425d4,
+ 0x4074a5ee,
+ 0x407525ff,
+ 0x4075a613,
+ 0x40762621,
+ 0x40769199,
+ 0x40772646,
+ 0x4077a668,
+ 0x40782683,
+ 0x4078a698,
+ 0x407926af,
+ 0x4079a6c5,
+ 0x407a26d1,
+ 0x407aa6e4,
+ 0x407b26f9,
+ 0x407ba70b,
+ 0x407c2720,
+ 0x407ca729,
+ 0x407d200b,
+ 0x41f42144,
+ 0x41f921d6,
+ 0x41fe20c9,
+ 0x41fea2a5,
+ 0x41ff2396,
+ 0x4203215d,
+ 0x4208217f,
+ 0x4208a1bb,
+ 0x420920ad,
+ 0x4209a1f5,
+ 0x420a2104,
+ 0x420aa0e4,
+ 0x420b2124,
+ 0x420ba19d,
+ 0x420c23b2,
+ 0x420ca272,
+ 0x420d228c,
+ 0x420da2c3,
+ 0x421222dd,
+ 0x42172379,
+ 0x4217a31f,
+ 0x421c2341,
+ 0x421f22fc,
+ 0x422123c9,
+ 0x4226235c,
+ 0x422b2462,
+ 0x422ba42b,
+ 0x422c244a,
+ 0x422ca405,
+ 0x422d23e4,
+ 0x4432072b,
+ 0x4432873a,
+ 0x44330746,
+ 0x44338754,
+ 0x44340767,
+ 0x44348778,
+ 0x4435077f,
+ 0x44358789,
+ 0x4436079c,
+ 0x443687b2,
+ 0x443707c4,
+ 0x443787d1,
+ 0x443807e0,
+ 0x443887e8,
+ 0x44390800,
+ 0x4439880e,
+ 0x443a0821,
+ 0x4c3211c3,
+ 0x4c3291d3,
+ 0x4c3311e6,
+ 0x4c339206,
+ 0x4c3400ac,
+ 0x4c3480ea,
+ 0x4c351212,
+ 0x4c359220,
+ 0x4c36123c,
+ 0x4c36924f,
+ 0x4c37125e,
+ 0x4c37926c,
+ 0x4c381281,
+ 0x4c38928d,
+ 0x4c3912ad,
+ 0x4c3992d7,
+ 0x4c3a12f0,
+ 0x4c3a9309,
+ 0x4c3b05fb,
+ 0x4c3b9322,
+ 0x4c3c1334,
+ 0x4c3c9343,
+ 0x4c3d135c,
+ 0x4c3d936b,
+ 0x4c3e1378,
+ 0x50322994,
+ 0x5032a9a3,
+ 0x503329ae,
+ 0x5033a9be,
+ 0x503429d7,
+ 0x5034a9f1,
+ 0x503529ff,
+ 0x5035aa15,
+ 0x50362a27,
+ 0x5036aa3d,
+ 0x50372a56,
+ 0x5037aa69,
+ 0x50382a81,
+ 0x5038aa92,
+ 0x50392aa7,
+ 0x5039aabb,
+ 0x503a2adb,
+ 0x503aaaf1,
+ 0x503b2b09,
+ 0x503bab1b,
+ 0x503c2b37,
+ 0x503cab4e,
+ 0x503d2b67,
+ 0x503dab7d,
+ 0x503e2b8a,
+ 0x503eaba0,
+ 0x503f2bb2,
+ 0x503f8382,
+ 0x50402bc5,
+ 0x5040abd5,
+ 0x50412bef,
+ 0x5041abfe,
+ 0x50422c18,
+ 0x5042ac35,
+ 0x50432c45,
+ 0x5043ac55,
+ 0x50442c64,
+ 0x5044843f,
+ 0x50452c78,
+ 0x5045ac96,
+ 0x50462ca9,
+ 0x5046acbf,
+ 0x50472cd1,
+ 0x5047ace6,
+ 0x50482d0c,
+ 0x5048ad1a,
+ 0x50492d2d,
+ 0x5049ad42,
+ 0x504a2d58,
+ 0x504aad68,
+ 0x504b2d88,
+ 0x504bad9b,
+ 0x504c2dbe,
+ 0x504cadec,
+ 0x504d2dfe,
+ 0x504dae1b,
+ 0x504e2e36,
+ 0x504eae52,
+ 0x504f2e64,
+ 0x504fae7b,
+ 0x50502e8a,
+ 0x505086ef,
+ 0x50512e9d,
+ 0x58320eb8,
+ 0x68320e7a,
+ 0x68328c25,
+ 0x68330c38,
+ 0x68338e88,
+ 0x68340e98,
+ 0x683480ea,
+ 0x6c320e56,
+ 0x6c328bfc,
+ 0x6c330e61,
+ 0x74320a0b,
+ 0x78320970,
+ 0x78328985,
+ 0x78330991,
0x78338083,
- 0x78340913,
- 0x78348928,
- 0x78350947,
- 0x78358969,
- 0x7836097e,
- 0x78368994,
- 0x783709a4,
- 0x783789b7,
- 0x783809ca,
- 0x783889dc,
- 0x783909e9,
- 0x78398a08,
- 0x783a0a1d,
- 0x783a8a2b,
- 0x783b0a35,
- 0x783b8a49,
- 0x783c0a60,
- 0x783c8a75,
- 0x783d0a8c,
- 0x783d8aa1,
- 0x783e09f7,
- 0x7c3211a3,
+ 0x783409a0,
+ 0x783489b5,
+ 0x783509d4,
+ 0x783589f6,
+ 0x78360a0b,
+ 0x78368a21,
+ 0x78370a31,
+ 0x78378a44,
+ 0x78380a57,
+ 0x78388a69,
+ 0x78390a76,
+ 0x78398a95,
+ 0x783a0aaa,
+ 0x783a8ab8,
+ 0x783b0ac2,
+ 0x783b8ad6,
+ 0x783c0aed,
+ 0x783c8b02,
+ 0x783d0b19,
+ 0x783d8b2e,
+ 0x783e0a84,
+ 0x7c3210c5,
};
const size_t kOpenSSLReasonValuesLen = sizeof(kOpenSSLReasonValues) / sizeof(kOpenSSLReasonValues[0]);
@@ -682,8 +676,10 @@ const char kOpenSSLReasonStringData[] =
"BN_LIB\0"
"BOOLEAN_IS_WRONG_LENGTH\0"
"BUFFER_TOO_SMALL\0"
+ "CONTEXT_NOT_INITIALISED\0"
"DECODE_ERROR\0"
"DEPTH_EXCEEDED\0"
+ "DIGEST_AND_KEY_TYPE_NOT_SUPPORTED\0"
"ENCODE_ERROR\0"
"ERROR_GETTING_TIME\0"
"EXPECTING_AN_ASN1_SEQUENCE\0"
@@ -755,10 +751,13 @@ const char kOpenSSLReasonStringData[] =
"UNEXPECTED_EOC\0"
"UNIVERSALSTRING_IS_WRONG_LENGTH\0"
"UNKNOWN_FORMAT\0"
+ "UNKNOWN_MESSAGE_DIGEST_ALGORITHM\0"
+ "UNKNOWN_SIGNATURE_ALGORITHM\0"
"UNKNOWN_TAG\0"
"UNSUPPORTED_ANY_DEFINED_BY_TYPE\0"
"UNSUPPORTED_PUBLIC_KEY_TYPE\0"
"UNSUPPORTED_TYPE\0"
+ "WRONG_PUBLIC_KEY_TYPE\0"
"WRONG_TAG\0"
"WRONG_TYPE\0"
"BAD_FOPEN_MODE\0"
@@ -831,6 +830,7 @@ const char kOpenSSLReasonStringData[] =
"MODULUS_TOO_LARGE\0"
"NO_PRIVATE_VALUE\0"
"BAD_Q_VALUE\0"
+ "BAD_VERSION\0"
"MISSING_PARAMETERS\0"
"NEED_NEW_SETUP_VALUES\0"
"BIGNUM_OUT_OF_RANGE\0"
@@ -838,6 +838,7 @@ const char kOpenSSLReasonStringData[] =
"D2I_ECPKPARAMETERS_FAILURE\0"
"EC_GROUP_NEW_BY_NAME_FAILURE\0"
"GROUP2PKPARAMETERS_FAILURE\0"
+ "GROUP_MISMATCH\0"
"I2D_ECPKPARAMETERS_FAILURE\0"
"INCOMPATIBLE_OBJECTS\0"
"INVALID_COMPRESSED_POINT\0"
@@ -864,27 +865,19 @@ const char kOpenSSLReasonStringData[] =
"NOT_IMPLEMENTED\0"
"RANDOM_NUMBER_GENERATION_FAILED\0"
"OPERATION_NOT_SUPPORTED\0"
- "BN_DECODE_ERROR\0"
"COMMAND_NOT_SUPPORTED\0"
- "CONTEXT_NOT_INITIALISED\0"
"DIFFERENT_KEY_TYPES\0"
"DIFFERENT_PARAMETERS\0"
- "DIGEST_AND_KEY_TYPE_NOT_SUPPORTED\0"
"EXPECTING_AN_EC_KEY_KEY\0"
"EXPECTING_AN_RSA_KEY\0"
- "EXPECTING_A_DH_KEY\0"
"EXPECTING_A_DSA_KEY\0"
"ILLEGAL_OR_UNSUPPORTED_PADDING_MODE\0"
- "INVALID_CURVE\0"
"INVALID_DIGEST_LENGTH\0"
"INVALID_DIGEST_TYPE\0"
"INVALID_KEYBITS\0"
"INVALID_MGF1_MD\0"
"INVALID_PADDING_MODE\0"
- "INVALID_PSS_PARAMETERS\0"
"INVALID_PSS_SALTLEN\0"
- "INVALID_SALT_LENGTH\0"
- "INVALID_TRAILER\0"
"KEYS_NOT_SET\0"
"NO_DEFAULT_DIGEST\0"
"NO_KEY_SET\0"
@@ -894,17 +887,8 @@ const char kOpenSSLReasonStringData[] =
"NO_PARAMETERS_SET\0"
"OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE\0"
"OPERATON_NOT_INITIALIZED\0"
- "PARAMETER_ENCODING_ERROR\0"
- "UNKNOWN_DIGEST\0"
- "UNKNOWN_MASK_DIGEST\0"
- "UNKNOWN_MESSAGE_DIGEST_ALGORITHM\0"
"UNKNOWN_PUBLIC_KEY_TYPE\0"
- "UNKNOWN_SIGNATURE_ALGORITHM\0"
"UNSUPPORTED_ALGORITHM\0"
- "UNSUPPORTED_MASK_ALGORITHM\0"
- "UNSUPPORTED_MASK_PARAMETER\0"
- "UNSUPPORTED_SIGNATURE_TYPE\0"
- "WRONG_PUBLIC_KEY_TYPE\0"
"OUTPUT_TOO_LARGE\0"
"UNKNOWN_NID\0"
"BAD_BASE64_DECODE\0"
@@ -940,13 +924,13 @@ const char kOpenSSLReasonStringData[] =
"UNKNOWN_ALGORITHM\0"
"UNKNOWN_CIPHER\0"
"UNKNOWN_CIPHER_ALGORITHM\0"
+ "UNKNOWN_DIGEST\0"
"UNKNOWN_HASH\0"
"UNSUPPORTED_PRIVATE_KEY_ALGORITHM\0"
"BAD_E_VALUE\0"
"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"
@@ -1087,6 +1071,7 @@ const char kOpenSSLReasonStringData[] =
"SERVERHELLO_TLSEXT\0"
"SESSION_ID_CONTEXT_UNINITIALIZED\0"
"SESSION_MAY_NOT_BE_CREATED\0"
+ "SHUTDOWN_WHILE_IN_INIT\0"
"SIGNATURE_ALGORITHMS_EXTENSION_SENT_BY_SERVER\0"
"SRTP_COULD_NOT_ALLOCATE_PROFILES\0"
"SRTP_UNKNOWN_PROTECTION_PROFILE\0"
@@ -1165,6 +1150,7 @@ const char kOpenSSLReasonStringData[] =
"IDP_MISMATCH\0"
"INVALID_DIRECTORY\0"
"INVALID_FIELD_NAME\0"
+ "INVALID_PSS_PARAMETERS\0"
"INVALID_TRUST\0"
"ISSUER_MISMATCH\0"
"KEY_TYPE_MISMATCH\0"
@@ -1180,8 +1166,6 @@ const char kOpenSSLReasonStringData[] =
"PUBLIC_KEY_DECODE_ERROR\0"
"PUBLIC_KEY_ENCODE_ERROR\0"
"SHOULD_RETRY\0"
- "UNABLE_TO_FIND_PARAMETERS_IN_CHAIN\0"
- "UNABLE_TO_GET_CERTS_PUBLIC_KEY\0"
"UNKNOWN_KEY_TYPE\0"
"UNKNOWN_PURPOSE_ID\0"
"UNKNOWN_TRUST_ID\0"
diff --git a/linux-aarch64/crypto/aes/aesv8-armx64.S b/linux-aarch64/crypto/aes/aesv8-armx64.S
index fa2abbcc..3e8cb16e 100644
--- a/linux-aarch64/crypto/aes/aesv8-armx64.S
+++ b/linux-aarch64/crypto/aes/aesv8-armx64.S
@@ -13,6 +13,7 @@
.long 0x1b,0x1b,0x1b,0x1b
.globl aes_v8_set_encrypt_key
+.hidden aes_v8_set_encrypt_key
.type aes_v8_set_encrypt_key,%function
.align 5
aes_v8_set_encrypt_key:
@@ -180,6 +181,7 @@ aes_v8_set_encrypt_key:
.size aes_v8_set_encrypt_key,.-aes_v8_set_encrypt_key
.globl aes_v8_set_decrypt_key
+.hidden aes_v8_set_decrypt_key
.type aes_v8_set_decrypt_key,%function
.align 5
aes_v8_set_decrypt_key:
@@ -219,6 +221,7 @@ aes_v8_set_decrypt_key:
ret
.size aes_v8_set_decrypt_key,.-aes_v8_set_decrypt_key
.globl aes_v8_encrypt
+.hidden aes_v8_encrypt
.type aes_v8_encrypt,%function
.align 5
aes_v8_encrypt:
@@ -248,6 +251,7 @@ aes_v8_encrypt:
ret
.size aes_v8_encrypt,.-aes_v8_encrypt
.globl aes_v8_decrypt
+.hidden aes_v8_decrypt
.type aes_v8_decrypt,%function
.align 5
aes_v8_decrypt:
@@ -277,6 +281,7 @@ aes_v8_decrypt:
ret
.size aes_v8_decrypt,.-aes_v8_decrypt
.globl aes_v8_cbc_encrypt
+.hidden aes_v8_cbc_encrypt
.type aes_v8_cbc_encrypt,%function
.align 5
aes_v8_cbc_encrypt:
@@ -567,6 +572,7 @@ aes_v8_cbc_encrypt:
ret
.size aes_v8_cbc_encrypt,.-aes_v8_cbc_encrypt
.globl aes_v8_ctr32_encrypt_blocks
+.hidden aes_v8_ctr32_encrypt_blocks
.type aes_v8_ctr32_encrypt_blocks,%function
.align 5
aes_v8_ctr32_encrypt_blocks:
@@ -748,4 +754,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
+#endif
diff --git a/linux-aarch64/crypto/bn/armv8-mont.S b/linux-aarch64/crypto/bn/armv8-mont.S
index 9355ce79..74702db6 100644
--- a/linux-aarch64/crypto/bn/armv8-mont.S
+++ b/linux-aarch64/crypto/bn/armv8-mont.S
@@ -2,6 +2,7 @@
.text
.globl bn_mul_mont
+.hidden bn_mul_mont
.type bn_mul_mont,%function
.align 5
bn_mul_mont:
@@ -1403,4 +1404,4 @@ __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
+#endif
diff --git a/linux-aarch64/crypto/chacha/chacha-armv8.S b/linux-aarch64/crypto/chacha/chacha-armv8.S
new file mode 100644
index 00000000..6ff6bffb
--- /dev/null
+++ b/linux-aarch64/crypto/chacha/chacha-armv8.S
@@ -0,0 +1,1971 @@
+#if defined(__aarch64__)
+#include <openssl/arm_arch.h>
+
+.text
+
+
+
+.align 5
+.Lsigma:
+.quad 0x3320646e61707865,0x6b20657479622d32 // endian-neutral
+.Lone:
+.long 1,0,0,0
+.LOPENSSL_armcap_P:
+#ifdef __ILP32__
+.long OPENSSL_armcap_P-.
+#else
+.quad OPENSSL_armcap_P-.
+#endif
+.byte 67,104,97,67,104,97,50,48,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+.align 2
+
+.globl ChaCha20_ctr32
+.hidden ChaCha20_ctr32
+.type ChaCha20_ctr32,%function
+.align 5
+ChaCha20_ctr32:
+ cbz x2,.Labort
+ adr x5,.LOPENSSL_armcap_P
+ cmp x2,#192
+ b.lo .Lshort
+#ifdef __ILP32__
+ ldrsw x6,[x5]
+#else
+ ldr x6,[x5]
+#endif
+ ldr w17,[x6,x5]
+ tst w17,#ARMV7_NEON
+ b.ne ChaCha20_neon
+
+.Lshort:
+ stp x29,x30,[sp,#-96]!
+ add x29,sp,#0
+
+ adr x5,.Lsigma
+ stp x19,x20,[sp,#16]
+ stp x21,x22,[sp,#32]
+ stp x23,x24,[sp,#48]
+ stp x25,x26,[sp,#64]
+ stp x27,x28,[sp,#80]
+ sub sp,sp,#64
+
+ ldp x22,x23,[x5] // load sigma
+ ldp x24,x25,[x3] // load key
+ ldp x26,x27,[x3,#16]
+ ldp x28,x30,[x4] // load counter
+#ifdef __ARMEB__
+ ror x24,x24,#32
+ ror x25,x25,#32
+ ror x26,x26,#32
+ ror x27,x27,#32
+ ror x28,x28,#32
+ ror x30,x30,#32
+#endif
+
+.Loop_outer:
+ mov w5,w22 // unpack key block
+ lsr x6,x22,#32
+ mov w7,w23
+ lsr x8,x23,#32
+ mov w9,w24
+ lsr x10,x24,#32
+ mov w11,w25
+ lsr x12,x25,#32
+ mov w13,w26
+ lsr x14,x26,#32
+ mov w15,w27
+ lsr x16,x27,#32
+ mov w17,w28
+ lsr x19,x28,#32
+ mov w20,w30
+ lsr x21,x30,#32
+
+ mov x4,#10
+ subs x2,x2,#64
+.Loop:
+ sub x4,x4,#1
+ add w5,w5,w9
+ add w6,w6,w10
+ add w7,w7,w11
+ add w8,w8,w12
+ eor w17,w17,w5
+ eor w19,w19,w6
+ eor w20,w20,w7
+ eor w21,w21,w8
+ ror w17,w17,#16
+ ror w19,w19,#16
+ ror w20,w20,#16
+ ror w21,w21,#16
+ add w13,w13,w17
+ add w14,w14,w19
+ add w15,w15,w20
+ add w16,w16,w21
+ eor w9,w9,w13
+ eor w10,w10,w14
+ eor w11,w11,w15
+ eor w12,w12,w16
+ ror w9,w9,#20
+ ror w10,w10,#20
+ ror w11,w11,#20
+ ror w12,w12,#20
+ add w5,w5,w9
+ add w6,w6,w10
+ add w7,w7,w11
+ add w8,w8,w12
+ eor w17,w17,w5
+ eor w19,w19,w6
+ eor w20,w20,w7
+ eor w21,w21,w8
+ ror w17,w17,#24
+ ror w19,w19,#24
+ ror w20,w20,#24
+ ror w21,w21,#24
+ add w13,w13,w17
+ add w14,w14,w19
+ add w15,w15,w20
+ add w16,w16,w21
+ eor w9,w9,w13
+ eor w10,w10,w14
+ eor w11,w11,w15
+ eor w12,w12,w16
+ ror w9,w9,#25
+ ror w10,w10,#25
+ ror w11,w11,#25
+ ror w12,w12,#25
+ add w5,w5,w10
+ add w6,w6,w11
+ add w7,w7,w12
+ add w8,w8,w9
+ eor w21,w21,w5
+ eor w17,w17,w6
+ eor w19,w19,w7
+ eor w20,w20,w8
+ ror w21,w21,#16
+ ror w17,w17,#16
+ ror w19,w19,#16
+ ror w20,w20,#16
+ add w15,w15,w21
+ add w16,w16,w17
+ add w13,w13,w19
+ add w14,w14,w20
+ eor w10,w10,w15
+ eor w11,w11,w16
+ eor w12,w12,w13
+ eor w9,w9,w14
+ ror w10,w10,#20
+ ror w11,w11,#20
+ ror w12,w12,#20
+ ror w9,w9,#20
+ add w5,w5,w10
+ add w6,w6,w11
+ add w7,w7,w12
+ add w8,w8,w9
+ eor w21,w21,w5
+ eor w17,w17,w6
+ eor w19,w19,w7
+ eor w20,w20,w8
+ ror w21,w21,#24
+ ror w17,w17,#24
+ ror w19,w19,#24
+ ror w20,w20,#24
+ add w15,w15,w21
+ add w16,w16,w17
+ add w13,w13,w19
+ add w14,w14,w20
+ eor w10,w10,w15
+ eor w11,w11,w16
+ eor w12,w12,w13
+ eor w9,w9,w14
+ ror w10,w10,#25
+ ror w11,w11,#25
+ ror w12,w12,#25
+ ror w9,w9,#25
+ cbnz x4,.Loop
+
+ add w5,w5,w22 // accumulate key block
+ add x6,x6,x22,lsr#32
+ add w7,w7,w23
+ add x8,x8,x23,lsr#32
+ add w9,w9,w24
+ add x10,x10,x24,lsr#32
+ add w11,w11,w25
+ add x12,x12,x25,lsr#32
+ add w13,w13,w26
+ add x14,x14,x26,lsr#32
+ add w15,w15,w27
+ add x16,x16,x27,lsr#32
+ add w17,w17,w28
+ add x19,x19,x28,lsr#32
+ add w20,w20,w30
+ add x21,x21,x30,lsr#32
+
+ b.lo .Ltail
+
+ add x5,x5,x6,lsl#32 // pack
+ add x7,x7,x8,lsl#32
+ ldp x6,x8,[x1,#0] // load input
+ add x9,x9,x10,lsl#32
+ add x11,x11,x12,lsl#32
+ ldp x10,x12,[x1,#16]
+ add x13,x13,x14,lsl#32
+ add x15,x15,x16,lsl#32
+ ldp x14,x16,[x1,#32]
+ add x17,x17,x19,lsl#32
+ add x20,x20,x21,lsl#32
+ ldp x19,x21,[x1,#48]
+ add x1,x1,#64
+#ifdef __ARMEB__
+ rev x5,x5
+ rev x7,x7
+ rev x9,x9
+ rev x11,x11
+ rev x13,x13
+ rev x15,x15
+ rev x17,x17
+ rev x20,x20
+#endif
+ eor x5,x5,x6
+ eor x7,x7,x8
+ eor x9,x9,x10
+ eor x11,x11,x12
+ eor x13,x13,x14
+ eor x15,x15,x16
+ eor x17,x17,x19
+ eor x20,x20,x21
+
+ stp x5,x7,[x0,#0] // store output
+ add x28,x28,#1 // increment counter
+ stp x9,x11,[x0,#16]
+ stp x13,x15,[x0,#32]
+ stp x17,x20,[x0,#48]
+ add x0,x0,#64
+
+ b.hi .Loop_outer
+
+ ldp x19,x20,[x29,#16]
+ add sp,sp,#64
+ ldp x21,x22,[x29,#32]
+ ldp x23,x24,[x29,#48]
+ ldp x25,x26,[x29,#64]
+ ldp x27,x28,[x29,#80]
+ ldp x29,x30,[sp],#96
+.Labort:
+ ret
+
+.align 4
+.Ltail:
+ add x2,x2,#64
+.Less_than_64:
+ sub x0,x0,#1
+ add x1,x1,x2
+ add x0,x0,x2
+ add x4,sp,x2
+ neg x2,x2
+
+ add x5,x5,x6,lsl#32 // pack
+ add x7,x7,x8,lsl#32
+ add x9,x9,x10,lsl#32
+ add x11,x11,x12,lsl#32
+ add x13,x13,x14,lsl#32
+ add x15,x15,x16,lsl#32
+ add x17,x17,x19,lsl#32
+ add x20,x20,x21,lsl#32
+#ifdef __ARMEB__
+ rev x5,x5
+ rev x7,x7
+ rev x9,x9
+ rev x11,x11
+ rev x13,x13
+ rev x15,x15
+ rev x17,x17
+ rev x20,x20
+#endif
+ stp x5,x7,[sp,#0]
+ stp x9,x11,[sp,#16]
+ stp x13,x15,[sp,#32]
+ stp x17,x20,[sp,#48]
+
+.Loop_tail:
+ ldrb w10,[x1,x2]
+ ldrb w11,[x4,x2]
+ add x2,x2,#1
+ eor w10,w10,w11
+ strb w10,[x0,x2]
+ cbnz x2,.Loop_tail
+
+ stp xzr,xzr,[sp,#0]
+ stp xzr,xzr,[sp,#16]
+ stp xzr,xzr,[sp,#32]
+ stp xzr,xzr,[sp,#48]
+
+ ldp x19,x20,[x29,#16]
+ add sp,sp,#64
+ ldp x21,x22,[x29,#32]
+ ldp x23,x24,[x29,#48]
+ ldp x25,x26,[x29,#64]
+ ldp x27,x28,[x29,#80]
+ ldp x29,x30,[sp],#96
+ ret
+.size ChaCha20_ctr32,.-ChaCha20_ctr32
+
+.type ChaCha20_neon,%function
+.align 5
+ChaCha20_neon:
+ stp x29,x30,[sp,#-96]!
+ add x29,sp,#0
+
+ adr x5,.Lsigma
+ stp x19,x20,[sp,#16]
+ stp x21,x22,[sp,#32]
+ stp x23,x24,[sp,#48]
+ stp x25,x26,[sp,#64]
+ stp x27,x28,[sp,#80]
+ cmp x2,#512
+ b.hs .L512_or_more_neon
+
+ sub sp,sp,#64
+
+ ldp x22,x23,[x5] // load sigma
+ ld1 {v24.4s},[x5],#16
+ ldp x24,x25,[x3] // load key
+ ldp x26,x27,[x3,#16]
+ ld1 {v25.4s,v26.4s},[x3]
+ ldp x28,x30,[x4] // load counter
+ ld1 {v27.4s},[x4]
+ ld1 {v31.4s},[x5]
+#ifdef __ARMEB__
+ rev64 v24.4s,v24.4s
+ ror x24,x24,#32
+ ror x25,x25,#32
+ ror x26,x26,#32
+ ror x27,x27,#32
+ ror x28,x28,#32
+ ror x30,x30,#32
+#endif
+ add v27.4s,v27.4s,v31.4s // += 1
+ add v28.4s,v27.4s,v31.4s
+ add v29.4s,v28.4s,v31.4s
+ shl v31.4s,v31.4s,#2 // 1 -> 4
+
+.Loop_outer_neon:
+ mov w5,w22 // unpack key block
+ lsr x6,x22,#32
+ mov v0.16b,v24.16b
+ mov w7,w23
+ lsr x8,x23,#32
+ mov v4.16b,v24.16b
+ mov w9,w24
+ lsr x10,x24,#32
+ mov v16.16b,v24.16b
+ mov w11,w25
+ mov v1.16b,v25.16b
+ lsr x12,x25,#32
+ mov v5.16b,v25.16b
+ mov w13,w26
+ mov v17.16b,v25.16b
+ lsr x14,x26,#32
+ mov v3.16b,v27.16b
+ mov w15,w27
+ mov v7.16b,v28.16b
+ lsr x16,x27,#32
+ mov v19.16b,v29.16b
+ mov w17,w28
+ mov v2.16b,v26.16b
+ lsr x19,x28,#32
+ mov v6.16b,v26.16b
+ mov w20,w30
+ mov v18.16b,v26.16b
+ lsr x21,x30,#32
+
+ mov x4,#10
+ subs x2,x2,#256
+.Loop_neon:
+ sub x4,x4,#1
+ add v0.4s,v0.4s,v1.4s
+ add w5,w5,w9
+ add v4.4s,v4.4s,v5.4s
+ add w6,w6,w10
+ add v16.4s,v16.4s,v17.4s
+ add w7,w7,w11
+ eor v3.16b,v3.16b,v0.16b
+ add w8,w8,w12
+ eor v7.16b,v7.16b,v4.16b
+ eor w17,w17,w5
+ eor v19.16b,v19.16b,v16.16b
+ eor w19,w19,w6
+ rev32 v3.8h,v3.8h
+ eor w20,w20,w7
+ rev32 v7.8h,v7.8h
+ eor w21,w21,w8
+ rev32 v19.8h,v19.8h
+ ror w17,w17,#16
+ add v2.4s,v2.4s,v3.4s
+ ror w19,w19,#16
+ add v6.4s,v6.4s,v7.4s
+ ror w20,w20,#16
+ add v18.4s,v18.4s,v19.4s
+ ror w21,w21,#16
+ eor v20.16b,v1.16b,v2.16b
+ add w13,w13,w17
+ eor v21.16b,v5.16b,v6.16b
+ add w14,w14,w19
+ eor v22.16b,v17.16b,v18.16b
+ add w15,w15,w20
+ ushr v1.4s,v20.4s,#20
+ add w16,w16,w21
+ ushr v5.4s,v21.4s,#20
+ eor w9,w9,w13
+ ushr v17.4s,v22.4s,#20
+ eor w10,w10,w14
+ sli v1.4s,v20.4s,#12
+ eor w11,w11,w15
+ sli v5.4s,v21.4s,#12
+ eor w12,w12,w16
+ sli v17.4s,v22.4s,#12
+ ror w9,w9,#20
+ add v0.4s,v0.4s,v1.4s
+ ror w10,w10,#20
+ add v4.4s,v4.4s,v5.4s
+ ror w11,w11,#20
+ add v16.4s,v16.4s,v17.4s
+ ror w12,w12,#20
+ eor v20.16b,v3.16b,v0.16b
+ add w5,w5,w9
+ eor v21.16b,v7.16b,v4.16b
+ add w6,w6,w10
+ eor v22.16b,v19.16b,v16.16b
+ add w7,w7,w11
+ ushr v3.4s,v20.4s,#24
+ add w8,w8,w12
+ ushr v7.4s,v21.4s,#24
+ eor w17,w17,w5
+ ushr v19.4s,v22.4s,#24
+ eor w19,w19,w6
+ sli v3.4s,v20.4s,#8
+ eor w20,w20,w7
+ sli v7.4s,v21.4s,#8
+ eor w21,w21,w8
+ sli v19.4s,v22.4s,#8
+ ror w17,w17,#24
+ add v2.4s,v2.4s,v3.4s
+ ror w19,w19,#24
+ add v6.4s,v6.4s,v7.4s
+ ror w20,w20,#24
+ add v18.4s,v18.4s,v19.4s
+ ror w21,w21,#24
+ eor v20.16b,v1.16b,v2.16b
+ add w13,w13,w17
+ eor v21.16b,v5.16b,v6.16b
+ add w14,w14,w19
+ eor v22.16b,v17.16b,v18.16b
+ add w15,w15,w20
+ ushr v1.4s,v20.4s,#25
+ add w16,w16,w21
+ ushr v5.4s,v21.4s,#25
+ eor w9,w9,w13
+ ushr v17.4s,v22.4s,#25
+ eor w10,w10,w14
+ sli v1.4s,v20.4s,#7
+ eor w11,w11,w15
+ sli v5.4s,v21.4s,#7
+ eor w12,w12,w16
+ sli v17.4s,v22.4s,#7
+ ror w9,w9,#25
+ ext v2.16b,v2.16b,v2.16b,#8
+ ror w10,w10,#25
+ ext v6.16b,v6.16b,v6.16b,#8
+ ror w11,w11,#25
+ ext v18.16b,v18.16b,v18.16b,#8
+ ror w12,w12,#25
+ ext v3.16b,v3.16b,v3.16b,#12
+ ext v7.16b,v7.16b,v7.16b,#12
+ ext v19.16b,v19.16b,v19.16b,#12
+ ext v1.16b,v1.16b,v1.16b,#4
+ ext v5.16b,v5.16b,v5.16b,#4
+ ext v17.16b,v17.16b,v17.16b,#4
+ add v0.4s,v0.4s,v1.4s
+ add w5,w5,w10
+ add v4.4s,v4.4s,v5.4s
+ add w6,w6,w11
+ add v16.4s,v16.4s,v17.4s
+ add w7,w7,w12
+ eor v3.16b,v3.16b,v0.16b
+ add w8,w8,w9
+ eor v7.16b,v7.16b,v4.16b
+ eor w21,w21,w5
+ eor v19.16b,v19.16b,v16.16b
+ eor w17,w17,w6
+ rev32 v3.8h,v3.8h
+ eor w19,w19,w7
+ rev32 v7.8h,v7.8h
+ eor w20,w20,w8
+ rev32 v19.8h,v19.8h
+ ror w21,w21,#16
+ add v2.4s,v2.4s,v3.4s
+ ror w17,w17,#16
+ add v6.4s,v6.4s,v7.4s
+ ror w19,w19,#16
+ add v18.4s,v18.4s,v19.4s
+ ror w20,w20,#16
+ eor v20.16b,v1.16b,v2.16b
+ add w15,w15,w21
+ eor v21.16b,v5.16b,v6.16b
+ add w16,w16,w17
+ eor v22.16b,v17.16b,v18.16b
+ add w13,w13,w19
+ ushr v1.4s,v20.4s,#20
+ add w14,w14,w20
+ ushr v5.4s,v21.4s,#20
+ eor w10,w10,w15
+ ushr v17.4s,v22.4s,#20
+ eor w11,w11,w16
+ sli v1.4s,v20.4s,#12
+ eor w12,w12,w13
+ sli v5.4s,v21.4s,#12
+ eor w9,w9,w14
+ sli v17.4s,v22.4s,#12
+ ror w10,w10,#20
+ add v0.4s,v0.4s,v1.4s
+ ror w11,w11,#20
+ add v4.4s,v4.4s,v5.4s
+ ror w12,w12,#20
+ add v16.4s,v16.4s,v17.4s
+ ror w9,w9,#20
+ eor v20.16b,v3.16b,v0.16b
+ add w5,w5,w10
+ eor v21.16b,v7.16b,v4.16b
+ add w6,w6,w11
+ eor v22.16b,v19.16b,v16.16b
+ add w7,w7,w12
+ ushr v3.4s,v20.4s,#24
+ add w8,w8,w9
+ ushr v7.4s,v21.4s,#24
+ eor w21,w21,w5
+ ushr v19.4s,v22.4s,#24
+ eor w17,w17,w6
+ sli v3.4s,v20.4s,#8
+ eor w19,w19,w7
+ sli v7.4s,v21.4s,#8
+ eor w20,w20,w8
+ sli v19.4s,v22.4s,#8
+ ror w21,w21,#24
+ add v2.4s,v2.4s,v3.4s
+ ror w17,w17,#24
+ add v6.4s,v6.4s,v7.4s
+ ror w19,w19,#24
+ add v18.4s,v18.4s,v19.4s
+ ror w20,w20,#24
+ eor v20.16b,v1.16b,v2.16b
+ add w15,w15,w21
+ eor v21.16b,v5.16b,v6.16b
+ add w16,w16,w17
+ eor v22.16b,v17.16b,v18.16b
+ add w13,w13,w19
+ ushr v1.4s,v20.4s,#25
+ add w14,w14,w20
+ ushr v5.4s,v21.4s,#25
+ eor w10,w10,w15
+ ushr v17.4s,v22.4s,#25
+ eor w11,w11,w16
+ sli v1.4s,v20.4s,#7
+ eor w12,w12,w13
+ sli v5.4s,v21.4s,#7
+ eor w9,w9,w14
+ sli v17.4s,v22.4s,#7
+ ror w10,w10,#25
+ ext v2.16b,v2.16b,v2.16b,#8
+ ror w11,w11,#25
+ ext v6.16b,v6.16b,v6.16b,#8
+ ror w12,w12,#25
+ ext v18.16b,v18.16b,v18.16b,#8
+ ror w9,w9,#25
+ ext v3.16b,v3.16b,v3.16b,#4
+ ext v7.16b,v7.16b,v7.16b,#4
+ ext v19.16b,v19.16b,v19.16b,#4
+ ext v1.16b,v1.16b,v1.16b,#12
+ ext v5.16b,v5.16b,v5.16b,#12
+ ext v17.16b,v17.16b,v17.16b,#12
+ cbnz x4,.Loop_neon
+
+ add w5,w5,w22 // accumulate key block
+ add v0.4s,v0.4s,v24.4s
+ add x6,x6,x22,lsr#32
+ add v4.4s,v4.4s,v24.4s
+ add w7,w7,w23
+ add v16.4s,v16.4s,v24.4s
+ add x8,x8,x23,lsr#32
+ add v2.4s,v2.4s,v26.4s
+ add w9,w9,w24
+ add v6.4s,v6.4s,v26.4s
+ add x10,x10,x24,lsr#32
+ add v18.4s,v18.4s,v26.4s
+ add w11,w11,w25
+ add v3.4s,v3.4s,v27.4s
+ add x12,x12,x25,lsr#32
+ add w13,w13,w26
+ add v7.4s,v7.4s,v28.4s
+ add x14,x14,x26,lsr#32
+ add w15,w15,w27
+ add v19.4s,v19.4s,v29.4s
+ add x16,x16,x27,lsr#32
+ add w17,w17,w28
+ add v1.4s,v1.4s,v25.4s
+ add x19,x19,x28,lsr#32
+ add w20,w20,w30
+ add v5.4s,v5.4s,v25.4s
+ add x21,x21,x30,lsr#32
+ add v17.4s,v17.4s,v25.4s
+
+ b.lo .Ltail_neon
+
+ add x5,x5,x6,lsl#32 // pack
+ add x7,x7,x8,lsl#32
+ ldp x6,x8,[x1,#0] // load input
+ add x9,x9,x10,lsl#32
+ add x11,x11,x12,lsl#32
+ ldp x10,x12,[x1,#16]
+ add x13,x13,x14,lsl#32
+ add x15,x15,x16,lsl#32
+ ldp x14,x16,[x1,#32]
+ add x17,x17,x19,lsl#32
+ add x20,x20,x21,lsl#32
+ ldp x19,x21,[x1,#48]
+ add x1,x1,#64
+#ifdef __ARMEB__
+ rev x5,x5
+ rev x7,x7
+ rev x9,x9
+ rev x11,x11
+ rev x13,x13
+ rev x15,x15
+ rev x17,x17
+ rev x20,x20
+#endif
+ ld1 {v20.16b,v21.16b,v22.16b,v23.16b},[x1],#64
+ eor x5,x5,x6
+ eor x7,x7,x8
+ eor x9,x9,x10
+ eor x11,x11,x12
+ eor x13,x13,x14
+ eor v0.16b,v0.16b,v20.16b
+ eor x15,x15,x16
+ eor v1.16b,v1.16b,v21.16b
+ eor x17,x17,x19
+ eor v2.16b,v2.16b,v22.16b
+ eor x20,x20,x21
+ eor v3.16b,v3.16b,v23.16b
+ ld1 {v20.16b,v21.16b,v22.16b,v23.16b},[x1],#64
+
+ stp x5,x7,[x0,#0] // store output
+ add x28,x28,#4 // increment counter
+ stp x9,x11,[x0,#16]
+ add v27.4s,v27.4s,v31.4s // += 4
+ stp x13,x15,[x0,#32]
+ add v28.4s,v28.4s,v31.4s
+ stp x17,x20,[x0,#48]
+ add v29.4s,v29.4s,v31.4s
+ add x0,x0,#64
+
+ st1 {v0.16b,v1.16b,v2.16b,v3.16b},[x0],#64
+ ld1 {v0.16b,v1.16b,v2.16b,v3.16b},[x1],#64
+
+ eor v4.16b,v4.16b,v20.16b
+ eor v5.16b,v5.16b,v21.16b
+ eor v6.16b,v6.16b,v22.16b
+ eor v7.16b,v7.16b,v23.16b
+ st1 {v4.16b,v5.16b,v6.16b,v7.16b},[x0],#64
+
+ eor v16.16b,v16.16b,v0.16b
+ eor v17.16b,v17.16b,v1.16b
+ eor v18.16b,v18.16b,v2.16b
+ eor v19.16b,v19.16b,v3.16b
+ st1 {v16.16b,v17.16b,v18.16b,v19.16b},[x0],#64
+
+ b.hi .Loop_outer_neon
+
+ ldp x19,x20,[x29,#16]
+ add sp,sp,#64
+ ldp x21,x22,[x29,#32]
+ ldp x23,x24,[x29,#48]
+ ldp x25,x26,[x29,#64]
+ ldp x27,x28,[x29,#80]
+ ldp x29,x30,[sp],#96
+ ret
+
+.Ltail_neon:
+ add x2,x2,#256
+ cmp x2,#64
+ b.lo .Less_than_64
+
+ add x5,x5,x6,lsl#32 // pack
+ add x7,x7,x8,lsl#32
+ ldp x6,x8,[x1,#0] // load input
+ add x9,x9,x10,lsl#32
+ add x11,x11,x12,lsl#32
+ ldp x10,x12,[x1,#16]
+ add x13,x13,x14,lsl#32
+ add x15,x15,x16,lsl#32
+ ldp x14,x16,[x1,#32]
+ add x17,x17,x19,lsl#32
+ add x20,x20,x21,lsl#32
+ ldp x19,x21,[x1,#48]
+ add x1,x1,#64
+#ifdef __ARMEB__
+ rev x5,x5
+ rev x7,x7
+ rev x9,x9
+ rev x11,x11
+ rev x13,x13
+ rev x15,x15
+ rev x17,x17
+ rev x20,x20
+#endif
+ eor x5,x5,x6
+ eor x7,x7,x8
+ eor x9,x9,x10
+ eor x11,x11,x12
+ eor x13,x13,x14
+ eor x15,x15,x16
+ eor x17,x17,x19
+ eor x20,x20,x21
+
+ stp x5,x7,[x0,#0] // store output
+ add x28,x28,#4 // increment counter
+ stp x9,x11,[x0,#16]
+ stp x13,x15,[x0,#32]
+ stp x17,x20,[x0,#48]
+ add x0,x0,#64
+ b.eq .Ldone_neon
+ sub x2,x2,#64
+ cmp x2,#64
+ b.lo .Less_than_128
+
+ ld1 {v20.16b,v21.16b,v22.16b,v23.16b},[x1],#64
+ eor v0.16b,v0.16b,v20.16b
+ eor v1.16b,v1.16b,v21.16b
+ eor v2.16b,v2.16b,v22.16b
+ eor v3.16b,v3.16b,v23.16b
+ st1 {v0.16b,v1.16b,v2.16b,v3.16b},[x0],#64
+ b.eq .Ldone_neon
+ sub x2,x2,#64
+ cmp x2,#64
+ b.lo .Less_than_192
+
+ ld1 {v20.16b,v21.16b,v22.16b,v23.16b},[x1],#64
+ eor v4.16b,v4.16b,v20.16b
+ eor v5.16b,v5.16b,v21.16b
+ eor v6.16b,v6.16b,v22.16b
+ eor v7.16b,v7.16b,v23.16b
+ st1 {v4.16b,v5.16b,v6.16b,v7.16b},[x0],#64
+ b.eq .Ldone_neon
+ sub x2,x2,#64
+
+ st1 {v16.16b,v17.16b,v18.16b,v19.16b},[sp]
+ b .Last_neon
+
+.Less_than_128:
+ st1 {v0.16b,v1.16b,v2.16b,v3.16b},[sp]
+ b .Last_neon
+.Less_than_192:
+ st1 {v4.16b,v5.16b,v6.16b,v7.16b},[sp]
+ b .Last_neon
+
+.align 4
+.Last_neon:
+ sub x0,x0,#1
+ add x1,x1,x2
+ add x0,x0,x2
+ add x4,sp,x2
+ neg x2,x2
+
+.Loop_tail_neon:
+ ldrb w10,[x1,x2]
+ ldrb w11,[x4,x2]
+ add x2,x2,#1
+ eor w10,w10,w11
+ strb w10,[x0,x2]
+ cbnz x2,.Loop_tail_neon
+
+ stp xzr,xzr,[sp,#0]
+ stp xzr,xzr,[sp,#16]
+ stp xzr,xzr,[sp,#32]
+ stp xzr,xzr,[sp,#48]
+
+.Ldone_neon:
+ ldp x19,x20,[x29,#16]
+ add sp,sp,#64
+ ldp x21,x22,[x29,#32]
+ ldp x23,x24,[x29,#48]
+ ldp x25,x26,[x29,#64]
+ ldp x27,x28,[x29,#80]
+ ldp x29,x30,[sp],#96
+ ret
+.size ChaCha20_neon,.-ChaCha20_neon
+.type ChaCha20_512_neon,%function
+.align 5
+ChaCha20_512_neon:
+ stp x29,x30,[sp,#-96]!
+ add x29,sp,#0
+
+ adr x5,.Lsigma
+ stp x19,x20,[sp,#16]
+ stp x21,x22,[sp,#32]
+ stp x23,x24,[sp,#48]
+ stp x25,x26,[sp,#64]
+ stp x27,x28,[sp,#80]
+
+.L512_or_more_neon:
+ sub sp,sp,#128+64
+
+ ldp x22,x23,[x5] // load sigma
+ ld1 {v24.4s},[x5],#16
+ ldp x24,x25,[x3] // load key
+ ldp x26,x27,[x3,#16]
+ ld1 {v25.4s,v26.4s},[x3]
+ ldp x28,x30,[x4] // load counter
+ ld1 {v27.4s},[x4]
+ ld1 {v31.4s},[x5]
+#ifdef __ARMEB__
+ rev64 v24.4s,v24.4s
+ ror x24,x24,#32
+ ror x25,x25,#32
+ ror x26,x26,#32
+ ror x27,x27,#32
+ ror x28,x28,#32
+ ror x30,x30,#32
+#endif
+ add v27.4s,v27.4s,v31.4s // += 1
+ stp q24,q25,[sp,#0] // off-load key block, invariant part
+ add v27.4s,v27.4s,v31.4s // not typo
+ str q26,[sp,#32]
+ add v28.4s,v27.4s,v31.4s
+ add v29.4s,v28.4s,v31.4s
+ add v30.4s,v29.4s,v31.4s
+ shl v31.4s,v31.4s,#2 // 1 -> 4
+
+ stp d8,d9,[sp,#128+0] // meet ABI requirements
+ stp d10,d11,[sp,#128+16]
+ stp d12,d13,[sp,#128+32]
+ stp d14,d15,[sp,#128+48]
+
+ sub x2,x2,#512 // not typo
+
+.Loop_outer_512_neon:
+ mov v0.16b,v24.16b
+ mov v4.16b,v24.16b
+ mov v8.16b,v24.16b
+ mov v12.16b,v24.16b
+ mov v16.16b,v24.16b
+ mov v20.16b,v24.16b
+ mov v1.16b,v25.16b
+ mov w5,w22 // unpack key block
+ mov v5.16b,v25.16b
+ lsr x6,x22,#32
+ mov v9.16b,v25.16b
+ mov w7,w23
+ mov v13.16b,v25.16b
+ lsr x8,x23,#32
+ mov v17.16b,v25.16b
+ mov w9,w24
+ mov v21.16b,v25.16b
+ lsr x10,x24,#32
+ mov v3.16b,v27.16b
+ mov w11,w25
+ mov v7.16b,v28.16b
+ lsr x12,x25,#32
+ mov v11.16b,v29.16b
+ mov w13,w26
+ mov v15.16b,v30.16b
+ lsr x14,x26,#32
+ mov v2.16b,v26.16b
+ mov w15,w27
+ mov v6.16b,v26.16b
+ lsr x16,x27,#32
+ add v19.4s,v3.4s,v31.4s // +4
+ mov w17,w28
+ add v23.4s,v7.4s,v31.4s // +4
+ lsr x19,x28,#32
+ mov v10.16b,v26.16b
+ mov w20,w30
+ mov v14.16b,v26.16b
+ lsr x21,x30,#32
+ mov v18.16b,v26.16b
+ stp q27,q28,[sp,#48] // off-load key block, variable part
+ mov v22.16b,v26.16b
+ str q29,[sp,#80]
+
+ mov x4,#5
+ subs x2,x2,#512
+.Loop_upper_neon:
+ sub x4,x4,#1
+ add v0.4s,v0.4s,v1.4s
+ add w5,w5,w9
+ add v4.4s,v4.4s,v5.4s
+ add w6,w6,w10
+ add v8.4s,v8.4s,v9.4s
+ add w7,w7,w11
+ add v12.4s,v12.4s,v13.4s
+ add w8,w8,w12
+ add v16.4s,v16.4s,v17.4s
+ eor w17,w17,w5
+ add v20.4s,v20.4s,v21.4s
+ eor w19,w19,w6
+ eor v3.16b,v3.16b,v0.16b
+ eor w20,w20,w7
+ eor v7.16b,v7.16b,v4.16b
+ eor w21,w21,w8
+ eor v11.16b,v11.16b,v8.16b
+ ror w17,w17,#16
+ eor v15.16b,v15.16b,v12.16b
+ ror w19,w19,#16
+ eor v19.16b,v19.16b,v16.16b
+ ror w20,w20,#16
+ eor v23.16b,v23.16b,v20.16b
+ ror w21,w21,#16
+ rev32 v3.8h,v3.8h
+ add w13,w13,w17
+ rev32 v7.8h,v7.8h
+ add w14,w14,w19
+ rev32 v11.8h,v11.8h
+ add w15,w15,w20
+ rev32 v15.8h,v15.8h
+ add w16,w16,w21
+ rev32 v19.8h,v19.8h
+ eor w9,w9,w13
+ rev32 v23.8h,v23.8h
+ eor w10,w10,w14
+ add v2.4s,v2.4s,v3.4s
+ eor w11,w11,w15
+ add v6.4s,v6.4s,v7.4s
+ eor w12,w12,w16
+ add v10.4s,v10.4s,v11.4s
+ ror w9,w9,#20
+ add v14.4s,v14.4s,v15.4s
+ ror w10,w10,#20
+ add v18.4s,v18.4s,v19.4s
+ ror w11,w11,#20
+ add v22.4s,v22.4s,v23.4s
+ ror w12,w12,#20
+ eor v24.16b,v1.16b,v2.16b
+ add w5,w5,w9
+ eor v25.16b,v5.16b,v6.16b
+ add w6,w6,w10
+ eor v26.16b,v9.16b,v10.16b
+ add w7,w7,w11
+ eor v27.16b,v13.16b,v14.16b
+ add w8,w8,w12
+ eor v28.16b,v17.16b,v18.16b
+ eor w17,w17,w5
+ eor v29.16b,v21.16b,v22.16b
+ eor w19,w19,w6
+ ushr v1.4s,v24.4s,#20
+ eor w20,w20,w7
+ ushr v5.4s,v25.4s,#20
+ eor w21,w21,w8
+ ushr v9.4s,v26.4s,#20
+ ror w17,w17,#24
+ ushr v13.4s,v27.4s,#20
+ ror w19,w19,#24
+ ushr v17.4s,v28.4s,#20
+ ror w20,w20,#24
+ ushr v21.4s,v29.4s,#20
+ ror w21,w21,#24
+ sli v1.4s,v24.4s,#12
+ add w13,w13,w17
+ sli v5.4s,v25.4s,#12
+ add w14,w14,w19
+ sli v9.4s,v26.4s,#12
+ add w15,w15,w20
+ sli v13.4s,v27.4s,#12
+ add w16,w16,w21
+ sli v17.4s,v28.4s,#12
+ eor w9,w9,w13
+ sli v21.4s,v29.4s,#12
+ eor w10,w10,w14
+ add v0.4s,v0.4s,v1.4s
+ eor w11,w11,w15
+ add v4.4s,v4.4s,v5.4s
+ eor w12,w12,w16
+ add v8.4s,v8.4s,v9.4s
+ ror w9,w9,#25
+ add v12.4s,v12.4s,v13.4s
+ ror w10,w10,#25
+ add v16.4s,v16.4s,v17.4s
+ ror w11,w11,#25
+ add v20.4s,v20.4s,v21.4s
+ ror w12,w12,#25
+ eor v24.16b,v3.16b,v0.16b
+ add w5,w5,w10
+ eor v25.16b,v7.16b,v4.16b
+ add w6,w6,w11
+ eor v26.16b,v11.16b,v8.16b
+ add w7,w7,w12
+ eor v27.16b,v15.16b,v12.16b
+ add w8,w8,w9
+ eor v28.16b,v19.16b,v16.16b
+ eor w21,w21,w5
+ eor v29.16b,v23.16b,v20.16b
+ eor w17,w17,w6
+ ushr v3.4s,v24.4s,#24
+ eor w19,w19,w7
+ ushr v7.4s,v25.4s,#24
+ eor w20,w20,w8
+ ushr v11.4s,v26.4s,#24
+ ror w21,w21,#16
+ ushr v15.4s,v27.4s,#24
+ ror w17,w17,#16
+ ushr v19.4s,v28.4s,#24
+ ror w19,w19,#16
+ ushr v23.4s,v29.4s,#24
+ ror w20,w20,#16
+ sli v3.4s,v24.4s,#8
+ add w15,w15,w21
+ sli v7.4s,v25.4s,#8
+ add w16,w16,w17
+ sli v11.4s,v26.4s,#8
+ add w13,w13,w19
+ sli v15.4s,v27.4s,#8
+ add w14,w14,w20
+ sli v19.4s,v28.4s,#8
+ eor w10,w10,w15
+ sli v23.4s,v29.4s,#8
+ eor w11,w11,w16
+ add v2.4s,v2.4s,v3.4s
+ eor w12,w12,w13
+ add v6.4s,v6.4s,v7.4s
+ eor w9,w9,w14
+ add v10.4s,v10.4s,v11.4s
+ ror w10,w10,#20
+ add v14.4s,v14.4s,v15.4s
+ ror w11,w11,#20
+ add v18.4s,v18.4s,v19.4s
+ ror w12,w12,#20
+ add v22.4s,v22.4s,v23.4s
+ ror w9,w9,#20
+ eor v24.16b,v1.16b,v2.16b
+ add w5,w5,w10
+ eor v25.16b,v5.16b,v6.16b
+ add w6,w6,w11
+ eor v26.16b,v9.16b,v10.16b
+ add w7,w7,w12
+ eor v27.16b,v13.16b,v14.16b
+ add w8,w8,w9
+ eor v28.16b,v17.16b,v18.16b
+ eor w21,w21,w5
+ eor v29.16b,v21.16b,v22.16b
+ eor w17,w17,w6
+ ushr v1.4s,v24.4s,#25
+ eor w19,w19,w7
+ ushr v5.4s,v25.4s,#25
+ eor w20,w20,w8
+ ushr v9.4s,v26.4s,#25
+ ror w21,w21,#24
+ ushr v13.4s,v27.4s,#25
+ ror w17,w17,#24
+ ushr v17.4s,v28.4s,#25
+ ror w19,w19,#24
+ ushr v21.4s,v29.4s,#25
+ ror w20,w20,#24
+ sli v1.4s,v24.4s,#7
+ add w15,w15,w21
+ sli v5.4s,v25.4s,#7
+ add w16,w16,w17
+ sli v9.4s,v26.4s,#7
+ add w13,w13,w19
+ sli v13.4s,v27.4s,#7
+ add w14,w14,w20
+ sli v17.4s,v28.4s,#7
+ eor w10,w10,w15
+ sli v21.4s,v29.4s,#7
+ eor w11,w11,w16
+ ext v2.16b,v2.16b,v2.16b,#8
+ eor w12,w12,w13
+ ext v6.16b,v6.16b,v6.16b,#8
+ eor w9,w9,w14
+ ext v10.16b,v10.16b,v10.16b,#8
+ ror w10,w10,#25
+ ext v14.16b,v14.16b,v14.16b,#8
+ ror w11,w11,#25
+ ext v18.16b,v18.16b,v18.16b,#8
+ ror w12,w12,#25
+ ext v22.16b,v22.16b,v22.16b,#8
+ ror w9,w9,#25
+ ext v3.16b,v3.16b,v3.16b,#12
+ ext v7.16b,v7.16b,v7.16b,#12
+ ext v11.16b,v11.16b,v11.16b,#12
+ ext v15.16b,v15.16b,v15.16b,#12
+ ext v19.16b,v19.16b,v19.16b,#12
+ ext v23.16b,v23.16b,v23.16b,#12
+ ext v1.16b,v1.16b,v1.16b,#4
+ ext v5.16b,v5.16b,v5.16b,#4
+ ext v9.16b,v9.16b,v9.16b,#4
+ ext v13.16b,v13.16b,v13.16b,#4
+ ext v17.16b,v17.16b,v17.16b,#4
+ ext v21.16b,v21.16b,v21.16b,#4
+ add v0.4s,v0.4s,v1.4s
+ add w5,w5,w9
+ add v4.4s,v4.4s,v5.4s
+ add w6,w6,w10
+ add v8.4s,v8.4s,v9.4s
+ add w7,w7,w11
+ add v12.4s,v12.4s,v13.4s
+ add w8,w8,w12
+ add v16.4s,v16.4s,v17.4s
+ eor w17,w17,w5
+ add v20.4s,v20.4s,v21.4s
+ eor w19,w19,w6
+ eor v3.16b,v3.16b,v0.16b
+ eor w20,w20,w7
+ eor v7.16b,v7.16b,v4.16b
+ eor w21,w21,w8
+ eor v11.16b,v11.16b,v8.16b
+ ror w17,w17,#16
+ eor v15.16b,v15.16b,v12.16b
+ ror w19,w19,#16
+ eor v19.16b,v19.16b,v16.16b
+ ror w20,w20,#16
+ eor v23.16b,v23.16b,v20.16b
+ ror w21,w21,#16
+ rev32 v3.8h,v3.8h
+ add w13,w13,w17
+ rev32 v7.8h,v7.8h
+ add w14,w14,w19
+ rev32 v11.8h,v11.8h
+ add w15,w15,w20
+ rev32 v15.8h,v15.8h
+ add w16,w16,w21
+ rev32 v19.8h,v19.8h
+ eor w9,w9,w13
+ rev32 v23.8h,v23.8h
+ eor w10,w10,w14
+ add v2.4s,v2.4s,v3.4s
+ eor w11,w11,w15
+ add v6.4s,v6.4s,v7.4s
+ eor w12,w12,w16
+ add v10.4s,v10.4s,v11.4s
+ ror w9,w9,#20
+ add v14.4s,v14.4s,v15.4s
+ ror w10,w10,#20
+ add v18.4s,v18.4s,v19.4s
+ ror w11,w11,#20
+ add v22.4s,v22.4s,v23.4s
+ ror w12,w12,#20
+ eor v24.16b,v1.16b,v2.16b
+ add w5,w5,w9
+ eor v25.16b,v5.16b,v6.16b
+ add w6,w6,w10
+ eor v26.16b,v9.16b,v10.16b
+ add w7,w7,w11
+ eor v27.16b,v13.16b,v14.16b
+ add w8,w8,w12
+ eor v28.16b,v17.16b,v18.16b
+ eor w17,w17,w5
+ eor v29.16b,v21.16b,v22.16b
+ eor w19,w19,w6
+ ushr v1.4s,v24.4s,#20
+ eor w20,w20,w7
+ ushr v5.4s,v25.4s,#20
+ eor w21,w21,w8
+ ushr v9.4s,v26.4s,#20
+ ror w17,w17,#24
+ ushr v13.4s,v27.4s,#20
+ ror w19,w19,#24
+ ushr v17.4s,v28.4s,#20
+ ror w20,w20,#24
+ ushr v21.4s,v29.4s,#20
+ ror w21,w21,#24
+ sli v1.4s,v24.4s,#12
+ add w13,w13,w17
+ sli v5.4s,v25.4s,#12
+ add w14,w14,w19
+ sli v9.4s,v26.4s,#12
+ add w15,w15,w20
+ sli v13.4s,v27.4s,#12
+ add w16,w16,w21
+ sli v17.4s,v28.4s,#12
+ eor w9,w9,w13
+ sli v21.4s,v29.4s,#12
+ eor w10,w10,w14
+ add v0.4s,v0.4s,v1.4s
+ eor w11,w11,w15
+ add v4.4s,v4.4s,v5.4s
+ eor w12,w12,w16
+ add v8.4s,v8.4s,v9.4s
+ ror w9,w9,#25
+ add v12.4s,v12.4s,v13.4s
+ ror w10,w10,#25
+ add v16.4s,v16.4s,v17.4s
+ ror w11,w11,#25
+ add v20.4s,v20.4s,v21.4s
+ ror w12,w12,#25
+ eor v24.16b,v3.16b,v0.16b
+ add w5,w5,w10
+ eor v25.16b,v7.16b,v4.16b
+ add w6,w6,w11
+ eor v26.16b,v11.16b,v8.16b
+ add w7,w7,w12
+ eor v27.16b,v15.16b,v12.16b
+ add w8,w8,w9
+ eor v28.16b,v19.16b,v16.16b
+ eor w21,w21,w5
+ eor v29.16b,v23.16b,v20.16b
+ eor w17,w17,w6
+ ushr v3.4s,v24.4s,#24
+ eor w19,w19,w7
+ ushr v7.4s,v25.4s,#24
+ eor w20,w20,w8
+ ushr v11.4s,v26.4s,#24
+ ror w21,w21,#16
+ ushr v15.4s,v27.4s,#24
+ ror w17,w17,#16
+ ushr v19.4s,v28.4s,#24
+ ror w19,w19,#16
+ ushr v23.4s,v29.4s,#24
+ ror w20,w20,#16
+ sli v3.4s,v24.4s,#8
+ add w15,w15,w21
+ sli v7.4s,v25.4s,#8
+ add w16,w16,w17
+ sli v11.4s,v26.4s,#8
+ add w13,w13,w19
+ sli v15.4s,v27.4s,#8
+ add w14,w14,w20
+ sli v19.4s,v28.4s,#8
+ eor w10,w10,w15
+ sli v23.4s,v29.4s,#8
+ eor w11,w11,w16
+ add v2.4s,v2.4s,v3.4s
+ eor w12,w12,w13
+ add v6.4s,v6.4s,v7.4s
+ eor w9,w9,w14
+ add v10.4s,v10.4s,v11.4s
+ ror w10,w10,#20
+ add v14.4s,v14.4s,v15.4s
+ ror w11,w11,#20
+ add v18.4s,v18.4s,v19.4s
+ ror w12,w12,#20
+ add v22.4s,v22.4s,v23.4s
+ ror w9,w9,#20
+ eor v24.16b,v1.16b,v2.16b
+ add w5,w5,w10
+ eor v25.16b,v5.16b,v6.16b
+ add w6,w6,w11
+ eor v26.16b,v9.16b,v10.16b
+ add w7,w7,w12
+ eor v27.16b,v13.16b,v14.16b
+ add w8,w8,w9
+ eor v28.16b,v17.16b,v18.16b
+ eor w21,w21,w5
+ eor v29.16b,v21.16b,v22.16b
+ eor w17,w17,w6
+ ushr v1.4s,v24.4s,#25
+ eor w19,w19,w7
+ ushr v5.4s,v25.4s,#25
+ eor w20,w20,w8
+ ushr v9.4s,v26.4s,#25
+ ror w21,w21,#24
+ ushr v13.4s,v27.4s,#25
+ ror w17,w17,#24
+ ushr v17.4s,v28.4s,#25
+ ror w19,w19,#24
+ ushr v21.4s,v29.4s,#25
+ ror w20,w20,#24
+ sli v1.4s,v24.4s,#7
+ add w15,w15,w21
+ sli v5.4s,v25.4s,#7
+ add w16,w16,w17
+ sli v9.4s,v26.4s,#7
+ add w13,w13,w19
+ sli v13.4s,v27.4s,#7
+ add w14,w14,w20
+ sli v17.4s,v28.4s,#7
+ eor w10,w10,w15
+ sli v21.4s,v29.4s,#7
+ eor w11,w11,w16
+ ext v2.16b,v2.16b,v2.16b,#8
+ eor w12,w12,w13
+ ext v6.16b,v6.16b,v6.16b,#8
+ eor w9,w9,w14
+ ext v10.16b,v10.16b,v10.16b,#8
+ ror w10,w10,#25
+ ext v14.16b,v14.16b,v14.16b,#8
+ ror w11,w11,#25
+ ext v18.16b,v18.16b,v18.16b,#8
+ ror w12,w12,#25
+ ext v22.16b,v22.16b,v22.16b,#8
+ ror w9,w9,#25
+ ext v3.16b,v3.16b,v3.16b,#4
+ ext v7.16b,v7.16b,v7.16b,#4
+ ext v11.16b,v11.16b,v11.16b,#4
+ ext v15.16b,v15.16b,v15.16b,#4
+ ext v19.16b,v19.16b,v19.16b,#4
+ ext v23.16b,v23.16b,v23.16b,#4
+ ext v1.16b,v1.16b,v1.16b,#12
+ ext v5.16b,v5.16b,v5.16b,#12
+ ext v9.16b,v9.16b,v9.16b,#12
+ ext v13.16b,v13.16b,v13.16b,#12
+ ext v17.16b,v17.16b,v17.16b,#12
+ ext v21.16b,v21.16b,v21.16b,#12
+ cbnz x4,.Loop_upper_neon
+
+ add w5,w5,w22 // accumulate key block
+ add x6,x6,x22,lsr#32
+ add w7,w7,w23
+ add x8,x8,x23,lsr#32
+ add w9,w9,w24
+ add x10,x10,x24,lsr#32
+ add w11,w11,w25
+ add x12,x12,x25,lsr#32
+ add w13,w13,w26
+ add x14,x14,x26,lsr#32
+ add w15,w15,w27
+ add x16,x16,x27,lsr#32
+ add w17,w17,w28
+ add x19,x19,x28,lsr#32
+ add w20,w20,w30
+ add x21,x21,x30,lsr#32
+
+ add x5,x5,x6,lsl#32 // pack
+ add x7,x7,x8,lsl#32
+ ldp x6,x8,[x1,#0] // load input
+ add x9,x9,x10,lsl#32
+ add x11,x11,x12,lsl#32
+ ldp x10,x12,[x1,#16]
+ add x13,x13,x14,lsl#32
+ add x15,x15,x16,lsl#32
+ ldp x14,x16,[x1,#32]
+ add x17,x17,x19,lsl#32
+ add x20,x20,x21,lsl#32
+ ldp x19,x21,[x1,#48]
+ add x1,x1,#64
+#ifdef __ARMEB__
+ rev x5,x5
+ rev x7,x7
+ rev x9,x9
+ rev x11,x11
+ rev x13,x13
+ rev x15,x15
+ rev x17,x17
+ rev x20,x20
+#endif
+ eor x5,x5,x6
+ eor x7,x7,x8
+ eor x9,x9,x10
+ eor x11,x11,x12
+ eor x13,x13,x14
+ eor x15,x15,x16
+ eor x17,x17,x19
+ eor x20,x20,x21
+
+ stp x5,x7,[x0,#0] // store output
+ add x28,x28,#1 // increment counter
+ mov w5,w22 // unpack key block
+ lsr x6,x22,#32
+ stp x9,x11,[x0,#16]
+ mov w7,w23
+ lsr x8,x23,#32
+ stp x13,x15,[x0,#32]
+ mov w9,w24
+ lsr x10,x24,#32
+ stp x17,x20,[x0,#48]
+ add x0,x0,#64
+ mov w11,w25
+ lsr x12,x25,#32
+ mov w13,w26
+ lsr x14,x26,#32
+ mov w15,w27
+ lsr x16,x27,#32
+ mov w17,w28
+ lsr x19,x28,#32
+ mov w20,w30
+ lsr x21,x30,#32
+
+ mov x4,#5
+.Loop_lower_neon:
+ sub x4,x4,#1
+ add v0.4s,v0.4s,v1.4s
+ add w5,w5,w9
+ add v4.4s,v4.4s,v5.4s
+ add w6,w6,w10
+ add v8.4s,v8.4s,v9.4s
+ add w7,w7,w11
+ add v12.4s,v12.4s,v13.4s
+ add w8,w8,w12
+ add v16.4s,v16.4s,v17.4s
+ eor w17,w17,w5
+ add v20.4s,v20.4s,v21.4s
+ eor w19,w19,w6
+ eor v3.16b,v3.16b,v0.16b
+ eor w20,w20,w7
+ eor v7.16b,v7.16b,v4.16b
+ eor w21,w21,w8
+ eor v11.16b,v11.16b,v8.16b
+ ror w17,w17,#16
+ eor v15.16b,v15.16b,v12.16b
+ ror w19,w19,#16
+ eor v19.16b,v19.16b,v16.16b
+ ror w20,w20,#16
+ eor v23.16b,v23.16b,v20.16b
+ ror w21,w21,#16
+ rev32 v3.8h,v3.8h
+ add w13,w13,w17
+ rev32 v7.8h,v7.8h
+ add w14,w14,w19
+ rev32 v11.8h,v11.8h
+ add w15,w15,w20
+ rev32 v15.8h,v15.8h
+ add w16,w16,w21
+ rev32 v19.8h,v19.8h
+ eor w9,w9,w13
+ rev32 v23.8h,v23.8h
+ eor w10,w10,w14
+ add v2.4s,v2.4s,v3.4s
+ eor w11,w11,w15
+ add v6.4s,v6.4s,v7.4s
+ eor w12,w12,w16
+ add v10.4s,v10.4s,v11.4s
+ ror w9,w9,#20
+ add v14.4s,v14.4s,v15.4s
+ ror w10,w10,#20
+ add v18.4s,v18.4s,v19.4s
+ ror w11,w11,#20
+ add v22.4s,v22.4s,v23.4s
+ ror w12,w12,#20
+ eor v24.16b,v1.16b,v2.16b
+ add w5,w5,w9
+ eor v25.16b,v5.16b,v6.16b
+ add w6,w6,w10
+ eor v26.16b,v9.16b,v10.16b
+ add w7,w7,w11
+ eor v27.16b,v13.16b,v14.16b
+ add w8,w8,w12
+ eor v28.16b,v17.16b,v18.16b
+ eor w17,w17,w5
+ eor v29.16b,v21.16b,v22.16b
+ eor w19,w19,w6
+ ushr v1.4s,v24.4s,#20
+ eor w20,w20,w7
+ ushr v5.4s,v25.4s,#20
+ eor w21,w21,w8
+ ushr v9.4s,v26.4s,#20
+ ror w17,w17,#24
+ ushr v13.4s,v27.4s,#20
+ ror w19,w19,#24
+ ushr v17.4s,v28.4s,#20
+ ror w20,w20,#24
+ ushr v21.4s,v29.4s,#20
+ ror w21,w21,#24
+ sli v1.4s,v24.4s,#12
+ add w13,w13,w17
+ sli v5.4s,v25.4s,#12
+ add w14,w14,w19
+ sli v9.4s,v26.4s,#12
+ add w15,w15,w20
+ sli v13.4s,v27.4s,#12
+ add w16,w16,w21
+ sli v17.4s,v28.4s,#12
+ eor w9,w9,w13
+ sli v21.4s,v29.4s,#12
+ eor w10,w10,w14
+ add v0.4s,v0.4s,v1.4s
+ eor w11,w11,w15
+ add v4.4s,v4.4s,v5.4s
+ eor w12,w12,w16
+ add v8.4s,v8.4s,v9.4s
+ ror w9,w9,#25
+ add v12.4s,v12.4s,v13.4s
+ ror w10,w10,#25
+ add v16.4s,v16.4s,v17.4s
+ ror w11,w11,#25
+ add v20.4s,v20.4s,v21.4s
+ ror w12,w12,#25
+ eor v24.16b,v3.16b,v0.16b
+ add w5,w5,w10
+ eor v25.16b,v7.16b,v4.16b
+ add w6,w6,w11
+ eor v26.16b,v11.16b,v8.16b
+ add w7,w7,w12
+ eor v27.16b,v15.16b,v12.16b
+ add w8,w8,w9
+ eor v28.16b,v19.16b,v16.16b
+ eor w21,w21,w5
+ eor v29.16b,v23.16b,v20.16b
+ eor w17,w17,w6
+ ushr v3.4s,v24.4s,#24
+ eor w19,w19,w7
+ ushr v7.4s,v25.4s,#24
+ eor w20,w20,w8
+ ushr v11.4s,v26.4s,#24
+ ror w21,w21,#16
+ ushr v15.4s,v27.4s,#24
+ ror w17,w17,#16
+ ushr v19.4s,v28.4s,#24
+ ror w19,w19,#16
+ ushr v23.4s,v29.4s,#24
+ ror w20,w20,#16
+ sli v3.4s,v24.4s,#8
+ add w15,w15,w21
+ sli v7.4s,v25.4s,#8
+ add w16,w16,w17
+ sli v11.4s,v26.4s,#8
+ add w13,w13,w19
+ sli v15.4s,v27.4s,#8
+ add w14,w14,w20
+ sli v19.4s,v28.4s,#8
+ eor w10,w10,w15
+ sli v23.4s,v29.4s,#8
+ eor w11,w11,w16
+ add v2.4s,v2.4s,v3.4s
+ eor w12,w12,w13
+ add v6.4s,v6.4s,v7.4s
+ eor w9,w9,w14
+ add v10.4s,v10.4s,v11.4s
+ ror w10,w10,#20
+ add v14.4s,v14.4s,v15.4s
+ ror w11,w11,#20
+ add v18.4s,v18.4s,v19.4s
+ ror w12,w12,#20
+ add v22.4s,v22.4s,v23.4s
+ ror w9,w9,#20
+ eor v24.16b,v1.16b,v2.16b
+ add w5,w5,w10
+ eor v25.16b,v5.16b,v6.16b
+ add w6,w6,w11
+ eor v26.16b,v9.16b,v10.16b
+ add w7,w7,w12
+ eor v27.16b,v13.16b,v14.16b
+ add w8,w8,w9
+ eor v28.16b,v17.16b,v18.16b
+ eor w21,w21,w5
+ eor v29.16b,v21.16b,v22.16b
+ eor w17,w17,w6
+ ushr v1.4s,v24.4s,#25
+ eor w19,w19,w7
+ ushr v5.4s,v25.4s,#25
+ eor w20,w20,w8
+ ushr v9.4s,v26.4s,#25
+ ror w21,w21,#24
+ ushr v13.4s,v27.4s,#25
+ ror w17,w17,#24
+ ushr v17.4s,v28.4s,#25
+ ror w19,w19,#24
+ ushr v21.4s,v29.4s,#25
+ ror w20,w20,#24
+ sli v1.4s,v24.4s,#7
+ add w15,w15,w21
+ sli v5.4s,v25.4s,#7
+ add w16,w16,w17
+ sli v9.4s,v26.4s,#7
+ add w13,w13,w19
+ sli v13.4s,v27.4s,#7
+ add w14,w14,w20
+ sli v17.4s,v28.4s,#7
+ eor w10,w10,w15
+ sli v21.4s,v29.4s,#7
+ eor w11,w11,w16
+ ext v2.16b,v2.16b,v2.16b,#8
+ eor w12,w12,w13
+ ext v6.16b,v6.16b,v6.16b,#8
+ eor w9,w9,w14
+ ext v10.16b,v10.16b,v10.16b,#8
+ ror w10,w10,#25
+ ext v14.16b,v14.16b,v14.16b,#8
+ ror w11,w11,#25
+ ext v18.16b,v18.16b,v18.16b,#8
+ ror w12,w12,#25
+ ext v22.16b,v22.16b,v22.16b,#8
+ ror w9,w9,#25
+ ext v3.16b,v3.16b,v3.16b,#12
+ ext v7.16b,v7.16b,v7.16b,#12
+ ext v11.16b,v11.16b,v11.16b,#12
+ ext v15.16b,v15.16b,v15.16b,#12
+ ext v19.16b,v19.16b,v19.16b,#12
+ ext v23.16b,v23.16b,v23.16b,#12
+ ext v1.16b,v1.16b,v1.16b,#4
+ ext v5.16b,v5.16b,v5.16b,#4
+ ext v9.16b,v9.16b,v9.16b,#4
+ ext v13.16b,v13.16b,v13.16b,#4
+ ext v17.16b,v17.16b,v17.16b,#4
+ ext v21.16b,v21.16b,v21.16b,#4
+ add v0.4s,v0.4s,v1.4s
+ add w5,w5,w9
+ add v4.4s,v4.4s,v5.4s
+ add w6,w6,w10
+ add v8.4s,v8.4s,v9.4s
+ add w7,w7,w11
+ add v12.4s,v12.4s,v13.4s
+ add w8,w8,w12
+ add v16.4s,v16.4s,v17.4s
+ eor w17,w17,w5
+ add v20.4s,v20.4s,v21.4s
+ eor w19,w19,w6
+ eor v3.16b,v3.16b,v0.16b
+ eor w20,w20,w7
+ eor v7.16b,v7.16b,v4.16b
+ eor w21,w21,w8
+ eor v11.16b,v11.16b,v8.16b
+ ror w17,w17,#16
+ eor v15.16b,v15.16b,v12.16b
+ ror w19,w19,#16
+ eor v19.16b,v19.16b,v16.16b
+ ror w20,w20,#16
+ eor v23.16b,v23.16b,v20.16b
+ ror w21,w21,#16
+ rev32 v3.8h,v3.8h
+ add w13,w13,w17
+ rev32 v7.8h,v7.8h
+ add w14,w14,w19
+ rev32 v11.8h,v11.8h
+ add w15,w15,w20
+ rev32 v15.8h,v15.8h
+ add w16,w16,w21
+ rev32 v19.8h,v19.8h
+ eor w9,w9,w13
+ rev32 v23.8h,v23.8h
+ eor w10,w10,w14
+ add v2.4s,v2.4s,v3.4s
+ eor w11,w11,w15
+ add v6.4s,v6.4s,v7.4s
+ eor w12,w12,w16
+ add v10.4s,v10.4s,v11.4s
+ ror w9,w9,#20
+ add v14.4s,v14.4s,v15.4s
+ ror w10,w10,#20
+ add v18.4s,v18.4s,v19.4s
+ ror w11,w11,#20
+ add v22.4s,v22.4s,v23.4s
+ ror w12,w12,#20
+ eor v24.16b,v1.16b,v2.16b
+ add w5,w5,w9
+ eor v25.16b,v5.16b,v6.16b
+ add w6,w6,w10
+ eor v26.16b,v9.16b,v10.16b
+ add w7,w7,w11
+ eor v27.16b,v13.16b,v14.16b
+ add w8,w8,w12
+ eor v28.16b,v17.16b,v18.16b
+ eor w17,w17,w5
+ eor v29.16b,v21.16b,v22.16b
+ eor w19,w19,w6
+ ushr v1.4s,v24.4s,#20
+ eor w20,w20,w7
+ ushr v5.4s,v25.4s,#20
+ eor w21,w21,w8
+ ushr v9.4s,v26.4s,#20
+ ror w17,w17,#24
+ ushr v13.4s,v27.4s,#20
+ ror w19,w19,#24
+ ushr v17.4s,v28.4s,#20
+ ror w20,w20,#24
+ ushr v21.4s,v29.4s,#20
+ ror w21,w21,#24
+ sli v1.4s,v24.4s,#12
+ add w13,w13,w17
+ sli v5.4s,v25.4s,#12
+ add w14,w14,w19
+ sli v9.4s,v26.4s,#12
+ add w15,w15,w20
+ sli v13.4s,v27.4s,#12
+ add w16,w16,w21
+ sli v17.4s,v28.4s,#12
+ eor w9,w9,w13
+ sli v21.4s,v29.4s,#12
+ eor w10,w10,w14
+ add v0.4s,v0.4s,v1.4s
+ eor w11,w11,w15
+ add v4.4s,v4.4s,v5.4s
+ eor w12,w12,w16
+ add v8.4s,v8.4s,v9.4s
+ ror w9,w9,#25
+ add v12.4s,v12.4s,v13.4s
+ ror w10,w10,#25
+ add v16.4s,v16.4s,v17.4s
+ ror w11,w11,#25
+ add v20.4s,v20.4s,v21.4s
+ ror w12,w12,#25
+ eor v24.16b,v3.16b,v0.16b
+ add w5,w5,w10
+ eor v25.16b,v7.16b,v4.16b
+ add w6,w6,w11
+ eor v26.16b,v11.16b,v8.16b
+ add w7,w7,w12
+ eor v27.16b,v15.16b,v12.16b
+ add w8,w8,w9
+ eor v28.16b,v19.16b,v16.16b
+ eor w21,w21,w5
+ eor v29.16b,v23.16b,v20.16b
+ eor w17,w17,w6
+ ushr v3.4s,v24.4s,#24
+ eor w19,w19,w7
+ ushr v7.4s,v25.4s,#24
+ eor w20,w20,w8
+ ushr v11.4s,v26.4s,#24
+ ror w21,w21,#16
+ ushr v15.4s,v27.4s,#24
+ ror w17,w17,#16
+ ushr v19.4s,v28.4s,#24
+ ror w19,w19,#16
+ ushr v23.4s,v29.4s,#24
+ ror w20,w20,#16
+ sli v3.4s,v24.4s,#8
+ add w15,w15,w21
+ sli v7.4s,v25.4s,#8
+ add w16,w16,w17
+ sli v11.4s,v26.4s,#8
+ add w13,w13,w19
+ sli v15.4s,v27.4s,#8
+ add w14,w14,w20
+ sli v19.4s,v28.4s,#8
+ eor w10,w10,w15
+ sli v23.4s,v29.4s,#8
+ eor w11,w11,w16
+ add v2.4s,v2.4s,v3.4s
+ eor w12,w12,w13
+ add v6.4s,v6.4s,v7.4s
+ eor w9,w9,w14
+ add v10.4s,v10.4s,v11.4s
+ ror w10,w10,#20
+ add v14.4s,v14.4s,v15.4s
+ ror w11,w11,#20
+ add v18.4s,v18.4s,v19.4s
+ ror w12,w12,#20
+ add v22.4s,v22.4s,v23.4s
+ ror w9,w9,#20
+ eor v24.16b,v1.16b,v2.16b
+ add w5,w5,w10
+ eor v25.16b,v5.16b,v6.16b
+ add w6,w6,w11
+ eor v26.16b,v9.16b,v10.16b
+ add w7,w7,w12
+ eor v27.16b,v13.16b,v14.16b
+ add w8,w8,w9
+ eor v28.16b,v17.16b,v18.16b
+ eor w21,w21,w5
+ eor v29.16b,v21.16b,v22.16b
+ eor w17,w17,w6
+ ushr v1.4s,v24.4s,#25
+ eor w19,w19,w7
+ ushr v5.4s,v25.4s,#25
+ eor w20,w20,w8
+ ushr v9.4s,v26.4s,#25
+ ror w21,w21,#24
+ ushr v13.4s,v27.4s,#25
+ ror w17,w17,#24
+ ushr v17.4s,v28.4s,#25
+ ror w19,w19,#24
+ ushr v21.4s,v29.4s,#25
+ ror w20,w20,#24
+ sli v1.4s,v24.4s,#7
+ add w15,w15,w21
+ sli v5.4s,v25.4s,#7
+ add w16,w16,w17
+ sli v9.4s,v26.4s,#7
+ add w13,w13,w19
+ sli v13.4s,v27.4s,#7
+ add w14,w14,w20
+ sli v17.4s,v28.4s,#7
+ eor w10,w10,w15
+ sli v21.4s,v29.4s,#7
+ eor w11,w11,w16
+ ext v2.16b,v2.16b,v2.16b,#8
+ eor w12,w12,w13
+ ext v6.16b,v6.16b,v6.16b,#8
+ eor w9,w9,w14
+ ext v10.16b,v10.16b,v10.16b,#8
+ ror w10,w10,#25
+ ext v14.16b,v14.16b,v14.16b,#8
+ ror w11,w11,#25
+ ext v18.16b,v18.16b,v18.16b,#8
+ ror w12,w12,#25
+ ext v22.16b,v22.16b,v22.16b,#8
+ ror w9,w9,#25
+ ext v3.16b,v3.16b,v3.16b,#4
+ ext v7.16b,v7.16b,v7.16b,#4
+ ext v11.16b,v11.16b,v11.16b,#4
+ ext v15.16b,v15.16b,v15.16b,#4
+ ext v19.16b,v19.16b,v19.16b,#4
+ ext v23.16b,v23.16b,v23.16b,#4
+ ext v1.16b,v1.16b,v1.16b,#12
+ ext v5.16b,v5.16b,v5.16b,#12
+ ext v9.16b,v9.16b,v9.16b,#12
+ ext v13.16b,v13.16b,v13.16b,#12
+ ext v17.16b,v17.16b,v17.16b,#12
+ ext v21.16b,v21.16b,v21.16b,#12
+ cbnz x4,.Loop_lower_neon
+
+ add w5,w5,w22 // accumulate key block
+ ldp q24,q25,[sp,#0]
+ add x6,x6,x22,lsr#32
+ ldp q26,q27,[sp,#32]
+ add w7,w7,w23
+ ldp q28,q29,[sp,#64]
+ add x8,x8,x23,lsr#32
+ add v0.4s,v0.4s,v24.4s
+ add w9,w9,w24
+ add v4.4s,v4.4s,v24.4s
+ add x10,x10,x24,lsr#32
+ add v8.4s,v8.4s,v24.4s
+ add w11,w11,w25
+ add v12.4s,v12.4s,v24.4s
+ add x12,x12,x25,lsr#32
+ add v16.4s,v16.4s,v24.4s
+ add w13,w13,w26
+ add v20.4s,v20.4s,v24.4s
+ add x14,x14,x26,lsr#32
+ add v2.4s,v2.4s,v26.4s
+ add w15,w15,w27
+ add v6.4s,v6.4s,v26.4s
+ add x16,x16,x27,lsr#32
+ add v10.4s,v10.4s,v26.4s
+ add w17,w17,w28
+ add v14.4s,v14.4s,v26.4s
+ add x19,x19,x28,lsr#32
+ add v18.4s,v18.4s,v26.4s
+ add w20,w20,w30
+ add v22.4s,v22.4s,v26.4s
+ add x21,x21,x30,lsr#32
+ add v19.4s,v19.4s,v31.4s // +4
+ add x5,x5,x6,lsl#32 // pack
+ add v23.4s,v23.4s,v31.4s // +4
+ add x7,x7,x8,lsl#32
+ add v3.4s,v3.4s,v27.4s
+ ldp x6,x8,[x1,#0] // load input
+ add v7.4s,v7.4s,v28.4s
+ add x9,x9,x10,lsl#32
+ add v11.4s,v11.4s,v29.4s
+ add x11,x11,x12,lsl#32
+ add v15.4s,v15.4s,v30.4s
+ ldp x10,x12,[x1,#16]
+ add v19.4s,v19.4s,v27.4s
+ add x13,x13,x14,lsl#32
+ add v23.4s,v23.4s,v28.4s
+ add x15,x15,x16,lsl#32
+ add v1.4s,v1.4s,v25.4s
+ ldp x14,x16,[x1,#32]
+ add v5.4s,v5.4s,v25.4s
+ add x17,x17,x19,lsl#32
+ add v9.4s,v9.4s,v25.4s
+ add x20,x20,x21,lsl#32
+ add v13.4s,v13.4s,v25.4s
+ ldp x19,x21,[x1,#48]
+ add v17.4s,v17.4s,v25.4s
+ add x1,x1,#64
+ add v21.4s,v21.4s,v25.4s
+
+#ifdef __ARMEB__
+ rev x5,x5
+ rev x7,x7
+ rev x9,x9
+ rev x11,x11
+ rev x13,x13
+ rev x15,x15
+ rev x17,x17
+ rev x20,x20
+#endif
+ ld1 {v24.16b,v25.16b,v26.16b,v27.16b},[x1],#64
+ eor x5,x5,x6
+ eor x7,x7,x8
+ eor x9,x9,x10
+ eor x11,x11,x12
+ eor x13,x13,x14
+ eor v0.16b,v0.16b,v24.16b
+ eor x15,x15,x16
+ eor v1.16b,v1.16b,v25.16b
+ eor x17,x17,x19
+ eor v2.16b,v2.16b,v26.16b
+ eor x20,x20,x21
+ eor v3.16b,v3.16b,v27.16b
+ ld1 {v24.16b,v25.16b,v26.16b,v27.16b},[x1],#64
+
+ stp x5,x7,[x0,#0] // store output
+ add x28,x28,#7 // increment counter
+ stp x9,x11,[x0,#16]
+ stp x13,x15,[x0,#32]
+ stp x17,x20,[x0,#48]
+ add x0,x0,#64
+ st1 {v0.16b,v1.16b,v2.16b,v3.16b},[x0],#64
+
+ ld1 {v0.16b,v1.16b,v2.16b,v3.16b},[x1],#64
+ eor v4.16b,v4.16b,v24.16b
+ eor v5.16b,v5.16b,v25.16b
+ eor v6.16b,v6.16b,v26.16b
+ eor v7.16b,v7.16b,v27.16b
+ st1 {v4.16b,v5.16b,v6.16b,v7.16b},[x0],#64
+
+ ld1 {v4.16b,v5.16b,v6.16b,v7.16b},[x1],#64
+ eor v8.16b,v8.16b,v0.16b
+ ldp q24,q25,[sp,#0]
+ eor v9.16b,v9.16b,v1.16b
+ ldp q26,q27,[sp,#32]
+ eor v10.16b,v10.16b,v2.16b
+ eor v11.16b,v11.16b,v3.16b
+ st1 {v8.16b,v9.16b,v10.16b,v11.16b},[x0],#64
+
+ ld1 {v8.16b,v9.16b,v10.16b,v11.16b},[x1],#64
+ eor v12.16b,v12.16b,v4.16b
+ eor v13.16b,v13.16b,v5.16b
+ eor v14.16b,v14.16b,v6.16b
+ eor v15.16b,v15.16b,v7.16b
+ st1 {v12.16b,v13.16b,v14.16b,v15.16b},[x0],#64
+
+ ld1 {v12.16b,v13.16b,v14.16b,v15.16b},[x1],#64
+ eor v16.16b,v16.16b,v8.16b
+ eor v17.16b,v17.16b,v9.16b
+ eor v18.16b,v18.16b,v10.16b
+ eor v19.16b,v19.16b,v11.16b
+ st1 {v16.16b,v17.16b,v18.16b,v19.16b},[x0],#64
+
+ shl v0.4s,v31.4s,#1 // 4 -> 8
+ eor v20.16b,v20.16b,v12.16b
+ eor v21.16b,v21.16b,v13.16b
+ eor v22.16b,v22.16b,v14.16b
+ eor v23.16b,v23.16b,v15.16b
+ st1 {v20.16b,v21.16b,v22.16b,v23.16b},[x0],#64
+
+ add v27.4s,v27.4s,v0.4s // += 8
+ add v28.4s,v28.4s,v0.4s
+ add v29.4s,v29.4s,v0.4s
+ add v30.4s,v30.4s,v0.4s
+
+ b.hs .Loop_outer_512_neon
+
+ adds x2,x2,#512
+ ushr v0.4s,v31.4s,#2 // 4 -> 1
+
+ ldp d8,d9,[sp,#128+0] // meet ABI requirements
+ ldp d10,d11,[sp,#128+16]
+ ldp d12,d13,[sp,#128+32]
+ ldp d14,d15,[sp,#128+48]
+
+ stp q24,q31,[sp,#0] // wipe off-load area
+ stp q24,q31,[sp,#32]
+ stp q24,q31,[sp,#64]
+
+ b.eq .Ldone_512_neon
+
+ cmp x2,#192
+ sub v27.4s,v27.4s,v0.4s // -= 1
+ sub v28.4s,v28.4s,v0.4s
+ sub v29.4s,v29.4s,v0.4s
+ add sp,sp,#128
+ b.hs .Loop_outer_neon
+
+ eor v25.16b,v25.16b,v25.16b
+ eor v26.16b,v26.16b,v26.16b
+ eor v27.16b,v27.16b,v27.16b
+ eor v28.16b,v28.16b,v28.16b
+ eor v29.16b,v29.16b,v29.16b
+ eor v30.16b,v30.16b,v30.16b
+ b .Loop_outer
+
+.Ldone_512_neon:
+ ldp x19,x20,[x29,#16]
+ add sp,sp,#128+64
+ ldp x21,x22,[x29,#32]
+ ldp x23,x24,[x29,#48]
+ ldp x25,x26,[x29,#64]
+ ldp x27,x28,[x29,#80]
+ ldp x29,x30,[sp],#96
+ ret
+.size ChaCha20_512_neon,.-ChaCha20_512_neon
+#endif
diff --git a/linux-aarch64/crypto/modes/ghashv8-armx64.S b/linux-aarch64/crypto/modes/ghashv8-armx64.S
index 8d44667e..f39f3ba8 100644
--- a/linux-aarch64/crypto/modes/ghashv8-armx64.S
+++ b/linux-aarch64/crypto/modes/ghashv8-armx64.S
@@ -6,6 +6,7 @@
.arch armv8-a+crypto
#endif
.globl gcm_init_v8
+.hidden gcm_init_v8
.type gcm_init_v8,%function
.align 4
gcm_init_v8:
@@ -56,6 +57,7 @@ gcm_init_v8:
ret
.size gcm_init_v8,.-gcm_init_v8
.globl gcm_gmult_v8
+.hidden gcm_gmult_v8
.type gcm_gmult_v8,%function
.align 4
gcm_gmult_v8:
@@ -97,6 +99,7 @@ gcm_gmult_v8:
ret
.size gcm_gmult_v8,.-gcm_gmult_v8
.globl gcm_ghash_v8
+.hidden gcm_ghash_v8
.type gcm_ghash_v8,%function
.align 4
gcm_ghash_v8:
@@ -229,4 +232,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
+#endif
diff --git a/linux-aarch64/crypto/sha/sha1-armv8.S b/linux-aarch64/crypto/sha/sha1-armv8.S
index 6cf9877e..cfb4aa02 100644
--- a/linux-aarch64/crypto/sha/sha1-armv8.S
+++ b/linux-aarch64/crypto/sha/sha1-armv8.S
@@ -5,6 +5,7 @@
.globl sha1_block_data_order
+.hidden sha1_block_data_order
.type sha1_block_data_order,%function
.align 6
sha1_block_data_order:
@@ -1212,4 +1213,4 @@ sha1_block_armv8:
.align 2
.align 2
.comm OPENSSL_armcap_P,4,4
-#endif \ No newline at end of file
+#endif
diff --git a/linux-aarch64/crypto/sha/sha256-armv8.S b/linux-aarch64/crypto/sha/sha256-armv8.S
index 0fad0094..bfc552cb 100644
--- a/linux-aarch64/crypto/sha/sha256-armv8.S
+++ b/linux-aarch64/crypto/sha/sha256-armv8.S
@@ -5,6 +5,7 @@
.globl sha256_block_data_order
+.hidden sha256_block_data_order
.type sha256_block_data_order,%function
.align 6
sha256_block_data_order:
@@ -1142,4 +1143,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
+#endif
diff --git a/linux-aarch64/crypto/sha/sha512-armv8.S b/linux-aarch64/crypto/sha/sha512-armv8.S
index 517c033f..46457229 100644
--- a/linux-aarch64/crypto/sha/sha512-armv8.S
+++ b/linux-aarch64/crypto/sha/sha512-armv8.S
@@ -5,6 +5,7 @@
.globl sha512_block_data_order
+.hidden sha512_block_data_order
.type sha512_block_data_order,%function
.align 6
sha512_block_data_order:
@@ -1022,4 +1023,4 @@ sha512_block_data_order:
.align 2
.align 2
.comm OPENSSL_armcap_P,4,4
-#endif \ No newline at end of file
+#endif
diff --git a/linux-arm/crypto/aes/aes-armv4.S b/linux-arm/crypto/aes/aes-armv4.S
index c4d70657..bc11e3f1 100644
--- a/linux-arm/crypto/aes/aes-armv4.S
+++ b/linux-arm/crypto/aes/aes-armv4.S
@@ -1197,4 +1197,4 @@ _armv4_AES_decrypt:
.align 2
#endif
-#endif \ No newline at end of file
+#endif
diff --git a/linux-arm/crypto/aes/aesv8-armx32.S b/linux-arm/crypto/aes/aesv8-armx32.S
index 6012b0ce..95a2ea4d 100644
--- a/linux-arm/crypto/aes/aesv8-armx32.S
+++ b/linux-arm/crypto/aes/aesv8-armx32.S
@@ -13,6 +13,7 @@
.long 0x1b,0x1b,0x1b,0x1b
.globl aes_v8_set_encrypt_key
+.hidden aes_v8_set_encrypt_key
.type aes_v8_set_encrypt_key,%function
.align 5
aes_v8_set_encrypt_key:
@@ -183,6 +184,7 @@ aes_v8_set_encrypt_key:
.size aes_v8_set_encrypt_key,.-aes_v8_set_encrypt_key
.globl aes_v8_set_decrypt_key
+.hidden aes_v8_set_decrypt_key
.type aes_v8_set_decrypt_key,%function
.align 5
aes_v8_set_decrypt_key:
@@ -220,6 +222,7 @@ aes_v8_set_decrypt_key:
ldmia sp!,{r4,pc}
.size aes_v8_set_decrypt_key,.-aes_v8_set_decrypt_key
.globl aes_v8_encrypt
+.hidden aes_v8_encrypt
.type aes_v8_encrypt,%function
.align 5
aes_v8_encrypt:
@@ -249,6 +252,7 @@ aes_v8_encrypt:
bx lr
.size aes_v8_encrypt,.-aes_v8_encrypt
.globl aes_v8_decrypt
+.hidden aes_v8_decrypt
.type aes_v8_decrypt,%function
.align 5
aes_v8_decrypt:
@@ -278,6 +282,7 @@ aes_v8_decrypt:
bx lr
.size aes_v8_decrypt,.-aes_v8_decrypt
.globl aes_v8_cbc_encrypt
+.hidden aes_v8_cbc_encrypt
.type aes_v8_cbc_encrypt,%function
.align 5
aes_v8_cbc_encrypt:
@@ -570,6 +575,7 @@ aes_v8_cbc_encrypt:
ldmia sp!,{r4,r5,r6,r7,r8,pc}
.size aes_v8_cbc_encrypt,.-aes_v8_cbc_encrypt
.globl aes_v8_ctr32_encrypt_blocks
+.hidden aes_v8_ctr32_encrypt_blocks
.type aes_v8_ctr32_encrypt_blocks,%function
.align 5
aes_v8_ctr32_encrypt_blocks:
@@ -753,4 +759,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
+#endif
diff --git a/linux-arm/crypto/aes/bsaes-armv7.S b/linux-arm/crypto/aes/bsaes-armv7.S
index a3ebec88..abb414d5 100644
--- a/linux-arm/crypto/aes/bsaes-armv7.S
+++ b/linux-arm/crypto/aes/bsaes-armv7.S
@@ -2574,4 +2574,4 @@ bsaes_xts_decrypt:
.size bsaes_xts_decrypt,.-bsaes_xts_decrypt
#endif
-#endif \ No newline at end of file
+#endif
diff --git a/linux-arm/crypto/bn/armv4-mont.S b/linux-arm/crypto/bn/armv4-mont.S
index fc671e8d..e59599f8 100644
--- a/linux-arm/crypto/bn/armv4-mont.S
+++ b/linux-arm/crypto/bn/armv4-mont.S
@@ -28,7 +28,7 @@ bn_mul_mont:
#ifdef __APPLE__
ldr r0,[r0]
#endif
- tst r0,#1 @ NEON available?
+ tst r0,#ARMV7_NEON @ NEON available?
ldmia sp, {r0,r2}
beq .Lialu
add sp,sp,#8
@@ -586,4 +586,4 @@ bn_mul8x_mont_neon:
.comm OPENSSL_armcap_P,4,4
.hidden OPENSSL_armcap_P
#endif
-#endif \ No newline at end of file
+#endif
diff --git a/linux-arm/crypto/chacha/chacha-armv4.S b/linux-arm/crypto/chacha/chacha-armv4.S
new file mode 100644
index 00000000..19a4d2c4
--- /dev/null
+++ b/linux-arm/crypto/chacha/chacha-armv4.S
@@ -0,0 +1,1471 @@
+#if defined(__arm__)
+#include <openssl/arm_arch.h>
+
+.text
+#if defined(__thumb2__)
+.syntax unified
+.thumb
+#else
+.code 32
+#endif
+
+#if defined(__thumb2__) || defined(__clang__)
+#define ldrhsb ldrbhs
+#endif
+
+.align 5
+.Lsigma:
+.long 0x61707865,0x3320646e,0x79622d32,0x6b206574 @ endian-neutral
+.Lone:
+.long 1,0,0,0
+#if __ARM_MAX_ARCH__>=7
+.LOPENSSL_armcap:
+.word OPENSSL_armcap_P-.LChaCha20_ctr32
+#else
+.word -1
+#endif
+
+.globl ChaCha20_ctr32
+.hidden ChaCha20_ctr32
+.type ChaCha20_ctr32,%function
+.align 5
+ChaCha20_ctr32:
+.LChaCha20_ctr32:
+ ldr r12,[sp,#0] @ pull pointer to counter and nonce
+ stmdb sp!,{r0,r1,r2,r4-r11,lr}
+#if __ARM_ARCH__<7 && !defined(__thumb2__)
+ sub r14,pc,#16 @ ChaCha20_ctr32
+#else
+ adr r14,.LChaCha20_ctr32
+#endif
+ cmp r2,#0 @ len==0?
+#ifdef __thumb2__
+ itt eq
+#endif
+ addeq sp,sp,#4*3
+ beq .Lno_data
+#if __ARM_MAX_ARCH__>=7
+ cmp r2,#192 @ test len
+ bls .Lshort
+ ldr r4,[r14,#-32]
+ ldr r4,[r14,r4]
+# ifdef __APPLE__
+ ldr r4,[r4]
+# endif
+ tst r4,#ARMV7_NEON
+ bne .LChaCha20_neon
+.Lshort:
+#endif
+ ldmia r12,{r4,r5,r6,r7} @ load counter and nonce
+ sub sp,sp,#4*(16) @ off-load area
+ sub r14,r14,#64 @ .Lsigma
+ stmdb sp!,{r4,r5,r6,r7} @ copy counter and nonce
+ ldmia r3,{r4,r5,r6,r7,r8,r9,r10,r11} @ load key
+ ldmia r14,{r0,r1,r2,r3} @ load sigma
+ stmdb sp!,{r4,r5,r6,r7,r8,r9,r10,r11} @ copy key
+ stmdb sp!,{r0,r1,r2,r3} @ copy sigma
+ str r10,[sp,#4*(16+10)] @ off-load "rx"
+ str r11,[sp,#4*(16+11)] @ off-load "rx"
+ b .Loop_outer_enter
+
+.align 4
+.Loop_outer:
+ ldmia sp,{r0,r1,r2,r3,r4,r5,r6,r7,r8,r9} @ load key material
+ str r11,[sp,#4*(32+2)] @ save len
+ str r12, [sp,#4*(32+1)] @ save inp
+ str r14, [sp,#4*(32+0)] @ save out
+.Loop_outer_enter:
+ ldr r11, [sp,#4*(15)]
+ ldr r12,[sp,#4*(12)] @ modulo-scheduled load
+ ldr r10, [sp,#4*(13)]
+ ldr r14,[sp,#4*(14)]
+ str r11, [sp,#4*(16+15)]
+ mov r11,#10
+ b .Loop
+
+.align 4
+.Loop:
+ subs r11,r11,#1
+ add r0,r0,r4
+ mov r12,r12,ror#16
+ add r1,r1,r5
+ mov r10,r10,ror#16
+ eor r12,r12,r0,ror#16
+ eor r10,r10,r1,ror#16
+ add r8,r8,r12
+ mov r4,r4,ror#20
+ add r9,r9,r10
+ mov r5,r5,ror#20
+ eor r4,r4,r8,ror#20
+ eor r5,r5,r9,ror#20
+ add r0,r0,r4
+ mov r12,r12,ror#24
+ add r1,r1,r5
+ mov r10,r10,ror#24
+ eor r12,r12,r0,ror#24
+ eor r10,r10,r1,ror#24
+ add r8,r8,r12
+ mov r4,r4,ror#25
+ add r9,r9,r10
+ mov r5,r5,ror#25
+ str r10,[sp,#4*(16+13)]
+ ldr r10,[sp,#4*(16+15)]
+ eor r4,r4,r8,ror#25
+ eor r5,r5,r9,ror#25
+ str r8,[sp,#4*(16+8)]
+ ldr r8,[sp,#4*(16+10)]
+ add r2,r2,r6
+ mov r14,r14,ror#16
+ str r9,[sp,#4*(16+9)]
+ ldr r9,[sp,#4*(16+11)]
+ add r3,r3,r7
+ mov r10,r10,ror#16
+ eor r14,r14,r2,ror#16
+ eor r10,r10,r3,ror#16
+ add r8,r8,r14
+ mov r6,r6,ror#20
+ add r9,r9,r10
+ mov r7,r7,ror#20
+ eor r6,r6,r8,ror#20
+ eor r7,r7,r9,ror#20
+ add r2,r2,r6
+ mov r14,r14,ror#24
+ add r3,r3,r7
+ mov r10,r10,ror#24
+ eor r14,r14,r2,ror#24
+ eor r10,r10,r3,ror#24
+ add r8,r8,r14
+ mov r6,r6,ror#25
+ add r9,r9,r10
+ mov r7,r7,ror#25
+ eor r6,r6,r8,ror#25
+ eor r7,r7,r9,ror#25
+ add r0,r0,r5
+ mov r10,r10,ror#16
+ add r1,r1,r6
+ mov r12,r12,ror#16
+ eor r10,r10,r0,ror#16
+ eor r12,r12,r1,ror#16
+ add r8,r8,r10
+ mov r5,r5,ror#20
+ add r9,r9,r12
+ mov r6,r6,ror#20
+ eor r5,r5,r8,ror#20
+ eor r6,r6,r9,ror#20
+ add r0,r0,r5
+ mov r10,r10,ror#24
+ add r1,r1,r6
+ mov r12,r12,ror#24
+ eor r10,r10,r0,ror#24
+ eor r12,r12,r1,ror#24
+ add r8,r8,r10
+ mov r5,r5,ror#25
+ str r10,[sp,#4*(16+15)]
+ ldr r10,[sp,#4*(16+13)]
+ add r9,r9,r12
+ mov r6,r6,ror#25
+ eor r5,r5,r8,ror#25
+ eor r6,r6,r9,ror#25
+ str r8,[sp,#4*(16+10)]
+ ldr r8,[sp,#4*(16+8)]
+ add r2,r2,r7
+ mov r10,r10,ror#16
+ str r9,[sp,#4*(16+11)]
+ ldr r9,[sp,#4*(16+9)]
+ add r3,r3,r4
+ mov r14,r14,ror#16
+ eor r10,r10,r2,ror#16
+ eor r14,r14,r3,ror#16
+ add r8,r8,r10
+ mov r7,r7,ror#20
+ add r9,r9,r14
+ mov r4,r4,ror#20
+ eor r7,r7,r8,ror#20
+ eor r4,r4,r9,ror#20
+ add r2,r2,r7
+ mov r10,r10,ror#24
+ add r3,r3,r4
+ mov r14,r14,ror#24
+ eor r10,r10,r2,ror#24
+ eor r14,r14,r3,ror#24
+ add r8,r8,r10
+ mov r7,r7,ror#25
+ add r9,r9,r14
+ mov r4,r4,ror#25
+ eor r7,r7,r8,ror#25
+ eor r4,r4,r9,ror#25
+ bne .Loop
+
+ ldr r11,[sp,#4*(32+2)] @ load len
+
+ str r8, [sp,#4*(16+8)] @ modulo-scheduled store
+ str r9, [sp,#4*(16+9)]
+ str r12,[sp,#4*(16+12)]
+ str r10, [sp,#4*(16+13)]
+ str r14,[sp,#4*(16+14)]
+
+ @ at this point we have first half of 512-bit result in
+ @ rx and second half at sp+4*(16+8)
+
+ cmp r11,#64 @ done yet?
+#ifdef __thumb2__
+ itete lo
+#endif
+ addlo r12,sp,#4*(0) @ shortcut or ...
+ ldrhs r12,[sp,#4*(32+1)] @ ... load inp
+ addlo r14,sp,#4*(0) @ shortcut or ...
+ ldrhs r14,[sp,#4*(32+0)] @ ... load out
+
+ ldr r8,[sp,#4*(0)] @ load key material
+ ldr r9,[sp,#4*(1)]
+
+#if __ARM_ARCH__>=6 || !defined(__ARMEB__)
+# if __ARM_ARCH__<7
+ orr r10,r12,r14
+ tst r10,#3 @ are input and output aligned?
+ ldr r10,[sp,#4*(2)]
+ bne .Lunaligned
+ cmp r11,#64 @ restore flags
+# else
+ ldr r10,[sp,#4*(2)]
+# endif
+ ldr r11,[sp,#4*(3)]
+
+ add r0,r0,r8 @ accumulate key material
+ add r1,r1,r9
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhs r8,[r12],#16 @ load input
+ ldrhs r9,[r12,#-12]
+
+ add r2,r2,r10
+ add r3,r3,r11
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhs r10,[r12,#-8]
+ ldrhs r11,[r12,#-4]
+# if __ARM_ARCH__>=6 && defined(__ARMEB__)
+ rev r0,r0
+ rev r1,r1
+ rev r2,r2
+ rev r3,r3
+# endif
+# ifdef __thumb2__
+ itt hs
+# endif
+ eorhs r0,r0,r8 @ xor with input
+ eorhs r1,r1,r9
+ add r8,sp,#4*(4)
+ str r0,[r14],#16 @ store output
+# ifdef __thumb2__
+ itt hs
+# endif
+ eorhs r2,r2,r10
+ eorhs r3,r3,r11
+ ldmia r8,{r8,r9,r10,r11} @ load key material
+ str r1,[r14,#-12]
+ str r2,[r14,#-8]
+ str r3,[r14,#-4]
+
+ add r4,r4,r8 @ accumulate key material
+ add r5,r5,r9
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhs r8,[r12],#16 @ load input
+ ldrhs r9,[r12,#-12]
+ add r6,r6,r10
+ add r7,r7,r11
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhs r10,[r12,#-8]
+ ldrhs r11,[r12,#-4]
+# if __ARM_ARCH__>=6 && defined(__ARMEB__)
+ rev r4,r4
+ rev r5,r5
+ rev r6,r6
+ rev r7,r7
+# endif
+# ifdef __thumb2__
+ itt hs
+# endif
+ eorhs r4,r4,r8
+ eorhs r5,r5,r9
+ add r8,sp,#4*(8)
+ str r4,[r14],#16 @ store output
+# ifdef __thumb2__
+ itt hs
+# endif
+ eorhs r6,r6,r10
+ eorhs r7,r7,r11
+ str r5,[r14,#-12]
+ ldmia r8,{r8,r9,r10,r11} @ load key material
+ str r6,[r14,#-8]
+ add r0,sp,#4*(16+8)
+ str r7,[r14,#-4]
+
+ ldmia r0,{r0,r1,r2,r3,r4,r5,r6,r7} @ load second half
+
+ add r0,r0,r8 @ accumulate key material
+ add r1,r1,r9
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhs r8,[r12],#16 @ load input
+ ldrhs r9,[r12,#-12]
+# ifdef __thumb2__
+ itt hi
+# endif
+ strhi r10,[sp,#4*(16+10)] @ copy "rx" while at it
+ strhi r11,[sp,#4*(16+11)] @ copy "rx" while at it
+ add r2,r2,r10
+ add r3,r3,r11
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhs r10,[r12,#-8]
+ ldrhs r11,[r12,#-4]
+# if __ARM_ARCH__>=6 && defined(__ARMEB__)
+ rev r0,r0
+ rev r1,r1
+ rev r2,r2
+ rev r3,r3
+# endif
+# ifdef __thumb2__
+ itt hs
+# endif
+ eorhs r0,r0,r8
+ eorhs r1,r1,r9
+ add r8,sp,#4*(12)
+ str r0,[r14],#16 @ store output
+# ifdef __thumb2__
+ itt hs
+# endif
+ eorhs r2,r2,r10
+ eorhs r3,r3,r11
+ str r1,[r14,#-12]
+ ldmia r8,{r8,r9,r10,r11} @ load key material
+ str r2,[r14,#-8]
+ str r3,[r14,#-4]
+
+ add r4,r4,r8 @ accumulate key material
+ add r5,r5,r9
+# ifdef __thumb2__
+ itt hi
+# endif
+ addhi r8,r8,#1 @ next counter value
+ strhi r8,[sp,#4*(12)] @ save next counter value
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhs r8,[r12],#16 @ load input
+ ldrhs r9,[r12,#-12]
+ add r6,r6,r10
+ add r7,r7,r11
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhs r10,[r12,#-8]
+ ldrhs r11,[r12,#-4]
+# if __ARM_ARCH__>=6 && defined(__ARMEB__)
+ rev r4,r4
+ rev r5,r5
+ rev r6,r6
+ rev r7,r7
+# endif
+# ifdef __thumb2__
+ itt hs
+# endif
+ eorhs r4,r4,r8
+ eorhs r5,r5,r9
+# ifdef __thumb2__
+ it ne
+# endif
+ ldrne r8,[sp,#4*(32+2)] @ re-load len
+# ifdef __thumb2__
+ itt hs
+# endif
+ eorhs r6,r6,r10
+ eorhs r7,r7,r11
+ str r4,[r14],#16 @ store output
+ str r5,[r14,#-12]
+# ifdef __thumb2__
+ it hs
+# endif
+ subhs r11,r8,#64 @ len-=64
+ str r6,[r14,#-8]
+ str r7,[r14,#-4]
+ bhi .Loop_outer
+
+ beq .Ldone
+# if __ARM_ARCH__<7
+ b .Ltail
+
+.align 4
+.Lunaligned:@ unaligned endian-neutral path
+ cmp r11,#64 @ restore flags
+# endif
+#endif
+#if __ARM_ARCH__<7
+ ldr r11,[sp,#4*(3)]
+ add r0,r0,r8 @ accumulate key material
+ add r1,r1,r9
+ add r2,r2,r10
+# ifdef __thumb2__
+ itete lo
+# endif
+ eorlo r8,r8,r8 @ zero or ...
+ ldrhsb r8,[r12],#16 @ ... load input
+ eorlo r9,r9,r9
+ ldrhsb r9,[r12,#-12]
+
+ add r3,r3,r11
+# ifdef __thumb2__
+ itete lo
+# endif
+ eorlo r10,r10,r10
+ ldrhsb r10,[r12,#-8]
+ eorlo r11,r11,r11
+ ldrhsb r11,[r12,#-4]
+
+ eor r0,r8,r0 @ xor with input (or zero)
+ eor r1,r9,r1
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhsb r8,[r12,#-15] @ load more input
+ ldrhsb r9,[r12,#-11]
+ eor r2,r10,r2
+ strb r0,[r14],#16 @ store output
+ eor r3,r11,r3
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhsb r10,[r12,#-7]
+ ldrhsb r11,[r12,#-3]
+ strb r1,[r14,#-12]
+ eor r0,r8,r0,lsr#8
+ strb r2,[r14,#-8]
+ eor r1,r9,r1,lsr#8
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhsb r8,[r12,#-14] @ load more input
+ ldrhsb r9,[r12,#-10]
+ strb r3,[r14,#-4]
+ eor r2,r10,r2,lsr#8
+ strb r0,[r14,#-15]
+ eor r3,r11,r3,lsr#8
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhsb r10,[r12,#-6]
+ ldrhsb r11,[r12,#-2]
+ strb r1,[r14,#-11]
+ eor r0,r8,r0,lsr#8
+ strb r2,[r14,#-7]
+ eor r1,r9,r1,lsr#8
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhsb r8,[r12,#-13] @ load more input
+ ldrhsb r9,[r12,#-9]
+ strb r3,[r14,#-3]
+ eor r2,r10,r2,lsr#8
+ strb r0,[r14,#-14]
+ eor r3,r11,r3,lsr#8
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhsb r10,[r12,#-5]
+ ldrhsb r11,[r12,#-1]
+ strb r1,[r14,#-10]
+ strb r2,[r14,#-6]
+ eor r0,r8,r0,lsr#8
+ strb r3,[r14,#-2]
+ eor r1,r9,r1,lsr#8
+ strb r0,[r14,#-13]
+ eor r2,r10,r2,lsr#8
+ strb r1,[r14,#-9]
+ eor r3,r11,r3,lsr#8
+ strb r2,[r14,#-5]
+ strb r3,[r14,#-1]
+ add r8,sp,#4*(4+0)
+ ldmia r8,{r8,r9,r10,r11} @ load key material
+ add r0,sp,#4*(16+8)
+ add r4,r4,r8 @ accumulate key material
+ add r5,r5,r9
+ add r6,r6,r10
+# ifdef __thumb2__
+ itete lo
+# endif
+ eorlo r8,r8,r8 @ zero or ...
+ ldrhsb r8,[r12],#16 @ ... load input
+ eorlo r9,r9,r9
+ ldrhsb r9,[r12,#-12]
+
+ add r7,r7,r11
+# ifdef __thumb2__
+ itete lo
+# endif
+ eorlo r10,r10,r10
+ ldrhsb r10,[r12,#-8]
+ eorlo r11,r11,r11
+ ldrhsb r11,[r12,#-4]
+
+ eor r4,r8,r4 @ xor with input (or zero)
+ eor r5,r9,r5
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhsb r8,[r12,#-15] @ load more input
+ ldrhsb r9,[r12,#-11]
+ eor r6,r10,r6
+ strb r4,[r14],#16 @ store output
+ eor r7,r11,r7
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhsb r10,[r12,#-7]
+ ldrhsb r11,[r12,#-3]
+ strb r5,[r14,#-12]
+ eor r4,r8,r4,lsr#8
+ strb r6,[r14,#-8]
+ eor r5,r9,r5,lsr#8
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhsb r8,[r12,#-14] @ load more input
+ ldrhsb r9,[r12,#-10]
+ strb r7,[r14,#-4]
+ eor r6,r10,r6,lsr#8
+ strb r4,[r14,#-15]
+ eor r7,r11,r7,lsr#8
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhsb r10,[r12,#-6]
+ ldrhsb r11,[r12,#-2]
+ strb r5,[r14,#-11]
+ eor r4,r8,r4,lsr#8
+ strb r6,[r14,#-7]
+ eor r5,r9,r5,lsr#8
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhsb r8,[r12,#-13] @ load more input
+ ldrhsb r9,[r12,#-9]
+ strb r7,[r14,#-3]
+ eor r6,r10,r6,lsr#8
+ strb r4,[r14,#-14]
+ eor r7,r11,r7,lsr#8
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhsb r10,[r12,#-5]
+ ldrhsb r11,[r12,#-1]
+ strb r5,[r14,#-10]
+ strb r6,[r14,#-6]
+ eor r4,r8,r4,lsr#8
+ strb r7,[r14,#-2]
+ eor r5,r9,r5,lsr#8
+ strb r4,[r14,#-13]
+ eor r6,r10,r6,lsr#8
+ strb r5,[r14,#-9]
+ eor r7,r11,r7,lsr#8
+ strb r6,[r14,#-5]
+ strb r7,[r14,#-1]
+ add r8,sp,#4*(4+4)
+ ldmia r8,{r8,r9,r10,r11} @ load key material
+ ldmia r0,{r0,r1,r2,r3,r4,r5,r6,r7} @ load second half
+# ifdef __thumb2__
+ itt hi
+# endif
+ strhi r10,[sp,#4*(16+10)] @ copy "rx"
+ strhi r11,[sp,#4*(16+11)] @ copy "rx"
+ add r0,r0,r8 @ accumulate key material
+ add r1,r1,r9
+ add r2,r2,r10
+# ifdef __thumb2__
+ itete lo
+# endif
+ eorlo r8,r8,r8 @ zero or ...
+ ldrhsb r8,[r12],#16 @ ... load input
+ eorlo r9,r9,r9
+ ldrhsb r9,[r12,#-12]
+
+ add r3,r3,r11
+# ifdef __thumb2__
+ itete lo
+# endif
+ eorlo r10,r10,r10
+ ldrhsb r10,[r12,#-8]
+ eorlo r11,r11,r11
+ ldrhsb r11,[r12,#-4]
+
+ eor r0,r8,r0 @ xor with input (or zero)
+ eor r1,r9,r1
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhsb r8,[r12,#-15] @ load more input
+ ldrhsb r9,[r12,#-11]
+ eor r2,r10,r2
+ strb r0,[r14],#16 @ store output
+ eor r3,r11,r3
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhsb r10,[r12,#-7]
+ ldrhsb r11,[r12,#-3]
+ strb r1,[r14,#-12]
+ eor r0,r8,r0,lsr#8
+ strb r2,[r14,#-8]
+ eor r1,r9,r1,lsr#8
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhsb r8,[r12,#-14] @ load more input
+ ldrhsb r9,[r12,#-10]
+ strb r3,[r14,#-4]
+ eor r2,r10,r2,lsr#8
+ strb r0,[r14,#-15]
+ eor r3,r11,r3,lsr#8
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhsb r10,[r12,#-6]
+ ldrhsb r11,[r12,#-2]
+ strb r1,[r14,#-11]
+ eor r0,r8,r0,lsr#8
+ strb r2,[r14,#-7]
+ eor r1,r9,r1,lsr#8
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhsb r8,[r12,#-13] @ load more input
+ ldrhsb r9,[r12,#-9]
+ strb r3,[r14,#-3]
+ eor r2,r10,r2,lsr#8
+ strb r0,[r14,#-14]
+ eor r3,r11,r3,lsr#8
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhsb r10,[r12,#-5]
+ ldrhsb r11,[r12,#-1]
+ strb r1,[r14,#-10]
+ strb r2,[r14,#-6]
+ eor r0,r8,r0,lsr#8
+ strb r3,[r14,#-2]
+ eor r1,r9,r1,lsr#8
+ strb r0,[r14,#-13]
+ eor r2,r10,r2,lsr#8
+ strb r1,[r14,#-9]
+ eor r3,r11,r3,lsr#8
+ strb r2,[r14,#-5]
+ strb r3,[r14,#-1]
+ add r8,sp,#4*(4+8)
+ ldmia r8,{r8,r9,r10,r11} @ load key material
+ add r4,r4,r8 @ accumulate key material
+# ifdef __thumb2__
+ itt hi
+# endif
+ addhi r8,r8,#1 @ next counter value
+ strhi r8,[sp,#4*(12)] @ save next counter value
+ add r5,r5,r9
+ add r6,r6,r10
+# ifdef __thumb2__
+ itete lo
+# endif
+ eorlo r8,r8,r8 @ zero or ...
+ ldrhsb r8,[r12],#16 @ ... load input
+ eorlo r9,r9,r9
+ ldrhsb r9,[r12,#-12]
+
+ add r7,r7,r11
+# ifdef __thumb2__
+ itete lo
+# endif
+ eorlo r10,r10,r10
+ ldrhsb r10,[r12,#-8]
+ eorlo r11,r11,r11
+ ldrhsb r11,[r12,#-4]
+
+ eor r4,r8,r4 @ xor with input (or zero)
+ eor r5,r9,r5
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhsb r8,[r12,#-15] @ load more input
+ ldrhsb r9,[r12,#-11]
+ eor r6,r10,r6
+ strb r4,[r14],#16 @ store output
+ eor r7,r11,r7
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhsb r10,[r12,#-7]
+ ldrhsb r11,[r12,#-3]
+ strb r5,[r14,#-12]
+ eor r4,r8,r4,lsr#8
+ strb r6,[r14,#-8]
+ eor r5,r9,r5,lsr#8
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhsb r8,[r12,#-14] @ load more input
+ ldrhsb r9,[r12,#-10]
+ strb r7,[r14,#-4]
+ eor r6,r10,r6,lsr#8
+ strb r4,[r14,#-15]
+ eor r7,r11,r7,lsr#8
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhsb r10,[r12,#-6]
+ ldrhsb r11,[r12,#-2]
+ strb r5,[r14,#-11]
+ eor r4,r8,r4,lsr#8
+ strb r6,[r14,#-7]
+ eor r5,r9,r5,lsr#8
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhsb r8,[r12,#-13] @ load more input
+ ldrhsb r9,[r12,#-9]
+ strb r7,[r14,#-3]
+ eor r6,r10,r6,lsr#8
+ strb r4,[r14,#-14]
+ eor r7,r11,r7,lsr#8
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhsb r10,[r12,#-5]
+ ldrhsb r11,[r12,#-1]
+ strb r5,[r14,#-10]
+ strb r6,[r14,#-6]
+ eor r4,r8,r4,lsr#8
+ strb r7,[r14,#-2]
+ eor r5,r9,r5,lsr#8
+ strb r4,[r14,#-13]
+ eor r6,r10,r6,lsr#8
+ strb r5,[r14,#-9]
+ eor r7,r11,r7,lsr#8
+ strb r6,[r14,#-5]
+ strb r7,[r14,#-1]
+# ifdef __thumb2__
+ it ne
+# endif
+ ldrne r8,[sp,#4*(32+2)] @ re-load len
+# ifdef __thumb2__
+ it hs
+# endif
+ subhs r11,r8,#64 @ len-=64
+ bhi .Loop_outer
+
+ beq .Ldone
+#endif
+
+.Ltail:
+ ldr r12,[sp,#4*(32+1)] @ load inp
+ add r9,sp,#4*(0)
+ ldr r14,[sp,#4*(32+0)] @ load out
+
+.Loop_tail:
+ ldrb r10,[r9],#1 @ read buffer on stack
+ ldrb r11,[r12],#1 @ read input
+ subs r8,r8,#1
+ eor r11,r11,r10
+ strb r11,[r14],#1 @ store output
+ bne .Loop_tail
+
+.Ldone:
+ add sp,sp,#4*(32+3)
+.Lno_data:
+ ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11,pc}
+.size ChaCha20_ctr32,.-ChaCha20_ctr32
+#if __ARM_MAX_ARCH__>=7
+.arch armv7-a
+.fpu neon
+
+.type ChaCha20_neon,%function
+.align 5
+ChaCha20_neon:
+ ldr r12,[sp,#0] @ pull pointer to counter and nonce
+ stmdb sp!,{r0,r1,r2,r4-r11,lr}
+.LChaCha20_neon:
+ adr r14,.Lsigma
+ vstmdb sp!,{d8,d9,d10,d11,d12,d13,d14,d15} @ ABI spec says so
+ stmdb sp!,{r0,r1,r2,r3}
+
+ vld1.32 {q1,q2},[r3] @ load key
+ ldmia r3,{r4,r5,r6,r7,r8,r9,r10,r11} @ load key
+
+ sub sp,sp,#4*(16+16)
+ vld1.32 {q3},[r12] @ load counter and nonce
+ add r12,sp,#4*8
+ ldmia r14,{r0,r1,r2,r3} @ load sigma
+ vld1.32 {q0},[r14]! @ load sigma
+ vld1.32 {q12},[r14] @ one
+ vst1.32 {q2,q3},[r12] @ copy 1/2key|counter|nonce
+ vst1.32 {q0,q1},[sp] @ copy sigma|1/2key
+
+ str r10,[sp,#4*(16+10)] @ off-load "rx"
+ str r11,[sp,#4*(16+11)] @ off-load "rx"
+ vshl.i32 d26,d24,#1 @ two
+ vstr d24,[sp,#4*(16+0)]
+ vshl.i32 d28,d24,#2 @ four
+ vstr d26,[sp,#4*(16+2)]
+ vmov q4,q0
+ vstr d28,[sp,#4*(16+4)]
+ vmov q8,q0
+ vmov q5,q1
+ vmov q9,q1
+ b .Loop_neon_enter
+
+.align 4
+.Loop_neon_outer:
+ ldmia sp,{r0,r1,r2,r3,r4,r5,r6,r7,r8,r9} @ load key material
+ cmp r11,#64*2 @ if len<=64*2
+ bls .Lbreak_neon @ switch to integer-only
+ vmov q4,q0
+ str r11,[sp,#4*(32+2)] @ save len
+ vmov q8,q0
+ str r12, [sp,#4*(32+1)] @ save inp
+ vmov q5,q1
+ str r14, [sp,#4*(32+0)] @ save out
+ vmov q9,q1
+.Loop_neon_enter:
+ ldr r11, [sp,#4*(15)]
+ vadd.i32 q7,q3,q12 @ counter+1
+ ldr r12,[sp,#4*(12)] @ modulo-scheduled load
+ vmov q6,q2
+ ldr r10, [sp,#4*(13)]
+ vmov q10,q2
+ ldr r14,[sp,#4*(14)]
+ vadd.i32 q11,q7,q12 @ counter+2
+ str r11, [sp,#4*(16+15)]
+ mov r11,#10
+ add r12,r12,#3 @ counter+3
+ b .Loop_neon
+
+.align 4
+.Loop_neon:
+ subs r11,r11,#1
+ vadd.i32 q0,q0,q1
+ add r0,r0,r4
+ vadd.i32 q4,q4,q5
+ mov r12,r12,ror#16
+ vadd.i32 q8,q8,q9
+ add r1,r1,r5
+ veor q3,q3,q0
+ mov r10,r10,ror#16
+ veor q7,q7,q4
+ eor r12,r12,r0,ror#16
+ veor q11,q11,q8
+ eor r10,r10,r1,ror#16
+ vrev32.16 q3,q3
+ add r8,r8,r12
+ vrev32.16 q7,q7
+ mov r4,r4,ror#20
+ vrev32.16 q11,q11
+ add r9,r9,r10
+ vadd.i32 q2,q2,q3
+ mov r5,r5,ror#20
+ vadd.i32 q6,q6,q7
+ eor r4,r4,r8,ror#20
+ vadd.i32 q10,q10,q11
+ eor r5,r5,r9,ror#20
+ veor q12,q1,q2
+ add r0,r0,r4
+ veor q13,q5,q6
+ mov r12,r12,ror#24
+ veor q14,q9,q10
+ add r1,r1,r5
+ vshr.u32 q1,q12,#20
+ mov r10,r10,ror#24
+ vshr.u32 q5,q13,#20
+ eor r12,r12,r0,ror#24
+ vshr.u32 q9,q14,#20
+ eor r10,r10,r1,ror#24
+ vsli.32 q1,q12,#12
+ add r8,r8,r12
+ vsli.32 q5,q13,#12
+ mov r4,r4,ror#25
+ vsli.32 q9,q14,#12
+ add r9,r9,r10
+ vadd.i32 q0,q0,q1
+ mov r5,r5,ror#25
+ vadd.i32 q4,q4,q5
+ str r10,[sp,#4*(16+13)]
+ vadd.i32 q8,q8,q9
+ ldr r10,[sp,#4*(16+15)]
+ veor q12,q3,q0
+ eor r4,r4,r8,ror#25
+ veor q13,q7,q4
+ eor r5,r5,r9,ror#25
+ veor q14,q11,q8
+ str r8,[sp,#4*(16+8)]
+ vshr.u32 q3,q12,#24
+ ldr r8,[sp,#4*(16+10)]
+ vshr.u32 q7,q13,#24
+ add r2,r2,r6
+ vshr.u32 q11,q14,#24
+ mov r14,r14,ror#16
+ vsli.32 q3,q12,#8
+ str r9,[sp,#4*(16+9)]
+ vsli.32 q7,q13,#8
+ ldr r9,[sp,#4*(16+11)]
+ vsli.32 q11,q14,#8
+ add r3,r3,r7
+ vadd.i32 q2,q2,q3
+ mov r10,r10,ror#16
+ vadd.i32 q6,q6,q7
+ eor r14,r14,r2,ror#16
+ vadd.i32 q10,q10,q11
+ eor r10,r10,r3,ror#16
+ veor q12,q1,q2
+ add r8,r8,r14
+ veor q13,q5,q6
+ mov r6,r6,ror#20
+ veor q14,q9,q10
+ add r9,r9,r10
+ vshr.u32 q1,q12,#25
+ mov r7,r7,ror#20
+ vshr.u32 q5,q13,#25
+ eor r6,r6,r8,ror#20
+ vshr.u32 q9,q14,#25
+ eor r7,r7,r9,ror#20
+ vsli.32 q1,q12,#7
+ add r2,r2,r6
+ vsli.32 q5,q13,#7
+ mov r14,r14,ror#24
+ vsli.32 q9,q14,#7
+ add r3,r3,r7
+ vext.8 q2,q2,q2,#8
+ mov r10,r10,ror#24
+ vext.8 q6,q6,q6,#8
+ eor r14,r14,r2,ror#24
+ vext.8 q10,q10,q10,#8
+ eor r10,r10,r3,ror#24
+ vext.8 q1,q1,q1,#4
+ add r8,r8,r14
+ vext.8 q5,q5,q5,#4
+ mov r6,r6,ror#25
+ vext.8 q9,q9,q9,#4
+ add r9,r9,r10
+ vext.8 q3,q3,q3,#12
+ mov r7,r7,ror#25
+ vext.8 q7,q7,q7,#12
+ eor r6,r6,r8,ror#25
+ vext.8 q11,q11,q11,#12
+ eor r7,r7,r9,ror#25
+ vadd.i32 q0,q0,q1
+ add r0,r0,r5
+ vadd.i32 q4,q4,q5
+ mov r10,r10,ror#16
+ vadd.i32 q8,q8,q9
+ add r1,r1,r6
+ veor q3,q3,q0
+ mov r12,r12,ror#16
+ veor q7,q7,q4
+ eor r10,r10,r0,ror#16
+ veor q11,q11,q8
+ eor r12,r12,r1,ror#16
+ vrev32.16 q3,q3
+ add r8,r8,r10
+ vrev32.16 q7,q7
+ mov r5,r5,ror#20
+ vrev32.16 q11,q11
+ add r9,r9,r12
+ vadd.i32 q2,q2,q3
+ mov r6,r6,ror#20
+ vadd.i32 q6,q6,q7
+ eor r5,r5,r8,ror#20
+ vadd.i32 q10,q10,q11
+ eor r6,r6,r9,ror#20
+ veor q12,q1,q2
+ add r0,r0,r5
+ veor q13,q5,q6
+ mov r10,r10,ror#24
+ veor q14,q9,q10
+ add r1,r1,r6
+ vshr.u32 q1,q12,#20
+ mov r12,r12,ror#24
+ vshr.u32 q5,q13,#20
+ eor r10,r10,r0,ror#24
+ vshr.u32 q9,q14,#20
+ eor r12,r12,r1,ror#24
+ vsli.32 q1,q12,#12
+ add r8,r8,r10
+ vsli.32 q5,q13,#12
+ mov r5,r5,ror#25
+ vsli.32 q9,q14,#12
+ str r10,[sp,#4*(16+15)]
+ vadd.i32 q0,q0,q1
+ ldr r10,[sp,#4*(16+13)]
+ vadd.i32 q4,q4,q5
+ add r9,r9,r12
+ vadd.i32 q8,q8,q9
+ mov r6,r6,ror#25
+ veor q12,q3,q0
+ eor r5,r5,r8,ror#25
+ veor q13,q7,q4
+ eor r6,r6,r9,ror#25
+ veor q14,q11,q8
+ str r8,[sp,#4*(16+10)]
+ vshr.u32 q3,q12,#24
+ ldr r8,[sp,#4*(16+8)]
+ vshr.u32 q7,q13,#24
+ add r2,r2,r7
+ vshr.u32 q11,q14,#24
+ mov r10,r10,ror#16
+ vsli.32 q3,q12,#8
+ str r9,[sp,#4*(16+11)]
+ vsli.32 q7,q13,#8
+ ldr r9,[sp,#4*(16+9)]
+ vsli.32 q11,q14,#8
+ add r3,r3,r4
+ vadd.i32 q2,q2,q3
+ mov r14,r14,ror#16
+ vadd.i32 q6,q6,q7
+ eor r10,r10,r2,ror#16
+ vadd.i32 q10,q10,q11
+ eor r14,r14,r3,ror#16
+ veor q12,q1,q2
+ add r8,r8,r10
+ veor q13,q5,q6
+ mov r7,r7,ror#20
+ veor q14,q9,q10
+ add r9,r9,r14
+ vshr.u32 q1,q12,#25
+ mov r4,r4,ror#20
+ vshr.u32 q5,q13,#25
+ eor r7,r7,r8,ror#20
+ vshr.u32 q9,q14,#25
+ eor r4,r4,r9,ror#20
+ vsli.32 q1,q12,#7
+ add r2,r2,r7
+ vsli.32 q5,q13,#7
+ mov r10,r10,ror#24
+ vsli.32 q9,q14,#7
+ add r3,r3,r4
+ vext.8 q2,q2,q2,#8
+ mov r14,r14,ror#24
+ vext.8 q6,q6,q6,#8
+ eor r10,r10,r2,ror#24
+ vext.8 q10,q10,q10,#8
+ eor r14,r14,r3,ror#24
+ vext.8 q1,q1,q1,#12
+ add r8,r8,r10
+ vext.8 q5,q5,q5,#12
+ mov r7,r7,ror#25
+ vext.8 q9,q9,q9,#12
+ add r9,r9,r14
+ vext.8 q3,q3,q3,#4
+ mov r4,r4,ror#25
+ vext.8 q7,q7,q7,#4
+ eor r7,r7,r8,ror#25
+ vext.8 q11,q11,q11,#4
+ eor r4,r4,r9,ror#25
+ bne .Loop_neon
+
+ add r11,sp,#32
+ vld1.32 {q12,q13},[sp] @ load key material
+ vld1.32 {q14,q15},[r11]
+
+ ldr r11,[sp,#4*(32+2)] @ load len
+
+ str r8, [sp,#4*(16+8)] @ modulo-scheduled store
+ str r9, [sp,#4*(16+9)]
+ str r12,[sp,#4*(16+12)]
+ str r10, [sp,#4*(16+13)]
+ str r14,[sp,#4*(16+14)]
+
+ @ at this point we have first half of 512-bit result in
+ @ rx and second half at sp+4*(16+8)
+
+ ldr r12,[sp,#4*(32+1)] @ load inp
+ ldr r14,[sp,#4*(32+0)] @ load out
+
+ vadd.i32 q0,q0,q12 @ accumulate key material
+ vadd.i32 q4,q4,q12
+ vadd.i32 q8,q8,q12
+ vldr d24,[sp,#4*(16+0)] @ one
+
+ vadd.i32 q1,q1,q13
+ vadd.i32 q5,q5,q13
+ vadd.i32 q9,q9,q13
+ vldr d26,[sp,#4*(16+2)] @ two
+
+ vadd.i32 q2,q2,q14
+ vadd.i32 q6,q6,q14
+ vadd.i32 q10,q10,q14
+ vadd.i32 d14,d14,d24 @ counter+1
+ vadd.i32 d22,d22,d26 @ counter+2
+
+ vadd.i32 q3,q3,q15
+ vadd.i32 q7,q7,q15
+ vadd.i32 q11,q11,q15
+
+ cmp r11,#64*4
+ blo .Ltail_neon
+
+ vld1.8 {q12,q13},[r12]! @ load input
+ mov r11,sp
+ vld1.8 {q14,q15},[r12]!
+ veor q0,q0,q12 @ xor with input
+ veor q1,q1,q13
+ vld1.8 {q12,q13},[r12]!
+ veor q2,q2,q14
+ veor q3,q3,q15
+ vld1.8 {q14,q15},[r12]!
+
+ veor q4,q4,q12
+ vst1.8 {q0,q1},[r14]! @ store output
+ veor q5,q5,q13
+ vld1.8 {q12,q13},[r12]!
+ veor q6,q6,q14
+ vst1.8 {q2,q3},[r14]!
+ veor q7,q7,q15
+ vld1.8 {q14,q15},[r12]!
+
+ veor q8,q8,q12
+ vld1.32 {q0,q1},[r11]! @ load for next iteration
+ veor d25,d25,d25
+ vldr d24,[sp,#4*(16+4)] @ four
+ veor q9,q9,q13
+ vld1.32 {q2,q3},[r11]
+ veor q10,q10,q14
+ vst1.8 {q4,q5},[r14]!
+ veor q11,q11,q15
+ vst1.8 {q6,q7},[r14]!
+
+ vadd.i32 d6,d6,d24 @ next counter value
+ vldr d24,[sp,#4*(16+0)] @ one
+
+ ldmia sp,{r8,r9,r10,r11} @ load key material
+ add r0,r0,r8 @ accumulate key material
+ ldr r8,[r12],#16 @ load input
+ vst1.8 {q8,q9},[r14]!
+ add r1,r1,r9
+ ldr r9,[r12,#-12]
+ vst1.8 {q10,q11},[r14]!
+ add r2,r2,r10
+ ldr r10,[r12,#-8]
+ add r3,r3,r11
+ ldr r11,[r12,#-4]
+# ifdef __ARMEB__
+ rev r0,r0
+ rev r1,r1
+ rev r2,r2
+ rev r3,r3
+# endif
+ eor r0,r0,r8 @ xor with input
+ add r8,sp,#4*(4)
+ eor r1,r1,r9
+ str r0,[r14],#16 @ store output
+ eor r2,r2,r10
+ str r1,[r14,#-12]
+ eor r3,r3,r11
+ ldmia r8,{r8,r9,r10,r11} @ load key material
+ str r2,[r14,#-8]
+ str r3,[r14,#-4]
+
+ add r4,r4,r8 @ accumulate key material
+ ldr r8,[r12],#16 @ load input
+ add r5,r5,r9
+ ldr r9,[r12,#-12]
+ add r6,r6,r10
+ ldr r10,[r12,#-8]
+ add r7,r7,r11
+ ldr r11,[r12,#-4]
+# ifdef __ARMEB__
+ rev r4,r4
+ rev r5,r5
+ rev r6,r6
+ rev r7,r7
+# endif
+ eor r4,r4,r8
+ add r8,sp,#4*(8)
+ eor r5,r5,r9
+ str r4,[r14],#16 @ store output
+ eor r6,r6,r10
+ str r5,[r14,#-12]
+ eor r7,r7,r11
+ ldmia r8,{r8,r9,r10,r11} @ load key material
+ str r6,[r14,#-8]
+ add r0,sp,#4*(16+8)
+ str r7,[r14,#-4]
+
+ ldmia r0,{r0,r1,r2,r3,r4,r5,r6,r7} @ load second half
+
+ add r0,r0,r8 @ accumulate key material
+ ldr r8,[r12],#16 @ load input
+ add r1,r1,r9
+ ldr r9,[r12,#-12]
+# ifdef __thumb2__
+ it hi
+# endif
+ strhi r10,[sp,#4*(16+10)] @ copy "rx" while at it
+ add r2,r2,r10
+ ldr r10,[r12,#-8]
+# ifdef __thumb2__
+ it hi
+# endif
+ strhi r11,[sp,#4*(16+11)] @ copy "rx" while at it
+ add r3,r3,r11
+ ldr r11,[r12,#-4]
+# ifdef __ARMEB__
+ rev r0,r0
+ rev r1,r1
+ rev r2,r2
+ rev r3,r3
+# endif
+ eor r0,r0,r8
+ add r8,sp,#4*(12)
+ eor r1,r1,r9
+ str r0,[r14],#16 @ store output
+ eor r2,r2,r10
+ str r1,[r14,#-12]
+ eor r3,r3,r11
+ ldmia r8,{r8,r9,r10,r11} @ load key material
+ str r2,[r14,#-8]
+ str r3,[r14,#-4]
+
+ add r4,r4,r8 @ accumulate key material
+ add r8,r8,#4 @ next counter value
+ add r5,r5,r9
+ str r8,[sp,#4*(12)] @ save next counter value
+ ldr r8,[r12],#16 @ load input
+ add r6,r6,r10
+ add r4,r4,#3 @ counter+3
+ ldr r9,[r12,#-12]
+ add r7,r7,r11
+ ldr r10,[r12,#-8]
+ ldr r11,[r12,#-4]
+# ifdef __ARMEB__
+ rev r4,r4
+ rev r5,r5
+ rev r6,r6
+ rev r7,r7
+# endif
+ eor r4,r4,r8
+# ifdef __thumb2__
+ it hi
+# endif
+ ldrhi r8,[sp,#4*(32+2)] @ re-load len
+ eor r5,r5,r9
+ eor r6,r6,r10
+ str r4,[r14],#16 @ store output
+ eor r7,r7,r11
+ str r5,[r14,#-12]
+ sub r11,r8,#64*4 @ len-=64*4
+ str r6,[r14,#-8]
+ str r7,[r14,#-4]
+ bhi .Loop_neon_outer
+
+ b .Ldone_neon
+
+.align 4
+.Lbreak_neon:
+ @ harmonize NEON and integer-only stack frames: load data
+ @ from NEON frame, but save to integer-only one; distance
+ @ between the two is 4*(32+4+16-32)=4*(20).
+
+ str r11, [sp,#4*(20+32+2)] @ save len
+ add r11,sp,#4*(32+4)
+ str r12, [sp,#4*(20+32+1)] @ save inp
+ str r14, [sp,#4*(20+32+0)] @ save out
+
+ ldr r12,[sp,#4*(16+10)]
+ ldr r14,[sp,#4*(16+11)]
+ vldmia r11,{d8,d9,d10,d11,d12,d13,d14,d15} @ fulfill ABI requirement
+ str r12,[sp,#4*(20+16+10)] @ copy "rx"
+ str r14,[sp,#4*(20+16+11)] @ copy "rx"
+
+ ldr r11, [sp,#4*(15)]
+ ldr r12,[sp,#4*(12)] @ modulo-scheduled load
+ ldr r10, [sp,#4*(13)]
+ ldr r14,[sp,#4*(14)]
+ str r11, [sp,#4*(20+16+15)]
+ add r11,sp,#4*(20)
+ vst1.32 {q0,q1},[r11]! @ copy key
+ add sp,sp,#4*(20) @ switch frame
+ vst1.32 {q2,q3},[r11]
+ mov r11,#10
+ b .Loop @ go integer-only
+
+.align 4
+.Ltail_neon:
+ cmp r11,#64*3
+ bhs .L192_or_more_neon
+ cmp r11,#64*2
+ bhs .L128_or_more_neon
+ cmp r11,#64*1
+ bhs .L64_or_more_neon
+
+ add r8,sp,#4*(8)
+ vst1.8 {q0,q1},[sp]
+ add r10,sp,#4*(0)
+ vst1.8 {q2,q3},[r8]
+ b .Loop_tail_neon
+
+.align 4
+.L64_or_more_neon:
+ vld1.8 {q12,q13},[r12]!
+ vld1.8 {q14,q15},[r12]!
+ veor q0,q0,q12
+ veor q1,q1,q13
+ veor q2,q2,q14
+ veor q3,q3,q15
+ vst1.8 {q0,q1},[r14]!
+ vst1.8 {q2,q3},[r14]!
+
+ beq .Ldone_neon
+
+ add r8,sp,#4*(8)
+ vst1.8 {q4,q5},[sp]
+ add r10,sp,#4*(0)
+ vst1.8 {q6,q7},[r8]
+ sub r11,r11,#64*1 @ len-=64*1
+ b .Loop_tail_neon
+
+.align 4
+.L128_or_more_neon:
+ vld1.8 {q12,q13},[r12]!
+ vld1.8 {q14,q15},[r12]!
+ veor q0,q0,q12
+ veor q1,q1,q13
+ vld1.8 {q12,q13},[r12]!
+ veor q2,q2,q14
+ veor q3,q3,q15
+ vld1.8 {q14,q15},[r12]!
+
+ veor q4,q4,q12
+ veor q5,q5,q13
+ vst1.8 {q0,q1},[r14]!
+ veor q6,q6,q14
+ vst1.8 {q2,q3},[r14]!
+ veor q7,q7,q15
+ vst1.8 {q4,q5},[r14]!
+ vst1.8 {q6,q7},[r14]!
+
+ beq .Ldone_neon
+
+ add r8,sp,#4*(8)
+ vst1.8 {q8,q9},[sp]
+ add r10,sp,#4*(0)
+ vst1.8 {q10,q11},[r8]
+ sub r11,r11,#64*2 @ len-=64*2
+ b .Loop_tail_neon
+
+.align 4
+.L192_or_more_neon:
+ vld1.8 {q12,q13},[r12]!
+ vld1.8 {q14,q15},[r12]!
+ veor q0,q0,q12
+ veor q1,q1,q13
+ vld1.8 {q12,q13},[r12]!
+ veor q2,q2,q14
+ veor q3,q3,q15
+ vld1.8 {q14,q15},[r12]!
+
+ veor q4,q4,q12
+ veor q5,q5,q13
+ vld1.8 {q12,q13},[r12]!
+ veor q6,q6,q14
+ vst1.8 {q0,q1},[r14]!
+ veor q7,q7,q15
+ vld1.8 {q14,q15},[r12]!
+
+ veor q8,q8,q12
+ vst1.8 {q2,q3},[r14]!
+ veor q9,q9,q13
+ vst1.8 {q4,q5},[r14]!
+ veor q10,q10,q14
+ vst1.8 {q6,q7},[r14]!
+ veor q11,q11,q15
+ vst1.8 {q8,q9},[r14]!
+ vst1.8 {q10,q11},[r14]!
+
+ beq .Ldone_neon
+
+ ldmia sp,{r8,r9,r10,r11} @ load key material
+ add r0,r0,r8 @ accumulate key material
+ add r8,sp,#4*(4)
+ add r1,r1,r9
+ add r2,r2,r10
+ add r3,r3,r11
+ ldmia r8,{r8,r9,r10,r11} @ load key material
+
+ add r4,r4,r8 @ accumulate key material
+ add r8,sp,#4*(8)
+ add r5,r5,r9
+ add r6,r6,r10
+ add r7,r7,r11
+ ldmia r8,{r8,r9,r10,r11} @ load key material
+# ifdef __ARMEB__
+ rev r0,r0
+ rev r1,r1
+ rev r2,r2
+ rev r3,r3
+ rev r4,r4
+ rev r5,r5
+ rev r6,r6
+ rev r7,r7
+# endif
+ stmia sp,{r0,r1,r2,r3,r4,r5,r6,r7}
+ add r0,sp,#4*(16+8)
+
+ ldmia r0,{r0,r1,r2,r3,r4,r5,r6,r7} @ load second half
+
+ add r0,r0,r8 @ accumulate key material
+ add r8,sp,#4*(12)
+ add r1,r1,r9
+ add r2,r2,r10
+ add r3,r3,r11
+ ldmia r8,{r8,r9,r10,r11} @ load key material
+
+ add r4,r4,r8 @ accumulate key material
+ add r8,sp,#4*(8)
+ add r5,r5,r9
+ add r4,r4,#3 @ counter+3
+ add r6,r6,r10
+ add r7,r7,r11
+ ldr r11,[sp,#4*(32+2)] @ re-load len
+# ifdef __ARMEB__
+ rev r0,r0
+ rev r1,r1
+ rev r2,r2
+ rev r3,r3
+ rev r4,r4
+ rev r5,r5
+ rev r6,r6
+ rev r7,r7
+# endif
+ stmia r8,{r0,r1,r2,r3,r4,r5,r6,r7}
+ add r10,sp,#4*(0)
+ sub r11,r11,#64*3 @ len-=64*3
+
+.Loop_tail_neon:
+ ldrb r8,[r10],#1 @ read buffer on stack
+ ldrb r9,[r12],#1 @ read input
+ subs r11,r11,#1
+ eor r8,r8,r9
+ strb r8,[r14],#1 @ store ouput
+ bne .Loop_tail_neon
+
+.Ldone_neon:
+ add sp,sp,#4*(32+4)
+ vldmia sp,{d8,d9,d10,d11,d12,d13,d14,d15}
+ add sp,sp,#4*(16+3)
+ ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11,pc}
+.size ChaCha20_neon,.-ChaCha20_neon
+.comm OPENSSL_armcap_P,4,4
+#endif
+#endif
diff --git a/linux-arm/crypto/modes/ghash-armv4.S b/linux-arm/crypto/modes/ghash-armv4.S
index d955d827..791b2890 100644
--- a/linux-arm/crypto/modes/ghash-armv4.S
+++ b/linux-arm/crypto/modes/ghash-armv4.S
@@ -535,4 +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 \ No newline at end of file
+#endif
diff --git a/linux-arm/crypto/modes/ghashv8-armx32.S b/linux-arm/crypto/modes/ghashv8-armx32.S
index 9a38ded4..0e1e6314 100644
--- a/linux-arm/crypto/modes/ghashv8-armx32.S
+++ b/linux-arm/crypto/modes/ghashv8-armx32.S
@@ -5,6 +5,7 @@
.fpu neon
.code 32
.globl gcm_init_v8
+.hidden gcm_init_v8
.type gcm_init_v8,%function
.align 4
gcm_init_v8:
@@ -55,6 +56,7 @@ gcm_init_v8:
bx lr
.size gcm_init_v8,.-gcm_init_v8
.globl gcm_gmult_v8
+.hidden gcm_gmult_v8
.type gcm_gmult_v8,%function
.align 4
gcm_gmult_v8:
@@ -96,6 +98,7 @@ gcm_gmult_v8:
bx lr
.size gcm_gmult_v8,.-gcm_gmult_v8
.globl gcm_ghash_v8
+.hidden gcm_ghash_v8
.type gcm_ghash_v8,%function
.align 4
gcm_ghash_v8:
@@ -230,4 +233,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
+#endif
diff --git a/linux-arm/crypto/sha/sha1-armv4-large.S b/linux-arm/crypto/sha/sha1-armv4-large.S
index 66d0ef3e..36955faf 100644
--- a/linux-arm/crypto/sha/sha1-armv4-large.S
+++ b/linux-arm/crypto/sha/sha1-armv4-large.S
@@ -5,6 +5,7 @@
.code 32
.globl sha1_block_data_order
+.hidden sha1_block_data_order
.type sha1_block_data_order,%function
.align 5
@@ -1459,4 +1460,4 @@ sha1_block_data_order_armv8:
.comm OPENSSL_armcap_P,4,4
.hidden OPENSSL_armcap_P
#endif
-#endif \ No newline at end of file
+#endif
diff --git a/linux-arm/crypto/sha/sha256-armv4.S b/linux-arm/crypto/sha/sha256-armv4.S
index 9fc3e0b8..60400413 100644
--- a/linux-arm/crypto/sha/sha256-armv4.S
+++ b/linux-arm/crypto/sha/sha256-armv4.S
@@ -85,6 +85,7 @@ K256:
.align 5
.globl sha256_block_data_order
+.hidden sha256_block_data_order
.type sha256_block_data_order,%function
sha256_block_data_order:
.Lsha256_block_data_order:
@@ -1875,6 +1876,7 @@ sha256_block_data_order:
.fpu neon
.globl sha256_block_data_order_neon
+.hidden sha256_block_data_order_neon
.type sha256_block_data_order_neon,%function
.align 4
sha256_block_data_order_neon:
@@ -2815,4 +2817,4 @@ sha256_block_data_order_armv8:
.comm OPENSSL_armcap_P,4,4
.hidden OPENSSL_armcap_P
#endif
-#endif \ No newline at end of file
+#endif
diff --git a/linux-arm/crypto/sha/sha512-armv4.S b/linux-arm/crypto/sha/sha512-armv4.S
index 834ede9c..93a7bf85 100644
--- a/linux-arm/crypto/sha/sha512-armv4.S
+++ b/linux-arm/crypto/sha/sha512-armv4.S
@@ -133,6 +133,7 @@ K512:
#endif
.globl sha512_block_data_order
+.hidden sha512_block_data_order
.type sha512_block_data_order,%function
sha512_block_data_order:
.Lsha512_block_data_order:
@@ -147,7 +148,7 @@ sha512_block_data_order:
#ifdef __APPLE__
ldr r12,[r12]
#endif
- tst r12,#1
+ tst r12,#ARMV7_NEON
bne .LNEON
#endif
add r2,r1,r2,lsl#7 @ len to point at the end of inp
@@ -533,6 +534,7 @@ sha512_block_data_order:
.fpu neon
.globl sha512_block_data_order_neon
+.hidden sha512_block_data_order_neon
.type sha512_block_data_order_neon,%function
.align 4
sha512_block_data_order_neon:
@@ -1866,4 +1868,4 @@ sha512_block_data_order_neon:
.comm OPENSSL_armcap_P,4,4
.hidden OPENSSL_armcap_P
#endif
-#endif \ No newline at end of file
+#endif
diff --git a/linux-x86/crypto/chacha/chacha-x86.S b/linux-x86/crypto/chacha/chacha-x86.S
new file mode 100644
index 00000000..f28459e9
--- /dev/null
+++ b/linux-x86/crypto/chacha/chacha-x86.S
@@ -0,0 +1,989 @@
+#if defined(__i386__)
+.file "chacha-x86.S"
+.text
+.globl ChaCha20_ctr32
+.hidden ChaCha20_ctr32
+.type ChaCha20_ctr32,@function
+.align 16
+ChaCha20_ctr32:
+.L_ChaCha20_ctr32_begin:
+ pushl %ebp
+ pushl %ebx
+ pushl %esi
+ pushl %edi
+ xorl %eax,%eax
+ cmpl 28(%esp),%eax
+ je .L000no_data
+ call .Lpic_point
+.Lpic_point:
+ popl %eax
+ leal OPENSSL_ia32cap_P-.Lpic_point(%eax),%ebp
+ testl $16777216,(%ebp)
+ jz .L001x86
+ testl $512,4(%ebp)
+ jz .L001x86
+ jmp .Lssse3_shortcut
+.L001x86:
+ movl 32(%esp),%esi
+ movl 36(%esp),%edi
+ subl $132,%esp
+ movl (%esi),%eax
+ movl 4(%esi),%ebx
+ movl 8(%esi),%ecx
+ movl 12(%esi),%edx
+ movl %eax,80(%esp)
+ movl %ebx,84(%esp)
+ movl %ecx,88(%esp)
+ movl %edx,92(%esp)
+ movl 16(%esi),%eax
+ movl 20(%esi),%ebx
+ movl 24(%esi),%ecx
+ movl 28(%esi),%edx
+ movl %eax,96(%esp)
+ movl %ebx,100(%esp)
+ movl %ecx,104(%esp)
+ movl %edx,108(%esp)
+ movl (%edi),%eax
+ movl 4(%edi),%ebx
+ movl 8(%edi),%ecx
+ movl 12(%edi),%edx
+ subl $1,%eax
+ movl %eax,112(%esp)
+ movl %ebx,116(%esp)
+ movl %ecx,120(%esp)
+ movl %edx,124(%esp)
+ jmp .L002entry
+.align 16
+.L003outer_loop:
+ movl %ebx,156(%esp)
+ movl %eax,152(%esp)
+ movl %ecx,160(%esp)
+.L002entry:
+ movl $1634760805,%eax
+ movl $857760878,4(%esp)
+ movl $2036477234,8(%esp)
+ movl $1797285236,12(%esp)
+ movl 84(%esp),%ebx
+ movl 88(%esp),%ebp
+ movl 104(%esp),%ecx
+ movl 108(%esp),%esi
+ movl 116(%esp),%edx
+ movl 120(%esp),%edi
+ movl %ebx,20(%esp)
+ movl %ebp,24(%esp)
+ movl %ecx,40(%esp)
+ movl %esi,44(%esp)
+ movl %edx,52(%esp)
+ movl %edi,56(%esp)
+ movl 92(%esp),%ebx
+ movl 124(%esp),%edi
+ movl 112(%esp),%edx
+ movl 80(%esp),%ebp
+ movl 96(%esp),%ecx
+ movl 100(%esp),%esi
+ addl $1,%edx
+ movl %ebx,28(%esp)
+ movl %edi,60(%esp)
+ movl %edx,112(%esp)
+ movl $10,%ebx
+ jmp .L004loop
+.align 16
+.L004loop:
+ addl %ebp,%eax
+ movl %ebx,128(%esp)
+ movl %ebp,%ebx
+ xorl %eax,%edx
+ roll $16,%edx
+ addl %edx,%ecx
+ xorl %ecx,%ebx
+ movl 52(%esp),%edi
+ roll $12,%ebx
+ movl 20(%esp),%ebp
+ addl %ebx,%eax
+ xorl %eax,%edx
+ movl %eax,(%esp)
+ roll $8,%edx
+ movl 4(%esp),%eax
+ addl %edx,%ecx
+ movl %edx,48(%esp)
+ xorl %ecx,%ebx
+ addl %ebp,%eax
+ roll $7,%ebx
+ xorl %eax,%edi
+ movl %ecx,32(%esp)
+ roll $16,%edi
+ movl %ebx,16(%esp)
+ addl %edi,%esi
+ movl 40(%esp),%ecx
+ xorl %esi,%ebp
+ movl 56(%esp),%edx
+ roll $12,%ebp
+ movl 24(%esp),%ebx
+ addl %ebp,%eax
+ xorl %eax,%edi
+ movl %eax,4(%esp)
+ roll $8,%edi
+ movl 8(%esp),%eax
+ addl %edi,%esi
+ movl %edi,52(%esp)
+ xorl %esi,%ebp
+ addl %ebx,%eax
+ roll $7,%ebp
+ xorl %eax,%edx
+ movl %esi,36(%esp)
+ roll $16,%edx
+ movl %ebp,20(%esp)
+ addl %edx,%ecx
+ movl 44(%esp),%esi
+ xorl %ecx,%ebx
+ movl 60(%esp),%edi
+ roll $12,%ebx
+ movl 28(%esp),%ebp
+ addl %ebx,%eax
+ xorl %eax,%edx
+ movl %eax,8(%esp)
+ roll $8,%edx
+ movl 12(%esp),%eax
+ addl %edx,%ecx
+ movl %edx,56(%esp)
+ xorl %ecx,%ebx
+ addl %ebp,%eax
+ roll $7,%ebx
+ xorl %eax,%edi
+ roll $16,%edi
+ movl %ebx,24(%esp)
+ addl %edi,%esi
+ xorl %esi,%ebp
+ roll $12,%ebp
+ movl 20(%esp),%ebx
+ addl %ebp,%eax
+ xorl %eax,%edi
+ movl %eax,12(%esp)
+ roll $8,%edi
+ movl (%esp),%eax
+ addl %edi,%esi
+ movl %edi,%edx
+ xorl %esi,%ebp
+ addl %ebx,%eax
+ roll $7,%ebp
+ xorl %eax,%edx
+ roll $16,%edx
+ movl %ebp,28(%esp)
+ addl %edx,%ecx
+ xorl %ecx,%ebx
+ movl 48(%esp),%edi
+ roll $12,%ebx
+ movl 24(%esp),%ebp
+ addl %ebx,%eax
+ xorl %eax,%edx
+ movl %eax,(%esp)
+ roll $8,%edx
+ movl 4(%esp),%eax
+ addl %edx,%ecx
+ movl %edx,60(%esp)
+ xorl %ecx,%ebx
+ addl %ebp,%eax
+ roll $7,%ebx
+ xorl %eax,%edi
+ movl %ecx,40(%esp)
+ roll $16,%edi
+ movl %ebx,20(%esp)
+ addl %edi,%esi
+ movl 32(%esp),%ecx
+ xorl %esi,%ebp
+ movl 52(%esp),%edx
+ roll $12,%ebp
+ movl 28(%esp),%ebx
+ addl %ebp,%eax
+ xorl %eax,%edi
+ movl %eax,4(%esp)
+ roll $8,%edi
+ movl 8(%esp),%eax
+ addl %edi,%esi
+ movl %edi,48(%esp)
+ xorl %esi,%ebp
+ addl %ebx,%eax
+ roll $7,%ebp
+ xorl %eax,%edx
+ movl %esi,44(%esp)
+ roll $16,%edx
+ movl %ebp,24(%esp)
+ addl %edx,%ecx
+ movl 36(%esp),%esi
+ xorl %ecx,%ebx
+ movl 56(%esp),%edi
+ roll $12,%ebx
+ movl 16(%esp),%ebp
+ addl %ebx,%eax
+ xorl %eax,%edx
+ movl %eax,8(%esp)
+ roll $8,%edx
+ movl 12(%esp),%eax
+ addl %edx,%ecx
+ movl %edx,52(%esp)
+ xorl %ecx,%ebx
+ addl %ebp,%eax
+ roll $7,%ebx
+ xorl %eax,%edi
+ roll $16,%edi
+ movl %ebx,28(%esp)
+ addl %edi,%esi
+ xorl %esi,%ebp
+ movl 48(%esp),%edx
+ roll $12,%ebp
+ movl 128(%esp),%ebx
+ addl %ebp,%eax
+ xorl %eax,%edi
+ movl %eax,12(%esp)
+ roll $8,%edi
+ movl (%esp),%eax
+ addl %edi,%esi
+ movl %edi,56(%esp)
+ xorl %esi,%ebp
+ roll $7,%ebp
+ decl %ebx
+ jnz .L004loop
+ movl 160(%esp),%ebx
+ addl $1634760805,%eax
+ addl 80(%esp),%ebp
+ addl 96(%esp),%ecx
+ addl 100(%esp),%esi
+ cmpl $64,%ebx
+ jb .L005tail
+ movl 156(%esp),%ebx
+ addl 112(%esp),%edx
+ addl 120(%esp),%edi
+ xorl (%ebx),%eax
+ xorl 16(%ebx),%ebp
+ movl %eax,(%esp)
+ movl 152(%esp),%eax
+ xorl 32(%ebx),%ecx
+ xorl 36(%ebx),%esi
+ xorl 48(%ebx),%edx
+ xorl 56(%ebx),%edi
+ movl %ebp,16(%esp)
+ movl (%esp),%ebp
+ movl %ecx,32(%esp)
+ movl %esi,36(%esp)
+ movl %edx,48(%esp)
+ movl %edi,56(%esp)
+ movl %ebp,(%eax)
+ movl 4(%esp),%ebp
+ movl 8(%esp),%ecx
+ movl 12(%esp),%esi
+ movl 20(%esp),%edx
+ movl 24(%esp),%edi
+ addl $857760878,%ebp
+ addl $2036477234,%ecx
+ addl $1797285236,%esi
+ addl 84(%esp),%edx
+ addl 88(%esp),%edi
+ xorl 4(%ebx),%ebp
+ xorl 8(%ebx),%ecx
+ xorl 12(%ebx),%esi
+ xorl 20(%ebx),%edx
+ xorl 24(%ebx),%edi
+ movl %ebp,4(%eax)
+ movl 16(%esp),%ebp
+ movl %ecx,8(%eax)
+ movl %esi,12(%eax)
+ movl %ebp,16(%eax)
+ movl %edx,20(%eax)
+ movl %edi,24(%eax)
+ movl 28(%esp),%ecx
+ movl 32(%esp),%edx
+ movl 36(%esp),%edi
+ addl 92(%esp),%ecx
+ movl 40(%esp),%ebp
+ xorl 28(%ebx),%ecx
+ movl 44(%esp),%esi
+ movl %ecx,28(%eax)
+ movl %edx,32(%eax)
+ movl %edi,36(%eax)
+ addl 104(%esp),%ebp
+ addl 108(%esp),%esi
+ xorl 40(%ebx),%ebp
+ xorl 44(%ebx),%esi
+ movl %ebp,40(%eax)
+ movl %esi,44(%eax)
+ movl 48(%esp),%ecx
+ movl 56(%esp),%esi
+ movl 52(%esp),%edx
+ movl 60(%esp),%edi
+ addl 116(%esp),%edx
+ addl 124(%esp),%edi
+ xorl 52(%ebx),%edx
+ xorl 60(%ebx),%edi
+ leal 64(%ebx),%ebx
+ movl %ecx,48(%eax)
+ movl 160(%esp),%ecx
+ movl %edx,52(%eax)
+ movl %esi,56(%eax)
+ movl %edi,60(%eax)
+ leal 64(%eax),%eax
+ subl $64,%ecx
+ jnz .L003outer_loop
+ jmp .L006done
+.L005tail:
+ addl 112(%esp),%edx
+ addl 120(%esp),%edi
+ movl %eax,(%esp)
+ movl %ebp,16(%esp)
+ movl %ecx,32(%esp)
+ movl %esi,36(%esp)
+ movl %edx,48(%esp)
+ movl %edi,56(%esp)
+ movl 4(%esp),%ebp
+ movl 8(%esp),%ecx
+ movl 12(%esp),%esi
+ movl 20(%esp),%edx
+ movl 24(%esp),%edi
+ addl $857760878,%ebp
+ addl $2036477234,%ecx
+ addl $1797285236,%esi
+ addl 84(%esp),%edx
+ addl 88(%esp),%edi
+ movl %ebp,4(%esp)
+ movl %ecx,8(%esp)
+ movl %esi,12(%esp)
+ movl %edx,20(%esp)
+ movl %edi,24(%esp)
+ movl 28(%esp),%ebp
+ movl 40(%esp),%ecx
+ movl 44(%esp),%esi
+ movl 52(%esp),%edx
+ movl 60(%esp),%edi
+ addl 92(%esp),%ebp
+ addl 104(%esp),%ecx
+ addl 108(%esp),%esi
+ addl 116(%esp),%edx
+ addl 124(%esp),%edi
+ movl %ebp,28(%esp)
+ movl 156(%esp),%ebp
+ movl %ecx,40(%esp)
+ movl 152(%esp),%ecx
+ movl %esi,44(%esp)
+ xorl %esi,%esi
+ movl %edx,52(%esp)
+ movl %edi,60(%esp)
+ xorl %eax,%eax
+ xorl %edx,%edx
+.L007tail_loop:
+ movb (%esi,%ebp,1),%al
+ movb (%esp,%esi,1),%dl
+ leal 1(%esi),%esi
+ xorb %dl,%al
+ movb %al,-1(%ecx,%esi,1)
+ decl %ebx
+ jnz .L007tail_loop
+.L006done:
+ addl $132,%esp
+.L000no_data:
+ popl %edi
+ popl %esi
+ popl %ebx
+ popl %ebp
+ ret
+.size ChaCha20_ctr32,.-.L_ChaCha20_ctr32_begin
+.globl ChaCha20_ssse3
+.hidden ChaCha20_ssse3
+.type ChaCha20_ssse3,@function
+.align 16
+ChaCha20_ssse3:
+.L_ChaCha20_ssse3_begin:
+ pushl %ebp
+ pushl %ebx
+ pushl %esi
+ pushl %edi
+.Lssse3_shortcut:
+ movl 20(%esp),%edi
+ movl 24(%esp),%esi
+ movl 28(%esp),%ecx
+ movl 32(%esp),%edx
+ movl 36(%esp),%ebx
+ movl %esp,%ebp
+ subl $524,%esp
+ andl $-64,%esp
+ movl %ebp,512(%esp)
+ leal .Lssse3_data-.Lpic_point(%eax),%eax
+ movdqu (%ebx),%xmm3
+ cmpl $256,%ecx
+ jb .L0081x
+ movl %edx,516(%esp)
+ movl %ebx,520(%esp)
+ subl $256,%ecx
+ leal 384(%esp),%ebp
+ movdqu (%edx),%xmm7
+ pshufd $0,%xmm3,%xmm0
+ pshufd $85,%xmm3,%xmm1
+ pshufd $170,%xmm3,%xmm2
+ pshufd $255,%xmm3,%xmm3
+ paddd 48(%eax),%xmm0
+ pshufd $0,%xmm7,%xmm4
+ pshufd $85,%xmm7,%xmm5
+ psubd 64(%eax),%xmm0
+ pshufd $170,%xmm7,%xmm6
+ pshufd $255,%xmm7,%xmm7
+ movdqa %xmm0,64(%ebp)
+ movdqa %xmm1,80(%ebp)
+ movdqa %xmm2,96(%ebp)
+ movdqa %xmm3,112(%ebp)
+ movdqu 16(%edx),%xmm3
+ movdqa %xmm4,-64(%ebp)
+ movdqa %xmm5,-48(%ebp)
+ movdqa %xmm6,-32(%ebp)
+ movdqa %xmm7,-16(%ebp)
+ movdqa 32(%eax),%xmm7
+ leal 128(%esp),%ebx
+ pshufd $0,%xmm3,%xmm0
+ pshufd $85,%xmm3,%xmm1
+ pshufd $170,%xmm3,%xmm2
+ pshufd $255,%xmm3,%xmm3
+ pshufd $0,%xmm7,%xmm4
+ pshufd $85,%xmm7,%xmm5
+ pshufd $170,%xmm7,%xmm6
+ pshufd $255,%xmm7,%xmm7
+ movdqa %xmm0,(%ebp)
+ movdqa %xmm1,16(%ebp)
+ movdqa %xmm2,32(%ebp)
+ movdqa %xmm3,48(%ebp)
+ movdqa %xmm4,-128(%ebp)
+ movdqa %xmm5,-112(%ebp)
+ movdqa %xmm6,-96(%ebp)
+ movdqa %xmm7,-80(%ebp)
+ leal 128(%esi),%esi
+ leal 128(%edi),%edi
+ jmp .L009outer_loop
+.align 16
+.L009outer_loop:
+ movdqa -112(%ebp),%xmm1
+ movdqa -96(%ebp),%xmm2
+ movdqa -80(%ebp),%xmm3
+ movdqa -48(%ebp),%xmm5
+ movdqa -32(%ebp),%xmm6
+ movdqa -16(%ebp),%xmm7
+ movdqa %xmm1,-112(%ebx)
+ movdqa %xmm2,-96(%ebx)
+ movdqa %xmm3,-80(%ebx)
+ movdqa %xmm5,-48(%ebx)
+ movdqa %xmm6,-32(%ebx)
+ movdqa %xmm7,-16(%ebx)
+ movdqa 32(%ebp),%xmm2
+ movdqa 48(%ebp),%xmm3
+ movdqa 64(%ebp),%xmm4
+ movdqa 80(%ebp),%xmm5
+ movdqa 96(%ebp),%xmm6
+ movdqa 112(%ebp),%xmm7
+ paddd 64(%eax),%xmm4
+ movdqa %xmm2,32(%ebx)
+ movdqa %xmm3,48(%ebx)
+ movdqa %xmm4,64(%ebx)
+ movdqa %xmm5,80(%ebx)
+ movdqa %xmm6,96(%ebx)
+ movdqa %xmm7,112(%ebx)
+ movdqa %xmm4,64(%ebp)
+ movdqa -128(%ebp),%xmm0
+ movdqa %xmm4,%xmm6
+ movdqa -64(%ebp),%xmm3
+ movdqa (%ebp),%xmm4
+ movdqa 16(%ebp),%xmm5
+ movl $10,%edx
+ nop
+.align 16
+.L010loop:
+ paddd %xmm3,%xmm0
+ movdqa %xmm3,%xmm2
+ pxor %xmm0,%xmm6
+ pshufb (%eax),%xmm6
+ paddd %xmm6,%xmm4
+ pxor %xmm4,%xmm2
+ movdqa -48(%ebx),%xmm3
+ movdqa %xmm2,%xmm1
+ pslld $12,%xmm2
+ psrld $20,%xmm1
+ por %xmm1,%xmm2
+ movdqa -112(%ebx),%xmm1
+ paddd %xmm2,%xmm0
+ movdqa 80(%ebx),%xmm7
+ pxor %xmm0,%xmm6
+ movdqa %xmm0,-128(%ebx)
+ pshufb 16(%eax),%xmm6
+ paddd %xmm6,%xmm4
+ movdqa %xmm6,64(%ebx)
+ pxor %xmm4,%xmm2
+ paddd %xmm3,%xmm1
+ movdqa %xmm2,%xmm0
+ pslld $7,%xmm2
+ psrld $25,%xmm0
+ pxor %xmm1,%xmm7
+ por %xmm0,%xmm2
+ movdqa %xmm4,(%ebx)
+ pshufb (%eax),%xmm7
+ movdqa %xmm2,-64(%ebx)
+ paddd %xmm7,%xmm5
+ movdqa 32(%ebx),%xmm4
+ pxor %xmm5,%xmm3
+ movdqa -32(%ebx),%xmm2
+ movdqa %xmm3,%xmm0
+ pslld $12,%xmm3
+ psrld $20,%xmm0
+ por %xmm0,%xmm3
+ movdqa -96(%ebx),%xmm0
+ paddd %xmm3,%xmm1
+ movdqa 96(%ebx),%xmm6
+ pxor %xmm1,%xmm7
+ movdqa %xmm1,-112(%ebx)
+ pshufb 16(%eax),%xmm7
+ paddd %xmm7,%xmm5
+ movdqa %xmm7,80(%ebx)
+ pxor %xmm5,%xmm3
+ paddd %xmm2,%xmm0
+ movdqa %xmm3,%xmm1
+ pslld $7,%xmm3
+ psrld $25,%xmm1
+ pxor %xmm0,%xmm6
+ por %xmm1,%xmm3
+ movdqa %xmm5,16(%ebx)
+ pshufb (%eax),%xmm6
+ movdqa %xmm3,-48(%ebx)
+ paddd %xmm6,%xmm4
+ movdqa 48(%ebx),%xmm5
+ pxor %xmm4,%xmm2
+ movdqa -16(%ebx),%xmm3
+ movdqa %xmm2,%xmm1
+ pslld $12,%xmm2
+ psrld $20,%xmm1
+ por %xmm1,%xmm2
+ movdqa -80(%ebx),%xmm1
+ paddd %xmm2,%xmm0
+ movdqa 112(%ebx),%xmm7
+ pxor %xmm0,%xmm6
+ movdqa %xmm0,-96(%ebx)
+ pshufb 16(%eax),%xmm6
+ paddd %xmm6,%xmm4
+ movdqa %xmm6,96(%ebx)
+ pxor %xmm4,%xmm2
+ paddd %xmm3,%xmm1
+ movdqa %xmm2,%xmm0
+ pslld $7,%xmm2
+ psrld $25,%xmm0
+ pxor %xmm1,%xmm7
+ por %xmm0,%xmm2
+ pshufb (%eax),%xmm7
+ movdqa %xmm2,-32(%ebx)
+ paddd %xmm7,%xmm5
+ pxor %xmm5,%xmm3
+ movdqa -48(%ebx),%xmm2
+ movdqa %xmm3,%xmm0
+ pslld $12,%xmm3
+ psrld $20,%xmm0
+ por %xmm0,%xmm3
+ movdqa -128(%ebx),%xmm0
+ paddd %xmm3,%xmm1
+ pxor %xmm1,%xmm7
+ movdqa %xmm1,-80(%ebx)
+ pshufb 16(%eax),%xmm7
+ paddd %xmm7,%xmm5
+ movdqa %xmm7,%xmm6
+ pxor %xmm5,%xmm3
+ paddd %xmm2,%xmm0
+ movdqa %xmm3,%xmm1
+ pslld $7,%xmm3
+ psrld $25,%xmm1
+ pxor %xmm0,%xmm6
+ por %xmm1,%xmm3
+ pshufb (%eax),%xmm6
+ movdqa %xmm3,-16(%ebx)
+ paddd %xmm6,%xmm4
+ pxor %xmm4,%xmm2
+ movdqa -32(%ebx),%xmm3
+ movdqa %xmm2,%xmm1
+ pslld $12,%xmm2
+ psrld $20,%xmm1
+ por %xmm1,%xmm2
+ movdqa -112(%ebx),%xmm1
+ paddd %xmm2,%xmm0
+ movdqa 64(%ebx),%xmm7
+ pxor %xmm0,%xmm6
+ movdqa %xmm0,-128(%ebx)
+ pshufb 16(%eax),%xmm6
+ paddd %xmm6,%xmm4
+ movdqa %xmm6,112(%ebx)
+ pxor %xmm4,%xmm2
+ paddd %xmm3,%xmm1
+ movdqa %xmm2,%xmm0
+ pslld $7,%xmm2
+ psrld $25,%xmm0
+ pxor %xmm1,%xmm7
+ por %xmm0,%xmm2
+ movdqa %xmm4,32(%ebx)
+ pshufb (%eax),%xmm7
+ movdqa %xmm2,-48(%ebx)
+ paddd %xmm7,%xmm5
+ movdqa (%ebx),%xmm4
+ pxor %xmm5,%xmm3
+ movdqa -16(%ebx),%xmm2
+ movdqa %xmm3,%xmm0
+ pslld $12,%xmm3
+ psrld $20,%xmm0
+ por %xmm0,%xmm3
+ movdqa -96(%ebx),%xmm0
+ paddd %xmm3,%xmm1
+ movdqa 80(%ebx),%xmm6
+ pxor %xmm1,%xmm7
+ movdqa %xmm1,-112(%ebx)
+ pshufb 16(%eax),%xmm7
+ paddd %xmm7,%xmm5
+ movdqa %xmm7,64(%ebx)
+ pxor %xmm5,%xmm3
+ paddd %xmm2,%xmm0
+ movdqa %xmm3,%xmm1
+ pslld $7,%xmm3
+ psrld $25,%xmm1
+ pxor %xmm0,%xmm6
+ por %xmm1,%xmm3
+ movdqa %xmm5,48(%ebx)
+ pshufb (%eax),%xmm6
+ movdqa %xmm3,-32(%ebx)
+ paddd %xmm6,%xmm4
+ movdqa 16(%ebx),%xmm5
+ pxor %xmm4,%xmm2
+ movdqa -64(%ebx),%xmm3
+ movdqa %xmm2,%xmm1
+ pslld $12,%xmm2
+ psrld $20,%xmm1
+ por %xmm1,%xmm2
+ movdqa -80(%ebx),%xmm1
+ paddd %xmm2,%xmm0
+ movdqa 96(%ebx),%xmm7
+ pxor %xmm0,%xmm6
+ movdqa %xmm0,-96(%ebx)
+ pshufb 16(%eax),%xmm6
+ paddd %xmm6,%xmm4
+ movdqa %xmm6,80(%ebx)
+ pxor %xmm4,%xmm2
+ paddd %xmm3,%xmm1
+ movdqa %xmm2,%xmm0
+ pslld $7,%xmm2
+ psrld $25,%xmm0
+ pxor %xmm1,%xmm7
+ por %xmm0,%xmm2
+ pshufb (%eax),%xmm7
+ movdqa %xmm2,-16(%ebx)
+ paddd %xmm7,%xmm5
+ pxor %xmm5,%xmm3
+ movdqa %xmm3,%xmm0
+ pslld $12,%xmm3
+ psrld $20,%xmm0
+ por %xmm0,%xmm3
+ movdqa -128(%ebx),%xmm0
+ paddd %xmm3,%xmm1
+ movdqa 64(%ebx),%xmm6
+ pxor %xmm1,%xmm7
+ movdqa %xmm1,-80(%ebx)
+ pshufb 16(%eax),%xmm7
+ paddd %xmm7,%xmm5
+ movdqa %xmm7,96(%ebx)
+ pxor %xmm5,%xmm3
+ movdqa %xmm3,%xmm1
+ pslld $7,%xmm3
+ psrld $25,%xmm1
+ por %xmm1,%xmm3
+ decl %edx
+ jnz .L010loop
+ movdqa %xmm3,-64(%ebx)
+ movdqa %xmm4,(%ebx)
+ movdqa %xmm5,16(%ebx)
+ movdqa %xmm6,64(%ebx)
+ movdqa %xmm7,96(%ebx)
+ movdqa -112(%ebx),%xmm1
+ movdqa -96(%ebx),%xmm2
+ movdqa -80(%ebx),%xmm3
+ paddd -128(%ebp),%xmm0
+ paddd -112(%ebp),%xmm1
+ paddd -96(%ebp),%xmm2
+ paddd -80(%ebp),%xmm3
+ movdqa %xmm0,%xmm6
+ punpckldq %xmm1,%xmm0
+ movdqa %xmm2,%xmm7
+ punpckldq %xmm3,%xmm2
+ punpckhdq %xmm1,%xmm6
+ punpckhdq %xmm3,%xmm7
+ movdqa %xmm0,%xmm1
+ punpcklqdq %xmm2,%xmm0
+ movdqa %xmm6,%xmm3
+ punpcklqdq %xmm7,%xmm6
+ punpckhqdq %xmm2,%xmm1
+ punpckhqdq %xmm7,%xmm3
+ movdqa %xmm0,-128(%ebx)
+ movdqa -64(%ebx),%xmm0
+ movdqa %xmm1,-112(%ebx)
+ movdqa %xmm6,-96(%ebx)
+ movdqa %xmm3,-80(%ebx)
+ movdqa -48(%ebx),%xmm1
+ movdqa -32(%ebx),%xmm2
+ movdqa -16(%ebx),%xmm3
+ paddd -64(%ebp),%xmm0
+ paddd -48(%ebp),%xmm1
+ paddd -32(%ebp),%xmm2
+ paddd -16(%ebp),%xmm3
+ movdqa %xmm0,%xmm6
+ punpckldq %xmm1,%xmm0
+ movdqa %xmm2,%xmm7
+ punpckldq %xmm3,%xmm2
+ punpckhdq %xmm1,%xmm6
+ punpckhdq %xmm3,%xmm7
+ movdqa %xmm0,%xmm1
+ punpcklqdq %xmm2,%xmm0
+ movdqa %xmm6,%xmm3
+ punpcklqdq %xmm7,%xmm6
+ punpckhqdq %xmm2,%xmm1
+ punpckhqdq %xmm7,%xmm3
+ movdqa %xmm0,-64(%ebx)
+ movdqa (%ebx),%xmm0
+ movdqa %xmm1,-48(%ebx)
+ movdqa %xmm6,-32(%ebx)
+ movdqa %xmm3,-16(%ebx)
+ movdqa 16(%ebx),%xmm1
+ movdqa 32(%ebx),%xmm2
+ movdqa 48(%ebx),%xmm3
+ paddd (%ebp),%xmm0
+ paddd 16(%ebp),%xmm1
+ paddd 32(%ebp),%xmm2
+ paddd 48(%ebp),%xmm3
+ movdqa %xmm0,%xmm6
+ punpckldq %xmm1,%xmm0
+ movdqa %xmm2,%xmm7
+ punpckldq %xmm3,%xmm2
+ punpckhdq %xmm1,%xmm6
+ punpckhdq %xmm3,%xmm7
+ movdqa %xmm0,%xmm1
+ punpcklqdq %xmm2,%xmm0
+ movdqa %xmm6,%xmm3
+ punpcklqdq %xmm7,%xmm6
+ punpckhqdq %xmm2,%xmm1
+ punpckhqdq %xmm7,%xmm3
+ movdqa %xmm0,(%ebx)
+ movdqa 64(%ebx),%xmm0
+ movdqa %xmm1,16(%ebx)
+ movdqa %xmm6,32(%ebx)
+ movdqa %xmm3,48(%ebx)
+ movdqa 80(%ebx),%xmm1
+ movdqa 96(%ebx),%xmm2
+ movdqa 112(%ebx),%xmm3
+ paddd 64(%ebp),%xmm0
+ paddd 80(%ebp),%xmm1
+ paddd 96(%ebp),%xmm2
+ paddd 112(%ebp),%xmm3
+ movdqa %xmm0,%xmm6
+ punpckldq %xmm1,%xmm0
+ movdqa %xmm2,%xmm7
+ punpckldq %xmm3,%xmm2
+ punpckhdq %xmm1,%xmm6
+ punpckhdq %xmm3,%xmm7
+ movdqa %xmm0,%xmm1
+ punpcklqdq %xmm2,%xmm0
+ movdqa %xmm6,%xmm3
+ punpcklqdq %xmm7,%xmm6
+ punpckhqdq %xmm2,%xmm1
+ punpckhqdq %xmm7,%xmm3
+ movdqa %xmm0,64(%ebx)
+ movdqa %xmm1,80(%ebx)
+ movdqa %xmm6,96(%ebx)
+ movdqa %xmm3,112(%ebx)
+ movdqu -128(%esi),%xmm0
+ movdqu -112(%esi),%xmm1
+ movdqu -96(%esi),%xmm2
+ movdqu -80(%esi),%xmm3
+ pxor -128(%ebx),%xmm0
+ pxor -64(%ebx),%xmm1
+ pxor (%ebx),%xmm2
+ pxor 64(%ebx),%xmm3
+ movdqu %xmm0,-128(%edi)
+ movdqu %xmm1,-112(%edi)
+ movdqu %xmm2,-96(%edi)
+ movdqu %xmm3,-80(%edi)
+ movdqu -64(%esi),%xmm0
+ movdqu -48(%esi),%xmm1
+ movdqu -32(%esi),%xmm2
+ movdqu -16(%esi),%xmm3
+ pxor -112(%ebx),%xmm0
+ pxor -48(%ebx),%xmm1
+ pxor 16(%ebx),%xmm2
+ pxor 80(%ebx),%xmm3
+ movdqu %xmm0,-64(%edi)
+ movdqu %xmm1,-48(%edi)
+ movdqu %xmm2,-32(%edi)
+ movdqu %xmm3,-16(%edi)
+ movdqu (%esi),%xmm0
+ movdqu 16(%esi),%xmm1
+ movdqu 32(%esi),%xmm2
+ movdqu 48(%esi),%xmm3
+ pxor -96(%ebx),%xmm0
+ pxor -32(%ebx),%xmm1
+ pxor 32(%ebx),%xmm2
+ pxor 96(%ebx),%xmm3
+ movdqu %xmm0,(%edi)
+ movdqu %xmm1,16(%edi)
+ movdqu %xmm2,32(%edi)
+ movdqu %xmm3,48(%edi)
+ movdqu 64(%esi),%xmm0
+ movdqu 80(%esi),%xmm1
+ movdqu 96(%esi),%xmm2
+ movdqu 112(%esi),%xmm3
+ pxor -80(%ebx),%xmm0
+ pxor -16(%ebx),%xmm1
+ pxor 48(%ebx),%xmm2
+ pxor 112(%ebx),%xmm3
+ movdqu %xmm0,64(%edi)
+ movdqu %xmm1,80(%edi)
+ movdqu %xmm2,96(%edi)
+ movdqu %xmm3,112(%edi)
+ leal 256(%esi),%esi
+ leal 256(%edi),%edi
+ subl $256,%ecx
+ jnc .L009outer_loop
+ addl $256,%ecx
+ jz .L011done
+ movl 520(%esp),%ebx
+ leal -128(%esi),%esi
+ movl 516(%esp),%edx
+ leal -128(%edi),%edi
+ movd 64(%ebp),%xmm2
+ movdqu (%ebx),%xmm3
+ paddd 96(%eax),%xmm2
+ pand 112(%eax),%xmm3
+ por %xmm2,%xmm3
+.L0081x:
+ movdqa 32(%eax),%xmm0
+ movdqu (%edx),%xmm1
+ movdqu 16(%edx),%xmm2
+ movdqa (%eax),%xmm6
+ movdqa 16(%eax),%xmm7
+ movl %ebp,48(%esp)
+ movdqa %xmm0,(%esp)
+ movdqa %xmm1,16(%esp)
+ movdqa %xmm2,32(%esp)
+ movdqa %xmm3,48(%esp)
+ movl $10,%edx
+ jmp .L012loop1x
+.align 16
+.L013outer1x:
+ movdqa 80(%eax),%xmm3
+ movdqa (%esp),%xmm0
+ movdqa 16(%esp),%xmm1
+ movdqa 32(%esp),%xmm2
+ paddd 48(%esp),%xmm3
+ movl $10,%edx
+ movdqa %xmm3,48(%esp)
+ jmp .L012loop1x
+.align 16
+.L012loop1x:
+ paddd %xmm1,%xmm0
+ pxor %xmm0,%xmm3
+.byte 102,15,56,0,222
+ paddd %xmm3,%xmm2
+ pxor %xmm2,%xmm1
+ movdqa %xmm1,%xmm4
+ psrld $20,%xmm1
+ pslld $12,%xmm4
+ por %xmm4,%xmm1
+ paddd %xmm1,%xmm0
+ pxor %xmm0,%xmm3
+.byte 102,15,56,0,223
+ paddd %xmm3,%xmm2
+ pxor %xmm2,%xmm1
+ movdqa %xmm1,%xmm4
+ psrld $25,%xmm1
+ pslld $7,%xmm4
+ por %xmm4,%xmm1
+ pshufd $78,%xmm2,%xmm2
+ pshufd $57,%xmm1,%xmm1
+ pshufd $147,%xmm3,%xmm3
+ nop
+ paddd %xmm1,%xmm0
+ pxor %xmm0,%xmm3
+.byte 102,15,56,0,222
+ paddd %xmm3,%xmm2
+ pxor %xmm2,%xmm1
+ movdqa %xmm1,%xmm4
+ psrld $20,%xmm1
+ pslld $12,%xmm4
+ por %xmm4,%xmm1
+ paddd %xmm1,%xmm0
+ pxor %xmm0,%xmm3
+.byte 102,15,56,0,223
+ paddd %xmm3,%xmm2
+ pxor %xmm2,%xmm1
+ movdqa %xmm1,%xmm4
+ psrld $25,%xmm1
+ pslld $7,%xmm4
+ por %xmm4,%xmm1
+ pshufd $78,%xmm2,%xmm2
+ pshufd $147,%xmm1,%xmm1
+ pshufd $57,%xmm3,%xmm3
+ decl %edx
+ jnz .L012loop1x
+ paddd (%esp),%xmm0
+ paddd 16(%esp),%xmm1
+ paddd 32(%esp),%xmm2
+ paddd 48(%esp),%xmm3
+ cmpl $64,%ecx
+ jb .L014tail
+ movdqu (%esi),%xmm4
+ movdqu 16(%esi),%xmm5
+ pxor %xmm4,%xmm0
+ movdqu 32(%esi),%xmm4
+ pxor %xmm5,%xmm1
+ movdqu 48(%esi),%xmm5
+ pxor %xmm4,%xmm2
+ pxor %xmm5,%xmm3
+ leal 64(%esi),%esi
+ movdqu %xmm0,(%edi)
+ movdqu %xmm1,16(%edi)
+ movdqu %xmm2,32(%edi)
+ movdqu %xmm3,48(%edi)
+ leal 64(%edi),%edi
+ subl $64,%ecx
+ jnz .L013outer1x
+ jmp .L011done
+.L014tail:
+ movdqa %xmm0,(%esp)
+ movdqa %xmm1,16(%esp)
+ movdqa %xmm2,32(%esp)
+ movdqa %xmm3,48(%esp)
+ xorl %eax,%eax
+ xorl %edx,%edx
+ xorl %ebp,%ebp
+.L015tail_loop:
+ movb (%esp,%ebp,1),%al
+ movb (%esi,%ebp,1),%dl
+ leal 1(%ebp),%ebp
+ xorb %dl,%al
+ movb %al,-1(%edi,%ebp,1)
+ decl %ecx
+ jnz .L015tail_loop
+.L011done:
+ movl 512(%esp),%esp
+ popl %edi
+ popl %esi
+ popl %ebx
+ popl %ebp
+ ret
+.size ChaCha20_ssse3,.-.L_ChaCha20_ssse3_begin
+.align 64
+.Lssse3_data:
+.byte 2,3,0,1,6,7,4,5,10,11,8,9,14,15,12,13
+.byte 3,0,1,2,7,4,5,6,11,8,9,10,15,12,13,14
+.long 1634760805,857760878,2036477234,1797285236
+.long 0,1,2,3
+.long 4,4,4,4
+.long 1,0,0,0
+.long 4,0,0,0
+.long 0,-1,-1,-1
+.align 64
+.byte 67,104,97,67,104,97,50,48,32,102,111,114,32,120,56,54
+.byte 44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32
+.byte 60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111
+.byte 114,103,62,0
+#endif
diff --git a/linux-x86/crypto/rc4/rc4-586.S b/linux-x86/crypto/rc4/rc4-586.S
index a5cce47c..d245589e 100644
--- a/linux-x86/crypto/rc4/rc4-586.S
+++ b/linux-x86/crypto/rc4/rc4-586.S
@@ -347,39 +347,4 @@ asm_RC4_set_key:
popl %ebp
ret
.size asm_RC4_set_key,.-.L_asm_RC4_set_key_begin
-.globl RC4_options
-.hidden RC4_options
-.type RC4_options,@function
-.align 16
-RC4_options:
-.L_RC4_options_begin:
- call .L018pic_point
-.L018pic_point:
- popl %eax
- leal .L019opts-.L018pic_point(%eax),%eax
- call .L020PIC_me_up
-.L020PIC_me_up:
- popl %edx
- leal OPENSSL_ia32cap_P-.L020PIC_me_up(%edx),%edx
- movl (%edx),%edx
- btl $20,%edx
- jc .L0211xchar
- btl $26,%edx
- jnc .L022ret
- addl $25,%eax
- ret
-.L0211xchar:
- addl $12,%eax
-.L022ret:
- ret
-.align 64
-.L019opts:
-.byte 114,99,52,40,52,120,44,105,110,116,41,0
-.byte 114,99,52,40,49,120,44,99,104,97,114,41,0
-.byte 114,99,52,40,56,120,44,109,109,120,41,0
-.byte 82,67,52,32,102,111,114,32,120,56,54,44,32,67,82,89
-.byte 80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114
-.byte 111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
-.align 64
-.size RC4_options,.-.L_RC4_options_begin
#endif
diff --git a/linux-x86_64/crypto/aes/aes-x86_64.S b/linux-x86_64/crypto/aes/aes-x86_64.S
index 5f4b057f..361e84c7 100644
--- a/linux-x86_64/crypto/aes/aes-x86_64.S
+++ b/linux-x86_64/crypto/aes/aes-x86_64.S
@@ -82,8 +82,8 @@ _x86_64_AES_encrypt:
movl 0(%r14,%rdi,8),%edi
movl 0(%r14,%rbp,8),%ebp
- andl $65280,%edi
- andl $65280,%ebp
+ andl $0x0000ff00,%edi
+ andl $0x0000ff00,%ebp
xorl %edi,%r10d
xorl %ebp,%r11d
@@ -95,8 +95,8 @@ _x86_64_AES_encrypt:
movl 0(%r14,%rsi,8),%esi
movl 0(%r14,%rdi,8),%edi
- andl $65280,%esi
- andl $65280,%edi
+ andl $0x0000ff00,%esi
+ andl $0x0000ff00,%edi
shrl $16,%ebx
xorl %esi,%r12d
xorl %edi,%r8d
@@ -109,9 +109,9 @@ _x86_64_AES_encrypt:
movl 0(%r14,%rdi,8),%edi
movl 0(%r14,%rbp,8),%ebp
- andl $16711680,%esi
- andl $16711680,%edi
- andl $16711680,%ebp
+ andl $0x00ff0000,%esi
+ andl $0x00ff0000,%edi
+ andl $0x00ff0000,%ebp
xorl %esi,%r10d
xorl %edi,%r11d
@@ -124,9 +124,9 @@ _x86_64_AES_encrypt:
movl 2(%r14,%rdi,8),%edi
movl 2(%r14,%rbp,8),%ebp
- andl $16711680,%esi
- andl $4278190080,%edi
- andl $4278190080,%ebp
+ andl $0x00ff0000,%esi
+ andl $0xff000000,%edi
+ andl $0xff000000,%ebp
xorl %esi,%r8d
xorl %edi,%r10d
@@ -139,8 +139,8 @@ _x86_64_AES_encrypt:
movl 2(%r14,%rdi,8),%edi
movl 16+0(%r15),%eax
- andl $4278190080,%esi
- andl $4278190080,%edi
+ andl $0xff000000,%esi
+ andl $0xff000000,%edi
xorl %esi,%r12d
xorl %edi,%r8d
@@ -242,8 +242,8 @@ _x86_64_AES_encrypt_compact:
xorl %r8d,%edx
cmpq 16(%rsp),%r15
je .Lenc_compact_done
- movl $2155905152,%r10d
- movl $2155905152,%r11d
+ movl $0x80808080,%r10d
+ movl $0x80808080,%r11d
andl %eax,%r10d
andl %ebx,%r11d
movl %r10d,%esi
@@ -254,10 +254,10 @@ _x86_64_AES_encrypt_compact:
leal (%rbx,%rbx,1),%r9d
subl %r10d,%esi
subl %r11d,%edi
- andl $4278124286,%r8d
- andl $4278124286,%r9d
- andl $454761243,%esi
- andl $454761243,%edi
+ andl $0xfefefefe,%r8d
+ andl $0xfefefefe,%r9d
+ andl $0x1b1b1b1b,%esi
+ andl $0x1b1b1b1b,%edi
movl %eax,%r10d
movl %ebx,%r11d
xorl %esi,%r8d
@@ -265,9 +265,9 @@ _x86_64_AES_encrypt_compact:
xorl %r8d,%eax
xorl %r9d,%ebx
- movl $2155905152,%r12d
+ movl $0x80808080,%r12d
roll $24,%eax
- movl $2155905152,%ebp
+ movl $0x80808080,%ebp
roll $24,%ebx
andl %ecx,%r12d
andl %edx,%ebp
@@ -290,10 +290,10 @@ _x86_64_AES_encrypt_compact:
xorl %r10d,%eax
xorl %r11d,%ebx
- andl $4278124286,%r8d
- andl $4278124286,%r9d
- andl $454761243,%esi
- andl $454761243,%edi
+ andl $0xfefefefe,%r8d
+ andl $0xfefefefe,%r9d
+ andl $0x1b1b1b1b,%esi
+ andl $0x1b1b1b1b,%edi
movl %ecx,%r12d
movl %edx,%ebp
xorl %esi,%r8d
@@ -345,7 +345,7 @@ asm_AES_encrypt:
andq $-64,%rsp
subq %rsp,%rcx
negq %rcx
- andq $960,%rcx
+ andq $0x3c0,%rcx
subq %rcx,%rsp
subq $32,%rsp
@@ -370,7 +370,7 @@ asm_AES_encrypt:
leaq .LAES_Te+2048(%rip),%r14
leaq 768(%rsp),%rbp
subq %r14,%rbp
- andq $768,%rbp
+ andq $0x300,%rbp
leaq (%r14,%rbp,1),%r14
call _x86_64_AES_encrypt_compact
@@ -791,7 +791,7 @@ asm_AES_decrypt:
andq $-64,%rsp
subq %rsp,%rcx
negq %rcx
- andq $960,%rcx
+ andq $0x3c0,%rcx
subq %rcx,%rsp
subq $32,%rsp
@@ -816,7 +816,7 @@ asm_AES_decrypt:
leaq .LAES_Td+2048(%rip),%r14
leaq 768(%rsp),%rbp
subq %r14,%rbp
- andq $768,%rbp
+ andq $0x300,%rbp
leaq (%r14,%rbp,1),%r14
shrq $3,%rbp
addq %rbp,%r14
@@ -1334,9 +1334,9 @@ asm_AES_cbc_encrypt:
movq %r14,%r10
leaq 2304(%r14),%r11
movq %r15,%r12
- andq $4095,%r10
- andq $4095,%r11
- andq $4095,%r12
+ andq $0xFFF,%r10
+ andq $0xFFF,%r11
+ andq $0xFFF,%r12
cmpq %r11,%r12
jb .Lcbc_te_break_out
@@ -1345,7 +1345,7 @@ asm_AES_cbc_encrypt:
jmp .Lcbc_te_ok
.Lcbc_te_break_out:
subq %r10,%r12
- andq $4095,%r12
+ andq $0xFFF,%r12
addq $320,%r12
subq %r12,%r15
.align 4
@@ -1371,7 +1371,7 @@ asm_AES_cbc_encrypt:
movq %r15,%r10
subq %r14,%r10
- andq $4095,%r10
+ andq $0xfff,%r10
cmpq $2304,%r10
jb .Lcbc_do_ecopy
cmpq $4096-248,%r10
@@ -1558,7 +1558,7 @@ asm_AES_cbc_encrypt:
leaq -88-63(%rcx),%r10
subq %rbp,%r10
negq %r10
- andq $960,%r10
+ andq $0x3c0,%r10
subq %r10,%rbp
xchgq %rsp,%rbp
@@ -1587,7 +1587,7 @@ asm_AES_cbc_encrypt:
leaq 2048(%r14),%r14
leaq 768-8(%rsp),%rax
subq %r14,%rax
- andq $768,%rax
+ andq $0x300,%rax
leaq (%r14,%rax,1),%r14
cmpq $0,%rbx
diff --git a/linux-x86_64/crypto/aes/aesni-x86_64.S b/linux-x86_64/crypto/aes/aesni-x86_64.S
index 1d51d5b5..5709a2d0 100644
--- a/linux-x86_64/crypto/aes/aesni-x86_64.S
+++ b/linux-x86_64/crypto/aes/aesni-x86_64.S
@@ -508,7 +508,7 @@ aesni_ecb_encrypt:
testl %r8d,%r8d
jz .Lecb_decrypt
- cmpq $128,%rdx
+ cmpq $0x80,%rdx
jb .Lecb_enc_tail
movdqu (%rdi),%xmm2
@@ -520,7 +520,7 @@ aesni_ecb_encrypt:
movdqu 96(%rdi),%xmm8
movdqu 112(%rdi),%xmm9
leaq 128(%rdi),%rdi
- subq $128,%rdx
+ subq $0x80,%rdx
jmp .Lecb_enc_loop8_enter
.align 16
.Lecb_enc_loop8:
@@ -548,7 +548,7 @@ aesni_ecb_encrypt:
call _aesni_encrypt8
- subq $128,%rdx
+ subq $0x80,%rdx
jnc .Lecb_enc_loop8
movups %xmm2,(%rsi)
@@ -562,22 +562,22 @@ aesni_ecb_encrypt:
movups %xmm8,96(%rsi)
movups %xmm9,112(%rsi)
leaq 128(%rsi),%rsi
- addq $128,%rdx
+ addq $0x80,%rdx
jz .Lecb_ret
.Lecb_enc_tail:
movups (%rdi),%xmm2
- cmpq $32,%rdx
+ cmpq $0x20,%rdx
jb .Lecb_enc_one
movups 16(%rdi),%xmm3
je .Lecb_enc_two
movups 32(%rdi),%xmm4
- cmpq $64,%rdx
+ cmpq $0x40,%rdx
jb .Lecb_enc_three
movups 48(%rdi),%xmm5
je .Lecb_enc_four
movups 64(%rdi),%xmm6
- cmpq $96,%rdx
+ cmpq $0x60,%rdx
jb .Lecb_enc_five
movups 80(%rdi),%xmm7
je .Lecb_enc_six
@@ -651,7 +651,7 @@ aesni_ecb_encrypt:
.align 16
.Lecb_decrypt:
- cmpq $128,%rdx
+ cmpq $0x80,%rdx
jb .Lecb_dec_tail
movdqu (%rdi),%xmm2
@@ -663,7 +663,7 @@ aesni_ecb_encrypt:
movdqu 96(%rdi),%xmm8
movdqu 112(%rdi),%xmm9
leaq 128(%rdi),%rdi
- subq $128,%rdx
+ subq $0x80,%rdx
jmp .Lecb_dec_loop8_enter
.align 16
.Lecb_dec_loop8:
@@ -692,7 +692,7 @@ aesni_ecb_encrypt:
call _aesni_decrypt8
movups (%r11),%xmm0
- subq $128,%rdx
+ subq $0x80,%rdx
jnc .Lecb_dec_loop8
movups %xmm2,(%rsi)
@@ -714,22 +714,22 @@ aesni_ecb_encrypt:
movups %xmm9,112(%rsi)
pxor %xmm9,%xmm9
leaq 128(%rsi),%rsi
- addq $128,%rdx
+ addq $0x80,%rdx
jz .Lecb_ret
.Lecb_dec_tail:
movups (%rdi),%xmm2
- cmpq $32,%rdx
+ cmpq $0x20,%rdx
jb .Lecb_dec_one
movups 16(%rdi),%xmm3
je .Lecb_dec_two
movups 32(%rdi),%xmm4
- cmpq $64,%rdx
+ cmpq $0x40,%rdx
jb .Lecb_dec_three
movups 48(%rdi),%xmm5
je .Lecb_dec_four
movups 64(%rdi),%xmm6
- cmpq $96,%rdx
+ cmpq $0x60,%rdx
jb .Lecb_dec_five
movups 80(%rdi),%xmm7
je .Lecb_dec_six
@@ -1607,7 +1607,7 @@ aesni_xts_encrypt:
movdqa .Lxts_magic(%rip),%xmm8
movdqa %xmm2,%xmm15
- pshufd $95,%xmm2,%xmm9
+ pshufd $0x5f,%xmm2,%xmm9
pxor %xmm0,%xmm1
movdqa %xmm9,%xmm14
paddd %xmm9,%xmm9
@@ -1706,7 +1706,7 @@ aesni_xts_encrypt:
.byte 102,15,56,220,248
movups 64(%r11),%xmm0
movdqa %xmm8,80(%rsp)
- pshufd $95,%xmm15,%xmm9
+ pshufd $0x5f,%xmm15,%xmm9
jmp .Lxts_enc_loop6
.align 32
.Lxts_enc_loop6:
@@ -1845,13 +1845,13 @@ aesni_xts_encrypt:
jz .Lxts_enc_done
pxor %xmm0,%xmm11
- cmpq $32,%rdx
+ cmpq $0x20,%rdx
jb .Lxts_enc_one
pxor %xmm0,%xmm12
je .Lxts_enc_two
pxor %xmm0,%xmm13
- cmpq $64,%rdx
+ cmpq $0x40,%rdx
jb .Lxts_enc_three
pxor %xmm0,%xmm14
je .Lxts_enc_four
@@ -2079,7 +2079,7 @@ aesni_xts_decrypt:
movdqa .Lxts_magic(%rip),%xmm8
movdqa %xmm2,%xmm15
- pshufd $95,%xmm2,%xmm9
+ pshufd $0x5f,%xmm2,%xmm9
pxor %xmm0,%xmm1
movdqa %xmm9,%xmm14
paddd %xmm9,%xmm9
@@ -2178,7 +2178,7 @@ aesni_xts_decrypt:
.byte 102,15,56,222,248
movups 64(%r11),%xmm0
movdqa %xmm8,80(%rsp)
- pshufd $95,%xmm15,%xmm9
+ pshufd $0x5f,%xmm15,%xmm9
jmp .Lxts_dec_loop6
.align 32
.Lxts_dec_loop6:
@@ -2318,13 +2318,13 @@ aesni_xts_decrypt:
jz .Lxts_dec_done
pxor %xmm0,%xmm12
- cmpq $32,%rdx
+ cmpq $0x20,%rdx
jb .Lxts_dec_one
pxor %xmm0,%xmm13
je .Lxts_dec_two
pxor %xmm0,%xmm14
- cmpq $64,%rdx
+ cmpq $0x40,%rdx
jb .Lxts_dec_three
je .Lxts_dec_four
@@ -2355,7 +2355,7 @@ aesni_xts_decrypt:
pcmpgtd %xmm15,%xmm14
movdqu %xmm6,64(%rsi)
leaq 80(%rsi),%rsi
- pshufd $19,%xmm14,%xmm11
+ pshufd $0x13,%xmm14,%xmm11
andq $15,%r9
jz .Lxts_dec_ret
@@ -2645,7 +2645,7 @@ aesni_cbc_encrypt:
leaq -8(%rax),%rbp
movups (%r8),%xmm10
movl %r10d,%eax
- cmpq $80,%rdx
+ cmpq $0x50,%rdx
jbe .Lcbc_dec_tail
movups (%rcx),%xmm0
@@ -2661,14 +2661,14 @@ aesni_cbc_encrypt:
movdqu 80(%rdi),%xmm7
movdqa %xmm6,%xmm15
movl OPENSSL_ia32cap_P+4(%rip),%r9d
- cmpq $112,%rdx
+ cmpq $0x70,%rdx
jbe .Lcbc_dec_six_or_seven
andl $71303168,%r9d
- subq $80,%rdx
+ subq $0x50,%rdx
cmpl $4194304,%r9d
je .Lcbc_dec_loop6_enter
- subq $32,%rdx
+ subq $0x20,%rdx
leaq 112(%rcx),%rcx
jmp .Lcbc_dec_loop8_enter
.align 16
@@ -2683,7 +2683,7 @@ aesni_cbc_encrypt:
movups 16-112(%rcx),%xmm1
pxor %xmm0,%xmm4
xorq %r11,%r11
- cmpq $112,%rdx
+ cmpq $0x70,%rdx
pxor %xmm0,%xmm5
pxor %xmm0,%xmm6
pxor %xmm0,%xmm7
@@ -2868,21 +2868,21 @@ aesni_cbc_encrypt:
movups %xmm8,96(%rsi)
leaq 112(%rsi),%rsi
- subq $128,%rdx
+ subq $0x80,%rdx
ja .Lcbc_dec_loop8
movaps %xmm9,%xmm2
leaq -112(%rcx),%rcx
- addq $112,%rdx
+ addq $0x70,%rdx
jle .Lcbc_dec_clear_tail_collected
movups %xmm9,(%rsi)
leaq 16(%rsi),%rsi
- cmpq $80,%rdx
+ cmpq $0x50,%rdx
jbe .Lcbc_dec_tail
movaps %xmm11,%xmm2
.Lcbc_dec_six_or_seven:
- cmpq $96,%rdx
+ cmpq $0x60,%rdx
ja .Lcbc_dec_seven
movaps %xmm7,%xmm8
@@ -2975,33 +2975,33 @@ aesni_cbc_encrypt:
movl %r10d,%eax
movdqu %xmm6,64(%rsi)
leaq 80(%rsi),%rsi
- subq $96,%rdx
+ subq $0x60,%rdx
ja .Lcbc_dec_loop6
movdqa %xmm7,%xmm2
- addq $80,%rdx
+ addq $0x50,%rdx
jle .Lcbc_dec_clear_tail_collected
movups %xmm7,(%rsi)
leaq 16(%rsi),%rsi
.Lcbc_dec_tail:
movups (%rdi),%xmm2
- subq $16,%rdx
+ subq $0x10,%rdx
jbe .Lcbc_dec_one
movups 16(%rdi),%xmm3
movaps %xmm2,%xmm11
- subq $16,%rdx
+ subq $0x10,%rdx
jbe .Lcbc_dec_two
movups 32(%rdi),%xmm4
movaps %xmm3,%xmm12
- subq $16,%rdx
+ subq $0x10,%rdx
jbe .Lcbc_dec_three
movups 48(%rdi),%xmm5
movaps %xmm4,%xmm13
- subq $16,%rdx
+ subq $0x10,%rdx
jbe .Lcbc_dec_four
movups 64(%rdi),%xmm6
@@ -3026,7 +3026,7 @@ aesni_cbc_encrypt:
movdqa %xmm6,%xmm2
pxor %xmm6,%xmm6
pxor %xmm7,%xmm7
- subq $16,%rdx
+ subq $0x10,%rdx
jmp .Lcbc_dec_tail_collected
.align 16
@@ -3345,7 +3345,7 @@ __aesni_set_encrypt_key:
pslldq $4,%xmm0
pxor %xmm3,%xmm0
- pshufd $255,%xmm0,%xmm3
+ pshufd $0xff,%xmm0,%xmm3
pxor %xmm1,%xmm3
pslldq $4,%xmm1
pxor %xmm1,%xmm3
@@ -3432,7 +3432,7 @@ __aesni_set_encrypt_key:
decl %r10d
jz .Ldone_key256
- pshufd $255,%xmm0,%xmm2
+ pshufd $0xff,%xmm0,%xmm2
pxor %xmm3,%xmm3
.byte 102,15,56,221,211
diff --git a/linux-x86_64/crypto/aes/bsaes-x86_64.S b/linux-x86_64/crypto/aes/bsaes-x86_64.S
index 8cfa4df5..c5491ce4 100644
--- a/linux-x86_64/crypto/aes/bsaes-x86_64.S
+++ b/linux-x86_64/crypto/aes/bsaes-x86_64.S
@@ -327,45 +327,45 @@ _bsaes_encrypt8_bitslice:
pxor %xmm2,%xmm5
decl %r10d
jl .Lenc_done
- pshufd $147,%xmm15,%xmm7
- pshufd $147,%xmm0,%xmm8
+ pshufd $0x93,%xmm15,%xmm7
+ pshufd $0x93,%xmm0,%xmm8
pxor %xmm7,%xmm15
- pshufd $147,%xmm3,%xmm9
+ pshufd $0x93,%xmm3,%xmm9
pxor %xmm8,%xmm0
- pshufd $147,%xmm5,%xmm10
+ pshufd $0x93,%xmm5,%xmm10
pxor %xmm9,%xmm3
- pshufd $147,%xmm2,%xmm11
+ pshufd $0x93,%xmm2,%xmm11
pxor %xmm10,%xmm5
- pshufd $147,%xmm6,%xmm12
+ pshufd $0x93,%xmm6,%xmm12
pxor %xmm11,%xmm2
- pshufd $147,%xmm1,%xmm13
+ pshufd $0x93,%xmm1,%xmm13
pxor %xmm12,%xmm6
- pshufd $147,%xmm4,%xmm14
+ pshufd $0x93,%xmm4,%xmm14
pxor %xmm13,%xmm1
pxor %xmm14,%xmm4
pxor %xmm15,%xmm8
pxor %xmm4,%xmm7
pxor %xmm4,%xmm8
- pshufd $78,%xmm15,%xmm15
+ pshufd $0x4E,%xmm15,%xmm15
pxor %xmm0,%xmm9
- pshufd $78,%xmm0,%xmm0
+ pshufd $0x4E,%xmm0,%xmm0
pxor %xmm2,%xmm12
pxor %xmm7,%xmm15
pxor %xmm6,%xmm13
pxor %xmm8,%xmm0
pxor %xmm5,%xmm11
- pshufd $78,%xmm2,%xmm7
+ pshufd $0x4E,%xmm2,%xmm7
pxor %xmm1,%xmm14
- pshufd $78,%xmm6,%xmm8
+ pshufd $0x4E,%xmm6,%xmm8
pxor %xmm3,%xmm10
- pshufd $78,%xmm5,%xmm2
+ pshufd $0x4E,%xmm5,%xmm2
pxor %xmm4,%xmm10
- pshufd $78,%xmm4,%xmm6
+ pshufd $0x4E,%xmm4,%xmm6
pxor %xmm4,%xmm11
- pshufd $78,%xmm1,%xmm5
+ pshufd $0x4E,%xmm1,%xmm5
pxor %xmm11,%xmm7
- pshufd $78,%xmm3,%xmm1
+ pshufd $0x4E,%xmm3,%xmm1
pxor %xmm12,%xmm8
pxor %xmm10,%xmm2
pxor %xmm14,%xmm6
@@ -799,24 +799,24 @@ _bsaes_decrypt8:
decl %r10d
jl .Ldec_done
- pshufd $78,%xmm15,%xmm7
- pshufd $78,%xmm2,%xmm13
+ pshufd $0x4E,%xmm15,%xmm7
+ pshufd $0x4E,%xmm2,%xmm13
pxor %xmm15,%xmm7
- pshufd $78,%xmm4,%xmm14
+ pshufd $0x4E,%xmm4,%xmm14
pxor %xmm2,%xmm13
- pshufd $78,%xmm0,%xmm8
+ pshufd $0x4E,%xmm0,%xmm8
pxor %xmm4,%xmm14
- pshufd $78,%xmm5,%xmm9
+ pshufd $0x4E,%xmm5,%xmm9
pxor %xmm0,%xmm8
- pshufd $78,%xmm3,%xmm10
+ pshufd $0x4E,%xmm3,%xmm10
pxor %xmm5,%xmm9
pxor %xmm13,%xmm15
pxor %xmm13,%xmm0
- pshufd $78,%xmm1,%xmm11
+ pshufd $0x4E,%xmm1,%xmm11
pxor %xmm3,%xmm10
pxor %xmm7,%xmm5
pxor %xmm8,%xmm3
- pshufd $78,%xmm6,%xmm12
+ pshufd $0x4E,%xmm6,%xmm12
pxor %xmm1,%xmm11
pxor %xmm14,%xmm0
pxor %xmm9,%xmm1
@@ -830,45 +830,45 @@ _bsaes_decrypt8:
pxor %xmm14,%xmm1
pxor %xmm14,%xmm6
pxor %xmm12,%xmm4
- pshufd $147,%xmm15,%xmm7
- pshufd $147,%xmm0,%xmm8
+ pshufd $0x93,%xmm15,%xmm7
+ pshufd $0x93,%xmm0,%xmm8
pxor %xmm7,%xmm15
- pshufd $147,%xmm5,%xmm9
+ pshufd $0x93,%xmm5,%xmm9
pxor %xmm8,%xmm0
- pshufd $147,%xmm3,%xmm10
+ pshufd $0x93,%xmm3,%xmm10
pxor %xmm9,%xmm5
- pshufd $147,%xmm1,%xmm11
+ pshufd $0x93,%xmm1,%xmm11
pxor %xmm10,%xmm3
- pshufd $147,%xmm6,%xmm12
+ pshufd $0x93,%xmm6,%xmm12
pxor %xmm11,%xmm1
- pshufd $147,%xmm2,%xmm13
+ pshufd $0x93,%xmm2,%xmm13
pxor %xmm12,%xmm6
- pshufd $147,%xmm4,%xmm14
+ pshufd $0x93,%xmm4,%xmm14
pxor %xmm13,%xmm2
pxor %xmm14,%xmm4
pxor %xmm15,%xmm8
pxor %xmm4,%xmm7
pxor %xmm4,%xmm8
- pshufd $78,%xmm15,%xmm15
+ pshufd $0x4E,%xmm15,%xmm15
pxor %xmm0,%xmm9
- pshufd $78,%xmm0,%xmm0
+ pshufd $0x4E,%xmm0,%xmm0
pxor %xmm1,%xmm12
pxor %xmm7,%xmm15
pxor %xmm6,%xmm13
pxor %xmm8,%xmm0
pxor %xmm3,%xmm11
- pshufd $78,%xmm1,%xmm7
+ pshufd $0x4E,%xmm1,%xmm7
pxor %xmm2,%xmm14
- pshufd $78,%xmm6,%xmm8
+ pshufd $0x4E,%xmm6,%xmm8
pxor %xmm5,%xmm10
- pshufd $78,%xmm3,%xmm1
+ pshufd $0x4E,%xmm3,%xmm1
pxor %xmm4,%xmm10
- pshufd $78,%xmm4,%xmm6
+ pshufd $0x4E,%xmm4,%xmm6
pxor %xmm4,%xmm11
- pshufd $78,%xmm2,%xmm3
+ pshufd $0x4E,%xmm2,%xmm3
pxor %xmm11,%xmm7
- pshufd $78,%xmm5,%xmm2
+ pshufd $0x4E,%xmm5,%xmm2
pxor %xmm12,%xmm8
pxor %xmm1,%xmm10
pxor %xmm14,%xmm6
@@ -1559,20 +1559,20 @@ bsaes_xts_encrypt:
movdqa %xmm7,(%rax)
andq $-16,%r14
- subq $128,%rsp
+ subq $0x80,%rsp
movdqa 32(%rbp),%xmm6
pxor %xmm14,%xmm14
movdqa .Lxts_magic(%rip),%xmm12
pcmpgtd %xmm6,%xmm14
- subq $128,%r14
+ subq $0x80,%r14
jc .Lxts_enc_short
jmp .Lxts_enc_loop
.align 16
.Lxts_enc_loop:
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm15
movdqa %xmm6,0(%rsp)
@@ -1580,7 +1580,7 @@ bsaes_xts_encrypt:
pand %xmm12,%xmm13
pcmpgtd %xmm6,%xmm14
pxor %xmm13,%xmm6
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm0
movdqa %xmm6,16(%rsp)
@@ -1589,7 +1589,7 @@ bsaes_xts_encrypt:
pcmpgtd %xmm6,%xmm14
pxor %xmm13,%xmm6
movdqu 0(%r12),%xmm7
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm1
movdqa %xmm6,32(%rsp)
@@ -1599,7 +1599,7 @@ bsaes_xts_encrypt:
pxor %xmm13,%xmm6
movdqu 16(%r12),%xmm8
pxor %xmm7,%xmm15
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm2
movdqa %xmm6,48(%rsp)
@@ -1609,7 +1609,7 @@ bsaes_xts_encrypt:
pxor %xmm13,%xmm6
movdqu 32(%r12),%xmm9
pxor %xmm8,%xmm0
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm3
movdqa %xmm6,64(%rsp)
@@ -1619,7 +1619,7 @@ bsaes_xts_encrypt:
pxor %xmm13,%xmm6
movdqu 48(%r12),%xmm10
pxor %xmm9,%xmm1
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm4
movdqa %xmm6,80(%rsp)
@@ -1629,7 +1629,7 @@ bsaes_xts_encrypt:
pxor %xmm13,%xmm6
movdqu 64(%r12),%xmm11
pxor %xmm10,%xmm2
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm5
movdqa %xmm6,96(%rsp)
@@ -1673,20 +1673,20 @@ bsaes_xts_encrypt:
pxor %xmm14,%xmm14
movdqa .Lxts_magic(%rip),%xmm12
pcmpgtd %xmm6,%xmm14
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
paddq %xmm6,%xmm6
pand %xmm12,%xmm13
pcmpgtd %xmm6,%xmm14
pxor %xmm13,%xmm6
- subq $128,%r14
+ subq $0x80,%r14
jnc .Lxts_enc_loop
.Lxts_enc_short:
- addq $128,%r14
+ addq $0x80,%r14
jz .Lxts_enc_done
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm15
movdqa %xmm6,0(%rsp)
@@ -1694,7 +1694,7 @@ bsaes_xts_encrypt:
pand %xmm12,%xmm13
pcmpgtd %xmm6,%xmm14
pxor %xmm13,%xmm6
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm0
movdqa %xmm6,16(%rsp)
@@ -1705,7 +1705,7 @@ bsaes_xts_encrypt:
movdqu 0(%r12),%xmm7
cmpq $16,%r14
je .Lxts_enc_1
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm1
movdqa %xmm6,32(%rsp)
@@ -1717,7 +1717,7 @@ bsaes_xts_encrypt:
cmpq $32,%r14
je .Lxts_enc_2
pxor %xmm7,%xmm15
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm2
movdqa %xmm6,48(%rsp)
@@ -1729,7 +1729,7 @@ bsaes_xts_encrypt:
cmpq $48,%r14
je .Lxts_enc_3
pxor %xmm8,%xmm0
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm3
movdqa %xmm6,64(%rsp)
@@ -1741,7 +1741,7 @@ bsaes_xts_encrypt:
cmpq $64,%r14
je .Lxts_enc_4
pxor %xmm9,%xmm1
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm4
movdqa %xmm6,80(%rsp)
@@ -1753,7 +1753,7 @@ bsaes_xts_encrypt:
cmpq $80,%r14
je .Lxts_enc_5
pxor %xmm10,%xmm2
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm5
movdqa %xmm6,96(%rsp)
@@ -2019,20 +2019,20 @@ bsaes_xts_decrypt:
shlq $4,%rax
subq %rax,%r14
- subq $128,%rsp
+ subq $0x80,%rsp
movdqa 32(%rbp),%xmm6
pxor %xmm14,%xmm14
movdqa .Lxts_magic(%rip),%xmm12
pcmpgtd %xmm6,%xmm14
- subq $128,%r14
+ subq $0x80,%r14
jc .Lxts_dec_short
jmp .Lxts_dec_loop
.align 16
.Lxts_dec_loop:
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm15
movdqa %xmm6,0(%rsp)
@@ -2040,7 +2040,7 @@ bsaes_xts_decrypt:
pand %xmm12,%xmm13
pcmpgtd %xmm6,%xmm14
pxor %xmm13,%xmm6
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm0
movdqa %xmm6,16(%rsp)
@@ -2049,7 +2049,7 @@ bsaes_xts_decrypt:
pcmpgtd %xmm6,%xmm14
pxor %xmm13,%xmm6
movdqu 0(%r12),%xmm7
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm1
movdqa %xmm6,32(%rsp)
@@ -2059,7 +2059,7 @@ bsaes_xts_decrypt:
pxor %xmm13,%xmm6
movdqu 16(%r12),%xmm8
pxor %xmm7,%xmm15
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm2
movdqa %xmm6,48(%rsp)
@@ -2069,7 +2069,7 @@ bsaes_xts_decrypt:
pxor %xmm13,%xmm6
movdqu 32(%r12),%xmm9
pxor %xmm8,%xmm0
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm3
movdqa %xmm6,64(%rsp)
@@ -2079,7 +2079,7 @@ bsaes_xts_decrypt:
pxor %xmm13,%xmm6
movdqu 48(%r12),%xmm10
pxor %xmm9,%xmm1
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm4
movdqa %xmm6,80(%rsp)
@@ -2089,7 +2089,7 @@ bsaes_xts_decrypt:
pxor %xmm13,%xmm6
movdqu 64(%r12),%xmm11
pxor %xmm10,%xmm2
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm5
movdqa %xmm6,96(%rsp)
@@ -2133,20 +2133,20 @@ bsaes_xts_decrypt:
pxor %xmm14,%xmm14
movdqa .Lxts_magic(%rip),%xmm12
pcmpgtd %xmm6,%xmm14
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
paddq %xmm6,%xmm6
pand %xmm12,%xmm13
pcmpgtd %xmm6,%xmm14
pxor %xmm13,%xmm6
- subq $128,%r14
+ subq $0x80,%r14
jnc .Lxts_dec_loop
.Lxts_dec_short:
- addq $128,%r14
+ addq $0x80,%r14
jz .Lxts_dec_done
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm15
movdqa %xmm6,0(%rsp)
@@ -2154,7 +2154,7 @@ bsaes_xts_decrypt:
pand %xmm12,%xmm13
pcmpgtd %xmm6,%xmm14
pxor %xmm13,%xmm6
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm0
movdqa %xmm6,16(%rsp)
@@ -2165,7 +2165,7 @@ bsaes_xts_decrypt:
movdqu 0(%r12),%xmm7
cmpq $16,%r14
je .Lxts_dec_1
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm1
movdqa %xmm6,32(%rsp)
@@ -2177,7 +2177,7 @@ bsaes_xts_decrypt:
cmpq $32,%r14
je .Lxts_dec_2
pxor %xmm7,%xmm15
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm2
movdqa %xmm6,48(%rsp)
@@ -2189,7 +2189,7 @@ bsaes_xts_decrypt:
cmpq $48,%r14
je .Lxts_dec_3
pxor %xmm8,%xmm0
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm3
movdqa %xmm6,64(%rsp)
@@ -2201,7 +2201,7 @@ bsaes_xts_decrypt:
cmpq $64,%r14
je .Lxts_dec_4
pxor %xmm9,%xmm1
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm4
movdqa %xmm6,80(%rsp)
@@ -2213,7 +2213,7 @@ bsaes_xts_decrypt:
cmpq $80,%r14
je .Lxts_dec_5
pxor %xmm10,%xmm2
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm5
movdqa %xmm6,96(%rsp)
@@ -2390,7 +2390,7 @@ bsaes_xts_decrypt:
pxor %xmm14,%xmm14
movdqa .Lxts_magic(%rip),%xmm12
pcmpgtd %xmm6,%xmm14
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
movdqa %xmm6,%xmm5
paddq %xmm6,%xmm6
pand %xmm12,%xmm13
diff --git a/linux-x86_64/crypto/aes/vpaes-x86_64.S b/linux-x86_64/crypto/aes/vpaes-x86_64.S
index 1d124246..4dfafa97 100644
--- a/linux-x86_64/crypto/aes/vpaes-x86_64.S
+++ b/linux-x86_64/crypto/aes/vpaes-x86_64.S
@@ -61,7 +61,7 @@ _vpaes_encrypt_core:
addq $16,%r11
pxor %xmm0,%xmm3
.byte 102,15,56,0,193
- andq $48,%r11
+ andq $0x30,%r11
subq $1,%rax
pxor %xmm3,%xmm0
@@ -121,10 +121,10 @@ _vpaes_decrypt_core:
pand %xmm9,%xmm0
.byte 102,15,56,0,208
movdqa .Lk_dipt+16(%rip),%xmm0
- xorq $48,%r11
+ xorq $0x30,%r11
leaq .Lk_dsbd(%rip),%r10
.byte 102,15,56,0,193
- andq $48,%r11
+ andq $0x30,%r11
pxor %xmm5,%xmm2
movdqa .Lk_mc_forward+48(%rip),%xmm5
pxor %xmm2,%xmm0
@@ -243,7 +243,7 @@ _vpaes_schedule_core:
movdqa (%r8,%r10,1),%xmm1
.byte 102,15,56,0,217
movdqu %xmm3,(%rdx)
- xorq $48,%r8
+ xorq $0x30,%r8
.Lschedule_go:
cmpl $192,%esi
@@ -333,7 +333,7 @@ _vpaes_schedule_core:
call _vpaes_schedule_mangle
- pshufd $255,%xmm0,%xmm0
+ pshufd $0xFF,%xmm0,%xmm0
movdqa %xmm7,%xmm5
movdqa %xmm6,%xmm7
call _vpaes_schedule_low_round
@@ -400,8 +400,8 @@ _vpaes_schedule_core:
.type _vpaes_schedule_192_smear,@function
.align 16
_vpaes_schedule_192_smear:
- pshufd $128,%xmm6,%xmm1
- pshufd $254,%xmm7,%xmm0
+ pshufd $0x80,%xmm6,%xmm1
+ pshufd $0xFE,%xmm7,%xmm0
pxor %xmm1,%xmm6
pxor %xmm1,%xmm1
pxor %xmm0,%xmm6
@@ -438,7 +438,7 @@ _vpaes_schedule_round:
pxor %xmm1,%xmm7
- pshufd $255,%xmm0,%xmm0
+ pshufd $0xFF,%xmm0,%xmm0
.byte 102,15,58,15,192,1
@@ -597,7 +597,7 @@ _vpaes_schedule_mangle:
movdqa (%r8,%r10,1),%xmm1
.byte 102,15,56,0,217
addq $-16,%r8
- andq $48,%r8
+ andq $0x30,%r8
movdqu %xmm3,(%rdx)
.byte 0xf3,0xc3
.size _vpaes_schedule_mangle,.-_vpaes_schedule_mangle
@@ -616,7 +616,7 @@ vpaes_set_encrypt_key:
movl %eax,240(%rdx)
movl $0,%ecx
- movl $48,%r8d
+ movl $0x30,%r8d
call _vpaes_schedule_core
xorl %eax,%eax
.byte 0xf3,0xc3
diff --git a/linux-x86_64/crypto/bn/rsaz-x86_64.S b/linux-x86_64/crypto/bn/rsaz-x86_64.S
index dd3d3106..21531d1c 100644
--- a/linux-x86_64/crypto/bn/rsaz-x86_64.S
+++ b/linux-x86_64/crypto/bn/rsaz-x86_64.S
@@ -466,48 +466,94 @@ rsaz_512_mul_gather4:
pushq %r14
pushq %r15
- movl %r9d,%r9d
- subq $128+24,%rsp
+ subq $152,%rsp
.Lmul_gather4_body:
- movl 64(%rdx,%r9,4),%eax
-.byte 102,72,15,110,199
- movl (%rdx,%r9,4),%ebx
-.byte 102,72,15,110,201
+ movd %r9d,%xmm8
+ movdqa .Linc+16(%rip),%xmm1
+ movdqa .Linc(%rip),%xmm0
+
+ pshufd $0,%xmm8,%xmm8
+ movdqa %xmm1,%xmm7
+ movdqa %xmm1,%xmm2
+ paddd %xmm0,%xmm1
+ pcmpeqd %xmm8,%xmm0
+ movdqa %xmm7,%xmm3
+ paddd %xmm1,%xmm2
+ pcmpeqd %xmm8,%xmm1
+ movdqa %xmm7,%xmm4
+ paddd %xmm2,%xmm3
+ pcmpeqd %xmm8,%xmm2
+ movdqa %xmm7,%xmm5
+ paddd %xmm3,%xmm4
+ pcmpeqd %xmm8,%xmm3
+ movdqa %xmm7,%xmm6
+ paddd %xmm4,%xmm5
+ pcmpeqd %xmm8,%xmm4
+ paddd %xmm5,%xmm6
+ pcmpeqd %xmm8,%xmm5
+ paddd %xmm6,%xmm7
+ pcmpeqd %xmm8,%xmm6
+ pcmpeqd %xmm8,%xmm7
+
+ movdqa 0(%rdx),%xmm8
+ movdqa 16(%rdx),%xmm9
+ movdqa 32(%rdx),%xmm10
+ movdqa 48(%rdx),%xmm11
+ pand %xmm0,%xmm8
+ movdqa 64(%rdx),%xmm12
+ pand %xmm1,%xmm9
+ movdqa 80(%rdx),%xmm13
+ pand %xmm2,%xmm10
+ movdqa 96(%rdx),%xmm14
+ pand %xmm3,%xmm11
+ movdqa 112(%rdx),%xmm15
+ leaq 128(%rdx),%rbp
+ pand %xmm4,%xmm12
+ pand %xmm5,%xmm13
+ pand %xmm6,%xmm14
+ pand %xmm7,%xmm15
+ por %xmm10,%xmm8
+ por %xmm11,%xmm9
+ por %xmm12,%xmm8
+ por %xmm13,%xmm9
+ por %xmm14,%xmm8
+ por %xmm15,%xmm9
+
+ por %xmm9,%xmm8
+ pshufd $0x4e,%xmm8,%xmm9
+ por %xmm9,%xmm8
+.byte 102,76,15,126,195
+
movq %r8,128(%rsp)
+ movq %rdi,128+8(%rsp)
+ movq %rcx,128+16(%rsp)
- shlq $32,%rax
- orq %rax,%rbx
movq (%rsi),%rax
movq 8(%rsi),%rcx
- leaq 128(%rdx,%r9,4),%rbp
mulq %rbx
movq %rax,(%rsp)
movq %rcx,%rax
movq %rdx,%r8
mulq %rbx
- movd (%rbp),%xmm4
addq %rax,%r8
movq 16(%rsi),%rax
movq %rdx,%r9
adcq $0,%r9
mulq %rbx
- movd 64(%rbp),%xmm5
addq %rax,%r9
movq 24(%rsi),%rax
movq %rdx,%r10
adcq $0,%r10
mulq %rbx
- pslldq $4,%xmm5
addq %rax,%r10
movq 32(%rsi),%rax
movq %rdx,%r11
adcq $0,%r11
mulq %rbx
- por %xmm5,%xmm4
addq %rax,%r11
movq 40(%rsi),%rax
movq %rdx,%r12
@@ -520,14 +566,12 @@ rsaz_512_mul_gather4:
adcq $0,%r13
mulq %rbx
- leaq 128(%rbp),%rbp
addq %rax,%r13
movq 56(%rsi),%rax
movq %rdx,%r14
adcq $0,%r14
mulq %rbx
-.byte 102,72,15,126,227
addq %rax,%r14
movq (%rsi),%rax
movq %rdx,%r15
@@ -539,6 +583,35 @@ rsaz_512_mul_gather4:
.align 32
.Loop_mul_gather:
+ movdqa 0(%rbp),%xmm8
+ movdqa 16(%rbp),%xmm9
+ movdqa 32(%rbp),%xmm10
+ movdqa 48(%rbp),%xmm11
+ pand %xmm0,%xmm8
+ movdqa 64(%rbp),%xmm12
+ pand %xmm1,%xmm9
+ movdqa 80(%rbp),%xmm13
+ pand %xmm2,%xmm10
+ movdqa 96(%rbp),%xmm14
+ pand %xmm3,%xmm11
+ movdqa 112(%rbp),%xmm15
+ leaq 128(%rbp),%rbp
+ pand %xmm4,%xmm12
+ pand %xmm5,%xmm13
+ pand %xmm6,%xmm14
+ pand %xmm7,%xmm15
+ por %xmm10,%xmm8
+ por %xmm11,%xmm9
+ por %xmm12,%xmm8
+ por %xmm13,%xmm9
+ por %xmm14,%xmm8
+ por %xmm15,%xmm9
+
+ por %xmm9,%xmm8
+ pshufd $0x4e,%xmm8,%xmm9
+ por %xmm9,%xmm8
+.byte 102,76,15,126,195
+
mulq %rbx
addq %rax,%r8
movq 8(%rsi),%rax
@@ -547,7 +620,6 @@ rsaz_512_mul_gather4:
adcq $0,%r8
mulq %rbx
- movd (%rbp),%xmm4
addq %rax,%r9
movq 16(%rsi),%rax
adcq $0,%rdx
@@ -556,7 +628,6 @@ rsaz_512_mul_gather4:
adcq $0,%r9
mulq %rbx
- movd 64(%rbp),%xmm5
addq %rax,%r10
movq 24(%rsi),%rax
adcq $0,%rdx
@@ -565,7 +636,6 @@ rsaz_512_mul_gather4:
adcq $0,%r10
mulq %rbx
- pslldq $4,%xmm5
addq %rax,%r11
movq 32(%rsi),%rax
adcq $0,%rdx
@@ -574,7 +644,6 @@ rsaz_512_mul_gather4:
adcq $0,%r11
mulq %rbx
- por %xmm5,%xmm4
addq %rax,%r12
movq 40(%rsi),%rax
adcq $0,%rdx
@@ -599,7 +668,6 @@ rsaz_512_mul_gather4:
adcq $0,%r14
mulq %rbx
-.byte 102,72,15,126,227
addq %rax,%r15
movq (%rsi),%rax
adcq $0,%rdx
@@ -607,7 +675,6 @@ rsaz_512_mul_gather4:
movq %rdx,%r15
adcq $0,%r15
- leaq 128(%rbp),%rbp
leaq 8(%rdi),%rdi
decl %ecx
@@ -622,8 +689,8 @@ rsaz_512_mul_gather4:
movq %r14,48(%rdi)
movq %r15,56(%rdi)
-.byte 102,72,15,126,199
-.byte 102,72,15,126,205
+ movq 128+8(%rsp),%rdi
+ movq 128+16(%rsp),%rbp
movq (%rsp),%r8
movq 8(%rsp),%r9
@@ -673,7 +740,7 @@ rsaz_512_mul_scatter4:
movl %r9d,%r9d
subq $128+24,%rsp
.Lmul_scatter4_body:
- leaq (%r8,%r9,4),%r8
+ leaq (%r8,%r9,8),%r8
.byte 102,72,15,110,199
.byte 102,72,15,110,202
.byte 102,73,15,110,208
@@ -709,30 +776,14 @@ rsaz_512_mul_scatter4:
call __rsaz_512_subtract
- movl %r8d,0(%rsi)
- shrq $32,%r8
- movl %r9d,128(%rsi)
- shrq $32,%r9
- movl %r10d,256(%rsi)
- shrq $32,%r10
- movl %r11d,384(%rsi)
- shrq $32,%r11
- movl %r12d,512(%rsi)
- shrq $32,%r12
- movl %r13d,640(%rsi)
- shrq $32,%r13
- movl %r14d,768(%rsi)
- shrq $32,%r14
- movl %r15d,896(%rsi)
- shrq $32,%r15
- movl %r8d,64(%rsi)
- movl %r9d,192(%rsi)
- movl %r10d,320(%rsi)
- movl %r11d,448(%rsi)
- movl %r12d,576(%rsi)
- movl %r13d,704(%rsi)
- movl %r14d,832(%rsi)
- movl %r15d,960(%rsi)
+ movq %r8,0(%rsi)
+ movq %r9,128(%rsi)
+ movq %r10,256(%rsi)
+ movq %r11,384(%rsi)
+ movq %r12,512(%rsi)
+ movq %r13,640(%rsi)
+ movq %r14,768(%rsi)
+ movq %r15,896(%rsi)
leaq 128+24+48(%rsp),%rax
movq -48(%rax),%r15
@@ -1087,16 +1138,14 @@ __rsaz_512_mul:
.type rsaz_512_scatter4,@function
.align 16
rsaz_512_scatter4:
- leaq (%rdi,%rdx,4),%rdi
+ leaq (%rdi,%rdx,8),%rdi
movl $8,%r9d
jmp .Loop_scatter
.align 16
.Loop_scatter:
movq (%rsi),%rax
leaq 8(%rsi),%rsi
- movl %eax,(%rdi)
- shrq $32,%rax
- movl %eax,64(%rdi)
+ movq %rax,(%rdi)
leaq 128(%rdi),%rdi
decl %r9d
jnz .Loop_scatter
@@ -1108,20 +1157,73 @@ rsaz_512_scatter4:
.type rsaz_512_gather4,@function
.align 16
rsaz_512_gather4:
- leaq (%rsi,%rdx,4),%rsi
+ movd %edx,%xmm8
+ movdqa .Linc+16(%rip),%xmm1
+ movdqa .Linc(%rip),%xmm0
+
+ pshufd $0,%xmm8,%xmm8
+ movdqa %xmm1,%xmm7
+ movdqa %xmm1,%xmm2
+ paddd %xmm0,%xmm1
+ pcmpeqd %xmm8,%xmm0
+ movdqa %xmm7,%xmm3
+ paddd %xmm1,%xmm2
+ pcmpeqd %xmm8,%xmm1
+ movdqa %xmm7,%xmm4
+ paddd %xmm2,%xmm3
+ pcmpeqd %xmm8,%xmm2
+ movdqa %xmm7,%xmm5
+ paddd %xmm3,%xmm4
+ pcmpeqd %xmm8,%xmm3
+ movdqa %xmm7,%xmm6
+ paddd %xmm4,%xmm5
+ pcmpeqd %xmm8,%xmm4
+ paddd %xmm5,%xmm6
+ pcmpeqd %xmm8,%xmm5
+ paddd %xmm6,%xmm7
+ pcmpeqd %xmm8,%xmm6
+ pcmpeqd %xmm8,%xmm7
movl $8,%r9d
jmp .Loop_gather
.align 16
.Loop_gather:
- movl (%rsi),%eax
- movl 64(%rsi),%r8d
+ movdqa 0(%rsi),%xmm8
+ movdqa 16(%rsi),%xmm9
+ movdqa 32(%rsi),%xmm10
+ movdqa 48(%rsi),%xmm11
+ pand %xmm0,%xmm8
+ movdqa 64(%rsi),%xmm12
+ pand %xmm1,%xmm9
+ movdqa 80(%rsi),%xmm13
+ pand %xmm2,%xmm10
+ movdqa 96(%rsi),%xmm14
+ pand %xmm3,%xmm11
+ movdqa 112(%rsi),%xmm15
leaq 128(%rsi),%rsi
- shlq $32,%r8
- orq %r8,%rax
- movq %rax,(%rdi)
+ pand %xmm4,%xmm12
+ pand %xmm5,%xmm13
+ pand %xmm6,%xmm14
+ pand %xmm7,%xmm15
+ por %xmm10,%xmm8
+ por %xmm11,%xmm9
+ por %xmm12,%xmm8
+ por %xmm13,%xmm9
+ por %xmm14,%xmm8
+ por %xmm15,%xmm9
+
+ por %xmm9,%xmm8
+ pshufd $0x4e,%xmm8,%xmm9
+ por %xmm9,%xmm8
+ movq %xmm8,(%rdi)
leaq 8(%rdi),%rdi
decl %r9d
jnz .Loop_gather
.byte 0xf3,0xc3
+.LSEH_end_rsaz_512_gather4:
.size rsaz_512_gather4,.-rsaz_512_gather4
+
+.align 64
+.Linc:
+.long 0,0, 1,1
+.long 2,2, 2,2
#endif
diff --git a/linux-x86_64/crypto/bn/x86_64-mont.S b/linux-x86_64/crypto/bn/x86_64-mont.S
index 4d401c67..83926ad7 100644
--- a/linux-x86_64/crypto/bn/x86_64-mont.S
+++ b/linux-x86_64/crypto/bn/x86_64-mont.S
@@ -636,20 +636,20 @@ bn_sqr8x_mont:
- leaq -64(%rsp,%r9,4),%r11
+ leaq -64(%rsp,%r9,2),%r11
movq (%r8),%r8
subq %rsi,%r11
andq $4095,%r11
cmpq %r11,%r10
jb .Lsqr8x_sp_alt
subq %r11,%rsp
- leaq -64(%rsp,%r9,4),%rsp
+ leaq -64(%rsp,%r9,2),%rsp
jmp .Lsqr8x_sp_done
.align 32
.Lsqr8x_sp_alt:
- leaq 4096-64(,%r9,4),%r10
- leaq -64(%rsp,%r9,4),%rsp
+ leaq 4096-64(,%r9,2),%r10
+ leaq -64(%rsp,%r9,2),%rsp
subq %r10,%r11
movq $0,%r10
cmovcq %r10,%r11
@@ -659,58 +659,80 @@ bn_sqr8x_mont:
movq %r9,%r10
negq %r9
- leaq 64(%rsp,%r9,2),%r11
movq %r8,32(%rsp)
movq %rax,40(%rsp)
.Lsqr8x_body:
- movq %r9,%rbp
-.byte 102,73,15,110,211
- shrq $3+2,%rbp
- movl OPENSSL_ia32cap_P+8(%rip),%eax
- jmp .Lsqr8x_copy_n
-
-.align 32
-.Lsqr8x_copy_n:
- movq 0(%rcx),%xmm0
- movq 8(%rcx),%xmm1
- movq 16(%rcx),%xmm3
- movq 24(%rcx),%xmm4
- leaq 32(%rcx),%rcx
- movdqa %xmm0,0(%r11)
- movdqa %xmm1,16(%r11)
- movdqa %xmm3,32(%r11)
- movdqa %xmm4,48(%r11)
- leaq 64(%r11),%r11
- decq %rbp
- jnz .Lsqr8x_copy_n
-
+.byte 102,72,15,110,209
pxor %xmm0,%xmm0
.byte 102,72,15,110,207
.byte 102,73,15,110,218
call bn_sqr8x_internal
+
+
+
+ leaq (%rdi,%r9,1),%rbx
+ movq %r9,%rcx
+ movq %r9,%rdx
+.byte 102,72,15,126,207
+ sarq $3+2,%rcx
+ jmp .Lsqr8x_sub
+
+.align 32
+.Lsqr8x_sub:
+ movq 0(%rbx),%r12
+ movq 8(%rbx),%r13
+ movq 16(%rbx),%r14
+ movq 24(%rbx),%r15
+ leaq 32(%rbx),%rbx
+ sbbq 0(%rbp),%r12
+ sbbq 8(%rbp),%r13
+ sbbq 16(%rbp),%r14
+ sbbq 24(%rbp),%r15
+ leaq 32(%rbp),%rbp
+ movq %r12,0(%rdi)
+ movq %r13,8(%rdi)
+ movq %r14,16(%rdi)
+ movq %r15,24(%rdi)
+ leaq 32(%rdi),%rdi
+ incq %rcx
+ jnz .Lsqr8x_sub
+
+ sbbq $0,%rax
+ leaq (%rbx,%r9,1),%rbx
+ leaq (%rdi,%r9,1),%rdi
+
+.byte 102,72,15,110,200
pxor %xmm0,%xmm0
- leaq 48(%rsp),%rax
- leaq 64(%rsp,%r9,2),%rdx
- shrq $3+2,%r9
+ pshufd $0,%xmm1,%xmm1
movq 40(%rsp),%rsi
- jmp .Lsqr8x_zero
+ jmp .Lsqr8x_cond_copy
.align 32
-.Lsqr8x_zero:
- movdqa %xmm0,0(%rax)
- movdqa %xmm0,16(%rax)
- movdqa %xmm0,32(%rax)
- movdqa %xmm0,48(%rax)
- leaq 64(%rax),%rax
- movdqa %xmm0,0(%rdx)
- movdqa %xmm0,16(%rdx)
- movdqa %xmm0,32(%rdx)
- movdqa %xmm0,48(%rdx)
- leaq 64(%rdx),%rdx
- decq %r9
- jnz .Lsqr8x_zero
+.Lsqr8x_cond_copy:
+ movdqa 0(%rbx),%xmm2
+ movdqa 16(%rbx),%xmm3
+ leaq 32(%rbx),%rbx
+ movdqu 0(%rdi),%xmm4
+ movdqu 16(%rdi),%xmm5
+ leaq 32(%rdi),%rdi
+ movdqa %xmm0,-32(%rbx)
+ movdqa %xmm0,-16(%rbx)
+ movdqa %xmm0,-32(%rbx,%rdx,1)
+ movdqa %xmm0,-16(%rbx,%rdx,1)
+ pcmpeqd %xmm1,%xmm0
+ pand %xmm1,%xmm2
+ pand %xmm1,%xmm3
+ pand %xmm0,%xmm4
+ pand %xmm0,%xmm5
+ pxor %xmm0,%xmm0
+ por %xmm2,%xmm4
+ por %xmm3,%xmm5
+ movdqu %xmm4,-32(%rdi)
+ movdqu %xmm5,-16(%rdi)
+ addq $32,%r9
+ jnz .Lsqr8x_cond_copy
movq $1,%rax
movq -48(%rsi),%r15
diff --git a/linux-x86_64/crypto/bn/x86_64-mont5.S b/linux-x86_64/crypto/bn/x86_64-mont5.S
index 214064e6..554df1ff 100644
--- a/linux-x86_64/crypto/bn/x86_64-mont5.S
+++ b/linux-x86_64/crypto/bn/x86_64-mont5.S
@@ -17,46 +17,151 @@ bn_mul_mont_gather5:
.Lmul_enter:
movl %r9d,%r9d
movq %rsp,%rax
- movl 8(%rsp),%r10d
+ movd 8(%rsp),%xmm5
+ leaq .Linc(%rip),%r10
pushq %rbx
pushq %rbp
pushq %r12
pushq %r13
pushq %r14
pushq %r15
+
leaq 2(%r9),%r11
negq %r11
- leaq (%rsp,%r11,8),%rsp
+ leaq -264(%rsp,%r11,8),%rsp
andq $-1024,%rsp
movq %rax,8(%rsp,%r9,8)
.Lmul_body:
- movq %rdx,%r12
- movq %r10,%r11
- shrq $3,%r10
- andq $7,%r11
- notq %r10
- leaq .Lmagic_masks(%rip),%rax
- andq $3,%r10
- leaq 96(%r12,%r11,8),%r12
- movq 0(%rax,%r10,8),%xmm4
- movq 8(%rax,%r10,8),%xmm5
- movq 16(%rax,%r10,8),%xmm6
- movq 24(%rax,%r10,8),%xmm7
-
- movq -96(%r12),%xmm0
- movq -32(%r12),%xmm1
- pand %xmm4,%xmm0
- movq 32(%r12),%xmm2
- pand %xmm5,%xmm1
- movq 96(%r12),%xmm3
- pand %xmm6,%xmm2
- por %xmm1,%xmm0
- pand %xmm7,%xmm3
+ leaq 128(%rdx),%r12
+ movdqa 0(%r10),%xmm0
+ movdqa 16(%r10),%xmm1
+ leaq 24-112(%rsp,%r9,8),%r10
+ andq $-16,%r10
+
+ pshufd $0,%xmm5,%xmm5
+ movdqa %xmm1,%xmm4
+ movdqa %xmm1,%xmm2
+ paddd %xmm0,%xmm1
+ pcmpeqd %xmm5,%xmm0
+.byte 0x67
+ movdqa %xmm4,%xmm3
+ paddd %xmm1,%xmm2
+ pcmpeqd %xmm5,%xmm1
+ movdqa %xmm0,112(%r10)
+ movdqa %xmm4,%xmm0
+
+ paddd %xmm2,%xmm3
+ pcmpeqd %xmm5,%xmm2
+ movdqa %xmm1,128(%r10)
+ movdqa %xmm4,%xmm1
+
+ paddd %xmm3,%xmm0
+ pcmpeqd %xmm5,%xmm3
+ movdqa %xmm2,144(%r10)
+ movdqa %xmm4,%xmm2
+
+ paddd %xmm0,%xmm1
+ pcmpeqd %xmm5,%xmm0
+ movdqa %xmm3,160(%r10)
+ movdqa %xmm4,%xmm3
+ paddd %xmm1,%xmm2
+ pcmpeqd %xmm5,%xmm1
+ movdqa %xmm0,176(%r10)
+ movdqa %xmm4,%xmm0
+
+ paddd %xmm2,%xmm3
+ pcmpeqd %xmm5,%xmm2
+ movdqa %xmm1,192(%r10)
+ movdqa %xmm4,%xmm1
+
+ paddd %xmm3,%xmm0
+ pcmpeqd %xmm5,%xmm3
+ movdqa %xmm2,208(%r10)
+ movdqa %xmm4,%xmm2
+
+ paddd %xmm0,%xmm1
+ pcmpeqd %xmm5,%xmm0
+ movdqa %xmm3,224(%r10)
+ movdqa %xmm4,%xmm3
+ paddd %xmm1,%xmm2
+ pcmpeqd %xmm5,%xmm1
+ movdqa %xmm0,240(%r10)
+ movdqa %xmm4,%xmm0
+
+ paddd %xmm2,%xmm3
+ pcmpeqd %xmm5,%xmm2
+ movdqa %xmm1,256(%r10)
+ movdqa %xmm4,%xmm1
+
+ paddd %xmm3,%xmm0
+ pcmpeqd %xmm5,%xmm3
+ movdqa %xmm2,272(%r10)
+ movdqa %xmm4,%xmm2
+
+ paddd %xmm0,%xmm1
+ pcmpeqd %xmm5,%xmm0
+ movdqa %xmm3,288(%r10)
+ movdqa %xmm4,%xmm3
+ paddd %xmm1,%xmm2
+ pcmpeqd %xmm5,%xmm1
+ movdqa %xmm0,304(%r10)
+
+ paddd %xmm2,%xmm3
+.byte 0x67
+ pcmpeqd %xmm5,%xmm2
+ movdqa %xmm1,320(%r10)
+
+ pcmpeqd %xmm5,%xmm3
+ movdqa %xmm2,336(%r10)
+ pand 64(%r12),%xmm0
+
+ pand 80(%r12),%xmm1
+ pand 96(%r12),%xmm2
+ movdqa %xmm3,352(%r10)
+ pand 112(%r12),%xmm3
+ por %xmm2,%xmm0
+ por %xmm3,%xmm1
+ movdqa -128(%r12),%xmm4
+ movdqa -112(%r12),%xmm5
+ movdqa -96(%r12),%xmm2
+ pand 112(%r10),%xmm4
+ movdqa -80(%r12),%xmm3
+ pand 128(%r10),%xmm5
+ por %xmm4,%xmm0
+ pand 144(%r10),%xmm2
+ por %xmm5,%xmm1
+ pand 160(%r10),%xmm3
por %xmm2,%xmm0
+ por %xmm3,%xmm1
+ movdqa -64(%r12),%xmm4
+ movdqa -48(%r12),%xmm5
+ movdqa -32(%r12),%xmm2
+ pand 176(%r10),%xmm4
+ movdqa -16(%r12),%xmm3
+ pand 192(%r10),%xmm5
+ por %xmm4,%xmm0
+ pand 208(%r10),%xmm2
+ por %xmm5,%xmm1
+ pand 224(%r10),%xmm3
+ por %xmm2,%xmm0
+ por %xmm3,%xmm1
+ movdqa 0(%r12),%xmm4
+ movdqa 16(%r12),%xmm5
+ movdqa 32(%r12),%xmm2
+ pand 240(%r10),%xmm4
+ movdqa 48(%r12),%xmm3
+ pand 256(%r10),%xmm5
+ por %xmm4,%xmm0
+ pand 272(%r10),%xmm2
+ por %xmm5,%xmm1
+ pand 288(%r10),%xmm3
+ por %xmm2,%xmm0
+ por %xmm3,%xmm1
+ por %xmm1,%xmm0
+ pshufd $0x4e,%xmm0,%xmm1
+ por %xmm1,%xmm0
leaq 256(%r12),%r12
- por %xmm3,%xmm0
-
.byte 102,72,15,126,195
movq (%r8),%r8
@@ -65,29 +170,14 @@ bn_mul_mont_gather5:
xorq %r14,%r14
xorq %r15,%r15
- movq -96(%r12),%xmm0
- movq -32(%r12),%xmm1
- pand %xmm4,%xmm0
- movq 32(%r12),%xmm2
- pand %xmm5,%xmm1
-
movq %r8,%rbp
mulq %rbx
movq %rax,%r10
movq (%rcx),%rax
- movq 96(%r12),%xmm3
- pand %xmm6,%xmm2
- por %xmm1,%xmm0
- pand %xmm7,%xmm3
-
imulq %r10,%rbp
movq %rdx,%r11
- por %xmm2,%xmm0
- leaq 256(%r12),%r12
- por %xmm3,%xmm0
-
mulq %rbp
addq %rax,%r10
movq 8(%rsi),%rax
@@ -120,14 +210,12 @@ bn_mul_mont_gather5:
cmpq %r9,%r15
jne .L1st
-.byte 102,72,15,126,195
addq %rax,%r13
- movq (%rsi),%rax
adcq $0,%rdx
addq %r11,%r13
adcq $0,%rdx
- movq %r13,-16(%rsp,%r15,8)
+ movq %r13,-16(%rsp,%r9,8)
movq %rdx,%r13
movq %r10,%r11
@@ -141,33 +229,78 @@ bn_mul_mont_gather5:
jmp .Louter
.align 16
.Louter:
+ leaq 24+128(%rsp,%r9,8),%rdx
+ andq $-16,%rdx
+ pxor %xmm4,%xmm4
+ pxor %xmm5,%xmm5
+ movdqa -128(%r12),%xmm0
+ movdqa -112(%r12),%xmm1
+ movdqa -96(%r12),%xmm2
+ movdqa -80(%r12),%xmm3
+ pand -128(%rdx),%xmm0
+ pand -112(%rdx),%xmm1
+ por %xmm0,%xmm4
+ pand -96(%rdx),%xmm2
+ por %xmm1,%xmm5
+ pand -80(%rdx),%xmm3
+ por %xmm2,%xmm4
+ por %xmm3,%xmm5
+ movdqa -64(%r12),%xmm0
+ movdqa -48(%r12),%xmm1
+ movdqa -32(%r12),%xmm2
+ movdqa -16(%r12),%xmm3
+ pand -64(%rdx),%xmm0
+ pand -48(%rdx),%xmm1
+ por %xmm0,%xmm4
+ pand -32(%rdx),%xmm2
+ por %xmm1,%xmm5
+ pand -16(%rdx),%xmm3
+ por %xmm2,%xmm4
+ por %xmm3,%xmm5
+ movdqa 0(%r12),%xmm0
+ movdqa 16(%r12),%xmm1
+ movdqa 32(%r12),%xmm2
+ movdqa 48(%r12),%xmm3
+ pand 0(%rdx),%xmm0
+ pand 16(%rdx),%xmm1
+ por %xmm0,%xmm4
+ pand 32(%rdx),%xmm2
+ por %xmm1,%xmm5
+ pand 48(%rdx),%xmm3
+ por %xmm2,%xmm4
+ por %xmm3,%xmm5
+ movdqa 64(%r12),%xmm0
+ movdqa 80(%r12),%xmm1
+ movdqa 96(%r12),%xmm2
+ movdqa 112(%r12),%xmm3
+ pand 64(%rdx),%xmm0
+ pand 80(%rdx),%xmm1
+ por %xmm0,%xmm4
+ pand 96(%rdx),%xmm2
+ por %xmm1,%xmm5
+ pand 112(%rdx),%xmm3
+ por %xmm2,%xmm4
+ por %xmm3,%xmm5
+ por %xmm5,%xmm4
+ pshufd $0x4e,%xmm4,%xmm0
+ por %xmm4,%xmm0
+ leaq 256(%r12),%r12
+
+ movq (%rsi),%rax
+.byte 102,72,15,126,195
+
xorq %r15,%r15
movq %r8,%rbp
movq (%rsp),%r10
- movq -96(%r12),%xmm0
- movq -32(%r12),%xmm1
- pand %xmm4,%xmm0
- movq 32(%r12),%xmm2
- pand %xmm5,%xmm1
-
mulq %rbx
addq %rax,%r10
movq (%rcx),%rax
adcq $0,%rdx
- movq 96(%r12),%xmm3
- pand %xmm6,%xmm2
- por %xmm1,%xmm0
- pand %xmm7,%xmm3
-
imulq %r10,%rbp
movq %rdx,%r11
- por %xmm2,%xmm0
- leaq 256(%r12),%r12
- por %xmm3,%xmm0
-
mulq %rbp
addq %rax,%r10
movq 8(%rsi),%rax
@@ -203,15 +336,12 @@ bn_mul_mont_gather5:
cmpq %r9,%r15
jne .Linner
-.byte 102,72,15,126,195
-
addq %rax,%r13
- movq (%rsi),%rax
adcq $0,%rdx
addq %r10,%r13
- movq (%rsp,%r15,8),%r10
+ movq (%rsp,%r9,8),%r10
adcq $0,%rdx
- movq %r13,-16(%rsp,%r15,8)
+ movq %r13,-16(%rsp,%r9,8)
movq %rdx,%r13
xorq %rdx,%rdx
@@ -257,6 +387,7 @@ bn_mul_mont_gather5:
movq 8(%rsp,%r9,8),%rsi
movq $1,%rax
+
movq -48(%rsi),%r15
movq -40(%rsi),%r14
movq -32(%rsi),%r13
@@ -279,10 +410,10 @@ bn_mul4x_mont_gather5:
pushq %r13
pushq %r14
pushq %r15
+
.byte 0x67
- movl %r9d,%r10d
shll $3,%r9d
- shll $3+2,%r10d
+ leaq (%r9,%r9,2),%r10
negq %r9
@@ -292,19 +423,21 @@ bn_mul4x_mont_gather5:
- leaq -64(%rsp,%r9,2),%r11
- subq %rsi,%r11
+
+
+ leaq -320(%rsp,%r9,2),%r11
+ subq %rdi,%r11
andq $4095,%r11
cmpq %r11,%r10
jb .Lmul4xsp_alt
subq %r11,%rsp
- leaq -64(%rsp,%r9,2),%rsp
+ leaq -320(%rsp,%r9,2),%rsp
jmp .Lmul4xsp_done
.align 32
.Lmul4xsp_alt:
- leaq 4096-64(,%r9,2),%r10
- leaq -64(%rsp,%r9,2),%rsp
+ leaq 4096-320(,%r9,2),%r10
+ leaq -320(%rsp,%r9,2),%rsp
subq %r10,%r11
movq $0,%r10
cmovcq %r10,%r11
@@ -320,6 +453,7 @@ bn_mul4x_mont_gather5:
movq 40(%rsp),%rsi
movq $1,%rax
+
movq -48(%rsi),%r15
movq -40(%rsi),%r14
movq -32(%rsi),%r13
@@ -335,47 +469,141 @@ bn_mul4x_mont_gather5:
.align 32
mul4x_internal:
shlq $5,%r9
- movl 8(%rax),%r10d
- leaq 256(%rdx,%r9,1),%r13
+ movd 8(%rax),%xmm5
+ leaq .Linc(%rip),%rax
+ leaq 128(%rdx,%r9,1),%r13
shrq $5,%r9
- movq %r10,%r11
- shrq $3,%r10
- andq $7,%r11
- notq %r10
- leaq .Lmagic_masks(%rip),%rax
- andq $3,%r10
- leaq 96(%rdx,%r11,8),%r12
- movq 0(%rax,%r10,8),%xmm4
- movq 8(%rax,%r10,8),%xmm5
- addq $7,%r11
- movq 16(%rax,%r10,8),%xmm6
- movq 24(%rax,%r10,8),%xmm7
- andq $7,%r11
-
- movq -96(%r12),%xmm0
- leaq 256(%r12),%r14
- movq -32(%r12),%xmm1
- pand %xmm4,%xmm0
- movq 32(%r12),%xmm2
- pand %xmm5,%xmm1
- movq 96(%r12),%xmm3
- pand %xmm6,%xmm2
-.byte 0x67
- por %xmm1,%xmm0
- movq -96(%r14),%xmm1
-.byte 0x67
- pand %xmm7,%xmm3
-.byte 0x67
- por %xmm2,%xmm0
- movq -32(%r14),%xmm2
+ movdqa 0(%rax),%xmm0
+ movdqa 16(%rax),%xmm1
+ leaq 88-112(%rsp,%r9,1),%r10
+ leaq 128(%rdx),%r12
+
+ pshufd $0,%xmm5,%xmm5
+ movdqa %xmm1,%xmm4
+.byte 0x67,0x67
+ movdqa %xmm1,%xmm2
+ paddd %xmm0,%xmm1
+ pcmpeqd %xmm5,%xmm0
.byte 0x67
- pand %xmm4,%xmm1
+ movdqa %xmm4,%xmm3
+ paddd %xmm1,%xmm2
+ pcmpeqd %xmm5,%xmm1
+ movdqa %xmm0,112(%r10)
+ movdqa %xmm4,%xmm0
+
+ paddd %xmm2,%xmm3
+ pcmpeqd %xmm5,%xmm2
+ movdqa %xmm1,128(%r10)
+ movdqa %xmm4,%xmm1
+
+ paddd %xmm3,%xmm0
+ pcmpeqd %xmm5,%xmm3
+ movdqa %xmm2,144(%r10)
+ movdqa %xmm4,%xmm2
+
+ paddd %xmm0,%xmm1
+ pcmpeqd %xmm5,%xmm0
+ movdqa %xmm3,160(%r10)
+ movdqa %xmm4,%xmm3
+ paddd %xmm1,%xmm2
+ pcmpeqd %xmm5,%xmm1
+ movdqa %xmm0,176(%r10)
+ movdqa %xmm4,%xmm0
+
+ paddd %xmm2,%xmm3
+ pcmpeqd %xmm5,%xmm2
+ movdqa %xmm1,192(%r10)
+ movdqa %xmm4,%xmm1
+
+ paddd %xmm3,%xmm0
+ pcmpeqd %xmm5,%xmm3
+ movdqa %xmm2,208(%r10)
+ movdqa %xmm4,%xmm2
+
+ paddd %xmm0,%xmm1
+ pcmpeqd %xmm5,%xmm0
+ movdqa %xmm3,224(%r10)
+ movdqa %xmm4,%xmm3
+ paddd %xmm1,%xmm2
+ pcmpeqd %xmm5,%xmm1
+ movdqa %xmm0,240(%r10)
+ movdqa %xmm4,%xmm0
+
+ paddd %xmm2,%xmm3
+ pcmpeqd %xmm5,%xmm2
+ movdqa %xmm1,256(%r10)
+ movdqa %xmm4,%xmm1
+
+ paddd %xmm3,%xmm0
+ pcmpeqd %xmm5,%xmm3
+ movdqa %xmm2,272(%r10)
+ movdqa %xmm4,%xmm2
+
+ paddd %xmm0,%xmm1
+ pcmpeqd %xmm5,%xmm0
+ movdqa %xmm3,288(%r10)
+ movdqa %xmm4,%xmm3
+ paddd %xmm1,%xmm2
+ pcmpeqd %xmm5,%xmm1
+ movdqa %xmm0,304(%r10)
+
+ paddd %xmm2,%xmm3
.byte 0x67
- por %xmm3,%xmm0
- movq 32(%r14),%xmm3
+ pcmpeqd %xmm5,%xmm2
+ movdqa %xmm1,320(%r10)
+ pcmpeqd %xmm5,%xmm3
+ movdqa %xmm2,336(%r10)
+ pand 64(%r12),%xmm0
+
+ pand 80(%r12),%xmm1
+ pand 96(%r12),%xmm2
+ movdqa %xmm3,352(%r10)
+ pand 112(%r12),%xmm3
+ por %xmm2,%xmm0
+ por %xmm3,%xmm1
+ movdqa -128(%r12),%xmm4
+ movdqa -112(%r12),%xmm5
+ movdqa -96(%r12),%xmm2
+ pand 112(%r10),%xmm4
+ movdqa -80(%r12),%xmm3
+ pand 128(%r10),%xmm5
+ por %xmm4,%xmm0
+ pand 144(%r10),%xmm2
+ por %xmm5,%xmm1
+ pand 160(%r10),%xmm3
+ por %xmm2,%xmm0
+ por %xmm3,%xmm1
+ movdqa -64(%r12),%xmm4
+ movdqa -48(%r12),%xmm5
+ movdqa -32(%r12),%xmm2
+ pand 176(%r10),%xmm4
+ movdqa -16(%r12),%xmm3
+ pand 192(%r10),%xmm5
+ por %xmm4,%xmm0
+ pand 208(%r10),%xmm2
+ por %xmm5,%xmm1
+ pand 224(%r10),%xmm3
+ por %xmm2,%xmm0
+ por %xmm3,%xmm1
+ movdqa 0(%r12),%xmm4
+ movdqa 16(%r12),%xmm5
+ movdqa 32(%r12),%xmm2
+ pand 240(%r10),%xmm4
+ movdqa 48(%r12),%xmm3
+ pand 256(%r10),%xmm5
+ por %xmm4,%xmm0
+ pand 272(%r10),%xmm2
+ por %xmm5,%xmm1
+ pand 288(%r10),%xmm3
+ por %xmm2,%xmm0
+ por %xmm3,%xmm1
+ por %xmm1,%xmm0
+ pshufd $0x4e,%xmm0,%xmm1
+ por %xmm1,%xmm0
+ leaq 256(%r12),%r12
.byte 102,72,15,126,195
- movq 96(%r14),%xmm0
+
movq %r13,16+8(%rsp)
movq %rdi,56+8(%rsp)
@@ -389,26 +617,10 @@ mul4x_internal:
movq %rax,%r10
movq (%rcx),%rax
- pand %xmm5,%xmm2
- pand %xmm6,%xmm3
- por %xmm2,%xmm1
-
imulq %r10,%rbp
-
-
-
-
-
-
-
- leaq 64+8(%rsp,%r11,8),%r14
+ leaq 64+8(%rsp),%r14
movq %rdx,%r11
- pand %xmm7,%xmm0
- por %xmm3,%xmm1
- leaq 512(%r12),%r12
- por %xmm1,%xmm0
-
mulq %rbp
addq %rax,%r10
movq 8(%rsi,%r9,1),%rax
@@ -417,7 +629,7 @@ mul4x_internal:
mulq %rbx
addq %rax,%r11
- movq 16(%rcx),%rax
+ movq 8(%rcx),%rax
adcq $0,%rdx
movq %rdx,%r10
@@ -427,7 +639,7 @@ mul4x_internal:
adcq $0,%rdx
addq %r11,%rdi
leaq 32(%r9),%r15
- leaq 64(%rcx),%rcx
+ leaq 32(%rcx),%rcx
adcq $0,%rdx
movq %rdi,(%r14)
movq %rdx,%r13
@@ -437,7 +649,7 @@ mul4x_internal:
.L1st4x:
mulq %rbx
addq %rax,%r10
- movq -32(%rcx),%rax
+ movq -16(%rcx),%rax
leaq 32(%r14),%r14
adcq $0,%rdx
movq %rdx,%r11
@@ -453,7 +665,7 @@ mul4x_internal:
mulq %rbx
addq %rax,%r11
- movq -16(%rcx),%rax
+ movq -8(%rcx),%rax
adcq $0,%rdx
movq %rdx,%r10
@@ -483,7 +695,7 @@ mul4x_internal:
mulq %rbx
addq %rax,%r11
- movq 16(%rcx),%rax
+ movq 8(%rcx),%rax
adcq $0,%rdx
movq %rdx,%r10
@@ -492,7 +704,7 @@ mul4x_internal:
movq 16(%rsi,%r15,1),%rax
adcq $0,%rdx
addq %r11,%rdi
- leaq 64(%rcx),%rcx
+ leaq 32(%rcx),%rcx
adcq $0,%rdx
movq %rdi,(%r14)
movq %rdx,%r13
@@ -502,7 +714,7 @@ mul4x_internal:
mulq %rbx
addq %rax,%r10
- movq -32(%rcx),%rax
+ movq -16(%rcx),%rax
leaq 32(%r14),%r14
adcq $0,%rdx
movq %rdx,%r11
@@ -518,7 +730,7 @@ mul4x_internal:
mulq %rbx
addq %rax,%r11
- movq -16(%rcx),%rax
+ movq -8(%rcx),%rax
adcq $0,%rdx
movq %rdx,%r10
@@ -531,8 +743,7 @@ mul4x_internal:
movq %rdi,-16(%r14)
movq %rdx,%r13
-.byte 102,72,15,126,195
- leaq (%rcx,%r9,2),%rcx
+ leaq (%rcx,%r9,1),%rcx
xorq %rdi,%rdi
addq %r10,%r13
@@ -543,6 +754,63 @@ mul4x_internal:
.align 32
.Louter4x:
+ leaq 16+128(%r14),%rdx
+ pxor %xmm4,%xmm4
+ pxor %xmm5,%xmm5
+ movdqa -128(%r12),%xmm0
+ movdqa -112(%r12),%xmm1
+ movdqa -96(%r12),%xmm2
+ movdqa -80(%r12),%xmm3
+ pand -128(%rdx),%xmm0
+ pand -112(%rdx),%xmm1
+ por %xmm0,%xmm4
+ pand -96(%rdx),%xmm2
+ por %xmm1,%xmm5
+ pand -80(%rdx),%xmm3
+ por %xmm2,%xmm4
+ por %xmm3,%xmm5
+ movdqa -64(%r12),%xmm0
+ movdqa -48(%r12),%xmm1
+ movdqa -32(%r12),%xmm2
+ movdqa -16(%r12),%xmm3
+ pand -64(%rdx),%xmm0
+ pand -48(%rdx),%xmm1
+ por %xmm0,%xmm4
+ pand -32(%rdx),%xmm2
+ por %xmm1,%xmm5
+ pand -16(%rdx),%xmm3
+ por %xmm2,%xmm4
+ por %xmm3,%xmm5
+ movdqa 0(%r12),%xmm0
+ movdqa 16(%r12),%xmm1
+ movdqa 32(%r12),%xmm2
+ movdqa 48(%r12),%xmm3
+ pand 0(%rdx),%xmm0
+ pand 16(%rdx),%xmm1
+ por %xmm0,%xmm4
+ pand 32(%rdx),%xmm2
+ por %xmm1,%xmm5
+ pand 48(%rdx),%xmm3
+ por %xmm2,%xmm4
+ por %xmm3,%xmm5
+ movdqa 64(%r12),%xmm0
+ movdqa 80(%r12),%xmm1
+ movdqa 96(%r12),%xmm2
+ movdqa 112(%r12),%xmm3
+ pand 64(%rdx),%xmm0
+ pand 80(%rdx),%xmm1
+ por %xmm0,%xmm4
+ pand 96(%rdx),%xmm2
+ por %xmm1,%xmm5
+ pand 112(%rdx),%xmm3
+ por %xmm2,%xmm4
+ por %xmm3,%xmm5
+ por %xmm5,%xmm4
+ pshufd $0x4e,%xmm4,%xmm0
+ por %xmm4,%xmm0
+ leaq 256(%r12),%r12
+.byte 102,72,15,126,195
+
movq (%r14,%r9,1),%r10
movq %r8,%rbp
mulq %rbx
@@ -550,25 +818,11 @@ mul4x_internal:
movq (%rcx),%rax
adcq $0,%rdx
- movq -96(%r12),%xmm0
- movq -32(%r12),%xmm1
- pand %xmm4,%xmm0
- movq 32(%r12),%xmm2
- pand %xmm5,%xmm1
- movq 96(%r12),%xmm3
-
imulq %r10,%rbp
-.byte 0x67
movq %rdx,%r11
movq %rdi,(%r14)
- pand %xmm6,%xmm2
- por %xmm1,%xmm0
- pand %xmm7,%xmm3
- por %xmm2,%xmm0
leaq (%r14,%r9,1),%r14
- leaq 256(%r12),%r12
- por %xmm3,%xmm0
mulq %rbp
addq %rax,%r10
@@ -578,7 +832,7 @@ mul4x_internal:
mulq %rbx
addq %rax,%r11
- movq 16(%rcx),%rax
+ movq 8(%rcx),%rax
adcq $0,%rdx
addq 8(%r14),%r11
adcq $0,%rdx
@@ -590,7 +844,7 @@ mul4x_internal:
adcq $0,%rdx
addq %r11,%rdi
leaq 32(%r9),%r15
- leaq 64(%rcx),%rcx
+ leaq 32(%rcx),%rcx
adcq $0,%rdx
movq %rdx,%r13
jmp .Linner4x
@@ -599,7 +853,7 @@ mul4x_internal:
.Linner4x:
mulq %rbx
addq %rax,%r10
- movq -32(%rcx),%rax
+ movq -16(%rcx),%rax
adcq $0,%rdx
addq 16(%r14),%r10
leaq 32(%r14),%r14
@@ -617,7 +871,7 @@ mul4x_internal:
mulq %rbx
addq %rax,%r11
- movq -16(%rcx),%rax
+ movq -8(%rcx),%rax
adcq $0,%rdx
addq -8(%r14),%r11
adcq $0,%rdx
@@ -651,7 +905,7 @@ mul4x_internal:
mulq %rbx
addq %rax,%r11
- movq 16(%rcx),%rax
+ movq 8(%rcx),%rax
adcq $0,%rdx
addq 8(%r14),%r11
adcq $0,%rdx
@@ -662,7 +916,7 @@ mul4x_internal:
movq 16(%rsi,%r15,1),%rax
adcq $0,%rdx
addq %r11,%rdi
- leaq 64(%rcx),%rcx
+ leaq 32(%rcx),%rcx
adcq $0,%rdx
movq %r13,-8(%r14)
movq %rdx,%r13
@@ -672,7 +926,7 @@ mul4x_internal:
mulq %rbx
addq %rax,%r10
- movq -32(%rcx),%rax
+ movq -16(%rcx),%rax
adcq $0,%rdx
addq 16(%r14),%r10
leaq 32(%r14),%r14
@@ -691,7 +945,7 @@ mul4x_internal:
mulq %rbx
addq %rax,%r11
movq %rbp,%rax
- movq -16(%rcx),%rbp
+ movq -8(%rcx),%rbp
adcq $0,%rdx
addq -8(%r14),%r11
adcq $0,%rdx
@@ -706,9 +960,8 @@ mul4x_internal:
movq %r13,-24(%r14)
movq %rdx,%r13
-.byte 102,72,15,126,195
movq %rdi,-16(%r14)
- leaq (%rcx,%r9,2),%rcx
+ leaq (%rcx,%r9,1),%rcx
xorq %rdi,%rdi
addq %r10,%r13
@@ -719,16 +972,23 @@ mul4x_internal:
cmpq 16+8(%rsp),%r12
jb .Louter4x
+ xorq %rax,%rax
subq %r13,%rbp
adcq %r15,%r15
orq %r15,%rdi
- xorq $1,%rdi
+ subq %rdi,%rax
leaq (%r14,%r9,1),%rbx
- leaq (%rcx,%rdi,8),%rbp
+ movq (%rcx),%r12
+ leaq (%rcx),%rbp
movq %r9,%rcx
sarq $3+2,%rcx
movq 56+8(%rsp),%rdi
- jmp .Lsqr4x_sub
+ decq %r12
+ xorq %r10,%r10
+ movq 8(%rbp),%r13
+ movq 16(%rbp),%r14
+ movq 24(%rbp),%r15
+ jmp .Lsqr4x_sub_entry
.size mul4x_internal,.-mul4x_internal
.globl bn_power5
.hidden bn_power5
@@ -742,9 +1002,9 @@ bn_power5:
pushq %r13
pushq %r14
pushq %r15
- movl %r9d,%r10d
+
shll $3,%r9d
- shll $3+2,%r10d
+ leal (%r9,%r9,2),%r10d
negq %r9
movq (%r8),%r8
@@ -754,19 +1014,20 @@ bn_power5:
- leaq -64(%rsp,%r9,2),%r11
- subq %rsi,%r11
+
+ leaq -320(%rsp,%r9,2),%r11
+ subq %rdi,%r11
andq $4095,%r11
cmpq %r11,%r10
jb .Lpwr_sp_alt
subq %r11,%rsp
- leaq -64(%rsp,%r9,2),%rsp
+ leaq -320(%rsp,%r9,2),%rsp
jmp .Lpwr_sp_done
.align 32
.Lpwr_sp_alt:
- leaq 4096-64(,%r9,2),%r10
- leaq -64(%rsp,%r9,2),%rsp
+ leaq 4096-320(,%r9,2),%r10
+ leaq -320(%rsp,%r9,2),%rsp
subq %r10,%r11
movq $0,%r10
cmovcq %r10,%r11
@@ -794,10 +1055,15 @@ bn_power5:
.byte 102,72,15,110,226
call __bn_sqr8x_internal
+ call __bn_post4x_internal
call __bn_sqr8x_internal
+ call __bn_post4x_internal
call __bn_sqr8x_internal
+ call __bn_post4x_internal
call __bn_sqr8x_internal
+ call __bn_post4x_internal
call __bn_sqr8x_internal
+ call __bn_post4x_internal
.byte 102,72,15,126,209
.byte 102,72,15,126,226
@@ -1342,9 +1608,9 @@ __bn_sqr8x_internal:
movq %rbx,-16(%rdi)
movq %r8,-8(%rdi)
.byte 102,72,15,126,213
-sqr8x_reduction:
+__bn_sqr8x_reduction:
xorq %rax,%rax
- leaq (%rbp,%r9,2),%rcx
+ leaq (%r9,%rbp,1),%rcx
leaq 48+8(%rsp,%r9,2),%rdx
movq %rcx,0+8(%rsp)
leaq 48+8(%rsp,%r9,1),%rdi
@@ -1377,14 +1643,14 @@ sqr8x_reduction:
.align 32
.L8x_reduce:
mulq %rbx
- movq 16(%rbp),%rax
+ movq 8(%rbp),%rax
negq %r8
movq %rdx,%r8
adcq $0,%r8
mulq %rbx
addq %rax,%r9
- movq 32(%rbp),%rax
+ movq 16(%rbp),%rax
adcq $0,%rdx
addq %r9,%r8
movq %rbx,48-8+8(%rsp,%rcx,8)
@@ -1393,7 +1659,7 @@ sqr8x_reduction:
mulq %rbx
addq %rax,%r10
- movq 48(%rbp),%rax
+ movq 24(%rbp),%rax
adcq $0,%rdx
addq %r10,%r9
movq 32+8(%rsp),%rsi
@@ -1402,7 +1668,7 @@ sqr8x_reduction:
mulq %rbx
addq %rax,%r11
- movq 64(%rbp),%rax
+ movq 32(%rbp),%rax
adcq $0,%rdx
imulq %r8,%rsi
addq %r11,%r10
@@ -1411,7 +1677,7 @@ sqr8x_reduction:
mulq %rbx
addq %rax,%r12
- movq 80(%rbp),%rax
+ movq 40(%rbp),%rax
adcq $0,%rdx
addq %r12,%r11
movq %rdx,%r12
@@ -1419,7 +1685,7 @@ sqr8x_reduction:
mulq %rbx
addq %rax,%r13
- movq 96(%rbp),%rax
+ movq 48(%rbp),%rax
adcq $0,%rdx
addq %r13,%r12
movq %rdx,%r13
@@ -1427,7 +1693,7 @@ sqr8x_reduction:
mulq %rbx
addq %rax,%r14
- movq 112(%rbp),%rax
+ movq 56(%rbp),%rax
adcq $0,%rdx
addq %r14,%r13
movq %rdx,%r14
@@ -1445,7 +1711,7 @@ sqr8x_reduction:
decl %ecx
jnz .L8x_reduce
- leaq 128(%rbp),%rbp
+ leaq 64(%rbp),%rbp
xorq %rax,%rax
movq 8+8(%rsp),%rdx
cmpq 0+8(%rsp),%rbp
@@ -1471,14 +1737,14 @@ sqr8x_reduction:
.L8x_tail:
mulq %rbx
addq %rax,%r8
- movq 16(%rbp),%rax
+ movq 8(%rbp),%rax
movq %r8,(%rdi)
movq %rdx,%r8
adcq $0,%r8
mulq %rbx
addq %rax,%r9
- movq 32(%rbp),%rax
+ movq 16(%rbp),%rax
adcq $0,%rdx
addq %r9,%r8
leaq 8(%rdi),%rdi
@@ -1487,7 +1753,7 @@ sqr8x_reduction:
mulq %rbx
addq %rax,%r10
- movq 48(%rbp),%rax
+ movq 24(%rbp),%rax
adcq $0,%rdx
addq %r10,%r9
movq %rdx,%r10
@@ -1495,7 +1761,7 @@ sqr8x_reduction:
mulq %rbx
addq %rax,%r11
- movq 64(%rbp),%rax
+ movq 32(%rbp),%rax
adcq $0,%rdx
addq %r11,%r10
movq %rdx,%r11
@@ -1503,7 +1769,7 @@ sqr8x_reduction:
mulq %rbx
addq %rax,%r12
- movq 80(%rbp),%rax
+ movq 40(%rbp),%rax
adcq $0,%rdx
addq %r12,%r11
movq %rdx,%r12
@@ -1511,7 +1777,7 @@ sqr8x_reduction:
mulq %rbx
addq %rax,%r13
- movq 96(%rbp),%rax
+ movq 48(%rbp),%rax
adcq $0,%rdx
addq %r13,%r12
movq %rdx,%r13
@@ -1519,7 +1785,7 @@ sqr8x_reduction:
mulq %rbx
addq %rax,%r14
- movq 112(%rbp),%rax
+ movq 56(%rbp),%rax
adcq $0,%rdx
addq %r14,%r13
movq %rdx,%r14
@@ -1537,7 +1803,7 @@ sqr8x_reduction:
decl %ecx
jnz .L8x_tail
- leaq 128(%rbp),%rbp
+ leaq 64(%rbp),%rbp
movq 8+8(%rsp),%rdx
cmpq 0+8(%rsp),%rbp
jae .L8x_tail_done
@@ -1583,7 +1849,7 @@ sqr8x_reduction:
adcq 48(%rdi),%r14
adcq 56(%rdi),%r15
adcq $0,%rax
- movq -16(%rbp),%rcx
+ movq -8(%rbp),%rcx
xorq %rsi,%rsi
.byte 102,72,15,126,213
@@ -1601,44 +1867,62 @@ sqr8x_reduction:
cmpq %rdx,%rdi
jb .L8x_reduction_loop
-
- subq %r15,%rcx
+ .byte 0xf3,0xc3
+.size bn_sqr8x_internal,.-bn_sqr8x_internal
+.type __bn_post4x_internal,@function
+.align 32
+__bn_post4x_internal:
+ movq 0(%rbp),%r12
leaq (%rdi,%r9,1),%rbx
- adcq %rsi,%rsi
movq %r9,%rcx
- orq %rsi,%rax
.byte 102,72,15,126,207
- xorq $1,%rax
+ negq %rax
.byte 102,72,15,126,206
- leaq (%rbp,%rax,8),%rbp
sarq $3+2,%rcx
- jmp .Lsqr4x_sub
+ decq %r12
+ xorq %r10,%r10
+ movq 8(%rbp),%r13
+ movq 16(%rbp),%r14
+ movq 24(%rbp),%r15
+ jmp .Lsqr4x_sub_entry
-.align 32
+.align 16
.Lsqr4x_sub:
-.byte 0x66
- movq 0(%rbx),%r12
- movq 8(%rbx),%r13
- sbbq 0(%rbp),%r12
- movq 16(%rbx),%r14
- sbbq 16(%rbp),%r13
- movq 24(%rbx),%r15
- leaq 32(%rbx),%rbx
- sbbq 32(%rbp),%r14
+ movq 0(%rbp),%r12
+ movq 8(%rbp),%r13
+ movq 16(%rbp),%r14
+ movq 24(%rbp),%r15
+.Lsqr4x_sub_entry:
+ leaq 32(%rbp),%rbp
+ notq %r12
+ notq %r13
+ notq %r14
+ notq %r15
+ andq %rax,%r12
+ andq %rax,%r13
+ andq %rax,%r14
+ andq %rax,%r15
+
+ negq %r10
+ adcq 0(%rbx),%r12
+ adcq 8(%rbx),%r13
+ adcq 16(%rbx),%r14
+ adcq 24(%rbx),%r15
movq %r12,0(%rdi)
- sbbq 48(%rbp),%r15
- leaq 64(%rbp),%rbp
+ leaq 32(%rbx),%rbx
movq %r13,8(%rdi)
+ sbbq %r10,%r10
movq %r14,16(%rdi)
movq %r15,24(%rdi)
leaq 32(%rdi),%rdi
incq %rcx
jnz .Lsqr4x_sub
+
movq %r9,%r10
negq %r9
.byte 0xf3,0xc3
-.size bn_sqr8x_internal,.-bn_sqr8x_internal
+.size __bn_post4x_internal,.-__bn_post4x_internal
.globl bn_from_montgomery
.hidden bn_from_montgomery
.type bn_from_montgomery,@function
@@ -1661,10 +1945,9 @@ bn_from_mont8x:
pushq %r13
pushq %r14
pushq %r15
-.byte 0x67
- movl %r9d,%r10d
+
shll $3,%r9d
- shll $3+2,%r10d
+ leaq (%r9,%r9,2),%r10
negq %r9
movq (%r8),%r8
@@ -1674,19 +1957,20 @@ bn_from_mont8x:
- leaq -64(%rsp,%r9,2),%r11
- subq %rsi,%r11
+
+ leaq -320(%rsp,%r9,2),%r11
+ subq %rdi,%r11
andq $4095,%r11
cmpq %r11,%r10
jb .Lfrom_sp_alt
subq %r11,%rsp
- leaq -64(%rsp,%r9,2),%rsp
+ leaq -320(%rsp,%r9,2),%rsp
jmp .Lfrom_sp_done
.align 32
.Lfrom_sp_alt:
- leaq 4096-64(,%r9,2),%r10
- leaq -64(%rsp,%r9,2),%rsp
+ leaq 4096-320(,%r9,2),%r10
+ leaq -320(%rsp,%r9,2),%rsp
subq %r10,%r11
movq $0,%r10
cmovcq %r10,%r11
@@ -1737,7 +2021,8 @@ bn_from_mont8x:
.byte 0x67
movq %rcx,%rbp
.byte 102,73,15,110,218
- call sqr8x_reduction
+ call __bn_sqr8x_reduction
+ call __bn_post4x_internal
pxor %xmm0,%xmm0
leaq 48(%rsp),%rax
@@ -1787,46 +2072,170 @@ bn_scatter5:
.globl bn_gather5
.hidden bn_gather5
.type bn_gather5,@function
-.align 16
+.align 32
bn_gather5:
- movl %ecx,%r11d
- shrl $3,%ecx
- andq $7,%r11
- notl %ecx
- leaq .Lmagic_masks(%rip),%rax
- andl $3,%ecx
- leaq 128(%rdx,%r11,8),%rdx
- movq 0(%rax,%rcx,8),%xmm4
- movq 8(%rax,%rcx,8),%xmm5
- movq 16(%rax,%rcx,8),%xmm6
- movq 24(%rax,%rcx,8),%xmm7
+.LSEH_begin_bn_gather5:
+
+.byte 0x4c,0x8d,0x14,0x24
+.byte 0x48,0x81,0xec,0x08,0x01,0x00,0x00
+ leaq .Linc(%rip),%rax
+ andq $-16,%rsp
+
+ movd %ecx,%xmm5
+ movdqa 0(%rax),%xmm0
+ movdqa 16(%rax),%xmm1
+ leaq 128(%rdx),%r11
+ leaq 128(%rsp),%rax
+
+ pshufd $0,%xmm5,%xmm5
+ movdqa %xmm1,%xmm4
+ movdqa %xmm1,%xmm2
+ paddd %xmm0,%xmm1
+ pcmpeqd %xmm5,%xmm0
+ movdqa %xmm4,%xmm3
+
+ paddd %xmm1,%xmm2
+ pcmpeqd %xmm5,%xmm1
+ movdqa %xmm0,-128(%rax)
+ movdqa %xmm4,%xmm0
+
+ paddd %xmm2,%xmm3
+ pcmpeqd %xmm5,%xmm2
+ movdqa %xmm1,-112(%rax)
+ movdqa %xmm4,%xmm1
+
+ paddd %xmm3,%xmm0
+ pcmpeqd %xmm5,%xmm3
+ movdqa %xmm2,-96(%rax)
+ movdqa %xmm4,%xmm2
+ paddd %xmm0,%xmm1
+ pcmpeqd %xmm5,%xmm0
+ movdqa %xmm3,-80(%rax)
+ movdqa %xmm4,%xmm3
+
+ paddd %xmm1,%xmm2
+ pcmpeqd %xmm5,%xmm1
+ movdqa %xmm0,-64(%rax)
+ movdqa %xmm4,%xmm0
+
+ paddd %xmm2,%xmm3
+ pcmpeqd %xmm5,%xmm2
+ movdqa %xmm1,-48(%rax)
+ movdqa %xmm4,%xmm1
+
+ paddd %xmm3,%xmm0
+ pcmpeqd %xmm5,%xmm3
+ movdqa %xmm2,-32(%rax)
+ movdqa %xmm4,%xmm2
+ paddd %xmm0,%xmm1
+ pcmpeqd %xmm5,%xmm0
+ movdqa %xmm3,-16(%rax)
+ movdqa %xmm4,%xmm3
+
+ paddd %xmm1,%xmm2
+ pcmpeqd %xmm5,%xmm1
+ movdqa %xmm0,0(%rax)
+ movdqa %xmm4,%xmm0
+
+ paddd %xmm2,%xmm3
+ pcmpeqd %xmm5,%xmm2
+ movdqa %xmm1,16(%rax)
+ movdqa %xmm4,%xmm1
+
+ paddd %xmm3,%xmm0
+ pcmpeqd %xmm5,%xmm3
+ movdqa %xmm2,32(%rax)
+ movdqa %xmm4,%xmm2
+ paddd %xmm0,%xmm1
+ pcmpeqd %xmm5,%xmm0
+ movdqa %xmm3,48(%rax)
+ movdqa %xmm4,%xmm3
+
+ paddd %xmm1,%xmm2
+ pcmpeqd %xmm5,%xmm1
+ movdqa %xmm0,64(%rax)
+ movdqa %xmm4,%xmm0
+
+ paddd %xmm2,%xmm3
+ pcmpeqd %xmm5,%xmm2
+ movdqa %xmm1,80(%rax)
+ movdqa %xmm4,%xmm1
+
+ paddd %xmm3,%xmm0
+ pcmpeqd %xmm5,%xmm3
+ movdqa %xmm2,96(%rax)
+ movdqa %xmm4,%xmm2
+ movdqa %xmm3,112(%rax)
jmp .Lgather
-.align 16
-.Lgather:
- movq -128(%rdx),%xmm0
- movq -64(%rdx),%xmm1
- pand %xmm4,%xmm0
- movq 0(%rdx),%xmm2
- pand %xmm5,%xmm1
- movq 64(%rdx),%xmm3
- pand %xmm6,%xmm2
- por %xmm1,%xmm0
- pand %xmm7,%xmm3
-.byte 0x67,0x67
- por %xmm2,%xmm0
- leaq 256(%rdx),%rdx
- por %xmm3,%xmm0
+.align 32
+.Lgather:
+ pxor %xmm4,%xmm4
+ pxor %xmm5,%xmm5
+ movdqa -128(%r11),%xmm0
+ movdqa -112(%r11),%xmm1
+ movdqa -96(%r11),%xmm2
+ pand -128(%rax),%xmm0
+ movdqa -80(%r11),%xmm3
+ pand -112(%rax),%xmm1
+ por %xmm0,%xmm4
+ pand -96(%rax),%xmm2
+ por %xmm1,%xmm5
+ pand -80(%rax),%xmm3
+ por %xmm2,%xmm4
+ por %xmm3,%xmm5
+ movdqa -64(%r11),%xmm0
+ movdqa -48(%r11),%xmm1
+ movdqa -32(%r11),%xmm2
+ pand -64(%rax),%xmm0
+ movdqa -16(%r11),%xmm3
+ pand -48(%rax),%xmm1
+ por %xmm0,%xmm4
+ pand -32(%rax),%xmm2
+ por %xmm1,%xmm5
+ pand -16(%rax),%xmm3
+ por %xmm2,%xmm4
+ por %xmm3,%xmm5
+ movdqa 0(%r11),%xmm0
+ movdqa 16(%r11),%xmm1
+ movdqa 32(%r11),%xmm2
+ pand 0(%rax),%xmm0
+ movdqa 48(%r11),%xmm3
+ pand 16(%rax),%xmm1
+ por %xmm0,%xmm4
+ pand 32(%rax),%xmm2
+ por %xmm1,%xmm5
+ pand 48(%rax),%xmm3
+ por %xmm2,%xmm4
+ por %xmm3,%xmm5
+ movdqa 64(%r11),%xmm0
+ movdqa 80(%r11),%xmm1
+ movdqa 96(%r11),%xmm2
+ pand 64(%rax),%xmm0
+ movdqa 112(%r11),%xmm3
+ pand 80(%rax),%xmm1
+ por %xmm0,%xmm4
+ pand 96(%rax),%xmm2
+ por %xmm1,%xmm5
+ pand 112(%rax),%xmm3
+ por %xmm2,%xmm4
+ por %xmm3,%xmm5
+ por %xmm5,%xmm4
+ leaq 256(%r11),%r11
+ pshufd $0x4e,%xmm4,%xmm0
+ por %xmm4,%xmm0
movq %xmm0,(%rdi)
leaq 8(%rdi),%rdi
subl $1,%esi
jnz .Lgather
+
+ leaq (%r10),%rsp
.byte 0xf3,0xc3
.LSEH_end_bn_gather5:
.size bn_gather5,.-bn_gather5
.align 64
-.Lmagic_masks:
-.long 0,0, 0,0, 0,0, -1,-1
-.long 0,0, 0,0, 0,0, 0,0
+.Linc:
+.long 0,0, 1,1
+.long 2,2, 2,2
.byte 77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,119,105,116,104,32,115,99,97,116,116,101,114,47,103,97,116,104,101,114,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
#endif
diff --git a/linux-x86_64/crypto/chacha/chacha-x86_64.S b/linux-x86_64/crypto/chacha/chacha-x86_64.S
new file mode 100644
index 00000000..e994940a
--- /dev/null
+++ b/linux-x86_64/crypto/chacha/chacha-x86_64.S
@@ -0,0 +1,1585 @@
+#if defined(__x86_64__)
+.text
+
+.extern OPENSSL_ia32cap_P
+.hidden OPENSSL_ia32cap_P
+
+.align 64
+.Lzero:
+.long 0,0,0,0
+.Lone:
+.long 1,0,0,0
+.Linc:
+.long 0,1,2,3
+.Lfour:
+.long 4,4,4,4
+.Lincy:
+.long 0,2,4,6,1,3,5,7
+.Leight:
+.long 8,8,8,8,8,8,8,8
+.Lrot16:
+.byte 0x2,0x3,0x0,0x1, 0x6,0x7,0x4,0x5, 0xa,0xb,0x8,0x9, 0xe,0xf,0xc,0xd
+.Lrot24:
+.byte 0x3,0x0,0x1,0x2, 0x7,0x4,0x5,0x6, 0xb,0x8,0x9,0xa, 0xf,0xc,0xd,0xe
+.Lsigma:
+.byte 101,120,112,97,110,100,32,51,50,45,98,121,116,101,32,107,0
+.byte 67,104,97,67,104,97,50,48,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+.globl ChaCha20_ctr32
+.hidden ChaCha20_ctr32
+.type ChaCha20_ctr32,@function
+.align 64
+ChaCha20_ctr32:
+ cmpq $0,%rdx
+ je .Lno_data
+ movq OPENSSL_ia32cap_P+4(%rip),%r10
+ testl $512,%r10d
+ jnz .LChaCha20_ssse3
+
+ pushq %rbx
+ pushq %rbp
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
+ subq $64+24,%rsp
+
+
+ movdqu (%rcx),%xmm1
+ movdqu 16(%rcx),%xmm2
+ movdqu (%r8),%xmm3
+ movdqa .Lone(%rip),%xmm4
+
+
+ movdqa %xmm1,16(%rsp)
+ movdqa %xmm2,32(%rsp)
+ movdqa %xmm3,48(%rsp)
+ movq %rdx,%rbp
+ jmp .Loop_outer
+
+.align 32
+.Loop_outer:
+ movl $0x61707865,%eax
+ movl $0x3320646e,%ebx
+ movl $0x79622d32,%ecx
+ movl $0x6b206574,%edx
+ movl 16(%rsp),%r8d
+ movl 20(%rsp),%r9d
+ movl 24(%rsp),%r10d
+ movl 28(%rsp),%r11d
+ movd %xmm3,%r12d
+ movl 52(%rsp),%r13d
+ movl 56(%rsp),%r14d
+ movl 60(%rsp),%r15d
+
+ movq %rbp,64+0(%rsp)
+ movl $10,%ebp
+ movq %rsi,64+8(%rsp)
+.byte 102,72,15,126,214
+ movq %rdi,64+16(%rsp)
+ movq %rsi,%rdi
+ shrq $32,%rdi
+ jmp .Loop
+
+.align 32
+.Loop:
+ addl %r8d,%eax
+ xorl %eax,%r12d
+ roll $16,%r12d
+ addl %r9d,%ebx
+ xorl %ebx,%r13d
+ roll $16,%r13d
+ addl %r12d,%esi
+ xorl %esi,%r8d
+ roll $12,%r8d
+ addl %r13d,%edi
+ xorl %edi,%r9d
+ roll $12,%r9d
+ addl %r8d,%eax
+ xorl %eax,%r12d
+ roll $8,%r12d
+ addl %r9d,%ebx
+ xorl %ebx,%r13d
+ roll $8,%r13d
+ addl %r12d,%esi
+ xorl %esi,%r8d
+ roll $7,%r8d
+ addl %r13d,%edi
+ xorl %edi,%r9d
+ roll $7,%r9d
+ movl %esi,32(%rsp)
+ movl %edi,36(%rsp)
+ movl 40(%rsp),%esi
+ movl 44(%rsp),%edi
+ addl %r10d,%ecx
+ xorl %ecx,%r14d
+ roll $16,%r14d
+ addl %r11d,%edx
+ xorl %edx,%r15d
+ roll $16,%r15d
+ addl %r14d,%esi
+ xorl %esi,%r10d
+ roll $12,%r10d
+ addl %r15d,%edi
+ xorl %edi,%r11d
+ roll $12,%r11d
+ addl %r10d,%ecx
+ xorl %ecx,%r14d
+ roll $8,%r14d
+ addl %r11d,%edx
+ xorl %edx,%r15d
+ roll $8,%r15d
+ addl %r14d,%esi
+ xorl %esi,%r10d
+ roll $7,%r10d
+ addl %r15d,%edi
+ xorl %edi,%r11d
+ roll $7,%r11d
+ addl %r9d,%eax
+ xorl %eax,%r15d
+ roll $16,%r15d
+ addl %r10d,%ebx
+ xorl %ebx,%r12d
+ roll $16,%r12d
+ addl %r15d,%esi
+ xorl %esi,%r9d
+ roll $12,%r9d
+ addl %r12d,%edi
+ xorl %edi,%r10d
+ roll $12,%r10d
+ addl %r9d,%eax
+ xorl %eax,%r15d
+ roll $8,%r15d
+ addl %r10d,%ebx
+ xorl %ebx,%r12d
+ roll $8,%r12d
+ addl %r15d,%esi
+ xorl %esi,%r9d
+ roll $7,%r9d
+ addl %r12d,%edi
+ xorl %edi,%r10d
+ roll $7,%r10d
+ movl %esi,40(%rsp)
+ movl %edi,44(%rsp)
+ movl 32(%rsp),%esi
+ movl 36(%rsp),%edi
+ addl %r11d,%ecx
+ xorl %ecx,%r13d
+ roll $16,%r13d
+ addl %r8d,%edx
+ xorl %edx,%r14d
+ roll $16,%r14d
+ addl %r13d,%esi
+ xorl %esi,%r11d
+ roll $12,%r11d
+ addl %r14d,%edi
+ xorl %edi,%r8d
+ roll $12,%r8d
+ addl %r11d,%ecx
+ xorl %ecx,%r13d
+ roll $8,%r13d
+ addl %r8d,%edx
+ xorl %edx,%r14d
+ roll $8,%r14d
+ addl %r13d,%esi
+ xorl %esi,%r11d
+ roll $7,%r11d
+ addl %r14d,%edi
+ xorl %edi,%r8d
+ roll $7,%r8d
+ decl %ebp
+ jnz .Loop
+ movl %edi,36(%rsp)
+ movl %esi,32(%rsp)
+ movq 64(%rsp),%rbp
+ movdqa %xmm2,%xmm1
+ movq 64+8(%rsp),%rsi
+ paddd %xmm4,%xmm3
+ movq 64+16(%rsp),%rdi
+
+ addl $0x61707865,%eax
+ addl $0x3320646e,%ebx
+ addl $0x79622d32,%ecx
+ addl $0x6b206574,%edx
+ addl 16(%rsp),%r8d
+ addl 20(%rsp),%r9d
+ addl 24(%rsp),%r10d
+ addl 28(%rsp),%r11d
+ addl 48(%rsp),%r12d
+ addl 52(%rsp),%r13d
+ addl 56(%rsp),%r14d
+ addl 60(%rsp),%r15d
+ paddd 32(%rsp),%xmm1
+
+ cmpq $64,%rbp
+ jb .Ltail
+
+ xorl 0(%rsi),%eax
+ xorl 4(%rsi),%ebx
+ xorl 8(%rsi),%ecx
+ xorl 12(%rsi),%edx
+ xorl 16(%rsi),%r8d
+ xorl 20(%rsi),%r9d
+ xorl 24(%rsi),%r10d
+ xorl 28(%rsi),%r11d
+ movdqu 32(%rsi),%xmm0
+ xorl 48(%rsi),%r12d
+ xorl 52(%rsi),%r13d
+ xorl 56(%rsi),%r14d
+ xorl 60(%rsi),%r15d
+ leaq 64(%rsi),%rsi
+ pxor %xmm1,%xmm0
+
+ movdqa %xmm2,32(%rsp)
+ movd %xmm3,48(%rsp)
+
+ movl %eax,0(%rdi)
+ movl %ebx,4(%rdi)
+ movl %ecx,8(%rdi)
+ movl %edx,12(%rdi)
+ movl %r8d,16(%rdi)
+ movl %r9d,20(%rdi)
+ movl %r10d,24(%rdi)
+ movl %r11d,28(%rdi)
+ movdqu %xmm0,32(%rdi)
+ movl %r12d,48(%rdi)
+ movl %r13d,52(%rdi)
+ movl %r14d,56(%rdi)
+ movl %r15d,60(%rdi)
+ leaq 64(%rdi),%rdi
+
+ subq $64,%rbp
+ jnz .Loop_outer
+
+ jmp .Ldone
+
+.align 16
+.Ltail:
+ movl %eax,0(%rsp)
+ movl %ebx,4(%rsp)
+ xorq %rbx,%rbx
+ movl %ecx,8(%rsp)
+ movl %edx,12(%rsp)
+ movl %r8d,16(%rsp)
+ movl %r9d,20(%rsp)
+ movl %r10d,24(%rsp)
+ movl %r11d,28(%rsp)
+ movdqa %xmm1,32(%rsp)
+ movl %r12d,48(%rsp)
+ movl %r13d,52(%rsp)
+ movl %r14d,56(%rsp)
+ movl %r15d,60(%rsp)
+
+.Loop_tail:
+ movzbl (%rsi,%rbx,1),%eax
+ movzbl (%rsp,%rbx,1),%edx
+ leaq 1(%rbx),%rbx
+ xorl %edx,%eax
+ movb %al,-1(%rdi,%rbx,1)
+ decq %rbp
+ jnz .Loop_tail
+
+.Ldone:
+ addq $64+24,%rsp
+ popq %r15
+ popq %r14
+ popq %r13
+ popq %r12
+ popq %rbp
+ popq %rbx
+.Lno_data:
+ .byte 0xf3,0xc3
+.size ChaCha20_ctr32,.-ChaCha20_ctr32
+.type ChaCha20_ssse3,@function
+.align 32
+ChaCha20_ssse3:
+.LChaCha20_ssse3:
+ cmpq $128,%rdx
+ ja .LChaCha20_4x
+
+.Ldo_sse3_after_all:
+ pushq %rbx
+ pushq %rbp
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
+
+ subq $64+24,%rsp
+ movdqa .Lsigma(%rip),%xmm0
+ movdqu (%rcx),%xmm1
+ movdqu 16(%rcx),%xmm2
+ movdqu (%r8),%xmm3
+ movdqa .Lrot16(%rip),%xmm6
+ movdqa .Lrot24(%rip),%xmm7
+
+ movdqa %xmm0,0(%rsp)
+ movdqa %xmm1,16(%rsp)
+ movdqa %xmm2,32(%rsp)
+ movdqa %xmm3,48(%rsp)
+ movl $10,%ebp
+ jmp .Loop_ssse3
+
+.align 32
+.Loop_outer_ssse3:
+ movdqa .Lone(%rip),%xmm3
+ movdqa 0(%rsp),%xmm0
+ movdqa 16(%rsp),%xmm1
+ movdqa 32(%rsp),%xmm2
+ paddd 48(%rsp),%xmm3
+ movl $10,%ebp
+ movdqa %xmm3,48(%rsp)
+ jmp .Loop_ssse3
+
+.align 32
+.Loop_ssse3:
+ paddd %xmm1,%xmm0
+ pxor %xmm0,%xmm3
+.byte 102,15,56,0,222
+ paddd %xmm3,%xmm2
+ pxor %xmm2,%xmm1
+ movdqa %xmm1,%xmm4
+ psrld $20,%xmm1
+ pslld $12,%xmm4
+ por %xmm4,%xmm1
+ paddd %xmm1,%xmm0
+ pxor %xmm0,%xmm3
+.byte 102,15,56,0,223
+ paddd %xmm3,%xmm2
+ pxor %xmm2,%xmm1
+ movdqa %xmm1,%xmm4
+ psrld $25,%xmm1
+ pslld $7,%xmm4
+ por %xmm4,%xmm1
+ pshufd $78,%xmm2,%xmm2
+ pshufd $57,%xmm1,%xmm1
+ pshufd $147,%xmm3,%xmm3
+ nop
+ paddd %xmm1,%xmm0
+ pxor %xmm0,%xmm3
+.byte 102,15,56,0,222
+ paddd %xmm3,%xmm2
+ pxor %xmm2,%xmm1
+ movdqa %xmm1,%xmm4
+ psrld $20,%xmm1
+ pslld $12,%xmm4
+ por %xmm4,%xmm1
+ paddd %xmm1,%xmm0
+ pxor %xmm0,%xmm3
+.byte 102,15,56,0,223
+ paddd %xmm3,%xmm2
+ pxor %xmm2,%xmm1
+ movdqa %xmm1,%xmm4
+ psrld $25,%xmm1
+ pslld $7,%xmm4
+ por %xmm4,%xmm1
+ pshufd $78,%xmm2,%xmm2
+ pshufd $147,%xmm1,%xmm1
+ pshufd $57,%xmm3,%xmm3
+ decl %ebp
+ jnz .Loop_ssse3
+ paddd 0(%rsp),%xmm0
+ paddd 16(%rsp),%xmm1
+ paddd 32(%rsp),%xmm2
+ paddd 48(%rsp),%xmm3
+
+ cmpq $64,%rdx
+ jb .Ltail_ssse3
+
+ movdqu 0(%rsi),%xmm4
+ movdqu 16(%rsi),%xmm5
+ pxor %xmm4,%xmm0
+ movdqu 32(%rsi),%xmm4
+ pxor %xmm5,%xmm1
+ movdqu 48(%rsi),%xmm5
+ leaq 64(%rsi),%rsi
+ pxor %xmm4,%xmm2
+ pxor %xmm5,%xmm3
+
+ movdqu %xmm0,0(%rdi)
+ movdqu %xmm1,16(%rdi)
+ movdqu %xmm2,32(%rdi)
+ movdqu %xmm3,48(%rdi)
+ leaq 64(%rdi),%rdi
+
+ subq $64,%rdx
+ jnz .Loop_outer_ssse3
+
+ jmp .Ldone_ssse3
+
+.align 16
+.Ltail_ssse3:
+ movdqa %xmm0,0(%rsp)
+ movdqa %xmm1,16(%rsp)
+ movdqa %xmm2,32(%rsp)
+ movdqa %xmm3,48(%rsp)
+ xorq %rbx,%rbx
+
+.Loop_tail_ssse3:
+ movzbl (%rsi,%rbx,1),%eax
+ movzbl (%rsp,%rbx,1),%ecx
+ leaq 1(%rbx),%rbx
+ xorl %ecx,%eax
+ movb %al,-1(%rdi,%rbx,1)
+ decq %rdx
+ jnz .Loop_tail_ssse3
+
+.Ldone_ssse3:
+ addq $64+24,%rsp
+ popq %r15
+ popq %r14
+ popq %r13
+ popq %r12
+ popq %rbp
+ popq %rbx
+ .byte 0xf3,0xc3
+.size ChaCha20_ssse3,.-ChaCha20_ssse3
+.type ChaCha20_4x,@function
+.align 32
+ChaCha20_4x:
+.LChaCha20_4x:
+ movq %r10,%r11
+ shrq $32,%r10
+ testq $32,%r10
+ jnz .LChaCha20_8x
+ cmpq $192,%rdx
+ ja .Lproceed4x
+
+ andq $71303168,%r11
+ cmpq $4194304,%r11
+ je .Ldo_sse3_after_all
+
+.Lproceed4x:
+ leaq -120(%rsp),%r11
+ subq $0x148+0,%rsp
+ movdqa .Lsigma(%rip),%xmm11
+ movdqu (%rcx),%xmm15
+ movdqu 16(%rcx),%xmm7
+ movdqu (%r8),%xmm3
+ leaq 256(%rsp),%rcx
+ leaq .Lrot16(%rip),%r10
+ leaq .Lrot24(%rip),%r11
+
+ pshufd $0x00,%xmm11,%xmm8
+ pshufd $0x55,%xmm11,%xmm9
+ movdqa %xmm8,64(%rsp)
+ pshufd $0xaa,%xmm11,%xmm10
+ movdqa %xmm9,80(%rsp)
+ pshufd $0xff,%xmm11,%xmm11
+ movdqa %xmm10,96(%rsp)
+ movdqa %xmm11,112(%rsp)
+
+ pshufd $0x00,%xmm15,%xmm12
+ pshufd $0x55,%xmm15,%xmm13
+ movdqa %xmm12,128-256(%rcx)
+ pshufd $0xaa,%xmm15,%xmm14
+ movdqa %xmm13,144-256(%rcx)
+ pshufd $0xff,%xmm15,%xmm15
+ movdqa %xmm14,160-256(%rcx)
+ movdqa %xmm15,176-256(%rcx)
+
+ pshufd $0x00,%xmm7,%xmm4
+ pshufd $0x55,%xmm7,%xmm5
+ movdqa %xmm4,192-256(%rcx)
+ pshufd $0xaa,%xmm7,%xmm6
+ movdqa %xmm5,208-256(%rcx)
+ pshufd $0xff,%xmm7,%xmm7
+ movdqa %xmm6,224-256(%rcx)
+ movdqa %xmm7,240-256(%rcx)
+
+ pshufd $0x00,%xmm3,%xmm0
+ pshufd $0x55,%xmm3,%xmm1
+ paddd .Linc(%rip),%xmm0
+ pshufd $0xaa,%xmm3,%xmm2
+ movdqa %xmm1,272-256(%rcx)
+ pshufd $0xff,%xmm3,%xmm3
+ movdqa %xmm2,288-256(%rcx)
+ movdqa %xmm3,304-256(%rcx)
+
+ jmp .Loop_enter4x
+
+.align 32
+.Loop_outer4x:
+ movdqa 64(%rsp),%xmm8
+ movdqa 80(%rsp),%xmm9
+ movdqa 96(%rsp),%xmm10
+ movdqa 112(%rsp),%xmm11
+ movdqa 128-256(%rcx),%xmm12
+ movdqa 144-256(%rcx),%xmm13
+ movdqa 160-256(%rcx),%xmm14
+ movdqa 176-256(%rcx),%xmm15
+ movdqa 192-256(%rcx),%xmm4
+ movdqa 208-256(%rcx),%xmm5
+ movdqa 224-256(%rcx),%xmm6
+ movdqa 240-256(%rcx),%xmm7
+ movdqa 256-256(%rcx),%xmm0
+ movdqa 272-256(%rcx),%xmm1
+ movdqa 288-256(%rcx),%xmm2
+ movdqa 304-256(%rcx),%xmm3
+ paddd .Lfour(%rip),%xmm0
+
+.Loop_enter4x:
+ movdqa %xmm6,32(%rsp)
+ movdqa %xmm7,48(%rsp)
+ movdqa (%r10),%xmm7
+ movl $10,%eax
+ movdqa %xmm0,256-256(%rcx)
+ jmp .Loop4x
+
+.align 32
+.Loop4x:
+ paddd %xmm12,%xmm8
+ paddd %xmm13,%xmm9
+ pxor %xmm8,%xmm0
+ pxor %xmm9,%xmm1
+.byte 102,15,56,0,199
+.byte 102,15,56,0,207
+ paddd %xmm0,%xmm4
+ paddd %xmm1,%xmm5
+ pxor %xmm4,%xmm12
+ pxor %xmm5,%xmm13
+ movdqa %xmm12,%xmm6
+ pslld $12,%xmm12
+ psrld $20,%xmm6
+ movdqa %xmm13,%xmm7
+ pslld $12,%xmm13
+ por %xmm6,%xmm12
+ psrld $20,%xmm7
+ movdqa (%r11),%xmm6
+ por %xmm7,%xmm13
+ paddd %xmm12,%xmm8
+ paddd %xmm13,%xmm9
+ pxor %xmm8,%xmm0
+ pxor %xmm9,%xmm1
+.byte 102,15,56,0,198
+.byte 102,15,56,0,206
+ paddd %xmm0,%xmm4
+ paddd %xmm1,%xmm5
+ pxor %xmm4,%xmm12
+ pxor %xmm5,%xmm13
+ movdqa %xmm12,%xmm7
+ pslld $7,%xmm12
+ psrld $25,%xmm7
+ movdqa %xmm13,%xmm6
+ pslld $7,%xmm13
+ por %xmm7,%xmm12
+ psrld $25,%xmm6
+ movdqa (%r10),%xmm7
+ por %xmm6,%xmm13
+ movdqa %xmm4,0(%rsp)
+ movdqa %xmm5,16(%rsp)
+ movdqa 32(%rsp),%xmm4
+ movdqa 48(%rsp),%xmm5
+ paddd %xmm14,%xmm10
+ paddd %xmm15,%xmm11
+ pxor %xmm10,%xmm2
+ pxor %xmm11,%xmm3
+.byte 102,15,56,0,215
+.byte 102,15,56,0,223
+ paddd %xmm2,%xmm4
+ paddd %xmm3,%xmm5
+ pxor %xmm4,%xmm14
+ pxor %xmm5,%xmm15
+ movdqa %xmm14,%xmm6
+ pslld $12,%xmm14
+ psrld $20,%xmm6
+ movdqa %xmm15,%xmm7
+ pslld $12,%xmm15
+ por %xmm6,%xmm14
+ psrld $20,%xmm7
+ movdqa (%r11),%xmm6
+ por %xmm7,%xmm15
+ paddd %xmm14,%xmm10
+ paddd %xmm15,%xmm11
+ pxor %xmm10,%xmm2
+ pxor %xmm11,%xmm3
+.byte 102,15,56,0,214
+.byte 102,15,56,0,222
+ paddd %xmm2,%xmm4
+ paddd %xmm3,%xmm5
+ pxor %xmm4,%xmm14
+ pxor %xmm5,%xmm15
+ movdqa %xmm14,%xmm7
+ pslld $7,%xmm14
+ psrld $25,%xmm7
+ movdqa %xmm15,%xmm6
+ pslld $7,%xmm15
+ por %xmm7,%xmm14
+ psrld $25,%xmm6
+ movdqa (%r10),%xmm7
+ por %xmm6,%xmm15
+ paddd %xmm13,%xmm8
+ paddd %xmm14,%xmm9
+ pxor %xmm8,%xmm3
+ pxor %xmm9,%xmm0
+.byte 102,15,56,0,223
+.byte 102,15,56,0,199
+ paddd %xmm3,%xmm4
+ paddd %xmm0,%xmm5
+ pxor %xmm4,%xmm13
+ pxor %xmm5,%xmm14
+ movdqa %xmm13,%xmm6
+ pslld $12,%xmm13
+ psrld $20,%xmm6
+ movdqa %xmm14,%xmm7
+ pslld $12,%xmm14
+ por %xmm6,%xmm13
+ psrld $20,%xmm7
+ movdqa (%r11),%xmm6
+ por %xmm7,%xmm14
+ paddd %xmm13,%xmm8
+ paddd %xmm14,%xmm9
+ pxor %xmm8,%xmm3
+ pxor %xmm9,%xmm0
+.byte 102,15,56,0,222
+.byte 102,15,56,0,198
+ paddd %xmm3,%xmm4
+ paddd %xmm0,%xmm5
+ pxor %xmm4,%xmm13
+ pxor %xmm5,%xmm14
+ movdqa %xmm13,%xmm7
+ pslld $7,%xmm13
+ psrld $25,%xmm7
+ movdqa %xmm14,%xmm6
+ pslld $7,%xmm14
+ por %xmm7,%xmm13
+ psrld $25,%xmm6
+ movdqa (%r10),%xmm7
+ por %xmm6,%xmm14
+ movdqa %xmm4,32(%rsp)
+ movdqa %xmm5,48(%rsp)
+ movdqa 0(%rsp),%xmm4
+ movdqa 16(%rsp),%xmm5
+ paddd %xmm15,%xmm10
+ paddd %xmm12,%xmm11
+ pxor %xmm10,%xmm1
+ pxor %xmm11,%xmm2
+.byte 102,15,56,0,207
+.byte 102,15,56,0,215
+ paddd %xmm1,%xmm4
+ paddd %xmm2,%xmm5
+ pxor %xmm4,%xmm15
+ pxor %xmm5,%xmm12
+ movdqa %xmm15,%xmm6
+ pslld $12,%xmm15
+ psrld $20,%xmm6
+ movdqa %xmm12,%xmm7
+ pslld $12,%xmm12
+ por %xmm6,%xmm15
+ psrld $20,%xmm7
+ movdqa (%r11),%xmm6
+ por %xmm7,%xmm12
+ paddd %xmm15,%xmm10
+ paddd %xmm12,%xmm11
+ pxor %xmm10,%xmm1
+ pxor %xmm11,%xmm2
+.byte 102,15,56,0,206
+.byte 102,15,56,0,214
+ paddd %xmm1,%xmm4
+ paddd %xmm2,%xmm5
+ pxor %xmm4,%xmm15
+ pxor %xmm5,%xmm12
+ movdqa %xmm15,%xmm7
+ pslld $7,%xmm15
+ psrld $25,%xmm7
+ movdqa %xmm12,%xmm6
+ pslld $7,%xmm12
+ por %xmm7,%xmm15
+ psrld $25,%xmm6
+ movdqa (%r10),%xmm7
+ por %xmm6,%xmm12
+ decl %eax
+ jnz .Loop4x
+
+ paddd 64(%rsp),%xmm8
+ paddd 80(%rsp),%xmm9
+ paddd 96(%rsp),%xmm10
+ paddd 112(%rsp),%xmm11
+
+ movdqa %xmm8,%xmm6
+ punpckldq %xmm9,%xmm8
+ movdqa %xmm10,%xmm7
+ punpckldq %xmm11,%xmm10
+ punpckhdq %xmm9,%xmm6
+ punpckhdq %xmm11,%xmm7
+ movdqa %xmm8,%xmm9
+ punpcklqdq %xmm10,%xmm8
+ movdqa %xmm6,%xmm11
+ punpcklqdq %xmm7,%xmm6
+ punpckhqdq %xmm10,%xmm9
+ punpckhqdq %xmm7,%xmm11
+ paddd 128-256(%rcx),%xmm12
+ paddd 144-256(%rcx),%xmm13
+ paddd 160-256(%rcx),%xmm14
+ paddd 176-256(%rcx),%xmm15
+
+ movdqa %xmm8,0(%rsp)
+ movdqa %xmm9,16(%rsp)
+ movdqa 32(%rsp),%xmm8
+ movdqa 48(%rsp),%xmm9
+
+ movdqa %xmm12,%xmm10
+ punpckldq %xmm13,%xmm12
+ movdqa %xmm14,%xmm7
+ punpckldq %xmm15,%xmm14
+ punpckhdq %xmm13,%xmm10
+ punpckhdq %xmm15,%xmm7
+ movdqa %xmm12,%xmm13
+ punpcklqdq %xmm14,%xmm12
+ movdqa %xmm10,%xmm15
+ punpcklqdq %xmm7,%xmm10
+ punpckhqdq %xmm14,%xmm13
+ punpckhqdq %xmm7,%xmm15
+ paddd 192-256(%rcx),%xmm4
+ paddd 208-256(%rcx),%xmm5
+ paddd 224-256(%rcx),%xmm8
+ paddd 240-256(%rcx),%xmm9
+
+ movdqa %xmm6,32(%rsp)
+ movdqa %xmm11,48(%rsp)
+
+ movdqa %xmm4,%xmm14
+ punpckldq %xmm5,%xmm4
+ movdqa %xmm8,%xmm7
+ punpckldq %xmm9,%xmm8
+ punpckhdq %xmm5,%xmm14
+ punpckhdq %xmm9,%xmm7
+ movdqa %xmm4,%xmm5
+ punpcklqdq %xmm8,%xmm4
+ movdqa %xmm14,%xmm9
+ punpcklqdq %xmm7,%xmm14
+ punpckhqdq %xmm8,%xmm5
+ punpckhqdq %xmm7,%xmm9
+ paddd 256-256(%rcx),%xmm0
+ paddd 272-256(%rcx),%xmm1
+ paddd 288-256(%rcx),%xmm2
+ paddd 304-256(%rcx),%xmm3
+
+ movdqa %xmm0,%xmm8
+ punpckldq %xmm1,%xmm0
+ movdqa %xmm2,%xmm7
+ punpckldq %xmm3,%xmm2
+ punpckhdq %xmm1,%xmm8
+ punpckhdq %xmm3,%xmm7
+ movdqa %xmm0,%xmm1
+ punpcklqdq %xmm2,%xmm0
+ movdqa %xmm8,%xmm3
+ punpcklqdq %xmm7,%xmm8
+ punpckhqdq %xmm2,%xmm1
+ punpckhqdq %xmm7,%xmm3
+ cmpq $256,%rdx
+ jb .Ltail4x
+
+ movdqu 0(%rsi),%xmm6
+ movdqu 16(%rsi),%xmm11
+ movdqu 32(%rsi),%xmm2
+ movdqu 48(%rsi),%xmm7
+ pxor 0(%rsp),%xmm6
+ pxor %xmm12,%xmm11
+ pxor %xmm4,%xmm2
+ pxor %xmm0,%xmm7
+
+ movdqu %xmm6,0(%rdi)
+ movdqu 64(%rsi),%xmm6
+ movdqu %xmm11,16(%rdi)
+ movdqu 80(%rsi),%xmm11
+ movdqu %xmm2,32(%rdi)
+ movdqu 96(%rsi),%xmm2
+ movdqu %xmm7,48(%rdi)
+ movdqu 112(%rsi),%xmm7
+ leaq 128(%rsi),%rsi
+ pxor 16(%rsp),%xmm6
+ pxor %xmm13,%xmm11
+ pxor %xmm5,%xmm2
+ pxor %xmm1,%xmm7
+
+ movdqu %xmm6,64(%rdi)
+ movdqu 0(%rsi),%xmm6
+ movdqu %xmm11,80(%rdi)
+ movdqu 16(%rsi),%xmm11
+ movdqu %xmm2,96(%rdi)
+ movdqu 32(%rsi),%xmm2
+ movdqu %xmm7,112(%rdi)
+ leaq 128(%rdi),%rdi
+ movdqu 48(%rsi),%xmm7
+ pxor 32(%rsp),%xmm6
+ pxor %xmm10,%xmm11
+ pxor %xmm14,%xmm2
+ pxor %xmm8,%xmm7
+
+ movdqu %xmm6,0(%rdi)
+ movdqu 64(%rsi),%xmm6
+ movdqu %xmm11,16(%rdi)
+ movdqu 80(%rsi),%xmm11
+ movdqu %xmm2,32(%rdi)
+ movdqu 96(%rsi),%xmm2
+ movdqu %xmm7,48(%rdi)
+ movdqu 112(%rsi),%xmm7
+ leaq 128(%rsi),%rsi
+ pxor 48(%rsp),%xmm6
+ pxor %xmm15,%xmm11
+ pxor %xmm9,%xmm2
+ pxor %xmm3,%xmm7
+ movdqu %xmm6,64(%rdi)
+ movdqu %xmm11,80(%rdi)
+ movdqu %xmm2,96(%rdi)
+ movdqu %xmm7,112(%rdi)
+ leaq 128(%rdi),%rdi
+
+ subq $256,%rdx
+ jnz .Loop_outer4x
+
+ jmp .Ldone4x
+
+.Ltail4x:
+ cmpq $192,%rdx
+ jae .L192_or_more4x
+ cmpq $128,%rdx
+ jae .L128_or_more4x
+ cmpq $64,%rdx
+ jae .L64_or_more4x
+
+
+ xorq %r10,%r10
+
+ movdqa %xmm12,16(%rsp)
+ movdqa %xmm4,32(%rsp)
+ movdqa %xmm0,48(%rsp)
+ jmp .Loop_tail4x
+
+.align 32
+.L64_or_more4x:
+ movdqu 0(%rsi),%xmm6
+ movdqu 16(%rsi),%xmm11
+ movdqu 32(%rsi),%xmm2
+ movdqu 48(%rsi),%xmm7
+ pxor 0(%rsp),%xmm6
+ pxor %xmm12,%xmm11
+ pxor %xmm4,%xmm2
+ pxor %xmm0,%xmm7
+ movdqu %xmm6,0(%rdi)
+ movdqu %xmm11,16(%rdi)
+ movdqu %xmm2,32(%rdi)
+ movdqu %xmm7,48(%rdi)
+ je .Ldone4x
+
+ movdqa 16(%rsp),%xmm6
+ leaq 64(%rsi),%rsi
+ xorq %r10,%r10
+ movdqa %xmm6,0(%rsp)
+ movdqa %xmm13,16(%rsp)
+ leaq 64(%rdi),%rdi
+ movdqa %xmm5,32(%rsp)
+ subq $64,%rdx
+ movdqa %xmm1,48(%rsp)
+ jmp .Loop_tail4x
+
+.align 32
+.L128_or_more4x:
+ movdqu 0(%rsi),%xmm6
+ movdqu 16(%rsi),%xmm11
+ movdqu 32(%rsi),%xmm2
+ movdqu 48(%rsi),%xmm7
+ pxor 0(%rsp),%xmm6
+ pxor %xmm12,%xmm11
+ pxor %xmm4,%xmm2
+ pxor %xmm0,%xmm7
+
+ movdqu %xmm6,0(%rdi)
+ movdqu 64(%rsi),%xmm6
+ movdqu %xmm11,16(%rdi)
+ movdqu 80(%rsi),%xmm11
+ movdqu %xmm2,32(%rdi)
+ movdqu 96(%rsi),%xmm2
+ movdqu %xmm7,48(%rdi)
+ movdqu 112(%rsi),%xmm7
+ pxor 16(%rsp),%xmm6
+ pxor %xmm13,%xmm11
+ pxor %xmm5,%xmm2
+ pxor %xmm1,%xmm7
+ movdqu %xmm6,64(%rdi)
+ movdqu %xmm11,80(%rdi)
+ movdqu %xmm2,96(%rdi)
+ movdqu %xmm7,112(%rdi)
+ je .Ldone4x
+
+ movdqa 32(%rsp),%xmm6
+ leaq 128(%rsi),%rsi
+ xorq %r10,%r10
+ movdqa %xmm6,0(%rsp)
+ movdqa %xmm10,16(%rsp)
+ leaq 128(%rdi),%rdi
+ movdqa %xmm14,32(%rsp)
+ subq $128,%rdx
+ movdqa %xmm8,48(%rsp)
+ jmp .Loop_tail4x
+
+.align 32
+.L192_or_more4x:
+ movdqu 0(%rsi),%xmm6
+ movdqu 16(%rsi),%xmm11
+ movdqu 32(%rsi),%xmm2
+ movdqu 48(%rsi),%xmm7
+ pxor 0(%rsp),%xmm6
+ pxor %xmm12,%xmm11
+ pxor %xmm4,%xmm2
+ pxor %xmm0,%xmm7
+
+ movdqu %xmm6,0(%rdi)
+ movdqu 64(%rsi),%xmm6
+ movdqu %xmm11,16(%rdi)
+ movdqu 80(%rsi),%xmm11
+ movdqu %xmm2,32(%rdi)
+ movdqu 96(%rsi),%xmm2
+ movdqu %xmm7,48(%rdi)
+ movdqu 112(%rsi),%xmm7
+ leaq 128(%rsi),%rsi
+ pxor 16(%rsp),%xmm6
+ pxor %xmm13,%xmm11
+ pxor %xmm5,%xmm2
+ pxor %xmm1,%xmm7
+
+ movdqu %xmm6,64(%rdi)
+ movdqu 0(%rsi),%xmm6
+ movdqu %xmm11,80(%rdi)
+ movdqu 16(%rsi),%xmm11
+ movdqu %xmm2,96(%rdi)
+ movdqu 32(%rsi),%xmm2
+ movdqu %xmm7,112(%rdi)
+ leaq 128(%rdi),%rdi
+ movdqu 48(%rsi),%xmm7
+ pxor 32(%rsp),%xmm6
+ pxor %xmm10,%xmm11
+ pxor %xmm14,%xmm2
+ pxor %xmm8,%xmm7
+ movdqu %xmm6,0(%rdi)
+ movdqu %xmm11,16(%rdi)
+ movdqu %xmm2,32(%rdi)
+ movdqu %xmm7,48(%rdi)
+ je .Ldone4x
+
+ movdqa 48(%rsp),%xmm6
+ leaq 64(%rsi),%rsi
+ xorq %r10,%r10
+ movdqa %xmm6,0(%rsp)
+ movdqa %xmm15,16(%rsp)
+ leaq 64(%rdi),%rdi
+ movdqa %xmm9,32(%rsp)
+ subq $192,%rdx
+ movdqa %xmm3,48(%rsp)
+
+.Loop_tail4x:
+ movzbl (%rsi,%r10,1),%eax
+ movzbl (%rsp,%r10,1),%ecx
+ leaq 1(%r10),%r10
+ xorl %ecx,%eax
+ movb %al,-1(%rdi,%r10,1)
+ decq %rdx
+ jnz .Loop_tail4x
+
+.Ldone4x:
+ addq $0x148+0,%rsp
+ .byte 0xf3,0xc3
+.size ChaCha20_4x,.-ChaCha20_4x
+.type ChaCha20_8x,@function
+.align 32
+ChaCha20_8x:
+.LChaCha20_8x:
+ movq %rsp,%r10
+ subq $0x280+8,%rsp
+ andq $-32,%rsp
+ vzeroupper
+ movq %r10,640(%rsp)
+
+
+
+
+
+
+
+
+
+
+ vbroadcasti128 .Lsigma(%rip),%ymm11
+ vbroadcasti128 (%rcx),%ymm3
+ vbroadcasti128 16(%rcx),%ymm15
+ vbroadcasti128 (%r8),%ymm7
+ leaq 256(%rsp),%rcx
+ leaq 512(%rsp),%rax
+ leaq .Lrot16(%rip),%r10
+ leaq .Lrot24(%rip),%r11
+
+ vpshufd $0x00,%ymm11,%ymm8
+ vpshufd $0x55,%ymm11,%ymm9
+ vmovdqa %ymm8,128-256(%rcx)
+ vpshufd $0xaa,%ymm11,%ymm10
+ vmovdqa %ymm9,160-256(%rcx)
+ vpshufd $0xff,%ymm11,%ymm11
+ vmovdqa %ymm10,192-256(%rcx)
+ vmovdqa %ymm11,224-256(%rcx)
+
+ vpshufd $0x00,%ymm3,%ymm0
+ vpshufd $0x55,%ymm3,%ymm1
+ vmovdqa %ymm0,256-256(%rcx)
+ vpshufd $0xaa,%ymm3,%ymm2
+ vmovdqa %ymm1,288-256(%rcx)
+ vpshufd $0xff,%ymm3,%ymm3
+ vmovdqa %ymm2,320-256(%rcx)
+ vmovdqa %ymm3,352-256(%rcx)
+
+ vpshufd $0x00,%ymm15,%ymm12
+ vpshufd $0x55,%ymm15,%ymm13
+ vmovdqa %ymm12,384-512(%rax)
+ vpshufd $0xaa,%ymm15,%ymm14
+ vmovdqa %ymm13,416-512(%rax)
+ vpshufd $0xff,%ymm15,%ymm15
+ vmovdqa %ymm14,448-512(%rax)
+ vmovdqa %ymm15,480-512(%rax)
+
+ vpshufd $0x00,%ymm7,%ymm4
+ vpshufd $0x55,%ymm7,%ymm5
+ vpaddd .Lincy(%rip),%ymm4,%ymm4
+ vpshufd $0xaa,%ymm7,%ymm6
+ vmovdqa %ymm5,544-512(%rax)
+ vpshufd $0xff,%ymm7,%ymm7
+ vmovdqa %ymm6,576-512(%rax)
+ vmovdqa %ymm7,608-512(%rax)
+
+ jmp .Loop_enter8x
+
+.align 32
+.Loop_outer8x:
+ vmovdqa 128-256(%rcx),%ymm8
+ vmovdqa 160-256(%rcx),%ymm9
+ vmovdqa 192-256(%rcx),%ymm10
+ vmovdqa 224-256(%rcx),%ymm11
+ vmovdqa 256-256(%rcx),%ymm0
+ vmovdqa 288-256(%rcx),%ymm1
+ vmovdqa 320-256(%rcx),%ymm2
+ vmovdqa 352-256(%rcx),%ymm3
+ vmovdqa 384-512(%rax),%ymm12
+ vmovdqa 416-512(%rax),%ymm13
+ vmovdqa 448-512(%rax),%ymm14
+ vmovdqa 480-512(%rax),%ymm15
+ vmovdqa 512-512(%rax),%ymm4
+ vmovdqa 544-512(%rax),%ymm5
+ vmovdqa 576-512(%rax),%ymm6
+ vmovdqa 608-512(%rax),%ymm7
+ vpaddd .Leight(%rip),%ymm4,%ymm4
+
+.Loop_enter8x:
+ vmovdqa %ymm14,64(%rsp)
+ vmovdqa %ymm15,96(%rsp)
+ vbroadcasti128 (%r10),%ymm15
+ vmovdqa %ymm4,512-512(%rax)
+ movl $10,%eax
+ jmp .Loop8x
+
+.align 32
+.Loop8x:
+ vpaddd %ymm0,%ymm8,%ymm8
+ vpxor %ymm4,%ymm8,%ymm4
+ vpshufb %ymm15,%ymm4,%ymm4
+ vpaddd %ymm1,%ymm9,%ymm9
+ vpxor %ymm5,%ymm9,%ymm5
+ vpshufb %ymm15,%ymm5,%ymm5
+ vpaddd %ymm4,%ymm12,%ymm12
+ vpxor %ymm0,%ymm12,%ymm0
+ vpslld $12,%ymm0,%ymm14
+ vpsrld $20,%ymm0,%ymm0
+ vpor %ymm0,%ymm14,%ymm0
+ vbroadcasti128 (%r11),%ymm14
+ vpaddd %ymm5,%ymm13,%ymm13
+ vpxor %ymm1,%ymm13,%ymm1
+ vpslld $12,%ymm1,%ymm15
+ vpsrld $20,%ymm1,%ymm1
+ vpor %ymm1,%ymm15,%ymm1
+ vpaddd %ymm0,%ymm8,%ymm8
+ vpxor %ymm4,%ymm8,%ymm4
+ vpshufb %ymm14,%ymm4,%ymm4
+ vpaddd %ymm1,%ymm9,%ymm9
+ vpxor %ymm5,%ymm9,%ymm5
+ vpshufb %ymm14,%ymm5,%ymm5
+ vpaddd %ymm4,%ymm12,%ymm12
+ vpxor %ymm0,%ymm12,%ymm0
+ vpslld $7,%ymm0,%ymm15
+ vpsrld $25,%ymm0,%ymm0
+ vpor %ymm0,%ymm15,%ymm0
+ vbroadcasti128 (%r10),%ymm15
+ vpaddd %ymm5,%ymm13,%ymm13
+ vpxor %ymm1,%ymm13,%ymm1
+ vpslld $7,%ymm1,%ymm14
+ vpsrld $25,%ymm1,%ymm1
+ vpor %ymm1,%ymm14,%ymm1
+ vmovdqa %ymm12,0(%rsp)
+ vmovdqa %ymm13,32(%rsp)
+ vmovdqa 64(%rsp),%ymm12
+ vmovdqa 96(%rsp),%ymm13
+ vpaddd %ymm2,%ymm10,%ymm10
+ vpxor %ymm6,%ymm10,%ymm6
+ vpshufb %ymm15,%ymm6,%ymm6
+ vpaddd %ymm3,%ymm11,%ymm11
+ vpxor %ymm7,%ymm11,%ymm7
+ vpshufb %ymm15,%ymm7,%ymm7
+ vpaddd %ymm6,%ymm12,%ymm12
+ vpxor %ymm2,%ymm12,%ymm2
+ vpslld $12,%ymm2,%ymm14
+ vpsrld $20,%ymm2,%ymm2
+ vpor %ymm2,%ymm14,%ymm2
+ vbroadcasti128 (%r11),%ymm14
+ vpaddd %ymm7,%ymm13,%ymm13
+ vpxor %ymm3,%ymm13,%ymm3
+ vpslld $12,%ymm3,%ymm15
+ vpsrld $20,%ymm3,%ymm3
+ vpor %ymm3,%ymm15,%ymm3
+ vpaddd %ymm2,%ymm10,%ymm10
+ vpxor %ymm6,%ymm10,%ymm6
+ vpshufb %ymm14,%ymm6,%ymm6
+ vpaddd %ymm3,%ymm11,%ymm11
+ vpxor %ymm7,%ymm11,%ymm7
+ vpshufb %ymm14,%ymm7,%ymm7
+ vpaddd %ymm6,%ymm12,%ymm12
+ vpxor %ymm2,%ymm12,%ymm2
+ vpslld $7,%ymm2,%ymm15
+ vpsrld $25,%ymm2,%ymm2
+ vpor %ymm2,%ymm15,%ymm2
+ vbroadcasti128 (%r10),%ymm15
+ vpaddd %ymm7,%ymm13,%ymm13
+ vpxor %ymm3,%ymm13,%ymm3
+ vpslld $7,%ymm3,%ymm14
+ vpsrld $25,%ymm3,%ymm3
+ vpor %ymm3,%ymm14,%ymm3
+ vpaddd %ymm1,%ymm8,%ymm8
+ vpxor %ymm7,%ymm8,%ymm7
+ vpshufb %ymm15,%ymm7,%ymm7
+ vpaddd %ymm2,%ymm9,%ymm9
+ vpxor %ymm4,%ymm9,%ymm4
+ vpshufb %ymm15,%ymm4,%ymm4
+ vpaddd %ymm7,%ymm12,%ymm12
+ vpxor %ymm1,%ymm12,%ymm1
+ vpslld $12,%ymm1,%ymm14
+ vpsrld $20,%ymm1,%ymm1
+ vpor %ymm1,%ymm14,%ymm1
+ vbroadcasti128 (%r11),%ymm14
+ vpaddd %ymm4,%ymm13,%ymm13
+ vpxor %ymm2,%ymm13,%ymm2
+ vpslld $12,%ymm2,%ymm15
+ vpsrld $20,%ymm2,%ymm2
+ vpor %ymm2,%ymm15,%ymm2
+ vpaddd %ymm1,%ymm8,%ymm8
+ vpxor %ymm7,%ymm8,%ymm7
+ vpshufb %ymm14,%ymm7,%ymm7
+ vpaddd %ymm2,%ymm9,%ymm9
+ vpxor %ymm4,%ymm9,%ymm4
+ vpshufb %ymm14,%ymm4,%ymm4
+ vpaddd %ymm7,%ymm12,%ymm12
+ vpxor %ymm1,%ymm12,%ymm1
+ vpslld $7,%ymm1,%ymm15
+ vpsrld $25,%ymm1,%ymm1
+ vpor %ymm1,%ymm15,%ymm1
+ vbroadcasti128 (%r10),%ymm15
+ vpaddd %ymm4,%ymm13,%ymm13
+ vpxor %ymm2,%ymm13,%ymm2
+ vpslld $7,%ymm2,%ymm14
+ vpsrld $25,%ymm2,%ymm2
+ vpor %ymm2,%ymm14,%ymm2
+ vmovdqa %ymm12,64(%rsp)
+ vmovdqa %ymm13,96(%rsp)
+ vmovdqa 0(%rsp),%ymm12
+ vmovdqa 32(%rsp),%ymm13
+ vpaddd %ymm3,%ymm10,%ymm10
+ vpxor %ymm5,%ymm10,%ymm5
+ vpshufb %ymm15,%ymm5,%ymm5
+ vpaddd %ymm0,%ymm11,%ymm11
+ vpxor %ymm6,%ymm11,%ymm6
+ vpshufb %ymm15,%ymm6,%ymm6
+ vpaddd %ymm5,%ymm12,%ymm12
+ vpxor %ymm3,%ymm12,%ymm3
+ vpslld $12,%ymm3,%ymm14
+ vpsrld $20,%ymm3,%ymm3
+ vpor %ymm3,%ymm14,%ymm3
+ vbroadcasti128 (%r11),%ymm14
+ vpaddd %ymm6,%ymm13,%ymm13
+ vpxor %ymm0,%ymm13,%ymm0
+ vpslld $12,%ymm0,%ymm15
+ vpsrld $20,%ymm0,%ymm0
+ vpor %ymm0,%ymm15,%ymm0
+ vpaddd %ymm3,%ymm10,%ymm10
+ vpxor %ymm5,%ymm10,%ymm5
+ vpshufb %ymm14,%ymm5,%ymm5
+ vpaddd %ymm0,%ymm11,%ymm11
+ vpxor %ymm6,%ymm11,%ymm6
+ vpshufb %ymm14,%ymm6,%ymm6
+ vpaddd %ymm5,%ymm12,%ymm12
+ vpxor %ymm3,%ymm12,%ymm3
+ vpslld $7,%ymm3,%ymm15
+ vpsrld $25,%ymm3,%ymm3
+ vpor %ymm3,%ymm15,%ymm3
+ vbroadcasti128 (%r10),%ymm15
+ vpaddd %ymm6,%ymm13,%ymm13
+ vpxor %ymm0,%ymm13,%ymm0
+ vpslld $7,%ymm0,%ymm14
+ vpsrld $25,%ymm0,%ymm0
+ vpor %ymm0,%ymm14,%ymm0
+ decl %eax
+ jnz .Loop8x
+
+ leaq 512(%rsp),%rax
+ vpaddd 128-256(%rcx),%ymm8,%ymm8
+ vpaddd 160-256(%rcx),%ymm9,%ymm9
+ vpaddd 192-256(%rcx),%ymm10,%ymm10
+ vpaddd 224-256(%rcx),%ymm11,%ymm11
+
+ vpunpckldq %ymm9,%ymm8,%ymm14
+ vpunpckldq %ymm11,%ymm10,%ymm15
+ vpunpckhdq %ymm9,%ymm8,%ymm8
+ vpunpckhdq %ymm11,%ymm10,%ymm10
+ vpunpcklqdq %ymm15,%ymm14,%ymm9
+ vpunpckhqdq %ymm15,%ymm14,%ymm14
+ vpunpcklqdq %ymm10,%ymm8,%ymm11
+ vpunpckhqdq %ymm10,%ymm8,%ymm8
+ vpaddd 256-256(%rcx),%ymm0,%ymm0
+ vpaddd 288-256(%rcx),%ymm1,%ymm1
+ vpaddd 320-256(%rcx),%ymm2,%ymm2
+ vpaddd 352-256(%rcx),%ymm3,%ymm3
+
+ vpunpckldq %ymm1,%ymm0,%ymm10
+ vpunpckldq %ymm3,%ymm2,%ymm15
+ vpunpckhdq %ymm1,%ymm0,%ymm0
+ vpunpckhdq %ymm3,%ymm2,%ymm2
+ vpunpcklqdq %ymm15,%ymm10,%ymm1
+ vpunpckhqdq %ymm15,%ymm10,%ymm10
+ vpunpcklqdq %ymm2,%ymm0,%ymm3
+ vpunpckhqdq %ymm2,%ymm0,%ymm0
+ vperm2i128 $0x20,%ymm1,%ymm9,%ymm15
+ vperm2i128 $0x31,%ymm1,%ymm9,%ymm1
+ vperm2i128 $0x20,%ymm10,%ymm14,%ymm9
+ vperm2i128 $0x31,%ymm10,%ymm14,%ymm10
+ vperm2i128 $0x20,%ymm3,%ymm11,%ymm14
+ vperm2i128 $0x31,%ymm3,%ymm11,%ymm3
+ vperm2i128 $0x20,%ymm0,%ymm8,%ymm11
+ vperm2i128 $0x31,%ymm0,%ymm8,%ymm0
+ vmovdqa %ymm15,0(%rsp)
+ vmovdqa %ymm9,32(%rsp)
+ vmovdqa 64(%rsp),%ymm15
+ vmovdqa 96(%rsp),%ymm9
+
+ vpaddd 384-512(%rax),%ymm12,%ymm12
+ vpaddd 416-512(%rax),%ymm13,%ymm13
+ vpaddd 448-512(%rax),%ymm15,%ymm15
+ vpaddd 480-512(%rax),%ymm9,%ymm9
+
+ vpunpckldq %ymm13,%ymm12,%ymm2
+ vpunpckldq %ymm9,%ymm15,%ymm8
+ vpunpckhdq %ymm13,%ymm12,%ymm12
+ vpunpckhdq %ymm9,%ymm15,%ymm15
+ vpunpcklqdq %ymm8,%ymm2,%ymm13
+ vpunpckhqdq %ymm8,%ymm2,%ymm2
+ vpunpcklqdq %ymm15,%ymm12,%ymm9
+ vpunpckhqdq %ymm15,%ymm12,%ymm12
+ vpaddd 512-512(%rax),%ymm4,%ymm4
+ vpaddd 544-512(%rax),%ymm5,%ymm5
+ vpaddd 576-512(%rax),%ymm6,%ymm6
+ vpaddd 608-512(%rax),%ymm7,%ymm7
+
+ vpunpckldq %ymm5,%ymm4,%ymm15
+ vpunpckldq %ymm7,%ymm6,%ymm8
+ vpunpckhdq %ymm5,%ymm4,%ymm4
+ vpunpckhdq %ymm7,%ymm6,%ymm6
+ vpunpcklqdq %ymm8,%ymm15,%ymm5
+ vpunpckhqdq %ymm8,%ymm15,%ymm15
+ vpunpcklqdq %ymm6,%ymm4,%ymm7
+ vpunpckhqdq %ymm6,%ymm4,%ymm4
+ vperm2i128 $0x20,%ymm5,%ymm13,%ymm8
+ vperm2i128 $0x31,%ymm5,%ymm13,%ymm5
+ vperm2i128 $0x20,%ymm15,%ymm2,%ymm13
+ vperm2i128 $0x31,%ymm15,%ymm2,%ymm15
+ vperm2i128 $0x20,%ymm7,%ymm9,%ymm2
+ vperm2i128 $0x31,%ymm7,%ymm9,%ymm7
+ vperm2i128 $0x20,%ymm4,%ymm12,%ymm9
+ vperm2i128 $0x31,%ymm4,%ymm12,%ymm4
+ vmovdqa 0(%rsp),%ymm6
+ vmovdqa 32(%rsp),%ymm12
+
+ cmpq $512,%rdx
+ jb .Ltail8x
+
+ vpxor 0(%rsi),%ymm6,%ymm6
+ vpxor 32(%rsi),%ymm8,%ymm8
+ vpxor 64(%rsi),%ymm1,%ymm1
+ vpxor 96(%rsi),%ymm5,%ymm5
+ leaq 128(%rsi),%rsi
+ vmovdqu %ymm6,0(%rdi)
+ vmovdqu %ymm8,32(%rdi)
+ vmovdqu %ymm1,64(%rdi)
+ vmovdqu %ymm5,96(%rdi)
+ leaq 128(%rdi),%rdi
+
+ vpxor 0(%rsi),%ymm12,%ymm12
+ vpxor 32(%rsi),%ymm13,%ymm13
+ vpxor 64(%rsi),%ymm10,%ymm10
+ vpxor 96(%rsi),%ymm15,%ymm15
+ leaq 128(%rsi),%rsi
+ vmovdqu %ymm12,0(%rdi)
+ vmovdqu %ymm13,32(%rdi)
+ vmovdqu %ymm10,64(%rdi)
+ vmovdqu %ymm15,96(%rdi)
+ leaq 128(%rdi),%rdi
+
+ vpxor 0(%rsi),%ymm14,%ymm14
+ vpxor 32(%rsi),%ymm2,%ymm2
+ vpxor 64(%rsi),%ymm3,%ymm3
+ vpxor 96(%rsi),%ymm7,%ymm7
+ leaq 128(%rsi),%rsi
+ vmovdqu %ymm14,0(%rdi)
+ vmovdqu %ymm2,32(%rdi)
+ vmovdqu %ymm3,64(%rdi)
+ vmovdqu %ymm7,96(%rdi)
+ leaq 128(%rdi),%rdi
+
+ vpxor 0(%rsi),%ymm11,%ymm11
+ vpxor 32(%rsi),%ymm9,%ymm9
+ vpxor 64(%rsi),%ymm0,%ymm0
+ vpxor 96(%rsi),%ymm4,%ymm4
+ leaq 128(%rsi),%rsi
+ vmovdqu %ymm11,0(%rdi)
+ vmovdqu %ymm9,32(%rdi)
+ vmovdqu %ymm0,64(%rdi)
+ vmovdqu %ymm4,96(%rdi)
+ leaq 128(%rdi),%rdi
+
+ subq $512,%rdx
+ jnz .Loop_outer8x
+
+ jmp .Ldone8x
+
+.Ltail8x:
+ cmpq $448,%rdx
+ jae .L448_or_more8x
+ cmpq $384,%rdx
+ jae .L384_or_more8x
+ cmpq $320,%rdx
+ jae .L320_or_more8x
+ cmpq $256,%rdx
+ jae .L256_or_more8x
+ cmpq $192,%rdx
+ jae .L192_or_more8x
+ cmpq $128,%rdx
+ jae .L128_or_more8x
+ cmpq $64,%rdx
+ jae .L64_or_more8x
+
+ xorq %r10,%r10
+ vmovdqa %ymm6,0(%rsp)
+ vmovdqa %ymm8,32(%rsp)
+ jmp .Loop_tail8x
+
+.align 32
+.L64_or_more8x:
+ vpxor 0(%rsi),%ymm6,%ymm6
+ vpxor 32(%rsi),%ymm8,%ymm8
+ vmovdqu %ymm6,0(%rdi)
+ vmovdqu %ymm8,32(%rdi)
+ je .Ldone8x
+
+ leaq 64(%rsi),%rsi
+ xorq %r10,%r10
+ vmovdqa %ymm1,0(%rsp)
+ leaq 64(%rdi),%rdi
+ subq $64,%rdx
+ vmovdqa %ymm5,32(%rsp)
+ jmp .Loop_tail8x
+
+.align 32
+.L128_or_more8x:
+ vpxor 0(%rsi),%ymm6,%ymm6
+ vpxor 32(%rsi),%ymm8,%ymm8
+ vpxor 64(%rsi),%ymm1,%ymm1
+ vpxor 96(%rsi),%ymm5,%ymm5
+ vmovdqu %ymm6,0(%rdi)
+ vmovdqu %ymm8,32(%rdi)
+ vmovdqu %ymm1,64(%rdi)
+ vmovdqu %ymm5,96(%rdi)
+ je .Ldone8x
+
+ leaq 128(%rsi),%rsi
+ xorq %r10,%r10
+ vmovdqa %ymm12,0(%rsp)
+ leaq 128(%rdi),%rdi
+ subq $128,%rdx
+ vmovdqa %ymm13,32(%rsp)
+ jmp .Loop_tail8x
+
+.align 32
+.L192_or_more8x:
+ vpxor 0(%rsi),%ymm6,%ymm6
+ vpxor 32(%rsi),%ymm8,%ymm8
+ vpxor 64(%rsi),%ymm1,%ymm1
+ vpxor 96(%rsi),%ymm5,%ymm5
+ vpxor 128(%rsi),%ymm12,%ymm12
+ vpxor 160(%rsi),%ymm13,%ymm13
+ vmovdqu %ymm6,0(%rdi)
+ vmovdqu %ymm8,32(%rdi)
+ vmovdqu %ymm1,64(%rdi)
+ vmovdqu %ymm5,96(%rdi)
+ vmovdqu %ymm12,128(%rdi)
+ vmovdqu %ymm13,160(%rdi)
+ je .Ldone8x
+
+ leaq 192(%rsi),%rsi
+ xorq %r10,%r10
+ vmovdqa %ymm10,0(%rsp)
+ leaq 192(%rdi),%rdi
+ subq $192,%rdx
+ vmovdqa %ymm15,32(%rsp)
+ jmp .Loop_tail8x
+
+.align 32
+.L256_or_more8x:
+ vpxor 0(%rsi),%ymm6,%ymm6
+ vpxor 32(%rsi),%ymm8,%ymm8
+ vpxor 64(%rsi),%ymm1,%ymm1
+ vpxor 96(%rsi),%ymm5,%ymm5
+ vpxor 128(%rsi),%ymm12,%ymm12
+ vpxor 160(%rsi),%ymm13,%ymm13
+ vpxor 192(%rsi),%ymm10,%ymm10
+ vpxor 224(%rsi),%ymm15,%ymm15
+ vmovdqu %ymm6,0(%rdi)
+ vmovdqu %ymm8,32(%rdi)
+ vmovdqu %ymm1,64(%rdi)
+ vmovdqu %ymm5,96(%rdi)
+ vmovdqu %ymm12,128(%rdi)
+ vmovdqu %ymm13,160(%rdi)
+ vmovdqu %ymm10,192(%rdi)
+ vmovdqu %ymm15,224(%rdi)
+ je .Ldone8x
+
+ leaq 256(%rsi),%rsi
+ xorq %r10,%r10
+ vmovdqa %ymm14,0(%rsp)
+ leaq 256(%rdi),%rdi
+ subq $256,%rdx
+ vmovdqa %ymm2,32(%rsp)
+ jmp .Loop_tail8x
+
+.align 32
+.L320_or_more8x:
+ vpxor 0(%rsi),%ymm6,%ymm6
+ vpxor 32(%rsi),%ymm8,%ymm8
+ vpxor 64(%rsi),%ymm1,%ymm1
+ vpxor 96(%rsi),%ymm5,%ymm5
+ vpxor 128(%rsi),%ymm12,%ymm12
+ vpxor 160(%rsi),%ymm13,%ymm13
+ vpxor 192(%rsi),%ymm10,%ymm10
+ vpxor 224(%rsi),%ymm15,%ymm15
+ vpxor 256(%rsi),%ymm14,%ymm14
+ vpxor 288(%rsi),%ymm2,%ymm2
+ vmovdqu %ymm6,0(%rdi)
+ vmovdqu %ymm8,32(%rdi)
+ vmovdqu %ymm1,64(%rdi)
+ vmovdqu %ymm5,96(%rdi)
+ vmovdqu %ymm12,128(%rdi)
+ vmovdqu %ymm13,160(%rdi)
+ vmovdqu %ymm10,192(%rdi)
+ vmovdqu %ymm15,224(%rdi)
+ vmovdqu %ymm14,256(%rdi)
+ vmovdqu %ymm2,288(%rdi)
+ je .Ldone8x
+
+ leaq 320(%rsi),%rsi
+ xorq %r10,%r10
+ vmovdqa %ymm3,0(%rsp)
+ leaq 320(%rdi),%rdi
+ subq $320,%rdx
+ vmovdqa %ymm7,32(%rsp)
+ jmp .Loop_tail8x
+
+.align 32
+.L384_or_more8x:
+ vpxor 0(%rsi),%ymm6,%ymm6
+ vpxor 32(%rsi),%ymm8,%ymm8
+ vpxor 64(%rsi),%ymm1,%ymm1
+ vpxor 96(%rsi),%ymm5,%ymm5
+ vpxor 128(%rsi),%ymm12,%ymm12
+ vpxor 160(%rsi),%ymm13,%ymm13
+ vpxor 192(%rsi),%ymm10,%ymm10
+ vpxor 224(%rsi),%ymm15,%ymm15
+ vpxor 256(%rsi),%ymm14,%ymm14
+ vpxor 288(%rsi),%ymm2,%ymm2
+ vpxor 320(%rsi),%ymm3,%ymm3
+ vpxor 352(%rsi),%ymm7,%ymm7
+ vmovdqu %ymm6,0(%rdi)
+ vmovdqu %ymm8,32(%rdi)
+ vmovdqu %ymm1,64(%rdi)
+ vmovdqu %ymm5,96(%rdi)
+ vmovdqu %ymm12,128(%rdi)
+ vmovdqu %ymm13,160(%rdi)
+ vmovdqu %ymm10,192(%rdi)
+ vmovdqu %ymm15,224(%rdi)
+ vmovdqu %ymm14,256(%rdi)
+ vmovdqu %ymm2,288(%rdi)
+ vmovdqu %ymm3,320(%rdi)
+ vmovdqu %ymm7,352(%rdi)
+ je .Ldone8x
+
+ leaq 384(%rsi),%rsi
+ xorq %r10,%r10
+ vmovdqa %ymm11,0(%rsp)
+ leaq 384(%rdi),%rdi
+ subq $384,%rdx
+ vmovdqa %ymm9,32(%rsp)
+ jmp .Loop_tail8x
+
+.align 32
+.L448_or_more8x:
+ vpxor 0(%rsi),%ymm6,%ymm6
+ vpxor 32(%rsi),%ymm8,%ymm8
+ vpxor 64(%rsi),%ymm1,%ymm1
+ vpxor 96(%rsi),%ymm5,%ymm5
+ vpxor 128(%rsi),%ymm12,%ymm12
+ vpxor 160(%rsi),%ymm13,%ymm13
+ vpxor 192(%rsi),%ymm10,%ymm10
+ vpxor 224(%rsi),%ymm15,%ymm15
+ vpxor 256(%rsi),%ymm14,%ymm14
+ vpxor 288(%rsi),%ymm2,%ymm2
+ vpxor 320(%rsi),%ymm3,%ymm3
+ vpxor 352(%rsi),%ymm7,%ymm7
+ vpxor 384(%rsi),%ymm11,%ymm11
+ vpxor 416(%rsi),%ymm9,%ymm9
+ vmovdqu %ymm6,0(%rdi)
+ vmovdqu %ymm8,32(%rdi)
+ vmovdqu %ymm1,64(%rdi)
+ vmovdqu %ymm5,96(%rdi)
+ vmovdqu %ymm12,128(%rdi)
+ vmovdqu %ymm13,160(%rdi)
+ vmovdqu %ymm10,192(%rdi)
+ vmovdqu %ymm15,224(%rdi)
+ vmovdqu %ymm14,256(%rdi)
+ vmovdqu %ymm2,288(%rdi)
+ vmovdqu %ymm3,320(%rdi)
+ vmovdqu %ymm7,352(%rdi)
+ vmovdqu %ymm11,384(%rdi)
+ vmovdqu %ymm9,416(%rdi)
+ je .Ldone8x
+
+ leaq 448(%rsi),%rsi
+ xorq %r10,%r10
+ vmovdqa %ymm0,0(%rsp)
+ leaq 448(%rdi),%rdi
+ subq $448,%rdx
+ vmovdqa %ymm4,32(%rsp)
+
+.Loop_tail8x:
+ movzbl (%rsi,%r10,1),%eax
+ movzbl (%rsp,%r10,1),%ecx
+ leaq 1(%r10),%r10
+ xorl %ecx,%eax
+ movb %al,-1(%rdi,%r10,1)
+ decq %rdx
+ jnz .Loop_tail8x
+
+.Ldone8x:
+ vzeroall
+ movq 640(%rsp),%rsp
+ .byte 0xf3,0xc3
+.size ChaCha20_8x,.-ChaCha20_8x
+#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
index 2884c69b..4abce6f9 100644
--- a/linux-x86_64/crypto/ec/p256-x86_64-asm.S
+++ b/linux-x86_64/crypto/ec/p256-x86_64-asm.S
@@ -894,6 +894,7 @@ ecp_nistz256_point_double:
pushq %r15
subq $160+8,%rsp
+.Lpoint_double_shortcutq:
movdqu 0(%rsi),%xmm0
movq %rsi,%rbx
movdqu 16(%rsi),%xmm1
@@ -1115,7 +1116,7 @@ ecp_nistz256_point_add:
por %xmm1,%xmm3
movdqu 0(%rsi),%xmm0
- pshufd $177,%xmm3,%xmm5
+ pshufd $0xb1,%xmm3,%xmm5
movdqu 16(%rsi),%xmm1
movdqu 32(%rsi),%xmm2
por %xmm3,%xmm5
@@ -1125,7 +1126,7 @@ ecp_nistz256_point_add:
movq 64+16(%rsi),%r15
movq 64+24(%rsi),%r8
movdqa %xmm0,480(%rsp)
- pshufd $30,%xmm5,%xmm4
+ pshufd $0x1e,%xmm5,%xmm4
movdqa %xmm1,480+16(%rsp)
por %xmm0,%xmm1
.byte 102,72,15,110,199
@@ -1145,10 +1146,10 @@ ecp_nistz256_point_add:
call __ecp_nistz256_sqr_montq
pcmpeqd %xmm4,%xmm5
- pshufd $177,%xmm3,%xmm4
+ pshufd $0xb1,%xmm3,%xmm4
por %xmm3,%xmm4
pshufd $0,%xmm5,%xmm5
- pshufd $30,%xmm4,%xmm3
+ pshufd $0x1e,%xmm4,%xmm3
por %xmm3,%xmm4
pxor %xmm3,%xmm3
pcmpeqd %xmm3,%xmm4
@@ -1157,6 +1158,7 @@ ecp_nistz256_point_add:
movq 64+8(%rbx),%r14
movq 64+16(%rbx),%r15
movq 64+24(%rbx),%r8
+.byte 102,72,15,110,203
leaq 64-0(%rbx),%rsi
leaq 32(%rsp),%rdi
@@ -1248,7 +1250,7 @@ ecp_nistz256_point_add:
testq %r8,%r8
jnz .Ladd_proceedq
testq %r9,%r9
- jz .Ladd_proceedq
+ jz .Ladd_doubleq
.byte 102,72,15,126,199
pxor %xmm0,%xmm0
@@ -1261,6 +1263,13 @@ ecp_nistz256_point_add:
jmp .Ladd_doneq
.align 32
+.Ladd_doubleq:
+.byte 102,72,15,126,206
+.byte 102,72,15,126,199
+ addq $416,%rsp
+ jmp .Lpoint_double_shortcutq
+
+.align 32
.Ladd_proceedq:
movq 0+64(%rsp),%rax
movq 8+64(%rsp),%r14
@@ -1508,13 +1517,13 @@ ecp_nistz256_point_add_affine:
por %xmm1,%xmm3
movdqu 0(%rbx),%xmm0
- pshufd $177,%xmm3,%xmm5
+ pshufd $0xb1,%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
+ pshufd $0x1e,%xmm5,%xmm4
movdqa %xmm1,416+16(%rsp)
por %xmm0,%xmm1
.byte 102,72,15,110,199
@@ -1530,13 +1539,13 @@ ecp_nistz256_point_add_affine:
call __ecp_nistz256_sqr_montq
pcmpeqd %xmm4,%xmm5
- pshufd $177,%xmm3,%xmm4
+ pshufd $0xb1,%xmm3,%xmm4
movq 0(%rbx),%rax
movq %r12,%r9
por %xmm3,%xmm4
pshufd $0,%xmm5,%xmm5
- pshufd $30,%xmm4,%xmm3
+ pshufd $0x1e,%xmm4,%xmm3
movq %r13,%r10
por %xmm3,%xmm4
pxor %xmm3,%xmm3
diff --git a/linux-x86_64/crypto/md5/md5-x86_64.S b/linux-x86_64/crypto/md5/md5-x86_64.S
index 76446896..05369e2a 100644
--- a/linux-x86_64/crypto/md5/md5-x86_64.S
+++ b/linux-x86_64/crypto/md5/md5-x86_64.S
@@ -495,14 +495,14 @@ md5_block_asm_data_order:
movl %ecx,%r11d
addl %ecx,%ebx
movl 0(%rsi),%r10d
- movl $4294967295,%r11d
+ movl $0xffffffff,%r11d
xorl %edx,%r11d
leal -198630844(%rax,%r10,1),%eax
orl %ebx,%r11d
xorl %ecx,%r11d
addl %r11d,%eax
movl 28(%rsi),%r10d
- movl $4294967295,%r11d
+ movl $0xffffffff,%r11d
roll $6,%eax
xorl %ecx,%r11d
addl %ebx,%eax
@@ -511,7 +511,7 @@ md5_block_asm_data_order:
xorl %ebx,%r11d
addl %r11d,%edx
movl 56(%rsi),%r10d
- movl $4294967295,%r11d
+ movl $0xffffffff,%r11d
roll $10,%edx
xorl %ebx,%r11d
addl %eax,%edx
@@ -520,7 +520,7 @@ md5_block_asm_data_order:
xorl %eax,%r11d
addl %r11d,%ecx
movl 20(%rsi),%r10d
- movl $4294967295,%r11d
+ movl $0xffffffff,%r11d
roll $15,%ecx
xorl %eax,%r11d
addl %edx,%ecx
@@ -529,7 +529,7 @@ md5_block_asm_data_order:
xorl %edx,%r11d
addl %r11d,%ebx
movl 48(%rsi),%r10d
- movl $4294967295,%r11d
+ movl $0xffffffff,%r11d
roll $21,%ebx
xorl %edx,%r11d
addl %ecx,%ebx
@@ -538,7 +538,7 @@ md5_block_asm_data_order:
xorl %ecx,%r11d
addl %r11d,%eax
movl 12(%rsi),%r10d
- movl $4294967295,%r11d
+ movl $0xffffffff,%r11d
roll $6,%eax
xorl %ecx,%r11d
addl %ebx,%eax
@@ -547,7 +547,7 @@ md5_block_asm_data_order:
xorl %ebx,%r11d
addl %r11d,%edx
movl 40(%rsi),%r10d
- movl $4294967295,%r11d
+ movl $0xffffffff,%r11d
roll $10,%edx
xorl %ebx,%r11d
addl %eax,%edx
@@ -556,7 +556,7 @@ md5_block_asm_data_order:
xorl %eax,%r11d
addl %r11d,%ecx
movl 4(%rsi),%r10d
- movl $4294967295,%r11d
+ movl $0xffffffff,%r11d
roll $15,%ecx
xorl %eax,%r11d
addl %edx,%ecx
@@ -565,7 +565,7 @@ md5_block_asm_data_order:
xorl %edx,%r11d
addl %r11d,%ebx
movl 32(%rsi),%r10d
- movl $4294967295,%r11d
+ movl $0xffffffff,%r11d
roll $21,%ebx
xorl %edx,%r11d
addl %ecx,%ebx
@@ -574,7 +574,7 @@ md5_block_asm_data_order:
xorl %ecx,%r11d
addl %r11d,%eax
movl 60(%rsi),%r10d
- movl $4294967295,%r11d
+ movl $0xffffffff,%r11d
roll $6,%eax
xorl %ecx,%r11d
addl %ebx,%eax
@@ -583,7 +583,7 @@ md5_block_asm_data_order:
xorl %ebx,%r11d
addl %r11d,%edx
movl 24(%rsi),%r10d
- movl $4294967295,%r11d
+ movl $0xffffffff,%r11d
roll $10,%edx
xorl %ebx,%r11d
addl %eax,%edx
@@ -592,7 +592,7 @@ md5_block_asm_data_order:
xorl %eax,%r11d
addl %r11d,%ecx
movl 52(%rsi),%r10d
- movl $4294967295,%r11d
+ movl $0xffffffff,%r11d
roll $15,%ecx
xorl %eax,%r11d
addl %edx,%ecx
@@ -601,7 +601,7 @@ md5_block_asm_data_order:
xorl %edx,%r11d
addl %r11d,%ebx
movl 16(%rsi),%r10d
- movl $4294967295,%r11d
+ movl $0xffffffff,%r11d
roll $21,%ebx
xorl %edx,%r11d
addl %ecx,%ebx
@@ -610,7 +610,7 @@ md5_block_asm_data_order:
xorl %ecx,%r11d
addl %r11d,%eax
movl 44(%rsi),%r10d
- movl $4294967295,%r11d
+ movl $0xffffffff,%r11d
roll $6,%eax
xorl %ecx,%r11d
addl %ebx,%eax
@@ -619,7 +619,7 @@ md5_block_asm_data_order:
xorl %ebx,%r11d
addl %r11d,%edx
movl 8(%rsi),%r10d
- movl $4294967295,%r11d
+ movl $0xffffffff,%r11d
roll $10,%edx
xorl %ebx,%r11d
addl %eax,%edx
@@ -628,7 +628,7 @@ md5_block_asm_data_order:
xorl %eax,%r11d
addl %r11d,%ecx
movl 36(%rsi),%r10d
- movl $4294967295,%r11d
+ movl $0xffffffff,%r11d
roll $15,%ecx
xorl %eax,%r11d
addl %edx,%ecx
@@ -637,7 +637,7 @@ md5_block_asm_data_order:
xorl %edx,%r11d
addl %r11d,%ebx
movl 0(%rsi),%r10d
- movl $4294967295,%r11d
+ movl $0xffffffff,%r11d
roll $21,%ebx
xorl %edx,%r11d
addl %ecx,%ebx
diff --git a/linux-x86_64/crypto/modes/ghash-x86_64.S b/linux-x86_64/crypto/modes/ghash-x86_64.S
index 1db7d69d..b47bdc9b 100644
--- a/linux-x86_64/crypto/modes/ghash-x86_64.S
+++ b/linux-x86_64/crypto/modes/ghash-x86_64.S
@@ -23,14 +23,14 @@ gcm_gmult_4bit:
movq $14,%rcx
movq 8(%rsi,%rax,1),%r8
movq (%rsi,%rax,1),%r9
- andb $240,%bl
+ andb $0xf0,%bl
movq %r8,%rdx
jmp .Loop1
.align 16
.Loop1:
shrq $4,%r8
- andq $15,%rdx
+ andq $0xf,%rdx
movq %r9,%r10
movb (%rdi,%rcx,1),%al
shrq $4,%r9
@@ -46,13 +46,13 @@ gcm_gmult_4bit:
js .Lbreak1
shrq $4,%r8
- andq $15,%rdx
+ andq $0xf,%rdx
movq %r9,%r10
shrq $4,%r9
xorq 8(%rsi,%rax,1),%r8
shlq $60,%r10
xorq (%rsi,%rax,1),%r9
- andb $240,%bl
+ andb $0xf0,%bl
xorq (%r11,%rdx,8),%r9
movq %r8,%rdx
xorq %r10,%r8
@@ -61,19 +61,19 @@ gcm_gmult_4bit:
.align 16
.Lbreak1:
shrq $4,%r8
- andq $15,%rdx
+ andq $0xf,%rdx
movq %r9,%r10
shrq $4,%r9
xorq 8(%rsi,%rax,1),%r8
shlq $60,%r10
xorq (%rsi,%rax,1),%r9
- andb $240,%bl
+ andb $0xf0,%bl
xorq (%r11,%rdx,8),%r9
movq %r8,%rdx
xorq %r10,%r8
shrq $4,%r8
- andq $15,%rdx
+ andq $0xf,%rdx
movq %r9,%r10
shrq $4,%r9
xorq 8(%rsi,%rbx,1),%r8
@@ -881,20 +881,20 @@ gcm_ghash_clmul:
movdqu 32(%rsi),%xmm7
.byte 102,65,15,56,0,194
- subq $16,%rcx
+ subq $0x10,%rcx
jz .Lodd_tail
movdqu 16(%rsi),%xmm6
movl OPENSSL_ia32cap_P+4(%rip),%eax
- cmpq $48,%rcx
+ cmpq $0x30,%rcx
jb .Lskip4x
andl $71303168,%eax
cmpl $4194304,%eax
je .Lskip4x
- subq $48,%rcx
- movq $11547335547999543296,%rax
+ subq $0x30,%rcx
+ movq $0xA040608020C0E000,%rax
movdqu 48(%rsi),%xmm14
movdqu 64(%rsi),%xmm15
@@ -941,7 +941,7 @@ gcm_ghash_clmul:
xorps %xmm13,%xmm5
leaq 64(%rdx),%rdx
- subq $64,%rcx
+ subq $0x40,%rcx
jc .Ltail4x
jmp .Lmod4_loop
@@ -1024,7 +1024,7 @@ gcm_ghash_clmul:
xorps %xmm13,%xmm5
leaq 64(%rdx),%rdx
- subq $64,%rcx
+ subq $0x40,%rcx
jnc .Lmod4_loop
.Ltail4x:
@@ -1068,10 +1068,10 @@ gcm_ghash_clmul:
pxor %xmm4,%xmm0
psrlq $1,%xmm0
pxor %xmm1,%xmm0
- addq $64,%rcx
+ addq $0x40,%rcx
jz .Ldone
movdqu 32(%rsi),%xmm7
- subq $16,%rcx
+ subq $0x10,%rcx
jz .Lodd_tail
.Lskip4x:
@@ -1094,7 +1094,7 @@ gcm_ghash_clmul:
leaq 32(%rdx),%rdx
nop
- subq $32,%rcx
+ subq $0x20,%rcx
jbe .Leven_tail
nop
jmp .Lmod_loop
@@ -1157,7 +1157,7 @@ gcm_ghash_clmul:
.byte 102,15,58,68,231,0
pxor %xmm1,%xmm0
- subq $32,%rcx
+ subq $0x20,%rcx
ja .Lmod_loop
.Leven_tail:
diff --git a/mac-x86/crypto/chacha/chacha-x86.S b/mac-x86/crypto/chacha/chacha-x86.S
new file mode 100644
index 00000000..9bd31b8c
--- /dev/null
+++ b/mac-x86/crypto/chacha/chacha-x86.S
@@ -0,0 +1,989 @@
+#if defined(__i386__)
+.file "chacha-x86.S"
+.text
+.globl _ChaCha20_ctr32
+.private_extern _ChaCha20_ctr32
+.align 4
+_ChaCha20_ctr32:
+L_ChaCha20_ctr32_begin:
+ pushl %ebp
+ pushl %ebx
+ pushl %esi
+ pushl %edi
+ xorl %eax,%eax
+ cmpl 28(%esp),%eax
+ je L000no_data
+ call Lpic_point
+Lpic_point:
+ popl %eax
+ movl L_OPENSSL_ia32cap_P$non_lazy_ptr-Lpic_point(%eax),%ebp
+ testl $16777216,(%ebp)
+ jz L001x86
+ testl $512,4(%ebp)
+ jz L001x86
+ jmp Lssse3_shortcut
+L001x86:
+ movl 32(%esp),%esi
+ movl 36(%esp),%edi
+ subl $132,%esp
+ movl (%esi),%eax
+ movl 4(%esi),%ebx
+ movl 8(%esi),%ecx
+ movl 12(%esi),%edx
+ movl %eax,80(%esp)
+ movl %ebx,84(%esp)
+ movl %ecx,88(%esp)
+ movl %edx,92(%esp)
+ movl 16(%esi),%eax
+ movl 20(%esi),%ebx
+ movl 24(%esi),%ecx
+ movl 28(%esi),%edx
+ movl %eax,96(%esp)
+ movl %ebx,100(%esp)
+ movl %ecx,104(%esp)
+ movl %edx,108(%esp)
+ movl (%edi),%eax
+ movl 4(%edi),%ebx
+ movl 8(%edi),%ecx
+ movl 12(%edi),%edx
+ subl $1,%eax
+ movl %eax,112(%esp)
+ movl %ebx,116(%esp)
+ movl %ecx,120(%esp)
+ movl %edx,124(%esp)
+ jmp L002entry
+.align 4,0x90
+L003outer_loop:
+ movl %ebx,156(%esp)
+ movl %eax,152(%esp)
+ movl %ecx,160(%esp)
+L002entry:
+ movl $1634760805,%eax
+ movl $857760878,4(%esp)
+ movl $2036477234,8(%esp)
+ movl $1797285236,12(%esp)
+ movl 84(%esp),%ebx
+ movl 88(%esp),%ebp
+ movl 104(%esp),%ecx
+ movl 108(%esp),%esi
+ movl 116(%esp),%edx
+ movl 120(%esp),%edi
+ movl %ebx,20(%esp)
+ movl %ebp,24(%esp)
+ movl %ecx,40(%esp)
+ movl %esi,44(%esp)
+ movl %edx,52(%esp)
+ movl %edi,56(%esp)
+ movl 92(%esp),%ebx
+ movl 124(%esp),%edi
+ movl 112(%esp),%edx
+ movl 80(%esp),%ebp
+ movl 96(%esp),%ecx
+ movl 100(%esp),%esi
+ addl $1,%edx
+ movl %ebx,28(%esp)
+ movl %edi,60(%esp)
+ movl %edx,112(%esp)
+ movl $10,%ebx
+ jmp L004loop
+.align 4,0x90
+L004loop:
+ addl %ebp,%eax
+ movl %ebx,128(%esp)
+ movl %ebp,%ebx
+ xorl %eax,%edx
+ roll $16,%edx
+ addl %edx,%ecx
+ xorl %ecx,%ebx
+ movl 52(%esp),%edi
+ roll $12,%ebx
+ movl 20(%esp),%ebp
+ addl %ebx,%eax
+ xorl %eax,%edx
+ movl %eax,(%esp)
+ roll $8,%edx
+ movl 4(%esp),%eax
+ addl %edx,%ecx
+ movl %edx,48(%esp)
+ xorl %ecx,%ebx
+ addl %ebp,%eax
+ roll $7,%ebx
+ xorl %eax,%edi
+ movl %ecx,32(%esp)
+ roll $16,%edi
+ movl %ebx,16(%esp)
+ addl %edi,%esi
+ movl 40(%esp),%ecx
+ xorl %esi,%ebp
+ movl 56(%esp),%edx
+ roll $12,%ebp
+ movl 24(%esp),%ebx
+ addl %ebp,%eax
+ xorl %eax,%edi
+ movl %eax,4(%esp)
+ roll $8,%edi
+ movl 8(%esp),%eax
+ addl %edi,%esi
+ movl %edi,52(%esp)
+ xorl %esi,%ebp
+ addl %ebx,%eax
+ roll $7,%ebp
+ xorl %eax,%edx
+ movl %esi,36(%esp)
+ roll $16,%edx
+ movl %ebp,20(%esp)
+ addl %edx,%ecx
+ movl 44(%esp),%esi
+ xorl %ecx,%ebx
+ movl 60(%esp),%edi
+ roll $12,%ebx
+ movl 28(%esp),%ebp
+ addl %ebx,%eax
+ xorl %eax,%edx
+ movl %eax,8(%esp)
+ roll $8,%edx
+ movl 12(%esp),%eax
+ addl %edx,%ecx
+ movl %edx,56(%esp)
+ xorl %ecx,%ebx
+ addl %ebp,%eax
+ roll $7,%ebx
+ xorl %eax,%edi
+ roll $16,%edi
+ movl %ebx,24(%esp)
+ addl %edi,%esi
+ xorl %esi,%ebp
+ roll $12,%ebp
+ movl 20(%esp),%ebx
+ addl %ebp,%eax
+ xorl %eax,%edi
+ movl %eax,12(%esp)
+ roll $8,%edi
+ movl (%esp),%eax
+ addl %edi,%esi
+ movl %edi,%edx
+ xorl %esi,%ebp
+ addl %ebx,%eax
+ roll $7,%ebp
+ xorl %eax,%edx
+ roll $16,%edx
+ movl %ebp,28(%esp)
+ addl %edx,%ecx
+ xorl %ecx,%ebx
+ movl 48(%esp),%edi
+ roll $12,%ebx
+ movl 24(%esp),%ebp
+ addl %ebx,%eax
+ xorl %eax,%edx
+ movl %eax,(%esp)
+ roll $8,%edx
+ movl 4(%esp),%eax
+ addl %edx,%ecx
+ movl %edx,60(%esp)
+ xorl %ecx,%ebx
+ addl %ebp,%eax
+ roll $7,%ebx
+ xorl %eax,%edi
+ movl %ecx,40(%esp)
+ roll $16,%edi
+ movl %ebx,20(%esp)
+ addl %edi,%esi
+ movl 32(%esp),%ecx
+ xorl %esi,%ebp
+ movl 52(%esp),%edx
+ roll $12,%ebp
+ movl 28(%esp),%ebx
+ addl %ebp,%eax
+ xorl %eax,%edi
+ movl %eax,4(%esp)
+ roll $8,%edi
+ movl 8(%esp),%eax
+ addl %edi,%esi
+ movl %edi,48(%esp)
+ xorl %esi,%ebp
+ addl %ebx,%eax
+ roll $7,%ebp
+ xorl %eax,%edx
+ movl %esi,44(%esp)
+ roll $16,%edx
+ movl %ebp,24(%esp)
+ addl %edx,%ecx
+ movl 36(%esp),%esi
+ xorl %ecx,%ebx
+ movl 56(%esp),%edi
+ roll $12,%ebx
+ movl 16(%esp),%ebp
+ addl %ebx,%eax
+ xorl %eax,%edx
+ movl %eax,8(%esp)
+ roll $8,%edx
+ movl 12(%esp),%eax
+ addl %edx,%ecx
+ movl %edx,52(%esp)
+ xorl %ecx,%ebx
+ addl %ebp,%eax
+ roll $7,%ebx
+ xorl %eax,%edi
+ roll $16,%edi
+ movl %ebx,28(%esp)
+ addl %edi,%esi
+ xorl %esi,%ebp
+ movl 48(%esp),%edx
+ roll $12,%ebp
+ movl 128(%esp),%ebx
+ addl %ebp,%eax
+ xorl %eax,%edi
+ movl %eax,12(%esp)
+ roll $8,%edi
+ movl (%esp),%eax
+ addl %edi,%esi
+ movl %edi,56(%esp)
+ xorl %esi,%ebp
+ roll $7,%ebp
+ decl %ebx
+ jnz L004loop
+ movl 160(%esp),%ebx
+ addl $1634760805,%eax
+ addl 80(%esp),%ebp
+ addl 96(%esp),%ecx
+ addl 100(%esp),%esi
+ cmpl $64,%ebx
+ jb L005tail
+ movl 156(%esp),%ebx
+ addl 112(%esp),%edx
+ addl 120(%esp),%edi
+ xorl (%ebx),%eax
+ xorl 16(%ebx),%ebp
+ movl %eax,(%esp)
+ movl 152(%esp),%eax
+ xorl 32(%ebx),%ecx
+ xorl 36(%ebx),%esi
+ xorl 48(%ebx),%edx
+ xorl 56(%ebx),%edi
+ movl %ebp,16(%esp)
+ movl (%esp),%ebp
+ movl %ecx,32(%esp)
+ movl %esi,36(%esp)
+ movl %edx,48(%esp)
+ movl %edi,56(%esp)
+ movl %ebp,(%eax)
+ movl 4(%esp),%ebp
+ movl 8(%esp),%ecx
+ movl 12(%esp),%esi
+ movl 20(%esp),%edx
+ movl 24(%esp),%edi
+ addl $857760878,%ebp
+ addl $2036477234,%ecx
+ addl $1797285236,%esi
+ addl 84(%esp),%edx
+ addl 88(%esp),%edi
+ xorl 4(%ebx),%ebp
+ xorl 8(%ebx),%ecx
+ xorl 12(%ebx),%esi
+ xorl 20(%ebx),%edx
+ xorl 24(%ebx),%edi
+ movl %ebp,4(%eax)
+ movl 16(%esp),%ebp
+ movl %ecx,8(%eax)
+ movl %esi,12(%eax)
+ movl %ebp,16(%eax)
+ movl %edx,20(%eax)
+ movl %edi,24(%eax)
+ movl 28(%esp),%ecx
+ movl 32(%esp),%edx
+ movl 36(%esp),%edi
+ addl 92(%esp),%ecx
+ movl 40(%esp),%ebp
+ xorl 28(%ebx),%ecx
+ movl 44(%esp),%esi
+ movl %ecx,28(%eax)
+ movl %edx,32(%eax)
+ movl %edi,36(%eax)
+ addl 104(%esp),%ebp
+ addl 108(%esp),%esi
+ xorl 40(%ebx),%ebp
+ xorl 44(%ebx),%esi
+ movl %ebp,40(%eax)
+ movl %esi,44(%eax)
+ movl 48(%esp),%ecx
+ movl 56(%esp),%esi
+ movl 52(%esp),%edx
+ movl 60(%esp),%edi
+ addl 116(%esp),%edx
+ addl 124(%esp),%edi
+ xorl 52(%ebx),%edx
+ xorl 60(%ebx),%edi
+ leal 64(%ebx),%ebx
+ movl %ecx,48(%eax)
+ movl 160(%esp),%ecx
+ movl %edx,52(%eax)
+ movl %esi,56(%eax)
+ movl %edi,60(%eax)
+ leal 64(%eax),%eax
+ subl $64,%ecx
+ jnz L003outer_loop
+ jmp L006done
+L005tail:
+ addl 112(%esp),%edx
+ addl 120(%esp),%edi
+ movl %eax,(%esp)
+ movl %ebp,16(%esp)
+ movl %ecx,32(%esp)
+ movl %esi,36(%esp)
+ movl %edx,48(%esp)
+ movl %edi,56(%esp)
+ movl 4(%esp),%ebp
+ movl 8(%esp),%ecx
+ movl 12(%esp),%esi
+ movl 20(%esp),%edx
+ movl 24(%esp),%edi
+ addl $857760878,%ebp
+ addl $2036477234,%ecx
+ addl $1797285236,%esi
+ addl 84(%esp),%edx
+ addl 88(%esp),%edi
+ movl %ebp,4(%esp)
+ movl %ecx,8(%esp)
+ movl %esi,12(%esp)
+ movl %edx,20(%esp)
+ movl %edi,24(%esp)
+ movl 28(%esp),%ebp
+ movl 40(%esp),%ecx
+ movl 44(%esp),%esi
+ movl 52(%esp),%edx
+ movl 60(%esp),%edi
+ addl 92(%esp),%ebp
+ addl 104(%esp),%ecx
+ addl 108(%esp),%esi
+ addl 116(%esp),%edx
+ addl 124(%esp),%edi
+ movl %ebp,28(%esp)
+ movl 156(%esp),%ebp
+ movl %ecx,40(%esp)
+ movl 152(%esp),%ecx
+ movl %esi,44(%esp)
+ xorl %esi,%esi
+ movl %edx,52(%esp)
+ movl %edi,60(%esp)
+ xorl %eax,%eax
+ xorl %edx,%edx
+L007tail_loop:
+ movb (%esi,%ebp,1),%al
+ movb (%esp,%esi,1),%dl
+ leal 1(%esi),%esi
+ xorb %dl,%al
+ movb %al,-1(%ecx,%esi,1)
+ decl %ebx
+ jnz L007tail_loop
+L006done:
+ addl $132,%esp
+L000no_data:
+ popl %edi
+ popl %esi
+ popl %ebx
+ popl %ebp
+ ret
+.globl _ChaCha20_ssse3
+.private_extern _ChaCha20_ssse3
+.align 4
+_ChaCha20_ssse3:
+L_ChaCha20_ssse3_begin:
+ pushl %ebp
+ pushl %ebx
+ pushl %esi
+ pushl %edi
+Lssse3_shortcut:
+ movl 20(%esp),%edi
+ movl 24(%esp),%esi
+ movl 28(%esp),%ecx
+ movl 32(%esp),%edx
+ movl 36(%esp),%ebx
+ movl %esp,%ebp
+ subl $524,%esp
+ andl $-64,%esp
+ movl %ebp,512(%esp)
+ leal Lssse3_data-Lpic_point(%eax),%eax
+ movdqu (%ebx),%xmm3
+ cmpl $256,%ecx
+ jb L0081x
+ movl %edx,516(%esp)
+ movl %ebx,520(%esp)
+ subl $256,%ecx
+ leal 384(%esp),%ebp
+ movdqu (%edx),%xmm7
+ pshufd $0,%xmm3,%xmm0
+ pshufd $85,%xmm3,%xmm1
+ pshufd $170,%xmm3,%xmm2
+ pshufd $255,%xmm3,%xmm3
+ paddd 48(%eax),%xmm0
+ pshufd $0,%xmm7,%xmm4
+ pshufd $85,%xmm7,%xmm5
+ psubd 64(%eax),%xmm0
+ pshufd $170,%xmm7,%xmm6
+ pshufd $255,%xmm7,%xmm7
+ movdqa %xmm0,64(%ebp)
+ movdqa %xmm1,80(%ebp)
+ movdqa %xmm2,96(%ebp)
+ movdqa %xmm3,112(%ebp)
+ movdqu 16(%edx),%xmm3
+ movdqa %xmm4,-64(%ebp)
+ movdqa %xmm5,-48(%ebp)
+ movdqa %xmm6,-32(%ebp)
+ movdqa %xmm7,-16(%ebp)
+ movdqa 32(%eax),%xmm7
+ leal 128(%esp),%ebx
+ pshufd $0,%xmm3,%xmm0
+ pshufd $85,%xmm3,%xmm1
+ pshufd $170,%xmm3,%xmm2
+ pshufd $255,%xmm3,%xmm3
+ pshufd $0,%xmm7,%xmm4
+ pshufd $85,%xmm7,%xmm5
+ pshufd $170,%xmm7,%xmm6
+ pshufd $255,%xmm7,%xmm7
+ movdqa %xmm0,(%ebp)
+ movdqa %xmm1,16(%ebp)
+ movdqa %xmm2,32(%ebp)
+ movdqa %xmm3,48(%ebp)
+ movdqa %xmm4,-128(%ebp)
+ movdqa %xmm5,-112(%ebp)
+ movdqa %xmm6,-96(%ebp)
+ movdqa %xmm7,-80(%ebp)
+ leal 128(%esi),%esi
+ leal 128(%edi),%edi
+ jmp L009outer_loop
+.align 4,0x90
+L009outer_loop:
+ movdqa -112(%ebp),%xmm1
+ movdqa -96(%ebp),%xmm2
+ movdqa -80(%ebp),%xmm3
+ movdqa -48(%ebp),%xmm5
+ movdqa -32(%ebp),%xmm6
+ movdqa -16(%ebp),%xmm7
+ movdqa %xmm1,-112(%ebx)
+ movdqa %xmm2,-96(%ebx)
+ movdqa %xmm3,-80(%ebx)
+ movdqa %xmm5,-48(%ebx)
+ movdqa %xmm6,-32(%ebx)
+ movdqa %xmm7,-16(%ebx)
+ movdqa 32(%ebp),%xmm2
+ movdqa 48(%ebp),%xmm3
+ movdqa 64(%ebp),%xmm4
+ movdqa 80(%ebp),%xmm5
+ movdqa 96(%ebp),%xmm6
+ movdqa 112(%ebp),%xmm7
+ paddd 64(%eax),%xmm4
+ movdqa %xmm2,32(%ebx)
+ movdqa %xmm3,48(%ebx)
+ movdqa %xmm4,64(%ebx)
+ movdqa %xmm5,80(%ebx)
+ movdqa %xmm6,96(%ebx)
+ movdqa %xmm7,112(%ebx)
+ movdqa %xmm4,64(%ebp)
+ movdqa -128(%ebp),%xmm0
+ movdqa %xmm4,%xmm6
+ movdqa -64(%ebp),%xmm3
+ movdqa (%ebp),%xmm4
+ movdqa 16(%ebp),%xmm5
+ movl $10,%edx
+ nop
+.align 4,0x90
+L010loop:
+ paddd %xmm3,%xmm0
+ movdqa %xmm3,%xmm2
+ pxor %xmm0,%xmm6
+ pshufb (%eax),%xmm6
+ paddd %xmm6,%xmm4
+ pxor %xmm4,%xmm2
+ movdqa -48(%ebx),%xmm3
+ movdqa %xmm2,%xmm1
+ pslld $12,%xmm2
+ psrld $20,%xmm1
+ por %xmm1,%xmm2
+ movdqa -112(%ebx),%xmm1
+ paddd %xmm2,%xmm0
+ movdqa 80(%ebx),%xmm7
+ pxor %xmm0,%xmm6
+ movdqa %xmm0,-128(%ebx)
+ pshufb 16(%eax),%xmm6
+ paddd %xmm6,%xmm4
+ movdqa %xmm6,64(%ebx)
+ pxor %xmm4,%xmm2
+ paddd %xmm3,%xmm1
+ movdqa %xmm2,%xmm0
+ pslld $7,%xmm2
+ psrld $25,%xmm0
+ pxor %xmm1,%xmm7
+ por %xmm0,%xmm2
+ movdqa %xmm4,(%ebx)
+ pshufb (%eax),%xmm7
+ movdqa %xmm2,-64(%ebx)
+ paddd %xmm7,%xmm5
+ movdqa 32(%ebx),%xmm4
+ pxor %xmm5,%xmm3
+ movdqa -32(%ebx),%xmm2
+ movdqa %xmm3,%xmm0
+ pslld $12,%xmm3
+ psrld $20,%xmm0
+ por %xmm0,%xmm3
+ movdqa -96(%ebx),%xmm0
+ paddd %xmm3,%xmm1
+ movdqa 96(%ebx),%xmm6
+ pxor %xmm1,%xmm7
+ movdqa %xmm1,-112(%ebx)
+ pshufb 16(%eax),%xmm7
+ paddd %xmm7,%xmm5
+ movdqa %xmm7,80(%ebx)
+ pxor %xmm5,%xmm3
+ paddd %xmm2,%xmm0
+ movdqa %xmm3,%xmm1
+ pslld $7,%xmm3
+ psrld $25,%xmm1
+ pxor %xmm0,%xmm6
+ por %xmm1,%xmm3
+ movdqa %xmm5,16(%ebx)
+ pshufb (%eax),%xmm6
+ movdqa %xmm3,-48(%ebx)
+ paddd %xmm6,%xmm4
+ movdqa 48(%ebx),%xmm5
+ pxor %xmm4,%xmm2
+ movdqa -16(%ebx),%xmm3
+ movdqa %xmm2,%xmm1
+ pslld $12,%xmm2
+ psrld $20,%xmm1
+ por %xmm1,%xmm2
+ movdqa -80(%ebx),%xmm1
+ paddd %xmm2,%xmm0
+ movdqa 112(%ebx),%xmm7
+ pxor %xmm0,%xmm6
+ movdqa %xmm0,-96(%ebx)
+ pshufb 16(%eax),%xmm6
+ paddd %xmm6,%xmm4
+ movdqa %xmm6,96(%ebx)
+ pxor %xmm4,%xmm2
+ paddd %xmm3,%xmm1
+ movdqa %xmm2,%xmm0
+ pslld $7,%xmm2
+ psrld $25,%xmm0
+ pxor %xmm1,%xmm7
+ por %xmm0,%xmm2
+ pshufb (%eax),%xmm7
+ movdqa %xmm2,-32(%ebx)
+ paddd %xmm7,%xmm5
+ pxor %xmm5,%xmm3
+ movdqa -48(%ebx),%xmm2
+ movdqa %xmm3,%xmm0
+ pslld $12,%xmm3
+ psrld $20,%xmm0
+ por %xmm0,%xmm3
+ movdqa -128(%ebx),%xmm0
+ paddd %xmm3,%xmm1
+ pxor %xmm1,%xmm7
+ movdqa %xmm1,-80(%ebx)
+ pshufb 16(%eax),%xmm7
+ paddd %xmm7,%xmm5
+ movdqa %xmm7,%xmm6
+ pxor %xmm5,%xmm3
+ paddd %xmm2,%xmm0
+ movdqa %xmm3,%xmm1
+ pslld $7,%xmm3
+ psrld $25,%xmm1
+ pxor %xmm0,%xmm6
+ por %xmm1,%xmm3
+ pshufb (%eax),%xmm6
+ movdqa %xmm3,-16(%ebx)
+ paddd %xmm6,%xmm4
+ pxor %xmm4,%xmm2
+ movdqa -32(%ebx),%xmm3
+ movdqa %xmm2,%xmm1
+ pslld $12,%xmm2
+ psrld $20,%xmm1
+ por %xmm1,%xmm2
+ movdqa -112(%ebx),%xmm1
+ paddd %xmm2,%xmm0
+ movdqa 64(%ebx),%xmm7
+ pxor %xmm0,%xmm6
+ movdqa %xmm0,-128(%ebx)
+ pshufb 16(%eax),%xmm6
+ paddd %xmm6,%xmm4
+ movdqa %xmm6,112(%ebx)
+ pxor %xmm4,%xmm2
+ paddd %xmm3,%xmm1
+ movdqa %xmm2,%xmm0
+ pslld $7,%xmm2
+ psrld $25,%xmm0
+ pxor %xmm1,%xmm7
+ por %xmm0,%xmm2
+ movdqa %xmm4,32(%ebx)
+ pshufb (%eax),%xmm7
+ movdqa %xmm2,-48(%ebx)
+ paddd %xmm7,%xmm5
+ movdqa (%ebx),%xmm4
+ pxor %xmm5,%xmm3
+ movdqa -16(%ebx),%xmm2
+ movdqa %xmm3,%xmm0
+ pslld $12,%xmm3
+ psrld $20,%xmm0
+ por %xmm0,%xmm3
+ movdqa -96(%ebx),%xmm0
+ paddd %xmm3,%xmm1
+ movdqa 80(%ebx),%xmm6
+ pxor %xmm1,%xmm7
+ movdqa %xmm1,-112(%ebx)
+ pshufb 16(%eax),%xmm7
+ paddd %xmm7,%xmm5
+ movdqa %xmm7,64(%ebx)
+ pxor %xmm5,%xmm3
+ paddd %xmm2,%xmm0
+ movdqa %xmm3,%xmm1
+ pslld $7,%xmm3
+ psrld $25,%xmm1
+ pxor %xmm0,%xmm6
+ por %xmm1,%xmm3
+ movdqa %xmm5,48(%ebx)
+ pshufb (%eax),%xmm6
+ movdqa %xmm3,-32(%ebx)
+ paddd %xmm6,%xmm4
+ movdqa 16(%ebx),%xmm5
+ pxor %xmm4,%xmm2
+ movdqa -64(%ebx),%xmm3
+ movdqa %xmm2,%xmm1
+ pslld $12,%xmm2
+ psrld $20,%xmm1
+ por %xmm1,%xmm2
+ movdqa -80(%ebx),%xmm1
+ paddd %xmm2,%xmm0
+ movdqa 96(%ebx),%xmm7
+ pxor %xmm0,%xmm6
+ movdqa %xmm0,-96(%ebx)
+ pshufb 16(%eax),%xmm6
+ paddd %xmm6,%xmm4
+ movdqa %xmm6,80(%ebx)
+ pxor %xmm4,%xmm2
+ paddd %xmm3,%xmm1
+ movdqa %xmm2,%xmm0
+ pslld $7,%xmm2
+ psrld $25,%xmm0
+ pxor %xmm1,%xmm7
+ por %xmm0,%xmm2
+ pshufb (%eax),%xmm7
+ movdqa %xmm2,-16(%ebx)
+ paddd %xmm7,%xmm5
+ pxor %xmm5,%xmm3
+ movdqa %xmm3,%xmm0
+ pslld $12,%xmm3
+ psrld $20,%xmm0
+ por %xmm0,%xmm3
+ movdqa -128(%ebx),%xmm0
+ paddd %xmm3,%xmm1
+ movdqa 64(%ebx),%xmm6
+ pxor %xmm1,%xmm7
+ movdqa %xmm1,-80(%ebx)
+ pshufb 16(%eax),%xmm7
+ paddd %xmm7,%xmm5
+ movdqa %xmm7,96(%ebx)
+ pxor %xmm5,%xmm3
+ movdqa %xmm3,%xmm1
+ pslld $7,%xmm3
+ psrld $25,%xmm1
+ por %xmm1,%xmm3
+ decl %edx
+ jnz L010loop
+ movdqa %xmm3,-64(%ebx)
+ movdqa %xmm4,(%ebx)
+ movdqa %xmm5,16(%ebx)
+ movdqa %xmm6,64(%ebx)
+ movdqa %xmm7,96(%ebx)
+ movdqa -112(%ebx),%xmm1
+ movdqa -96(%ebx),%xmm2
+ movdqa -80(%ebx),%xmm3
+ paddd -128(%ebp),%xmm0
+ paddd -112(%ebp),%xmm1
+ paddd -96(%ebp),%xmm2
+ paddd -80(%ebp),%xmm3
+ movdqa %xmm0,%xmm6
+ punpckldq %xmm1,%xmm0
+ movdqa %xmm2,%xmm7
+ punpckldq %xmm3,%xmm2
+ punpckhdq %xmm1,%xmm6
+ punpckhdq %xmm3,%xmm7
+ movdqa %xmm0,%xmm1
+ punpcklqdq %xmm2,%xmm0
+ movdqa %xmm6,%xmm3
+ punpcklqdq %xmm7,%xmm6
+ punpckhqdq %xmm2,%xmm1
+ punpckhqdq %xmm7,%xmm3
+ movdqa %xmm0,-128(%ebx)
+ movdqa -64(%ebx),%xmm0
+ movdqa %xmm1,-112(%ebx)
+ movdqa %xmm6,-96(%ebx)
+ movdqa %xmm3,-80(%ebx)
+ movdqa -48(%ebx),%xmm1
+ movdqa -32(%ebx),%xmm2
+ movdqa -16(%ebx),%xmm3
+ paddd -64(%ebp),%xmm0
+ paddd -48(%ebp),%xmm1
+ paddd -32(%ebp),%xmm2
+ paddd -16(%ebp),%xmm3
+ movdqa %xmm0,%xmm6
+ punpckldq %xmm1,%xmm0
+ movdqa %xmm2,%xmm7
+ punpckldq %xmm3,%xmm2
+ punpckhdq %xmm1,%xmm6
+ punpckhdq %xmm3,%xmm7
+ movdqa %xmm0,%xmm1
+ punpcklqdq %xmm2,%xmm0
+ movdqa %xmm6,%xmm3
+ punpcklqdq %xmm7,%xmm6
+ punpckhqdq %xmm2,%xmm1
+ punpckhqdq %xmm7,%xmm3
+ movdqa %xmm0,-64(%ebx)
+ movdqa (%ebx),%xmm0
+ movdqa %xmm1,-48(%ebx)
+ movdqa %xmm6,-32(%ebx)
+ movdqa %xmm3,-16(%ebx)
+ movdqa 16(%ebx),%xmm1
+ movdqa 32(%ebx),%xmm2
+ movdqa 48(%ebx),%xmm3
+ paddd (%ebp),%xmm0
+ paddd 16(%ebp),%xmm1
+ paddd 32(%ebp),%xmm2
+ paddd 48(%ebp),%xmm3
+ movdqa %xmm0,%xmm6
+ punpckldq %xmm1,%xmm0
+ movdqa %xmm2,%xmm7
+ punpckldq %xmm3,%xmm2
+ punpckhdq %xmm1,%xmm6
+ punpckhdq %xmm3,%xmm7
+ movdqa %xmm0,%xmm1
+ punpcklqdq %xmm2,%xmm0
+ movdqa %xmm6,%xmm3
+ punpcklqdq %xmm7,%xmm6
+ punpckhqdq %xmm2,%xmm1
+ punpckhqdq %xmm7,%xmm3
+ movdqa %xmm0,(%ebx)
+ movdqa 64(%ebx),%xmm0
+ movdqa %xmm1,16(%ebx)
+ movdqa %xmm6,32(%ebx)
+ movdqa %xmm3,48(%ebx)
+ movdqa 80(%ebx),%xmm1
+ movdqa 96(%ebx),%xmm2
+ movdqa 112(%ebx),%xmm3
+ paddd 64(%ebp),%xmm0
+ paddd 80(%ebp),%xmm1
+ paddd 96(%ebp),%xmm2
+ paddd 112(%ebp),%xmm3
+ movdqa %xmm0,%xmm6
+ punpckldq %xmm1,%xmm0
+ movdqa %xmm2,%xmm7
+ punpckldq %xmm3,%xmm2
+ punpckhdq %xmm1,%xmm6
+ punpckhdq %xmm3,%xmm7
+ movdqa %xmm0,%xmm1
+ punpcklqdq %xmm2,%xmm0
+ movdqa %xmm6,%xmm3
+ punpcklqdq %xmm7,%xmm6
+ punpckhqdq %xmm2,%xmm1
+ punpckhqdq %xmm7,%xmm3
+ movdqa %xmm0,64(%ebx)
+ movdqa %xmm1,80(%ebx)
+ movdqa %xmm6,96(%ebx)
+ movdqa %xmm3,112(%ebx)
+ movdqu -128(%esi),%xmm0
+ movdqu -112(%esi),%xmm1
+ movdqu -96(%esi),%xmm2
+ movdqu -80(%esi),%xmm3
+ pxor -128(%ebx),%xmm0
+ pxor -64(%ebx),%xmm1
+ pxor (%ebx),%xmm2
+ pxor 64(%ebx),%xmm3
+ movdqu %xmm0,-128(%edi)
+ movdqu %xmm1,-112(%edi)
+ movdqu %xmm2,-96(%edi)
+ movdqu %xmm3,-80(%edi)
+ movdqu -64(%esi),%xmm0
+ movdqu -48(%esi),%xmm1
+ movdqu -32(%esi),%xmm2
+ movdqu -16(%esi),%xmm3
+ pxor -112(%ebx),%xmm0
+ pxor -48(%ebx),%xmm1
+ pxor 16(%ebx),%xmm2
+ pxor 80(%ebx),%xmm3
+ movdqu %xmm0,-64(%edi)
+ movdqu %xmm1,-48(%edi)
+ movdqu %xmm2,-32(%edi)
+ movdqu %xmm3,-16(%edi)
+ movdqu (%esi),%xmm0
+ movdqu 16(%esi),%xmm1
+ movdqu 32(%esi),%xmm2
+ movdqu 48(%esi),%xmm3
+ pxor -96(%ebx),%xmm0
+ pxor -32(%ebx),%xmm1
+ pxor 32(%ebx),%xmm2
+ pxor 96(%ebx),%xmm3
+ movdqu %xmm0,(%edi)
+ movdqu %xmm1,16(%edi)
+ movdqu %xmm2,32(%edi)
+ movdqu %xmm3,48(%edi)
+ movdqu 64(%esi),%xmm0
+ movdqu 80(%esi),%xmm1
+ movdqu 96(%esi),%xmm2
+ movdqu 112(%esi),%xmm3
+ pxor -80(%ebx),%xmm0
+ pxor -16(%ebx),%xmm1
+ pxor 48(%ebx),%xmm2
+ pxor 112(%ebx),%xmm3
+ movdqu %xmm0,64(%edi)
+ movdqu %xmm1,80(%edi)
+ movdqu %xmm2,96(%edi)
+ movdqu %xmm3,112(%edi)
+ leal 256(%esi),%esi
+ leal 256(%edi),%edi
+ subl $256,%ecx
+ jnc L009outer_loop
+ addl $256,%ecx
+ jz L011done
+ movl 520(%esp),%ebx
+ leal -128(%esi),%esi
+ movl 516(%esp),%edx
+ leal -128(%edi),%edi
+ movd 64(%ebp),%xmm2
+ movdqu (%ebx),%xmm3
+ paddd 96(%eax),%xmm2
+ pand 112(%eax),%xmm3
+ por %xmm2,%xmm3
+L0081x:
+ movdqa 32(%eax),%xmm0
+ movdqu (%edx),%xmm1
+ movdqu 16(%edx),%xmm2
+ movdqa (%eax),%xmm6
+ movdqa 16(%eax),%xmm7
+ movl %ebp,48(%esp)
+ movdqa %xmm0,(%esp)
+ movdqa %xmm1,16(%esp)
+ movdqa %xmm2,32(%esp)
+ movdqa %xmm3,48(%esp)
+ movl $10,%edx
+ jmp L012loop1x
+.align 4,0x90
+L013outer1x:
+ movdqa 80(%eax),%xmm3
+ movdqa (%esp),%xmm0
+ movdqa 16(%esp),%xmm1
+ movdqa 32(%esp),%xmm2
+ paddd 48(%esp),%xmm3
+ movl $10,%edx
+ movdqa %xmm3,48(%esp)
+ jmp L012loop1x
+.align 4,0x90
+L012loop1x:
+ paddd %xmm1,%xmm0
+ pxor %xmm0,%xmm3
+.byte 102,15,56,0,222
+ paddd %xmm3,%xmm2
+ pxor %xmm2,%xmm1
+ movdqa %xmm1,%xmm4
+ psrld $20,%xmm1
+ pslld $12,%xmm4
+ por %xmm4,%xmm1
+ paddd %xmm1,%xmm0
+ pxor %xmm0,%xmm3
+.byte 102,15,56,0,223
+ paddd %xmm3,%xmm2
+ pxor %xmm2,%xmm1
+ movdqa %xmm1,%xmm4
+ psrld $25,%xmm1
+ pslld $7,%xmm4
+ por %xmm4,%xmm1
+ pshufd $78,%xmm2,%xmm2
+ pshufd $57,%xmm1,%xmm1
+ pshufd $147,%xmm3,%xmm3
+ nop
+ paddd %xmm1,%xmm0
+ pxor %xmm0,%xmm3
+.byte 102,15,56,0,222
+ paddd %xmm3,%xmm2
+ pxor %xmm2,%xmm1
+ movdqa %xmm1,%xmm4
+ psrld $20,%xmm1
+ pslld $12,%xmm4
+ por %xmm4,%xmm1
+ paddd %xmm1,%xmm0
+ pxor %xmm0,%xmm3
+.byte 102,15,56,0,223
+ paddd %xmm3,%xmm2
+ pxor %xmm2,%xmm1
+ movdqa %xmm1,%xmm4
+ psrld $25,%xmm1
+ pslld $7,%xmm4
+ por %xmm4,%xmm1
+ pshufd $78,%xmm2,%xmm2
+ pshufd $147,%xmm1,%xmm1
+ pshufd $57,%xmm3,%xmm3
+ decl %edx
+ jnz L012loop1x
+ paddd (%esp),%xmm0
+ paddd 16(%esp),%xmm1
+ paddd 32(%esp),%xmm2
+ paddd 48(%esp),%xmm3
+ cmpl $64,%ecx
+ jb L014tail
+ movdqu (%esi),%xmm4
+ movdqu 16(%esi),%xmm5
+ pxor %xmm4,%xmm0
+ movdqu 32(%esi),%xmm4
+ pxor %xmm5,%xmm1
+ movdqu 48(%esi),%xmm5
+ pxor %xmm4,%xmm2
+ pxor %xmm5,%xmm3
+ leal 64(%esi),%esi
+ movdqu %xmm0,(%edi)
+ movdqu %xmm1,16(%edi)
+ movdqu %xmm2,32(%edi)
+ movdqu %xmm3,48(%edi)
+ leal 64(%edi),%edi
+ subl $64,%ecx
+ jnz L013outer1x
+ jmp L011done
+L014tail:
+ movdqa %xmm0,(%esp)
+ movdqa %xmm1,16(%esp)
+ movdqa %xmm2,32(%esp)
+ movdqa %xmm3,48(%esp)
+ xorl %eax,%eax
+ xorl %edx,%edx
+ xorl %ebp,%ebp
+L015tail_loop:
+ movb (%esp,%ebp,1),%al
+ movb (%esi,%ebp,1),%dl
+ leal 1(%ebp),%ebp
+ xorb %dl,%al
+ movb %al,-1(%edi,%ebp,1)
+ decl %ecx
+ jnz L015tail_loop
+L011done:
+ movl 512(%esp),%esp
+ popl %edi
+ popl %esi
+ popl %ebx
+ popl %ebp
+ ret
+.align 6,0x90
+Lssse3_data:
+.byte 2,3,0,1,6,7,4,5,10,11,8,9,14,15,12,13
+.byte 3,0,1,2,7,4,5,6,11,8,9,10,15,12,13,14
+.long 1634760805,857760878,2036477234,1797285236
+.long 0,1,2,3
+.long 4,4,4,4
+.long 1,0,0,0
+.long 4,0,0,0
+.long 0,-1,-1,-1
+.align 6,0x90
+.byte 67,104,97,67,104,97,50,48,32,102,111,114,32,120,56,54
+.byte 44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32
+.byte 60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111
+.byte 114,103,62,0
+.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/rc4/rc4-586.S b/mac-x86/crypto/rc4/rc4-586.S
index faecdfa9..dcddc583 100644
--- a/mac-x86/crypto/rc4/rc4-586.S
+++ b/mac-x86/crypto/rc4/rc4-586.S
@@ -343,39 +343,6 @@ L015exit:
popl %ebx
popl %ebp
ret
-.globl _RC4_options
-.private_extern _RC4_options
-.align 4
-_RC4_options:
-L_RC4_options_begin:
- call L018pic_point
-L018pic_point:
- popl %eax
- leal L019opts-L018pic_point(%eax),%eax
- call L020PIC_me_up
-L020PIC_me_up:
- popl %edx
- movl L_OPENSSL_ia32cap_P$non_lazy_ptr-L020PIC_me_up(%edx),%edx
- movl (%edx),%edx
- btl $20,%edx
- jc L0211xchar
- btl $26,%edx
- jnc L022ret
- addl $25,%eax
- ret
-L0211xchar:
- addl $12,%eax
-L022ret:
- ret
-.align 6,0x90
-L019opts:
-.byte 114,99,52,40,52,120,44,105,110,116,41,0
-.byte 114,99,52,40,49,120,44,99,104,97,114,41,0
-.byte 114,99,52,40,56,120,44,109,109,120,41,0
-.byte 82,67,52,32,102,111,114,32,120,56,54,44,32,67,82,89
-.byte 80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114
-.byte 111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
-.align 6,0x90
.section __IMPORT,__pointers,non_lazy_symbol_pointers
L_OPENSSL_ia32cap_P$non_lazy_ptr:
.indirect_symbol _OPENSSL_ia32cap_P
diff --git a/mac-x86_64/crypto/aes/aes-x86_64.S b/mac-x86_64/crypto/aes/aes-x86_64.S
index 02f378bd..b5d188a0 100644
--- a/mac-x86_64/crypto/aes/aes-x86_64.S
+++ b/mac-x86_64/crypto/aes/aes-x86_64.S
@@ -82,8 +82,8 @@ L$enc_loop:
movl 0(%r14,%rdi,8),%edi
movl 0(%r14,%rbp,8),%ebp
- andl $65280,%edi
- andl $65280,%ebp
+ andl $0x0000ff00,%edi
+ andl $0x0000ff00,%ebp
xorl %edi,%r10d
xorl %ebp,%r11d
@@ -95,8 +95,8 @@ L$enc_loop:
movl 0(%r14,%rsi,8),%esi
movl 0(%r14,%rdi,8),%edi
- andl $65280,%esi
- andl $65280,%edi
+ andl $0x0000ff00,%esi
+ andl $0x0000ff00,%edi
shrl $16,%ebx
xorl %esi,%r12d
xorl %edi,%r8d
@@ -109,9 +109,9 @@ L$enc_loop:
movl 0(%r14,%rdi,8),%edi
movl 0(%r14,%rbp,8),%ebp
- andl $16711680,%esi
- andl $16711680,%edi
- andl $16711680,%ebp
+ andl $0x00ff0000,%esi
+ andl $0x00ff0000,%edi
+ andl $0x00ff0000,%ebp
xorl %esi,%r10d
xorl %edi,%r11d
@@ -124,9 +124,9 @@ L$enc_loop:
movl 2(%r14,%rdi,8),%edi
movl 2(%r14,%rbp,8),%ebp
- andl $16711680,%esi
- andl $4278190080,%edi
- andl $4278190080,%ebp
+ andl $0x00ff0000,%esi
+ andl $0xff000000,%edi
+ andl $0xff000000,%ebp
xorl %esi,%r8d
xorl %edi,%r10d
@@ -139,8 +139,8 @@ L$enc_loop:
movl 2(%r14,%rdi,8),%edi
movl 16+0(%r15),%eax
- andl $4278190080,%esi
- andl $4278190080,%edi
+ andl $0xff000000,%esi
+ andl $0xff000000,%edi
xorl %esi,%r12d
xorl %edi,%r8d
@@ -242,8 +242,8 @@ L$enc_loop_compact:
xorl %r8d,%edx
cmpq 16(%rsp),%r15
je L$enc_compact_done
- movl $2155905152,%r10d
- movl $2155905152,%r11d
+ movl $0x80808080,%r10d
+ movl $0x80808080,%r11d
andl %eax,%r10d
andl %ebx,%r11d
movl %r10d,%esi
@@ -254,10 +254,10 @@ L$enc_loop_compact:
leal (%rbx,%rbx,1),%r9d
subl %r10d,%esi
subl %r11d,%edi
- andl $4278124286,%r8d
- andl $4278124286,%r9d
- andl $454761243,%esi
- andl $454761243,%edi
+ andl $0xfefefefe,%r8d
+ andl $0xfefefefe,%r9d
+ andl $0x1b1b1b1b,%esi
+ andl $0x1b1b1b1b,%edi
movl %eax,%r10d
movl %ebx,%r11d
xorl %esi,%r8d
@@ -265,9 +265,9 @@ L$enc_loop_compact:
xorl %r8d,%eax
xorl %r9d,%ebx
- movl $2155905152,%r12d
+ movl $0x80808080,%r12d
roll $24,%eax
- movl $2155905152,%ebp
+ movl $0x80808080,%ebp
roll $24,%ebx
andl %ecx,%r12d
andl %edx,%ebp
@@ -290,10 +290,10 @@ L$enc_loop_compact:
xorl %r10d,%eax
xorl %r11d,%ebx
- andl $4278124286,%r8d
- andl $4278124286,%r9d
- andl $454761243,%esi
- andl $454761243,%edi
+ andl $0xfefefefe,%r8d
+ andl $0xfefefefe,%r9d
+ andl $0x1b1b1b1b,%esi
+ andl $0x1b1b1b1b,%edi
movl %ecx,%r12d
movl %edx,%ebp
xorl %esi,%r8d
@@ -345,7 +345,7 @@ _asm_AES_encrypt:
andq $-64,%rsp
subq %rsp,%rcx
negq %rcx
- andq $960,%rcx
+ andq $0x3c0,%rcx
subq %rcx,%rsp
subq $32,%rsp
@@ -370,7 +370,7 @@ L$enc_prologue:
leaq L$AES_Te+2048(%rip),%r14
leaq 768(%rsp),%rbp
subq %r14,%rbp
- andq $768,%rbp
+ andq $0x300,%rbp
leaq (%r14,%rbp,1),%r14
call _x86_64_AES_encrypt_compact
@@ -791,7 +791,7 @@ _asm_AES_decrypt:
andq $-64,%rsp
subq %rsp,%rcx
negq %rcx
- andq $960,%rcx
+ andq $0x3c0,%rcx
subq %rcx,%rsp
subq $32,%rsp
@@ -816,7 +816,7 @@ L$dec_prologue:
leaq L$AES_Td+2048(%rip),%r14
leaq 768(%rsp),%rbp
subq %r14,%rbp
- andq $768,%rbp
+ andq $0x300,%rbp
leaq (%r14,%rbp,1),%r14
shrq $3,%rbp
addq %rbp,%r14
@@ -1333,9 +1333,9 @@ L$cbc_picked_te:
movq %r14,%r10
leaq 2304(%r14),%r11
movq %r15,%r12
- andq $4095,%r10
- andq $4095,%r11
- andq $4095,%r12
+ andq $0xFFF,%r10
+ andq $0xFFF,%r11
+ andq $0xFFF,%r12
cmpq %r11,%r12
jb L$cbc_te_break_out
@@ -1344,7 +1344,7 @@ L$cbc_picked_te:
jmp L$cbc_te_ok
L$cbc_te_break_out:
subq %r10,%r12
- andq $4095,%r12
+ andq $0xFFF,%r12
addq $320,%r12
subq %r12,%r15
.p2align 2
@@ -1370,7 +1370,7 @@ L$cbc_fast_body:
movq %r15,%r10
subq %r14,%r10
- andq $4095,%r10
+ andq $0xfff,%r10
cmpq $2304,%r10
jb L$cbc_do_ecopy
cmpq $4096-248,%r10
@@ -1557,7 +1557,7 @@ L$cbc_slow_prologue:
leaq -88-63(%rcx),%r10
subq %rbp,%r10
negq %r10
- andq $960,%r10
+ andq $0x3c0,%r10
subq %r10,%rbp
xchgq %rsp,%rbp
@@ -1586,7 +1586,7 @@ L$cbc_slow_body:
leaq 2048(%r14),%r14
leaq 768-8(%rsp),%rax
subq %r14,%rax
- andq $768,%rax
+ andq $0x300,%rax
leaq (%r14,%rax,1),%r14
cmpq $0,%rbx
diff --git a/mac-x86_64/crypto/aes/aesni-x86_64.S b/mac-x86_64/crypto/aes/aesni-x86_64.S
index 69b22c26..3d98fa12 100644
--- a/mac-x86_64/crypto/aes/aesni-x86_64.S
+++ b/mac-x86_64/crypto/aes/aesni-x86_64.S
@@ -507,7 +507,7 @@ _aesni_ecb_encrypt:
testl %r8d,%r8d
jz L$ecb_decrypt
- cmpq $128,%rdx
+ cmpq $0x80,%rdx
jb L$ecb_enc_tail
movdqu (%rdi),%xmm2
@@ -519,7 +519,7 @@ _aesni_ecb_encrypt:
movdqu 96(%rdi),%xmm8
movdqu 112(%rdi),%xmm9
leaq 128(%rdi),%rdi
- subq $128,%rdx
+ subq $0x80,%rdx
jmp L$ecb_enc_loop8_enter
.p2align 4
L$ecb_enc_loop8:
@@ -547,7 +547,7 @@ L$ecb_enc_loop8_enter:
call _aesni_encrypt8
- subq $128,%rdx
+ subq $0x80,%rdx
jnc L$ecb_enc_loop8
movups %xmm2,(%rsi)
@@ -561,22 +561,22 @@ L$ecb_enc_loop8_enter:
movups %xmm8,96(%rsi)
movups %xmm9,112(%rsi)
leaq 128(%rsi),%rsi
- addq $128,%rdx
+ addq $0x80,%rdx
jz L$ecb_ret
L$ecb_enc_tail:
movups (%rdi),%xmm2
- cmpq $32,%rdx
+ cmpq $0x20,%rdx
jb L$ecb_enc_one
movups 16(%rdi),%xmm3
je L$ecb_enc_two
movups 32(%rdi),%xmm4
- cmpq $64,%rdx
+ cmpq $0x40,%rdx
jb L$ecb_enc_three
movups 48(%rdi),%xmm5
je L$ecb_enc_four
movups 64(%rdi),%xmm6
- cmpq $96,%rdx
+ cmpq $0x60,%rdx
jb L$ecb_enc_five
movups 80(%rdi),%xmm7
je L$ecb_enc_six
@@ -650,7 +650,7 @@ L$ecb_enc_six:
.p2align 4
L$ecb_decrypt:
- cmpq $128,%rdx
+ cmpq $0x80,%rdx
jb L$ecb_dec_tail
movdqu (%rdi),%xmm2
@@ -662,7 +662,7 @@ L$ecb_decrypt:
movdqu 96(%rdi),%xmm8
movdqu 112(%rdi),%xmm9
leaq 128(%rdi),%rdi
- subq $128,%rdx
+ subq $0x80,%rdx
jmp L$ecb_dec_loop8_enter
.p2align 4
L$ecb_dec_loop8:
@@ -691,7 +691,7 @@ L$ecb_dec_loop8_enter:
call _aesni_decrypt8
movups (%r11),%xmm0
- subq $128,%rdx
+ subq $0x80,%rdx
jnc L$ecb_dec_loop8
movups %xmm2,(%rsi)
@@ -713,22 +713,22 @@ L$ecb_dec_loop8_enter:
movups %xmm9,112(%rsi)
pxor %xmm9,%xmm9
leaq 128(%rsi),%rsi
- addq $128,%rdx
+ addq $0x80,%rdx
jz L$ecb_ret
L$ecb_dec_tail:
movups (%rdi),%xmm2
- cmpq $32,%rdx
+ cmpq $0x20,%rdx
jb L$ecb_dec_one
movups 16(%rdi),%xmm3
je L$ecb_dec_two
movups 32(%rdi),%xmm4
- cmpq $64,%rdx
+ cmpq $0x40,%rdx
jb L$ecb_dec_three
movups 48(%rdi),%xmm5
je L$ecb_dec_four
movups 64(%rdi),%xmm6
- cmpq $96,%rdx
+ cmpq $0x60,%rdx
jb L$ecb_dec_five
movups 80(%rdi),%xmm7
je L$ecb_dec_six
@@ -1606,7 +1606,7 @@ L$oop_enc1_8:
movdqa L$xts_magic(%rip),%xmm8
movdqa %xmm2,%xmm15
- pshufd $95,%xmm2,%xmm9
+ pshufd $0x5f,%xmm2,%xmm9
pxor %xmm0,%xmm1
movdqa %xmm9,%xmm14
paddd %xmm9,%xmm9
@@ -1705,7 +1705,7 @@ L$xts_enc_grandloop:
.byte 102,15,56,220,248
movups 64(%r11),%xmm0
movdqa %xmm8,80(%rsp)
- pshufd $95,%xmm15,%xmm9
+ pshufd $0x5f,%xmm15,%xmm9
jmp L$xts_enc_loop6
.p2align 5
L$xts_enc_loop6:
@@ -1844,13 +1844,13 @@ L$xts_enc_short:
jz L$xts_enc_done
pxor %xmm0,%xmm11
- cmpq $32,%rdx
+ cmpq $0x20,%rdx
jb L$xts_enc_one
pxor %xmm0,%xmm12
je L$xts_enc_two
pxor %xmm0,%xmm13
- cmpq $64,%rdx
+ cmpq $0x40,%rdx
jb L$xts_enc_three
pxor %xmm0,%xmm14
je L$xts_enc_four
@@ -2078,7 +2078,7 @@ L$oop_enc1_11:
movdqa L$xts_magic(%rip),%xmm8
movdqa %xmm2,%xmm15
- pshufd $95,%xmm2,%xmm9
+ pshufd $0x5f,%xmm2,%xmm9
pxor %xmm0,%xmm1
movdqa %xmm9,%xmm14
paddd %xmm9,%xmm9
@@ -2177,7 +2177,7 @@ L$xts_dec_grandloop:
.byte 102,15,56,222,248
movups 64(%r11),%xmm0
movdqa %xmm8,80(%rsp)
- pshufd $95,%xmm15,%xmm9
+ pshufd $0x5f,%xmm15,%xmm9
jmp L$xts_dec_loop6
.p2align 5
L$xts_dec_loop6:
@@ -2317,13 +2317,13 @@ L$xts_dec_short:
jz L$xts_dec_done
pxor %xmm0,%xmm12
- cmpq $32,%rdx
+ cmpq $0x20,%rdx
jb L$xts_dec_one
pxor %xmm0,%xmm13
je L$xts_dec_two
pxor %xmm0,%xmm14
- cmpq $64,%rdx
+ cmpq $0x40,%rdx
jb L$xts_dec_three
je L$xts_dec_four
@@ -2354,7 +2354,7 @@ L$xts_dec_short:
pcmpgtd %xmm15,%xmm14
movdqu %xmm6,64(%rsi)
leaq 80(%rsi),%rsi
- pshufd $19,%xmm14,%xmm11
+ pshufd $0x13,%xmm14,%xmm11
andq $15,%r9
jz L$xts_dec_ret
@@ -2644,7 +2644,7 @@ L$cbc_decrypt_bulk:
leaq -8(%rax),%rbp
movups (%r8),%xmm10
movl %r10d,%eax
- cmpq $80,%rdx
+ cmpq $0x50,%rdx
jbe L$cbc_dec_tail
movups (%rcx),%xmm0
@@ -2660,14 +2660,14 @@ L$cbc_decrypt_bulk:
movdqu 80(%rdi),%xmm7
movdqa %xmm6,%xmm15
movl _OPENSSL_ia32cap_P+4(%rip),%r9d
- cmpq $112,%rdx
+ cmpq $0x70,%rdx
jbe L$cbc_dec_six_or_seven
andl $71303168,%r9d
- subq $80,%rdx
+ subq $0x50,%rdx
cmpl $4194304,%r9d
je L$cbc_dec_loop6_enter
- subq $32,%rdx
+ subq $0x20,%rdx
leaq 112(%rcx),%rcx
jmp L$cbc_dec_loop8_enter
.p2align 4
@@ -2682,7 +2682,7 @@ L$cbc_dec_loop8_enter:
movups 16-112(%rcx),%xmm1
pxor %xmm0,%xmm4
xorq %r11,%r11
- cmpq $112,%rdx
+ cmpq $0x70,%rdx
pxor %xmm0,%xmm5
pxor %xmm0,%xmm6
pxor %xmm0,%xmm7
@@ -2867,21 +2867,21 @@ L$cbc_dec_done:
movups %xmm8,96(%rsi)
leaq 112(%rsi),%rsi
- subq $128,%rdx
+ subq $0x80,%rdx
ja L$cbc_dec_loop8
movaps %xmm9,%xmm2
leaq -112(%rcx),%rcx
- addq $112,%rdx
+ addq $0x70,%rdx
jle L$cbc_dec_clear_tail_collected
movups %xmm9,(%rsi)
leaq 16(%rsi),%rsi
- cmpq $80,%rdx
+ cmpq $0x50,%rdx
jbe L$cbc_dec_tail
movaps %xmm11,%xmm2
L$cbc_dec_six_or_seven:
- cmpq $96,%rdx
+ cmpq $0x60,%rdx
ja L$cbc_dec_seven
movaps %xmm7,%xmm8
@@ -2974,33 +2974,33 @@ L$cbc_dec_loop6_enter:
movl %r10d,%eax
movdqu %xmm6,64(%rsi)
leaq 80(%rsi),%rsi
- subq $96,%rdx
+ subq $0x60,%rdx
ja L$cbc_dec_loop6
movdqa %xmm7,%xmm2
- addq $80,%rdx
+ addq $0x50,%rdx
jle L$cbc_dec_clear_tail_collected
movups %xmm7,(%rsi)
leaq 16(%rsi),%rsi
L$cbc_dec_tail:
movups (%rdi),%xmm2
- subq $16,%rdx
+ subq $0x10,%rdx
jbe L$cbc_dec_one
movups 16(%rdi),%xmm3
movaps %xmm2,%xmm11
- subq $16,%rdx
+ subq $0x10,%rdx
jbe L$cbc_dec_two
movups 32(%rdi),%xmm4
movaps %xmm3,%xmm12
- subq $16,%rdx
+ subq $0x10,%rdx
jbe L$cbc_dec_three
movups 48(%rdi),%xmm5
movaps %xmm4,%xmm13
- subq $16,%rdx
+ subq $0x10,%rdx
jbe L$cbc_dec_four
movups 64(%rdi),%xmm6
@@ -3025,7 +3025,7 @@ L$cbc_dec_tail:
movdqa %xmm6,%xmm2
pxor %xmm6,%xmm6
pxor %xmm7,%xmm7
- subq $16,%rdx
+ subq $0x10,%rdx
jmp L$cbc_dec_tail_collected
.p2align 4
@@ -3344,7 +3344,7 @@ L$oop_key192:
pslldq $4,%xmm0
pxor %xmm3,%xmm0
- pshufd $255,%xmm0,%xmm3
+ pshufd $0xff,%xmm0,%xmm3
pxor %xmm1,%xmm3
pslldq $4,%xmm1
pxor %xmm1,%xmm3
@@ -3431,7 +3431,7 @@ L$oop_key256:
decl %r10d
jz L$done_key256
- pshufd $255,%xmm0,%xmm2
+ pshufd $0xff,%xmm0,%xmm2
pxor %xmm3,%xmm3
.byte 102,15,56,221,211
diff --git a/mac-x86_64/crypto/aes/bsaes-x86_64.S b/mac-x86_64/crypto/aes/bsaes-x86_64.S
index c2d04776..ad802e3d 100644
--- a/mac-x86_64/crypto/aes/bsaes-x86_64.S
+++ b/mac-x86_64/crypto/aes/bsaes-x86_64.S
@@ -325,45 +325,45 @@ L$enc_sbox:
pxor %xmm2,%xmm5
decl %r10d
jl L$enc_done
- pshufd $147,%xmm15,%xmm7
- pshufd $147,%xmm0,%xmm8
+ pshufd $0x93,%xmm15,%xmm7
+ pshufd $0x93,%xmm0,%xmm8
pxor %xmm7,%xmm15
- pshufd $147,%xmm3,%xmm9
+ pshufd $0x93,%xmm3,%xmm9
pxor %xmm8,%xmm0
- pshufd $147,%xmm5,%xmm10
+ pshufd $0x93,%xmm5,%xmm10
pxor %xmm9,%xmm3
- pshufd $147,%xmm2,%xmm11
+ pshufd $0x93,%xmm2,%xmm11
pxor %xmm10,%xmm5
- pshufd $147,%xmm6,%xmm12
+ pshufd $0x93,%xmm6,%xmm12
pxor %xmm11,%xmm2
- pshufd $147,%xmm1,%xmm13
+ pshufd $0x93,%xmm1,%xmm13
pxor %xmm12,%xmm6
- pshufd $147,%xmm4,%xmm14
+ pshufd $0x93,%xmm4,%xmm14
pxor %xmm13,%xmm1
pxor %xmm14,%xmm4
pxor %xmm15,%xmm8
pxor %xmm4,%xmm7
pxor %xmm4,%xmm8
- pshufd $78,%xmm15,%xmm15
+ pshufd $0x4E,%xmm15,%xmm15
pxor %xmm0,%xmm9
- pshufd $78,%xmm0,%xmm0
+ pshufd $0x4E,%xmm0,%xmm0
pxor %xmm2,%xmm12
pxor %xmm7,%xmm15
pxor %xmm6,%xmm13
pxor %xmm8,%xmm0
pxor %xmm5,%xmm11
- pshufd $78,%xmm2,%xmm7
+ pshufd $0x4E,%xmm2,%xmm7
pxor %xmm1,%xmm14
- pshufd $78,%xmm6,%xmm8
+ pshufd $0x4E,%xmm6,%xmm8
pxor %xmm3,%xmm10
- pshufd $78,%xmm5,%xmm2
+ pshufd $0x4E,%xmm5,%xmm2
pxor %xmm4,%xmm10
- pshufd $78,%xmm4,%xmm6
+ pshufd $0x4E,%xmm4,%xmm6
pxor %xmm4,%xmm11
- pshufd $78,%xmm1,%xmm5
+ pshufd $0x4E,%xmm1,%xmm5
pxor %xmm11,%xmm7
- pshufd $78,%xmm3,%xmm1
+ pshufd $0x4E,%xmm3,%xmm1
pxor %xmm12,%xmm8
pxor %xmm10,%xmm2
pxor %xmm14,%xmm6
@@ -797,24 +797,24 @@ L$dec_sbox:
decl %r10d
jl L$dec_done
- pshufd $78,%xmm15,%xmm7
- pshufd $78,%xmm2,%xmm13
+ pshufd $0x4E,%xmm15,%xmm7
+ pshufd $0x4E,%xmm2,%xmm13
pxor %xmm15,%xmm7
- pshufd $78,%xmm4,%xmm14
+ pshufd $0x4E,%xmm4,%xmm14
pxor %xmm2,%xmm13
- pshufd $78,%xmm0,%xmm8
+ pshufd $0x4E,%xmm0,%xmm8
pxor %xmm4,%xmm14
- pshufd $78,%xmm5,%xmm9
+ pshufd $0x4E,%xmm5,%xmm9
pxor %xmm0,%xmm8
- pshufd $78,%xmm3,%xmm10
+ pshufd $0x4E,%xmm3,%xmm10
pxor %xmm5,%xmm9
pxor %xmm13,%xmm15
pxor %xmm13,%xmm0
- pshufd $78,%xmm1,%xmm11
+ pshufd $0x4E,%xmm1,%xmm11
pxor %xmm3,%xmm10
pxor %xmm7,%xmm5
pxor %xmm8,%xmm3
- pshufd $78,%xmm6,%xmm12
+ pshufd $0x4E,%xmm6,%xmm12
pxor %xmm1,%xmm11
pxor %xmm14,%xmm0
pxor %xmm9,%xmm1
@@ -828,45 +828,45 @@ L$dec_sbox:
pxor %xmm14,%xmm1
pxor %xmm14,%xmm6
pxor %xmm12,%xmm4
- pshufd $147,%xmm15,%xmm7
- pshufd $147,%xmm0,%xmm8
+ pshufd $0x93,%xmm15,%xmm7
+ pshufd $0x93,%xmm0,%xmm8
pxor %xmm7,%xmm15
- pshufd $147,%xmm5,%xmm9
+ pshufd $0x93,%xmm5,%xmm9
pxor %xmm8,%xmm0
- pshufd $147,%xmm3,%xmm10
+ pshufd $0x93,%xmm3,%xmm10
pxor %xmm9,%xmm5
- pshufd $147,%xmm1,%xmm11
+ pshufd $0x93,%xmm1,%xmm11
pxor %xmm10,%xmm3
- pshufd $147,%xmm6,%xmm12
+ pshufd $0x93,%xmm6,%xmm12
pxor %xmm11,%xmm1
- pshufd $147,%xmm2,%xmm13
+ pshufd $0x93,%xmm2,%xmm13
pxor %xmm12,%xmm6
- pshufd $147,%xmm4,%xmm14
+ pshufd $0x93,%xmm4,%xmm14
pxor %xmm13,%xmm2
pxor %xmm14,%xmm4
pxor %xmm15,%xmm8
pxor %xmm4,%xmm7
pxor %xmm4,%xmm8
- pshufd $78,%xmm15,%xmm15
+ pshufd $0x4E,%xmm15,%xmm15
pxor %xmm0,%xmm9
- pshufd $78,%xmm0,%xmm0
+ pshufd $0x4E,%xmm0,%xmm0
pxor %xmm1,%xmm12
pxor %xmm7,%xmm15
pxor %xmm6,%xmm13
pxor %xmm8,%xmm0
pxor %xmm3,%xmm11
- pshufd $78,%xmm1,%xmm7
+ pshufd $0x4E,%xmm1,%xmm7
pxor %xmm2,%xmm14
- pshufd $78,%xmm6,%xmm8
+ pshufd $0x4E,%xmm6,%xmm8
pxor %xmm5,%xmm10
- pshufd $78,%xmm3,%xmm1
+ pshufd $0x4E,%xmm3,%xmm1
pxor %xmm4,%xmm10
- pshufd $78,%xmm4,%xmm6
+ pshufd $0x4E,%xmm4,%xmm6
pxor %xmm4,%xmm11
- pshufd $78,%xmm2,%xmm3
+ pshufd $0x4E,%xmm2,%xmm3
pxor %xmm11,%xmm7
- pshufd $78,%xmm5,%xmm2
+ pshufd $0x4E,%xmm5,%xmm2
pxor %xmm12,%xmm8
pxor %xmm1,%xmm10
pxor %xmm14,%xmm6
@@ -1556,20 +1556,20 @@ L$xts_enc_prologue:
movdqa %xmm7,(%rax)
andq $-16,%r14
- subq $128,%rsp
+ subq $0x80,%rsp
movdqa 32(%rbp),%xmm6
pxor %xmm14,%xmm14
movdqa L$xts_magic(%rip),%xmm12
pcmpgtd %xmm6,%xmm14
- subq $128,%r14
+ subq $0x80,%r14
jc L$xts_enc_short
jmp L$xts_enc_loop
.p2align 4
L$xts_enc_loop:
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm15
movdqa %xmm6,0(%rsp)
@@ -1577,7 +1577,7 @@ L$xts_enc_loop:
pand %xmm12,%xmm13
pcmpgtd %xmm6,%xmm14
pxor %xmm13,%xmm6
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm0
movdqa %xmm6,16(%rsp)
@@ -1586,7 +1586,7 @@ L$xts_enc_loop:
pcmpgtd %xmm6,%xmm14
pxor %xmm13,%xmm6
movdqu 0(%r12),%xmm7
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm1
movdqa %xmm6,32(%rsp)
@@ -1596,7 +1596,7 @@ L$xts_enc_loop:
pxor %xmm13,%xmm6
movdqu 16(%r12),%xmm8
pxor %xmm7,%xmm15
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm2
movdqa %xmm6,48(%rsp)
@@ -1606,7 +1606,7 @@ L$xts_enc_loop:
pxor %xmm13,%xmm6
movdqu 32(%r12),%xmm9
pxor %xmm8,%xmm0
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm3
movdqa %xmm6,64(%rsp)
@@ -1616,7 +1616,7 @@ L$xts_enc_loop:
pxor %xmm13,%xmm6
movdqu 48(%r12),%xmm10
pxor %xmm9,%xmm1
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm4
movdqa %xmm6,80(%rsp)
@@ -1626,7 +1626,7 @@ L$xts_enc_loop:
pxor %xmm13,%xmm6
movdqu 64(%r12),%xmm11
pxor %xmm10,%xmm2
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm5
movdqa %xmm6,96(%rsp)
@@ -1670,20 +1670,20 @@ L$xts_enc_loop:
pxor %xmm14,%xmm14
movdqa L$xts_magic(%rip),%xmm12
pcmpgtd %xmm6,%xmm14
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
paddq %xmm6,%xmm6
pand %xmm12,%xmm13
pcmpgtd %xmm6,%xmm14
pxor %xmm13,%xmm6
- subq $128,%r14
+ subq $0x80,%r14
jnc L$xts_enc_loop
L$xts_enc_short:
- addq $128,%r14
+ addq $0x80,%r14
jz L$xts_enc_done
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm15
movdqa %xmm6,0(%rsp)
@@ -1691,7 +1691,7 @@ L$xts_enc_short:
pand %xmm12,%xmm13
pcmpgtd %xmm6,%xmm14
pxor %xmm13,%xmm6
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm0
movdqa %xmm6,16(%rsp)
@@ -1702,7 +1702,7 @@ L$xts_enc_short:
movdqu 0(%r12),%xmm7
cmpq $16,%r14
je L$xts_enc_1
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm1
movdqa %xmm6,32(%rsp)
@@ -1714,7 +1714,7 @@ L$xts_enc_short:
cmpq $32,%r14
je L$xts_enc_2
pxor %xmm7,%xmm15
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm2
movdqa %xmm6,48(%rsp)
@@ -1726,7 +1726,7 @@ L$xts_enc_short:
cmpq $48,%r14
je L$xts_enc_3
pxor %xmm8,%xmm0
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm3
movdqa %xmm6,64(%rsp)
@@ -1738,7 +1738,7 @@ L$xts_enc_short:
cmpq $64,%r14
je L$xts_enc_4
pxor %xmm9,%xmm1
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm4
movdqa %xmm6,80(%rsp)
@@ -1750,7 +1750,7 @@ L$xts_enc_short:
cmpq $80,%r14
je L$xts_enc_5
pxor %xmm10,%xmm2
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm5
movdqa %xmm6,96(%rsp)
@@ -2016,20 +2016,20 @@ L$xts_dec_prologue:
shlq $4,%rax
subq %rax,%r14
- subq $128,%rsp
+ subq $0x80,%rsp
movdqa 32(%rbp),%xmm6
pxor %xmm14,%xmm14
movdqa L$xts_magic(%rip),%xmm12
pcmpgtd %xmm6,%xmm14
- subq $128,%r14
+ subq $0x80,%r14
jc L$xts_dec_short
jmp L$xts_dec_loop
.p2align 4
L$xts_dec_loop:
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm15
movdqa %xmm6,0(%rsp)
@@ -2037,7 +2037,7 @@ L$xts_dec_loop:
pand %xmm12,%xmm13
pcmpgtd %xmm6,%xmm14
pxor %xmm13,%xmm6
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm0
movdqa %xmm6,16(%rsp)
@@ -2046,7 +2046,7 @@ L$xts_dec_loop:
pcmpgtd %xmm6,%xmm14
pxor %xmm13,%xmm6
movdqu 0(%r12),%xmm7
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm1
movdqa %xmm6,32(%rsp)
@@ -2056,7 +2056,7 @@ L$xts_dec_loop:
pxor %xmm13,%xmm6
movdqu 16(%r12),%xmm8
pxor %xmm7,%xmm15
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm2
movdqa %xmm6,48(%rsp)
@@ -2066,7 +2066,7 @@ L$xts_dec_loop:
pxor %xmm13,%xmm6
movdqu 32(%r12),%xmm9
pxor %xmm8,%xmm0
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm3
movdqa %xmm6,64(%rsp)
@@ -2076,7 +2076,7 @@ L$xts_dec_loop:
pxor %xmm13,%xmm6
movdqu 48(%r12),%xmm10
pxor %xmm9,%xmm1
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm4
movdqa %xmm6,80(%rsp)
@@ -2086,7 +2086,7 @@ L$xts_dec_loop:
pxor %xmm13,%xmm6
movdqu 64(%r12),%xmm11
pxor %xmm10,%xmm2
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm5
movdqa %xmm6,96(%rsp)
@@ -2130,20 +2130,20 @@ L$xts_dec_loop:
pxor %xmm14,%xmm14
movdqa L$xts_magic(%rip),%xmm12
pcmpgtd %xmm6,%xmm14
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
paddq %xmm6,%xmm6
pand %xmm12,%xmm13
pcmpgtd %xmm6,%xmm14
pxor %xmm13,%xmm6
- subq $128,%r14
+ subq $0x80,%r14
jnc L$xts_dec_loop
L$xts_dec_short:
- addq $128,%r14
+ addq $0x80,%r14
jz L$xts_dec_done
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm15
movdqa %xmm6,0(%rsp)
@@ -2151,7 +2151,7 @@ L$xts_dec_short:
pand %xmm12,%xmm13
pcmpgtd %xmm6,%xmm14
pxor %xmm13,%xmm6
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm0
movdqa %xmm6,16(%rsp)
@@ -2162,7 +2162,7 @@ L$xts_dec_short:
movdqu 0(%r12),%xmm7
cmpq $16,%r14
je L$xts_dec_1
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm1
movdqa %xmm6,32(%rsp)
@@ -2174,7 +2174,7 @@ L$xts_dec_short:
cmpq $32,%r14
je L$xts_dec_2
pxor %xmm7,%xmm15
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm2
movdqa %xmm6,48(%rsp)
@@ -2186,7 +2186,7 @@ L$xts_dec_short:
cmpq $48,%r14
je L$xts_dec_3
pxor %xmm8,%xmm0
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm3
movdqa %xmm6,64(%rsp)
@@ -2198,7 +2198,7 @@ L$xts_dec_short:
cmpq $64,%r14
je L$xts_dec_4
pxor %xmm9,%xmm1
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm4
movdqa %xmm6,80(%rsp)
@@ -2210,7 +2210,7 @@ L$xts_dec_short:
cmpq $80,%r14
je L$xts_dec_5
pxor %xmm10,%xmm2
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
pxor %xmm14,%xmm14
movdqa %xmm6,%xmm5
movdqa %xmm6,96(%rsp)
@@ -2387,7 +2387,7 @@ L$xts_dec_done:
pxor %xmm14,%xmm14
movdqa L$xts_magic(%rip),%xmm12
pcmpgtd %xmm6,%xmm14
- pshufd $19,%xmm14,%xmm13
+ pshufd $0x13,%xmm14,%xmm13
movdqa %xmm6,%xmm5
paddq %xmm6,%xmm6
pand %xmm12,%xmm13
diff --git a/mac-x86_64/crypto/aes/vpaes-x86_64.S b/mac-x86_64/crypto/aes/vpaes-x86_64.S
index 711ea437..997cde80 100644
--- a/mac-x86_64/crypto/aes/vpaes-x86_64.S
+++ b/mac-x86_64/crypto/aes/vpaes-x86_64.S
@@ -61,7 +61,7 @@ L$enc_loop:
addq $16,%r11
pxor %xmm0,%xmm3
.byte 102,15,56,0,193
- andq $48,%r11
+ andq $0x30,%r11
subq $1,%rax
pxor %xmm3,%xmm0
@@ -121,10 +121,10 @@ _vpaes_decrypt_core:
pand %xmm9,%xmm0
.byte 102,15,56,0,208
movdqa L$k_dipt+16(%rip),%xmm0
- xorq $48,%r11
+ xorq $0x30,%r11
leaq L$k_dsbd(%rip),%r10
.byte 102,15,56,0,193
- andq $48,%r11
+ andq $0x30,%r11
pxor %xmm5,%xmm2
movdqa L$k_mc_forward+48(%rip),%xmm5
pxor %xmm2,%xmm0
@@ -243,7 +243,7 @@ L$schedule_am_decrypting:
movdqa (%r8,%r10,1),%xmm1
.byte 102,15,56,0,217
movdqu %xmm3,(%rdx)
- xorq $48,%r8
+ xorq $0x30,%r8
L$schedule_go:
cmpl $192,%esi
@@ -333,7 +333,7 @@ L$oop_schedule_256:
call _vpaes_schedule_mangle
- pshufd $255,%xmm0,%xmm0
+ pshufd $0xFF,%xmm0,%xmm0
movdqa %xmm7,%xmm5
movdqa %xmm6,%xmm7
call _vpaes_schedule_low_round
@@ -400,8 +400,8 @@ L$schedule_mangle_last_dec:
.p2align 4
_vpaes_schedule_192_smear:
- pshufd $128,%xmm6,%xmm1
- pshufd $254,%xmm7,%xmm0
+ pshufd $0x80,%xmm6,%xmm1
+ pshufd $0xFE,%xmm7,%xmm0
pxor %xmm1,%xmm6
pxor %xmm1,%xmm1
pxor %xmm0,%xmm6
@@ -438,7 +438,7 @@ _vpaes_schedule_round:
pxor %xmm1,%xmm7
- pshufd $255,%xmm0,%xmm0
+ pshufd $0xFF,%xmm0,%xmm0
.byte 102,15,58,15,192,1
@@ -597,7 +597,7 @@ L$schedule_mangle_both:
movdqa (%r8,%r10,1),%xmm1
.byte 102,15,56,0,217
addq $-16,%r8
- andq $48,%r8
+ andq $0x30,%r8
movdqu %xmm3,(%rdx)
.byte 0xf3,0xc3
@@ -616,7 +616,7 @@ _vpaes_set_encrypt_key:
movl %eax,240(%rdx)
movl $0,%ecx
- movl $48,%r8d
+ movl $0x30,%r8d
call _vpaes_schedule_core
xorl %eax,%eax
.byte 0xf3,0xc3
diff --git a/mac-x86_64/crypto/bn/rsaz-x86_64.S b/mac-x86_64/crypto/bn/rsaz-x86_64.S
index 5e9e82fe..337276f9 100644
--- a/mac-x86_64/crypto/bn/rsaz-x86_64.S
+++ b/mac-x86_64/crypto/bn/rsaz-x86_64.S
@@ -465,48 +465,94 @@ _rsaz_512_mul_gather4:
pushq %r14
pushq %r15
- movl %r9d,%r9d
- subq $128+24,%rsp
+ subq $152,%rsp
L$mul_gather4_body:
- movl 64(%rdx,%r9,4),%eax
-.byte 102,72,15,110,199
- movl (%rdx,%r9,4),%ebx
-.byte 102,72,15,110,201
+ movd %r9d,%xmm8
+ movdqa L$inc+16(%rip),%xmm1
+ movdqa L$inc(%rip),%xmm0
+
+ pshufd $0,%xmm8,%xmm8
+ movdqa %xmm1,%xmm7
+ movdqa %xmm1,%xmm2
+ paddd %xmm0,%xmm1
+ pcmpeqd %xmm8,%xmm0
+ movdqa %xmm7,%xmm3
+ paddd %xmm1,%xmm2
+ pcmpeqd %xmm8,%xmm1
+ movdqa %xmm7,%xmm4
+ paddd %xmm2,%xmm3
+ pcmpeqd %xmm8,%xmm2
+ movdqa %xmm7,%xmm5
+ paddd %xmm3,%xmm4
+ pcmpeqd %xmm8,%xmm3
+ movdqa %xmm7,%xmm6
+ paddd %xmm4,%xmm5
+ pcmpeqd %xmm8,%xmm4
+ paddd %xmm5,%xmm6
+ pcmpeqd %xmm8,%xmm5
+ paddd %xmm6,%xmm7
+ pcmpeqd %xmm8,%xmm6
+ pcmpeqd %xmm8,%xmm7
+
+ movdqa 0(%rdx),%xmm8
+ movdqa 16(%rdx),%xmm9
+ movdqa 32(%rdx),%xmm10
+ movdqa 48(%rdx),%xmm11
+ pand %xmm0,%xmm8
+ movdqa 64(%rdx),%xmm12
+ pand %xmm1,%xmm9
+ movdqa 80(%rdx),%xmm13
+ pand %xmm2,%xmm10
+ movdqa 96(%rdx),%xmm14
+ pand %xmm3,%xmm11
+ movdqa 112(%rdx),%xmm15
+ leaq 128(%rdx),%rbp
+ pand %xmm4,%xmm12
+ pand %xmm5,%xmm13
+ pand %xmm6,%xmm14
+ pand %xmm7,%xmm15
+ por %xmm10,%xmm8
+ por %xmm11,%xmm9
+ por %xmm12,%xmm8
+ por %xmm13,%xmm9
+ por %xmm14,%xmm8
+ por %xmm15,%xmm9
+
+ por %xmm9,%xmm8
+ pshufd $0x4e,%xmm8,%xmm9
+ por %xmm9,%xmm8
+.byte 102,76,15,126,195
+
movq %r8,128(%rsp)
+ movq %rdi,128+8(%rsp)
+ movq %rcx,128+16(%rsp)
- shlq $32,%rax
- orq %rax,%rbx
movq (%rsi),%rax
movq 8(%rsi),%rcx
- leaq 128(%rdx,%r9,4),%rbp
mulq %rbx
movq %rax,(%rsp)
movq %rcx,%rax
movq %rdx,%r8
mulq %rbx
- movd (%rbp),%xmm4
addq %rax,%r8
movq 16(%rsi),%rax
movq %rdx,%r9
adcq $0,%r9
mulq %rbx
- movd 64(%rbp),%xmm5
addq %rax,%r9
movq 24(%rsi),%rax
movq %rdx,%r10
adcq $0,%r10
mulq %rbx
- pslldq $4,%xmm5
addq %rax,%r10
movq 32(%rsi),%rax
movq %rdx,%r11
adcq $0,%r11
mulq %rbx
- por %xmm5,%xmm4
addq %rax,%r11
movq 40(%rsi),%rax
movq %rdx,%r12
@@ -519,14 +565,12 @@ L$mul_gather4_body:
adcq $0,%r13
mulq %rbx
- leaq 128(%rbp),%rbp
addq %rax,%r13
movq 56(%rsi),%rax
movq %rdx,%r14
adcq $0,%r14
mulq %rbx
-.byte 102,72,15,126,227
addq %rax,%r14
movq (%rsi),%rax
movq %rdx,%r15
@@ -538,6 +582,35 @@ L$mul_gather4_body:
.p2align 5
L$oop_mul_gather:
+ movdqa 0(%rbp),%xmm8
+ movdqa 16(%rbp),%xmm9
+ movdqa 32(%rbp),%xmm10
+ movdqa 48(%rbp),%xmm11
+ pand %xmm0,%xmm8
+ movdqa 64(%rbp),%xmm12
+ pand %xmm1,%xmm9
+ movdqa 80(%rbp),%xmm13
+ pand %xmm2,%xmm10
+ movdqa 96(%rbp),%xmm14
+ pand %xmm3,%xmm11
+ movdqa 112(%rbp),%xmm15
+ leaq 128(%rbp),%rbp
+ pand %xmm4,%xmm12
+ pand %xmm5,%xmm13
+ pand %xmm6,%xmm14
+ pand %xmm7,%xmm15
+ por %xmm10,%xmm8
+ por %xmm11,%xmm9
+ por %xmm12,%xmm8
+ por %xmm13,%xmm9
+ por %xmm14,%xmm8
+ por %xmm15,%xmm9
+
+ por %xmm9,%xmm8
+ pshufd $0x4e,%xmm8,%xmm9
+ por %xmm9,%xmm8
+.byte 102,76,15,126,195
+
mulq %rbx
addq %rax,%r8
movq 8(%rsi),%rax
@@ -546,7 +619,6 @@ L$oop_mul_gather:
adcq $0,%r8
mulq %rbx
- movd (%rbp),%xmm4
addq %rax,%r9
movq 16(%rsi),%rax
adcq $0,%rdx
@@ -555,7 +627,6 @@ L$oop_mul_gather:
adcq $0,%r9
mulq %rbx
- movd 64(%rbp),%xmm5
addq %rax,%r10
movq 24(%rsi),%rax
adcq $0,%rdx
@@ -564,7 +635,6 @@ L$oop_mul_gather:
adcq $0,%r10
mulq %rbx
- pslldq $4,%xmm5
addq %rax,%r11
movq 32(%rsi),%rax
adcq $0,%rdx
@@ -573,7 +643,6 @@ L$oop_mul_gather:
adcq $0,%r11
mulq %rbx
- por %xmm5,%xmm4
addq %rax,%r12
movq 40(%rsi),%rax
adcq $0,%rdx
@@ -598,7 +667,6 @@ L$oop_mul_gather:
adcq $0,%r14
mulq %rbx
-.byte 102,72,15,126,227
addq %rax,%r15
movq (%rsi),%rax
adcq $0,%rdx
@@ -606,7 +674,6 @@ L$oop_mul_gather:
movq %rdx,%r15
adcq $0,%r15
- leaq 128(%rbp),%rbp
leaq 8(%rdi),%rdi
decl %ecx
@@ -621,8 +688,8 @@ L$oop_mul_gather:
movq %r14,48(%rdi)
movq %r15,56(%rdi)
-.byte 102,72,15,126,199
-.byte 102,72,15,126,205
+ movq 128+8(%rsp),%rdi
+ movq 128+16(%rsp),%rbp
movq (%rsp),%r8
movq 8(%rsp),%r9
@@ -672,7 +739,7 @@ _rsaz_512_mul_scatter4:
movl %r9d,%r9d
subq $128+24,%rsp
L$mul_scatter4_body:
- leaq (%r8,%r9,4),%r8
+ leaq (%r8,%r9,8),%r8
.byte 102,72,15,110,199
.byte 102,72,15,110,202
.byte 102,73,15,110,208
@@ -708,30 +775,14 @@ L$mul_scatter4_body:
call __rsaz_512_subtract
- movl %r8d,0(%rsi)
- shrq $32,%r8
- movl %r9d,128(%rsi)
- shrq $32,%r9
- movl %r10d,256(%rsi)
- shrq $32,%r10
- movl %r11d,384(%rsi)
- shrq $32,%r11
- movl %r12d,512(%rsi)
- shrq $32,%r12
- movl %r13d,640(%rsi)
- shrq $32,%r13
- movl %r14d,768(%rsi)
- shrq $32,%r14
- movl %r15d,896(%rsi)
- shrq $32,%r15
- movl %r8d,64(%rsi)
- movl %r9d,192(%rsi)
- movl %r10d,320(%rsi)
- movl %r11d,448(%rsi)
- movl %r12d,576(%rsi)
- movl %r13d,704(%rsi)
- movl %r14d,832(%rsi)
- movl %r15d,960(%rsi)
+ movq %r8,0(%rsi)
+ movq %r9,128(%rsi)
+ movq %r10,256(%rsi)
+ movq %r11,384(%rsi)
+ movq %r12,512(%rsi)
+ movq %r13,640(%rsi)
+ movq %r14,768(%rsi)
+ movq %r15,896(%rsi)
leaq 128+24+48(%rsp),%rax
movq -48(%rax),%r15
@@ -1086,16 +1137,14 @@ L$oop_mul:
.p2align 4
_rsaz_512_scatter4:
- leaq (%rdi,%rdx,4),%rdi
+ leaq (%rdi,%rdx,8),%rdi
movl $8,%r9d
jmp L$oop_scatter
.p2align 4
L$oop_scatter:
movq (%rsi),%rax
leaq 8(%rsi),%rsi
- movl %eax,(%rdi)
- shrq $32,%rax
- movl %eax,64(%rdi)
+ movq %rax,(%rdi)
leaq 128(%rdi),%rdi
decl %r9d
jnz L$oop_scatter
@@ -1107,20 +1156,73 @@ L$oop_scatter:
.p2align 4
_rsaz_512_gather4:
- leaq (%rsi,%rdx,4),%rsi
+ movd %edx,%xmm8
+ movdqa L$inc+16(%rip),%xmm1
+ movdqa L$inc(%rip),%xmm0
+
+ pshufd $0,%xmm8,%xmm8
+ movdqa %xmm1,%xmm7
+ movdqa %xmm1,%xmm2
+ paddd %xmm0,%xmm1
+ pcmpeqd %xmm8,%xmm0
+ movdqa %xmm7,%xmm3
+ paddd %xmm1,%xmm2
+ pcmpeqd %xmm8,%xmm1
+ movdqa %xmm7,%xmm4
+ paddd %xmm2,%xmm3
+ pcmpeqd %xmm8,%xmm2
+ movdqa %xmm7,%xmm5
+ paddd %xmm3,%xmm4
+ pcmpeqd %xmm8,%xmm3
+ movdqa %xmm7,%xmm6
+ paddd %xmm4,%xmm5
+ pcmpeqd %xmm8,%xmm4
+ paddd %xmm5,%xmm6
+ pcmpeqd %xmm8,%xmm5
+ paddd %xmm6,%xmm7
+ pcmpeqd %xmm8,%xmm6
+ pcmpeqd %xmm8,%xmm7
movl $8,%r9d
jmp L$oop_gather
.p2align 4
L$oop_gather:
- movl (%rsi),%eax
- movl 64(%rsi),%r8d
+ movdqa 0(%rsi),%xmm8
+ movdqa 16(%rsi),%xmm9
+ movdqa 32(%rsi),%xmm10
+ movdqa 48(%rsi),%xmm11
+ pand %xmm0,%xmm8
+ movdqa 64(%rsi),%xmm12
+ pand %xmm1,%xmm9
+ movdqa 80(%rsi),%xmm13
+ pand %xmm2,%xmm10
+ movdqa 96(%rsi),%xmm14
+ pand %xmm3,%xmm11
+ movdqa 112(%rsi),%xmm15
leaq 128(%rsi),%rsi
- shlq $32,%r8
- orq %r8,%rax
- movq %rax,(%rdi)
+ pand %xmm4,%xmm12
+ pand %xmm5,%xmm13
+ pand %xmm6,%xmm14
+ pand %xmm7,%xmm15
+ por %xmm10,%xmm8
+ por %xmm11,%xmm9
+ por %xmm12,%xmm8
+ por %xmm13,%xmm9
+ por %xmm14,%xmm8
+ por %xmm15,%xmm9
+
+ por %xmm9,%xmm8
+ pshufd $0x4e,%xmm8,%xmm9
+ por %xmm9,%xmm8
+ movq %xmm8,(%rdi)
leaq 8(%rdi),%rdi
decl %r9d
jnz L$oop_gather
.byte 0xf3,0xc3
+L$SEH_end_rsaz_512_gather4:
+
+.p2align 6
+L$inc:
+.long 0,0, 1,1
+.long 2,2, 2,2
#endif
diff --git a/mac-x86_64/crypto/bn/x86_64-mont.S b/mac-x86_64/crypto/bn/x86_64-mont.S
index 6b9bc05b..51e5d199 100644
--- a/mac-x86_64/crypto/bn/x86_64-mont.S
+++ b/mac-x86_64/crypto/bn/x86_64-mont.S
@@ -634,20 +634,20 @@ L$sqr8x_enter:
- leaq -64(%rsp,%r9,4),%r11
+ leaq -64(%rsp,%r9,2),%r11
movq (%r8),%r8
subq %rsi,%r11
andq $4095,%r11
cmpq %r11,%r10
jb L$sqr8x_sp_alt
subq %r11,%rsp
- leaq -64(%rsp,%r9,4),%rsp
+ leaq -64(%rsp,%r9,2),%rsp
jmp L$sqr8x_sp_done
.p2align 5
L$sqr8x_sp_alt:
- leaq 4096-64(,%r9,4),%r10
- leaq -64(%rsp,%r9,4),%rsp
+ leaq 4096-64(,%r9,2),%r10
+ leaq -64(%rsp,%r9,2),%rsp
subq %r10,%r11
movq $0,%r10
cmovcq %r10,%r11
@@ -657,58 +657,80 @@ L$sqr8x_sp_done:
movq %r9,%r10
negq %r9
- leaq 64(%rsp,%r9,2),%r11
movq %r8,32(%rsp)
movq %rax,40(%rsp)
L$sqr8x_body:
- movq %r9,%rbp
-.byte 102,73,15,110,211
- shrq $3+2,%rbp
- movl _OPENSSL_ia32cap_P+8(%rip),%eax
- jmp L$sqr8x_copy_n
-
-.p2align 5
-L$sqr8x_copy_n:
- movq 0(%rcx),%xmm0
- movq 8(%rcx),%xmm1
- movq 16(%rcx),%xmm3
- movq 24(%rcx),%xmm4
- leaq 32(%rcx),%rcx
- movdqa %xmm0,0(%r11)
- movdqa %xmm1,16(%r11)
- movdqa %xmm3,32(%r11)
- movdqa %xmm4,48(%r11)
- leaq 64(%r11),%r11
- decq %rbp
- jnz L$sqr8x_copy_n
-
+.byte 102,72,15,110,209
pxor %xmm0,%xmm0
.byte 102,72,15,110,207
.byte 102,73,15,110,218
call _bn_sqr8x_internal
+
+
+
+ leaq (%rdi,%r9,1),%rbx
+ movq %r9,%rcx
+ movq %r9,%rdx
+.byte 102,72,15,126,207
+ sarq $3+2,%rcx
+ jmp L$sqr8x_sub
+
+.p2align 5
+L$sqr8x_sub:
+ movq 0(%rbx),%r12
+ movq 8(%rbx),%r13
+ movq 16(%rbx),%r14
+ movq 24(%rbx),%r15
+ leaq 32(%rbx),%rbx
+ sbbq 0(%rbp),%r12
+ sbbq 8(%rbp),%r13
+ sbbq 16(%rbp),%r14
+ sbbq 24(%rbp),%r15
+ leaq 32(%rbp),%rbp
+ movq %r12,0(%rdi)
+ movq %r13,8(%rdi)
+ movq %r14,16(%rdi)
+ movq %r15,24(%rdi)
+ leaq 32(%rdi),%rdi
+ incq %rcx
+ jnz L$sqr8x_sub
+
+ sbbq $0,%rax
+ leaq (%rbx,%r9,1),%rbx
+ leaq (%rdi,%r9,1),%rdi
+
+.byte 102,72,15,110,200
pxor %xmm0,%xmm0
- leaq 48(%rsp),%rax
- leaq 64(%rsp,%r9,2),%rdx
- shrq $3+2,%r9
+ pshufd $0,%xmm1,%xmm1
movq 40(%rsp),%rsi
- jmp L$sqr8x_zero
+ jmp L$sqr8x_cond_copy
.p2align 5
-L$sqr8x_zero:
- movdqa %xmm0,0(%rax)
- movdqa %xmm0,16(%rax)
- movdqa %xmm0,32(%rax)
- movdqa %xmm0,48(%rax)
- leaq 64(%rax),%rax
- movdqa %xmm0,0(%rdx)
- movdqa %xmm0,16(%rdx)
- movdqa %xmm0,32(%rdx)
- movdqa %xmm0,48(%rdx)
- leaq 64(%rdx),%rdx
- decq %r9
- jnz L$sqr8x_zero
+L$sqr8x_cond_copy:
+ movdqa 0(%rbx),%xmm2
+ movdqa 16(%rbx),%xmm3
+ leaq 32(%rbx),%rbx
+ movdqu 0(%rdi),%xmm4
+ movdqu 16(%rdi),%xmm5
+ leaq 32(%rdi),%rdi
+ movdqa %xmm0,-32(%rbx)
+ movdqa %xmm0,-16(%rbx)
+ movdqa %xmm0,-32(%rbx,%rdx,1)
+ movdqa %xmm0,-16(%rbx,%rdx,1)
+ pcmpeqd %xmm1,%xmm0
+ pand %xmm1,%xmm2
+ pand %xmm1,%xmm3
+ pand %xmm0,%xmm4
+ pand %xmm0,%xmm5
+ pxor %xmm0,%xmm0
+ por %xmm2,%xmm4
+ por %xmm3,%xmm5
+ movdqu %xmm4,-32(%rdi)
+ movdqu %xmm5,-16(%rdi)
+ addq $32,%r9
+ jnz L$sqr8x_cond_copy
movq $1,%rax
movq -48(%rsi),%r15
diff --git a/mac-x86_64/crypto/bn/x86_64-mont5.S b/mac-x86_64/crypto/bn/x86_64-mont5.S
index 461bfb22..f3ad8d78 100644
--- a/mac-x86_64/crypto/bn/x86_64-mont5.S
+++ b/mac-x86_64/crypto/bn/x86_64-mont5.S
@@ -16,46 +16,151 @@ _bn_mul_mont_gather5:
L$mul_enter:
movl %r9d,%r9d
movq %rsp,%rax
- movl 8(%rsp),%r10d
+ movd 8(%rsp),%xmm5
+ leaq L$inc(%rip),%r10
pushq %rbx
pushq %rbp
pushq %r12
pushq %r13
pushq %r14
pushq %r15
+
leaq 2(%r9),%r11
negq %r11
- leaq (%rsp,%r11,8),%rsp
+ leaq -264(%rsp,%r11,8),%rsp
andq $-1024,%rsp
movq %rax,8(%rsp,%r9,8)
L$mul_body:
- movq %rdx,%r12
- movq %r10,%r11
- shrq $3,%r10
- andq $7,%r11
- notq %r10
- leaq L$magic_masks(%rip),%rax
- andq $3,%r10
- leaq 96(%r12,%r11,8),%r12
- movq 0(%rax,%r10,8),%xmm4
- movq 8(%rax,%r10,8),%xmm5
- movq 16(%rax,%r10,8),%xmm6
- movq 24(%rax,%r10,8),%xmm7
-
- movq -96(%r12),%xmm0
- movq -32(%r12),%xmm1
- pand %xmm4,%xmm0
- movq 32(%r12),%xmm2
- pand %xmm5,%xmm1
- movq 96(%r12),%xmm3
- pand %xmm6,%xmm2
- por %xmm1,%xmm0
- pand %xmm7,%xmm3
+ leaq 128(%rdx),%r12
+ movdqa 0(%r10),%xmm0
+ movdqa 16(%r10),%xmm1
+ leaq 24-112(%rsp,%r9,8),%r10
+ andq $-16,%r10
+
+ pshufd $0,%xmm5,%xmm5
+ movdqa %xmm1,%xmm4
+ movdqa %xmm1,%xmm2
+ paddd %xmm0,%xmm1
+ pcmpeqd %xmm5,%xmm0
+.byte 0x67
+ movdqa %xmm4,%xmm3
+ paddd %xmm1,%xmm2
+ pcmpeqd %xmm5,%xmm1
+ movdqa %xmm0,112(%r10)
+ movdqa %xmm4,%xmm0
+
+ paddd %xmm2,%xmm3
+ pcmpeqd %xmm5,%xmm2
+ movdqa %xmm1,128(%r10)
+ movdqa %xmm4,%xmm1
+
+ paddd %xmm3,%xmm0
+ pcmpeqd %xmm5,%xmm3
+ movdqa %xmm2,144(%r10)
+ movdqa %xmm4,%xmm2
+
+ paddd %xmm0,%xmm1
+ pcmpeqd %xmm5,%xmm0
+ movdqa %xmm3,160(%r10)
+ movdqa %xmm4,%xmm3
+ paddd %xmm1,%xmm2
+ pcmpeqd %xmm5,%xmm1
+ movdqa %xmm0,176(%r10)
+ movdqa %xmm4,%xmm0
+
+ paddd %xmm2,%xmm3
+ pcmpeqd %xmm5,%xmm2
+ movdqa %xmm1,192(%r10)
+ movdqa %xmm4,%xmm1
+
+ paddd %xmm3,%xmm0
+ pcmpeqd %xmm5,%xmm3
+ movdqa %xmm2,208(%r10)
+ movdqa %xmm4,%xmm2
+
+ paddd %xmm0,%xmm1
+ pcmpeqd %xmm5,%xmm0
+ movdqa %xmm3,224(%r10)
+ movdqa %xmm4,%xmm3
+ paddd %xmm1,%xmm2
+ pcmpeqd %xmm5,%xmm1
+ movdqa %xmm0,240(%r10)
+ movdqa %xmm4,%xmm0
+
+ paddd %xmm2,%xmm3
+ pcmpeqd %xmm5,%xmm2
+ movdqa %xmm1,256(%r10)
+ movdqa %xmm4,%xmm1
+
+ paddd %xmm3,%xmm0
+ pcmpeqd %xmm5,%xmm3
+ movdqa %xmm2,272(%r10)
+ movdqa %xmm4,%xmm2
+
+ paddd %xmm0,%xmm1
+ pcmpeqd %xmm5,%xmm0
+ movdqa %xmm3,288(%r10)
+ movdqa %xmm4,%xmm3
+ paddd %xmm1,%xmm2
+ pcmpeqd %xmm5,%xmm1
+ movdqa %xmm0,304(%r10)
+
+ paddd %xmm2,%xmm3
+.byte 0x67
+ pcmpeqd %xmm5,%xmm2
+ movdqa %xmm1,320(%r10)
+
+ pcmpeqd %xmm5,%xmm3
+ movdqa %xmm2,336(%r10)
+ pand 64(%r12),%xmm0
+
+ pand 80(%r12),%xmm1
+ pand 96(%r12),%xmm2
+ movdqa %xmm3,352(%r10)
+ pand 112(%r12),%xmm3
+ por %xmm2,%xmm0
+ por %xmm3,%xmm1
+ movdqa -128(%r12),%xmm4
+ movdqa -112(%r12),%xmm5
+ movdqa -96(%r12),%xmm2
+ pand 112(%r10),%xmm4
+ movdqa -80(%r12),%xmm3
+ pand 128(%r10),%xmm5
+ por %xmm4,%xmm0
+ pand 144(%r10),%xmm2
+ por %xmm5,%xmm1
+ pand 160(%r10),%xmm3
por %xmm2,%xmm0
+ por %xmm3,%xmm1
+ movdqa -64(%r12),%xmm4
+ movdqa -48(%r12),%xmm5
+ movdqa -32(%r12),%xmm2
+ pand 176(%r10),%xmm4
+ movdqa -16(%r12),%xmm3
+ pand 192(%r10),%xmm5
+ por %xmm4,%xmm0
+ pand 208(%r10),%xmm2
+ por %xmm5,%xmm1
+ pand 224(%r10),%xmm3
+ por %xmm2,%xmm0
+ por %xmm3,%xmm1
+ movdqa 0(%r12),%xmm4
+ movdqa 16(%r12),%xmm5
+ movdqa 32(%r12),%xmm2
+ pand 240(%r10),%xmm4
+ movdqa 48(%r12),%xmm3
+ pand 256(%r10),%xmm5
+ por %xmm4,%xmm0
+ pand 272(%r10),%xmm2
+ por %xmm5,%xmm1
+ pand 288(%r10),%xmm3
+ por %xmm2,%xmm0
+ por %xmm3,%xmm1
+ por %xmm1,%xmm0
+ pshufd $0x4e,%xmm0,%xmm1
+ por %xmm1,%xmm0
leaq 256(%r12),%r12
- por %xmm3,%xmm0
-
.byte 102,72,15,126,195
movq (%r8),%r8
@@ -64,29 +169,14 @@ L$mul_body:
xorq %r14,%r14
xorq %r15,%r15
- movq -96(%r12),%xmm0
- movq -32(%r12),%xmm1
- pand %xmm4,%xmm0
- movq 32(%r12),%xmm2
- pand %xmm5,%xmm1
-
movq %r8,%rbp
mulq %rbx
movq %rax,%r10
movq (%rcx),%rax
- movq 96(%r12),%xmm3
- pand %xmm6,%xmm2
- por %xmm1,%xmm0
- pand %xmm7,%xmm3
-
imulq %r10,%rbp
movq %rdx,%r11
- por %xmm2,%xmm0
- leaq 256(%r12),%r12
- por %xmm3,%xmm0
-
mulq %rbp
addq %rax,%r10
movq 8(%rsi),%rax
@@ -119,14 +209,12 @@ L$1st_enter:
cmpq %r9,%r15
jne L$1st
-.byte 102,72,15,126,195
addq %rax,%r13
- movq (%rsi),%rax
adcq $0,%rdx
addq %r11,%r13
adcq $0,%rdx
- movq %r13,-16(%rsp,%r15,8)
+ movq %r13,-16(%rsp,%r9,8)
movq %rdx,%r13
movq %r10,%r11
@@ -140,33 +228,78 @@ L$1st_enter:
jmp L$outer
.p2align 4
L$outer:
+ leaq 24+128(%rsp,%r9,8),%rdx
+ andq $-16,%rdx
+ pxor %xmm4,%xmm4
+ pxor %xmm5,%xmm5
+ movdqa -128(%r12),%xmm0
+ movdqa -112(%r12),%xmm1
+ movdqa -96(%r12),%xmm2
+ movdqa -80(%r12),%xmm3
+ pand -128(%rdx),%xmm0
+ pand -112(%rdx),%xmm1
+ por %xmm0,%xmm4
+ pand -96(%rdx),%xmm2
+ por %xmm1,%xmm5
+ pand -80(%rdx),%xmm3
+ por %xmm2,%xmm4
+ por %xmm3,%xmm5
+ movdqa -64(%r12),%xmm0
+ movdqa -48(%r12),%xmm1
+ movdqa -32(%r12),%xmm2
+ movdqa -16(%r12),%xmm3
+ pand -64(%rdx),%xmm0
+ pand -48(%rdx),%xmm1
+ por %xmm0,%xmm4
+ pand -32(%rdx),%xmm2
+ por %xmm1,%xmm5
+ pand -16(%rdx),%xmm3
+ por %xmm2,%xmm4
+ por %xmm3,%xmm5
+ movdqa 0(%r12),%xmm0
+ movdqa 16(%r12),%xmm1
+ movdqa 32(%r12),%xmm2
+ movdqa 48(%r12),%xmm3
+ pand 0(%rdx),%xmm0
+ pand 16(%rdx),%xmm1
+ por %xmm0,%xmm4
+ pand 32(%rdx),%xmm2
+ por %xmm1,%xmm5
+ pand 48(%rdx),%xmm3
+ por %xmm2,%xmm4
+ por %xmm3,%xmm5
+ movdqa 64(%r12),%xmm0
+ movdqa 80(%r12),%xmm1
+ movdqa 96(%r12),%xmm2
+ movdqa 112(%r12),%xmm3
+ pand 64(%rdx),%xmm0
+ pand 80(%rdx),%xmm1
+ por %xmm0,%xmm4
+ pand 96(%rdx),%xmm2
+ por %xmm1,%xmm5
+ pand 112(%rdx),%xmm3
+ por %xmm2,%xmm4
+ por %xmm3,%xmm5
+ por %xmm5,%xmm4
+ pshufd $0x4e,%xmm4,%xmm0
+ por %xmm4,%xmm0
+ leaq 256(%r12),%r12
+
+ movq (%rsi),%rax
+.byte 102,72,15,126,195
+
xorq %r15,%r15
movq %r8,%rbp
movq (%rsp),%r10
- movq -96(%r12),%xmm0
- movq -32(%r12),%xmm1
- pand %xmm4,%xmm0
- movq 32(%r12),%xmm2
- pand %xmm5,%xmm1
-
mulq %rbx
addq %rax,%r10
movq (%rcx),%rax
adcq $0,%rdx
- movq 96(%r12),%xmm3
- pand %xmm6,%xmm2
- por %xmm1,%xmm0
- pand %xmm7,%xmm3
-
imulq %r10,%rbp
movq %rdx,%r11
- por %xmm2,%xmm0
- leaq 256(%r12),%r12
- por %xmm3,%xmm0
-
mulq %rbp
addq %rax,%r10
movq 8(%rsi),%rax
@@ -202,15 +335,12 @@ L$inner_enter:
cmpq %r9,%r15
jne L$inner
-.byte 102,72,15,126,195
-
addq %rax,%r13
- movq (%rsi),%rax
adcq $0,%rdx
addq %r10,%r13
- movq (%rsp,%r15,8),%r10
+ movq (%rsp,%r9,8),%r10
adcq $0,%rdx
- movq %r13,-16(%rsp,%r15,8)
+ movq %r13,-16(%rsp,%r9,8)
movq %rdx,%r13
xorq %rdx,%rdx
@@ -256,6 +386,7 @@ L$copy:
movq 8(%rsp,%r9,8),%rsi
movq $1,%rax
+
movq -48(%rsi),%r15
movq -40(%rsi),%r14
movq -32(%rsi),%r13
@@ -278,10 +409,10 @@ L$mul4x_enter:
pushq %r13
pushq %r14
pushq %r15
+
.byte 0x67
- movl %r9d,%r10d
shll $3,%r9d
- shll $3+2,%r10d
+ leaq (%r9,%r9,2),%r10
negq %r9
@@ -291,19 +422,21 @@ L$mul4x_enter:
- leaq -64(%rsp,%r9,2),%r11
- subq %rsi,%r11
+
+
+ leaq -320(%rsp,%r9,2),%r11
+ subq %rdi,%r11
andq $4095,%r11
cmpq %r11,%r10
jb L$mul4xsp_alt
subq %r11,%rsp
- leaq -64(%rsp,%r9,2),%rsp
+ leaq -320(%rsp,%r9,2),%rsp
jmp L$mul4xsp_done
.p2align 5
L$mul4xsp_alt:
- leaq 4096-64(,%r9,2),%r10
- leaq -64(%rsp,%r9,2),%rsp
+ leaq 4096-320(,%r9,2),%r10
+ leaq -320(%rsp,%r9,2),%rsp
subq %r10,%r11
movq $0,%r10
cmovcq %r10,%r11
@@ -319,6 +452,7 @@ L$mul4x_body:
movq 40(%rsp),%rsi
movq $1,%rax
+
movq -48(%rsi),%r15
movq -40(%rsi),%r14
movq -32(%rsi),%r13
@@ -334,47 +468,141 @@ L$mul4x_epilogue:
.p2align 5
mul4x_internal:
shlq $5,%r9
- movl 8(%rax),%r10d
- leaq 256(%rdx,%r9,1),%r13
+ movd 8(%rax),%xmm5
+ leaq L$inc(%rip),%rax
+ leaq 128(%rdx,%r9,1),%r13
shrq $5,%r9
- movq %r10,%r11
- shrq $3,%r10
- andq $7,%r11
- notq %r10
- leaq L$magic_masks(%rip),%rax
- andq $3,%r10
- leaq 96(%rdx,%r11,8),%r12
- movq 0(%rax,%r10,8),%xmm4
- movq 8(%rax,%r10,8),%xmm5
- addq $7,%r11
- movq 16(%rax,%r10,8),%xmm6
- movq 24(%rax,%r10,8),%xmm7
- andq $7,%r11
-
- movq -96(%r12),%xmm0
- leaq 256(%r12),%r14
- movq -32(%r12),%xmm1
- pand %xmm4,%xmm0
- movq 32(%r12),%xmm2
- pand %xmm5,%xmm1
- movq 96(%r12),%xmm3
- pand %xmm6,%xmm2
-.byte 0x67
- por %xmm1,%xmm0
- movq -96(%r14),%xmm1
-.byte 0x67
- pand %xmm7,%xmm3
-.byte 0x67
- por %xmm2,%xmm0
- movq -32(%r14),%xmm2
+ movdqa 0(%rax),%xmm0
+ movdqa 16(%rax),%xmm1
+ leaq 88-112(%rsp,%r9,1),%r10
+ leaq 128(%rdx),%r12
+
+ pshufd $0,%xmm5,%xmm5
+ movdqa %xmm1,%xmm4
+.byte 0x67,0x67
+ movdqa %xmm1,%xmm2
+ paddd %xmm0,%xmm1
+ pcmpeqd %xmm5,%xmm0
.byte 0x67
- pand %xmm4,%xmm1
+ movdqa %xmm4,%xmm3
+ paddd %xmm1,%xmm2
+ pcmpeqd %xmm5,%xmm1
+ movdqa %xmm0,112(%r10)
+ movdqa %xmm4,%xmm0
+
+ paddd %xmm2,%xmm3
+ pcmpeqd %xmm5,%xmm2
+ movdqa %xmm1,128(%r10)
+ movdqa %xmm4,%xmm1
+
+ paddd %xmm3,%xmm0
+ pcmpeqd %xmm5,%xmm3
+ movdqa %xmm2,144(%r10)
+ movdqa %xmm4,%xmm2
+
+ paddd %xmm0,%xmm1
+ pcmpeqd %xmm5,%xmm0
+ movdqa %xmm3,160(%r10)
+ movdqa %xmm4,%xmm3
+ paddd %xmm1,%xmm2
+ pcmpeqd %xmm5,%xmm1
+ movdqa %xmm0,176(%r10)
+ movdqa %xmm4,%xmm0
+
+ paddd %xmm2,%xmm3
+ pcmpeqd %xmm5,%xmm2
+ movdqa %xmm1,192(%r10)
+ movdqa %xmm4,%xmm1
+
+ paddd %xmm3,%xmm0
+ pcmpeqd %xmm5,%xmm3
+ movdqa %xmm2,208(%r10)
+ movdqa %xmm4,%xmm2
+
+ paddd %xmm0,%xmm1
+ pcmpeqd %xmm5,%xmm0
+ movdqa %xmm3,224(%r10)
+ movdqa %xmm4,%xmm3
+ paddd %xmm1,%xmm2
+ pcmpeqd %xmm5,%xmm1
+ movdqa %xmm0,240(%r10)
+ movdqa %xmm4,%xmm0
+
+ paddd %xmm2,%xmm3
+ pcmpeqd %xmm5,%xmm2
+ movdqa %xmm1,256(%r10)
+ movdqa %xmm4,%xmm1
+
+ paddd %xmm3,%xmm0
+ pcmpeqd %xmm5,%xmm3
+ movdqa %xmm2,272(%r10)
+ movdqa %xmm4,%xmm2
+
+ paddd %xmm0,%xmm1
+ pcmpeqd %xmm5,%xmm0
+ movdqa %xmm3,288(%r10)
+ movdqa %xmm4,%xmm3
+ paddd %xmm1,%xmm2
+ pcmpeqd %xmm5,%xmm1
+ movdqa %xmm0,304(%r10)
+
+ paddd %xmm2,%xmm3
.byte 0x67
- por %xmm3,%xmm0
- movq 32(%r14),%xmm3
+ pcmpeqd %xmm5,%xmm2
+ movdqa %xmm1,320(%r10)
+
+ pcmpeqd %xmm5,%xmm3
+ movdqa %xmm2,336(%r10)
+ pand 64(%r12),%xmm0
+ pand 80(%r12),%xmm1
+ pand 96(%r12),%xmm2
+ movdqa %xmm3,352(%r10)
+ pand 112(%r12),%xmm3
+ por %xmm2,%xmm0
+ por %xmm3,%xmm1
+ movdqa -128(%r12),%xmm4
+ movdqa -112(%r12),%xmm5
+ movdqa -96(%r12),%xmm2
+ pand 112(%r10),%xmm4
+ movdqa -80(%r12),%xmm3
+ pand 128(%r10),%xmm5
+ por %xmm4,%xmm0
+ pand 144(%r10),%xmm2
+ por %xmm5,%xmm1
+ pand 160(%r10),%xmm3
+ por %xmm2,%xmm0
+ por %xmm3,%xmm1
+ movdqa -64(%r12),%xmm4
+ movdqa -48(%r12),%xmm5
+ movdqa -32(%r12),%xmm2
+ pand 176(%r10),%xmm4
+ movdqa -16(%r12),%xmm3
+ pand 192(%r10),%xmm5
+ por %xmm4,%xmm0
+ pand 208(%r10),%xmm2
+ por %xmm5,%xmm1
+ pand 224(%r10),%xmm3
+ por %xmm2,%xmm0
+ por %xmm3,%xmm1
+ movdqa 0(%r12),%xmm4
+ movdqa 16(%r12),%xmm5
+ movdqa 32(%r12),%xmm2
+ pand 240(%r10),%xmm4
+ movdqa 48(%r12),%xmm3
+ pand 256(%r10),%xmm5
+ por %xmm4,%xmm0
+ pand 272(%r10),%xmm2
+ por %xmm5,%xmm1
+ pand 288(%r10),%xmm3
+ por %xmm2,%xmm0
+ por %xmm3,%xmm1
+ por %xmm1,%xmm0
+ pshufd $0x4e,%xmm0,%xmm1
+ por %xmm1,%xmm0
+ leaq 256(%r12),%r12
.byte 102,72,15,126,195
- movq 96(%r14),%xmm0
+
movq %r13,16+8(%rsp)
movq %rdi,56+8(%rsp)
@@ -388,26 +616,10 @@ mul4x_internal:
movq %rax,%r10
movq (%rcx),%rax
- pand %xmm5,%xmm2
- pand %xmm6,%xmm3
- por %xmm2,%xmm1
-
imulq %r10,%rbp
-
-
-
-
-
-
-
- leaq 64+8(%rsp,%r11,8),%r14
+ leaq 64+8(%rsp),%r14
movq %rdx,%r11
- pand %xmm7,%xmm0
- por %xmm3,%xmm1
- leaq 512(%r12),%r12
- por %xmm1,%xmm0
-
mulq %rbp
addq %rax,%r10
movq 8(%rsi,%r9,1),%rax
@@ -416,7 +628,7 @@ mul4x_internal:
mulq %rbx
addq %rax,%r11
- movq 16(%rcx),%rax
+ movq 8(%rcx),%rax
adcq $0,%rdx
movq %rdx,%r10
@@ -426,7 +638,7 @@ mul4x_internal:
adcq $0,%rdx
addq %r11,%rdi
leaq 32(%r9),%r15
- leaq 64(%rcx),%rcx
+ leaq 32(%rcx),%rcx
adcq $0,%rdx
movq %rdi,(%r14)
movq %rdx,%r13
@@ -436,7 +648,7 @@ mul4x_internal:
L$1st4x:
mulq %rbx
addq %rax,%r10
- movq -32(%rcx),%rax
+ movq -16(%rcx),%rax
leaq 32(%r14),%r14
adcq $0,%rdx
movq %rdx,%r11
@@ -452,7 +664,7 @@ L$1st4x:
mulq %rbx
addq %rax,%r11
- movq -16(%rcx),%rax
+ movq -8(%rcx),%rax
adcq $0,%rdx
movq %rdx,%r10
@@ -482,7 +694,7 @@ L$1st4x:
mulq %rbx
addq %rax,%r11
- movq 16(%rcx),%rax
+ movq 8(%rcx),%rax
adcq $0,%rdx
movq %rdx,%r10
@@ -491,7 +703,7 @@ L$1st4x:
movq 16(%rsi,%r15,1),%rax
adcq $0,%rdx
addq %r11,%rdi
- leaq 64(%rcx),%rcx
+ leaq 32(%rcx),%rcx
adcq $0,%rdx
movq %rdi,(%r14)
movq %rdx,%r13
@@ -501,7 +713,7 @@ L$1st4x:
mulq %rbx
addq %rax,%r10
- movq -32(%rcx),%rax
+ movq -16(%rcx),%rax
leaq 32(%r14),%r14
adcq $0,%rdx
movq %rdx,%r11
@@ -517,7 +729,7 @@ L$1st4x:
mulq %rbx
addq %rax,%r11
- movq -16(%rcx),%rax
+ movq -8(%rcx),%rax
adcq $0,%rdx
movq %rdx,%r10
@@ -530,8 +742,7 @@ L$1st4x:
movq %rdi,-16(%r14)
movq %rdx,%r13
-.byte 102,72,15,126,195
- leaq (%rcx,%r9,2),%rcx
+ leaq (%rcx,%r9,1),%rcx
xorq %rdi,%rdi
addq %r10,%r13
@@ -542,6 +753,63 @@ L$1st4x:
.p2align 5
L$outer4x:
+ leaq 16+128(%r14),%rdx
+ pxor %xmm4,%xmm4
+ pxor %xmm5,%xmm5
+ movdqa -128(%r12),%xmm0
+ movdqa -112(%r12),%xmm1
+ movdqa -96(%r12),%xmm2
+ movdqa -80(%r12),%xmm3
+ pand -128(%rdx),%xmm0
+ pand -112(%rdx),%xmm1
+ por %xmm0,%xmm4
+ pand -96(%rdx),%xmm2
+ por %xmm1,%xmm5
+ pand -80(%rdx),%xmm3
+ por %xmm2,%xmm4
+ por %xmm3,%xmm5
+ movdqa -64(%r12),%xmm0
+ movdqa -48(%r12),%xmm1
+ movdqa -32(%r12),%xmm2
+ movdqa -16(%r12),%xmm3
+ pand -64(%rdx),%xmm0
+ pand -48(%rdx),%xmm1
+ por %xmm0,%xmm4
+ pand -32(%rdx),%xmm2
+ por %xmm1,%xmm5
+ pand -16(%rdx),%xmm3
+ por %xmm2,%xmm4
+ por %xmm3,%xmm5
+ movdqa 0(%r12),%xmm0
+ movdqa 16(%r12),%xmm1
+ movdqa 32(%r12),%xmm2
+ movdqa 48(%r12),%xmm3
+ pand 0(%rdx),%xmm0
+ pand 16(%rdx),%xmm1
+ por %xmm0,%xmm4
+ pand 32(%rdx),%xmm2
+ por %xmm1,%xmm5
+ pand 48(%rdx),%xmm3
+ por %xmm2,%xmm4
+ por %xmm3,%xmm5
+ movdqa 64(%r12),%xmm0
+ movdqa 80(%r12),%xmm1
+ movdqa 96(%r12),%xmm2
+ movdqa 112(%r12),%xmm3
+ pand 64(%rdx),%xmm0
+ pand 80(%rdx),%xmm1
+ por %xmm0,%xmm4
+ pand 96(%rdx),%xmm2
+ por %xmm1,%xmm5
+ pand 112(%rdx),%xmm3
+ por %xmm2,%xmm4
+ por %xmm3,%xmm5
+ por %xmm5,%xmm4
+ pshufd $0x4e,%xmm4,%xmm0
+ por %xmm4,%xmm0
+ leaq 256(%r12),%r12
+.byte 102,72,15,126,195
+
movq (%r14,%r9,1),%r10
movq %r8,%rbp
mulq %rbx
@@ -549,25 +817,11 @@ L$outer4x:
movq (%rcx),%rax
adcq $0,%rdx
- movq -96(%r12),%xmm0
- movq -32(%r12),%xmm1
- pand %xmm4,%xmm0
- movq 32(%r12),%xmm2
- pand %xmm5,%xmm1
- movq 96(%r12),%xmm3
-
imulq %r10,%rbp
-.byte 0x67
movq %rdx,%r11
movq %rdi,(%r14)
- pand %xmm6,%xmm2
- por %xmm1,%xmm0
- pand %xmm7,%xmm3
- por %xmm2,%xmm0
leaq (%r14,%r9,1),%r14
- leaq 256(%r12),%r12
- por %xmm3,%xmm0
mulq %rbp
addq %rax,%r10
@@ -577,7 +831,7 @@ L$outer4x:
mulq %rbx
addq %rax,%r11
- movq 16(%rcx),%rax
+ movq 8(%rcx),%rax
adcq $0,%rdx
addq 8(%r14),%r11
adcq $0,%rdx
@@ -589,7 +843,7 @@ L$outer4x:
adcq $0,%rdx
addq %r11,%rdi
leaq 32(%r9),%r15
- leaq 64(%rcx),%rcx
+ leaq 32(%rcx),%rcx
adcq $0,%rdx
movq %rdx,%r13
jmp L$inner4x
@@ -598,7 +852,7 @@ L$outer4x:
L$inner4x:
mulq %rbx
addq %rax,%r10
- movq -32(%rcx),%rax
+ movq -16(%rcx),%rax
adcq $0,%rdx
addq 16(%r14),%r10
leaq 32(%r14),%r14
@@ -616,7 +870,7 @@ L$inner4x:
mulq %rbx
addq %rax,%r11
- movq -16(%rcx),%rax
+ movq -8(%rcx),%rax
adcq $0,%rdx
addq -8(%r14),%r11
adcq $0,%rdx
@@ -650,7 +904,7 @@ L$inner4x:
mulq %rbx
addq %rax,%r11
- movq 16(%rcx),%rax
+ movq 8(%rcx),%rax
adcq $0,%rdx
addq 8(%r14),%r11
adcq $0,%rdx
@@ -661,7 +915,7 @@ L$inner4x:
movq 16(%rsi,%r15,1),%rax
adcq $0,%rdx
addq %r11,%rdi
- leaq 64(%rcx),%rcx
+ leaq 32(%rcx),%rcx
adcq $0,%rdx
movq %r13,-8(%r14)
movq %rdx,%r13
@@ -671,7 +925,7 @@ L$inner4x:
mulq %rbx
addq %rax,%r10
- movq -32(%rcx),%rax
+ movq -16(%rcx),%rax
adcq $0,%rdx
addq 16(%r14),%r10
leaq 32(%r14),%r14
@@ -690,7 +944,7 @@ L$inner4x:
mulq %rbx
addq %rax,%r11
movq %rbp,%rax
- movq -16(%rcx),%rbp
+ movq -8(%rcx),%rbp
adcq $0,%rdx
addq -8(%r14),%r11
adcq $0,%rdx
@@ -705,9 +959,8 @@ L$inner4x:
movq %r13,-24(%r14)
movq %rdx,%r13
-.byte 102,72,15,126,195
movq %rdi,-16(%r14)
- leaq (%rcx,%r9,2),%rcx
+ leaq (%rcx,%r9,1),%rcx
xorq %rdi,%rdi
addq %r10,%r13
@@ -718,16 +971,23 @@ L$inner4x:
cmpq 16+8(%rsp),%r12
jb L$outer4x
+ xorq %rax,%rax
subq %r13,%rbp
adcq %r15,%r15
orq %r15,%rdi
- xorq $1,%rdi
+ subq %rdi,%rax
leaq (%r14,%r9,1),%rbx
- leaq (%rcx,%rdi,8),%rbp
+ movq (%rcx),%r12
+ leaq (%rcx),%rbp
movq %r9,%rcx
sarq $3+2,%rcx
movq 56+8(%rsp),%rdi
- jmp L$sqr4x_sub
+ decq %r12
+ xorq %r10,%r10
+ movq 8(%rbp),%r13
+ movq 16(%rbp),%r14
+ movq 24(%rbp),%r15
+ jmp L$sqr4x_sub_entry
.globl _bn_power5
.private_extern _bn_power5
@@ -741,9 +1001,9 @@ _bn_power5:
pushq %r13
pushq %r14
pushq %r15
- movl %r9d,%r10d
+
shll $3,%r9d
- shll $3+2,%r10d
+ leal (%r9,%r9,2),%r10d
negq %r9
movq (%r8),%r8
@@ -753,19 +1013,20 @@ _bn_power5:
- leaq -64(%rsp,%r9,2),%r11
- subq %rsi,%r11
+
+ leaq -320(%rsp,%r9,2),%r11
+ subq %rdi,%r11
andq $4095,%r11
cmpq %r11,%r10
jb L$pwr_sp_alt
subq %r11,%rsp
- leaq -64(%rsp,%r9,2),%rsp
+ leaq -320(%rsp,%r9,2),%rsp
jmp L$pwr_sp_done
.p2align 5
L$pwr_sp_alt:
- leaq 4096-64(,%r9,2),%r10
- leaq -64(%rsp,%r9,2),%rsp
+ leaq 4096-320(,%r9,2),%r10
+ leaq -320(%rsp,%r9,2),%rsp
subq %r10,%r11
movq $0,%r10
cmovcq %r10,%r11
@@ -793,10 +1054,15 @@ L$power5_body:
.byte 102,72,15,110,226
call __bn_sqr8x_internal
+ call __bn_post4x_internal
call __bn_sqr8x_internal
+ call __bn_post4x_internal
call __bn_sqr8x_internal
+ call __bn_post4x_internal
call __bn_sqr8x_internal
+ call __bn_post4x_internal
call __bn_sqr8x_internal
+ call __bn_post4x_internal
.byte 102,72,15,126,209
.byte 102,72,15,126,226
@@ -1341,9 +1607,9 @@ L$sqr4x_shift_n_add:
movq %rbx,-16(%rdi)
movq %r8,-8(%rdi)
.byte 102,72,15,126,213
-sqr8x_reduction:
+__bn_sqr8x_reduction:
xorq %rax,%rax
- leaq (%rbp,%r9,2),%rcx
+ leaq (%r9,%rbp,1),%rcx
leaq 48+8(%rsp,%r9,2),%rdx
movq %rcx,0+8(%rsp)
leaq 48+8(%rsp,%r9,1),%rdi
@@ -1376,14 +1642,14 @@ L$8x_reduction_loop:
.p2align 5
L$8x_reduce:
mulq %rbx
- movq 16(%rbp),%rax
+ movq 8(%rbp),%rax
negq %r8
movq %rdx,%r8
adcq $0,%r8
mulq %rbx
addq %rax,%r9
- movq 32(%rbp),%rax
+ movq 16(%rbp),%rax
adcq $0,%rdx
addq %r9,%r8
movq %rbx,48-8+8(%rsp,%rcx,8)
@@ -1392,7 +1658,7 @@ L$8x_reduce:
mulq %rbx
addq %rax,%r10
- movq 48(%rbp),%rax
+ movq 24(%rbp),%rax
adcq $0,%rdx
addq %r10,%r9
movq 32+8(%rsp),%rsi
@@ -1401,7 +1667,7 @@ L$8x_reduce:
mulq %rbx
addq %rax,%r11
- movq 64(%rbp),%rax
+ movq 32(%rbp),%rax
adcq $0,%rdx
imulq %r8,%rsi
addq %r11,%r10
@@ -1410,7 +1676,7 @@ L$8x_reduce:
mulq %rbx
addq %rax,%r12
- movq 80(%rbp),%rax
+ movq 40(%rbp),%rax
adcq $0,%rdx
addq %r12,%r11
movq %rdx,%r12
@@ -1418,7 +1684,7 @@ L$8x_reduce:
mulq %rbx
addq %rax,%r13
- movq 96(%rbp),%rax
+ movq 48(%rbp),%rax
adcq $0,%rdx
addq %r13,%r12
movq %rdx,%r13
@@ -1426,7 +1692,7 @@ L$8x_reduce:
mulq %rbx
addq %rax,%r14
- movq 112(%rbp),%rax
+ movq 56(%rbp),%rax
adcq $0,%rdx
addq %r14,%r13
movq %rdx,%r14
@@ -1444,7 +1710,7 @@ L$8x_reduce:
decl %ecx
jnz L$8x_reduce
- leaq 128(%rbp),%rbp
+ leaq 64(%rbp),%rbp
xorq %rax,%rax
movq 8+8(%rsp),%rdx
cmpq 0+8(%rsp),%rbp
@@ -1470,14 +1736,14 @@ L$8x_reduce:
L$8x_tail:
mulq %rbx
addq %rax,%r8
- movq 16(%rbp),%rax
+ movq 8(%rbp),%rax
movq %r8,(%rdi)
movq %rdx,%r8
adcq $0,%r8
mulq %rbx
addq %rax,%r9
- movq 32(%rbp),%rax
+ movq 16(%rbp),%rax
adcq $0,%rdx
addq %r9,%r8
leaq 8(%rdi),%rdi
@@ -1486,7 +1752,7 @@ L$8x_tail:
mulq %rbx
addq %rax,%r10
- movq 48(%rbp),%rax
+ movq 24(%rbp),%rax
adcq $0,%rdx
addq %r10,%r9
movq %rdx,%r10
@@ -1494,7 +1760,7 @@ L$8x_tail:
mulq %rbx
addq %rax,%r11
- movq 64(%rbp),%rax
+ movq 32(%rbp),%rax
adcq $0,%rdx
addq %r11,%r10
movq %rdx,%r11
@@ -1502,7 +1768,7 @@ L$8x_tail:
mulq %rbx
addq %rax,%r12
- movq 80(%rbp),%rax
+ movq 40(%rbp),%rax
adcq $0,%rdx
addq %r12,%r11
movq %rdx,%r12
@@ -1510,7 +1776,7 @@ L$8x_tail:
mulq %rbx
addq %rax,%r13
- movq 96(%rbp),%rax
+ movq 48(%rbp),%rax
adcq $0,%rdx
addq %r13,%r12
movq %rdx,%r13
@@ -1518,7 +1784,7 @@ L$8x_tail:
mulq %rbx
addq %rax,%r14
- movq 112(%rbp),%rax
+ movq 56(%rbp),%rax
adcq $0,%rdx
addq %r14,%r13
movq %rdx,%r14
@@ -1536,7 +1802,7 @@ L$8x_tail:
decl %ecx
jnz L$8x_tail
- leaq 128(%rbp),%rbp
+ leaq 64(%rbp),%rbp
movq 8+8(%rsp),%rdx
cmpq 0+8(%rsp),%rbp
jae L$8x_tail_done
@@ -1582,7 +1848,7 @@ L$8x_no_tail:
adcq 48(%rdi),%r14
adcq 56(%rdi),%r15
adcq $0,%rax
- movq -16(%rbp),%rcx
+ movq -8(%rbp),%rcx
xorq %rsi,%rsi
.byte 102,72,15,126,213
@@ -1600,40 +1866,58 @@ L$8x_no_tail:
cmpq %rdx,%rdi
jb L$8x_reduction_loop
+ .byte 0xf3,0xc3
+
- subq %r15,%rcx
+.p2align 5
+__bn_post4x_internal:
+ movq 0(%rbp),%r12
leaq (%rdi,%r9,1),%rbx
- adcq %rsi,%rsi
movq %r9,%rcx
- orq %rsi,%rax
.byte 102,72,15,126,207
- xorq $1,%rax
+ negq %rax
.byte 102,72,15,126,206
- leaq (%rbp,%rax,8),%rbp
sarq $3+2,%rcx
- jmp L$sqr4x_sub
+ decq %r12
+ xorq %r10,%r10
+ movq 8(%rbp),%r13
+ movq 16(%rbp),%r14
+ movq 24(%rbp),%r15
+ jmp L$sqr4x_sub_entry
-.p2align 5
+.p2align 4
L$sqr4x_sub:
-.byte 0x66
- movq 0(%rbx),%r12
- movq 8(%rbx),%r13
- sbbq 0(%rbp),%r12
- movq 16(%rbx),%r14
- sbbq 16(%rbp),%r13
- movq 24(%rbx),%r15
- leaq 32(%rbx),%rbx
- sbbq 32(%rbp),%r14
+ movq 0(%rbp),%r12
+ movq 8(%rbp),%r13
+ movq 16(%rbp),%r14
+ movq 24(%rbp),%r15
+L$sqr4x_sub_entry:
+ leaq 32(%rbp),%rbp
+ notq %r12
+ notq %r13
+ notq %r14
+ notq %r15
+ andq %rax,%r12
+ andq %rax,%r13
+ andq %rax,%r14
+ andq %rax,%r15
+
+ negq %r10
+ adcq 0(%rbx),%r12
+ adcq 8(%rbx),%r13
+ adcq 16(%rbx),%r14
+ adcq 24(%rbx),%r15
movq %r12,0(%rdi)
- sbbq 48(%rbp),%r15
- leaq 64(%rbp),%rbp
+ leaq 32(%rbx),%rbx
movq %r13,8(%rdi)
+ sbbq %r10,%r10
movq %r14,16(%rdi)
movq %r15,24(%rdi)
leaq 32(%rdi),%rdi
incq %rcx
jnz L$sqr4x_sub
+
movq %r9,%r10
negq %r9
.byte 0xf3,0xc3
@@ -1660,10 +1944,9 @@ bn_from_mont8x:
pushq %r13
pushq %r14
pushq %r15
-.byte 0x67
- movl %r9d,%r10d
+
shll $3,%r9d
- shll $3+2,%r10d
+ leaq (%r9,%r9,2),%r10
negq %r9
movq (%r8),%r8
@@ -1673,19 +1956,20 @@ bn_from_mont8x:
- leaq -64(%rsp,%r9,2),%r11
- subq %rsi,%r11
+
+ leaq -320(%rsp,%r9,2),%r11
+ subq %rdi,%r11
andq $4095,%r11
cmpq %r11,%r10
jb L$from_sp_alt
subq %r11,%rsp
- leaq -64(%rsp,%r9,2),%rsp
+ leaq -320(%rsp,%r9,2),%rsp
jmp L$from_sp_done
.p2align 5
L$from_sp_alt:
- leaq 4096-64(,%r9,2),%r10
- leaq -64(%rsp,%r9,2),%rsp
+ leaq 4096-320(,%r9,2),%r10
+ leaq -320(%rsp,%r9,2),%rsp
subq %r10,%r11
movq $0,%r10
cmovcq %r10,%r11
@@ -1736,7 +2020,8 @@ L$mul_by_1:
.byte 0x67
movq %rcx,%rbp
.byte 102,73,15,110,218
- call sqr8x_reduction
+ call __bn_sqr8x_reduction
+ call __bn_post4x_internal
pxor %xmm0,%xmm0
leaq 48(%rsp),%rax
@@ -1786,46 +2071,170 @@ L$scatter_epilogue:
.globl _bn_gather5
.private_extern _bn_gather5
-.p2align 4
+.p2align 5
_bn_gather5:
- movl %ecx,%r11d
- shrl $3,%ecx
- andq $7,%r11
- notl %ecx
- leaq L$magic_masks(%rip),%rax
- andl $3,%ecx
- leaq 128(%rdx,%r11,8),%rdx
- movq 0(%rax,%rcx,8),%xmm4
- movq 8(%rax,%rcx,8),%xmm5
- movq 16(%rax,%rcx,8),%xmm6
- movq 24(%rax,%rcx,8),%xmm7
+L$SEH_begin_bn_gather5:
+
+.byte 0x4c,0x8d,0x14,0x24
+.byte 0x48,0x81,0xec,0x08,0x01,0x00,0x00
+ leaq L$inc(%rip),%rax
+ andq $-16,%rsp
+
+ movd %ecx,%xmm5
+ movdqa 0(%rax),%xmm0
+ movdqa 16(%rax),%xmm1
+ leaq 128(%rdx),%r11
+ leaq 128(%rsp),%rax
+
+ pshufd $0,%xmm5,%xmm5
+ movdqa %xmm1,%xmm4
+ movdqa %xmm1,%xmm2
+ paddd %xmm0,%xmm1
+ pcmpeqd %xmm5,%xmm0
+ movdqa %xmm4,%xmm3
+
+ paddd %xmm1,%xmm2
+ pcmpeqd %xmm5,%xmm1
+ movdqa %xmm0,-128(%rax)
+ movdqa %xmm4,%xmm0
+
+ paddd %xmm2,%xmm3
+ pcmpeqd %xmm5,%xmm2
+ movdqa %xmm1,-112(%rax)
+ movdqa %xmm4,%xmm1
+
+ paddd %xmm3,%xmm0
+ pcmpeqd %xmm5,%xmm3
+ movdqa %xmm2,-96(%rax)
+ movdqa %xmm4,%xmm2
+ paddd %xmm0,%xmm1
+ pcmpeqd %xmm5,%xmm0
+ movdqa %xmm3,-80(%rax)
+ movdqa %xmm4,%xmm3
+
+ paddd %xmm1,%xmm2
+ pcmpeqd %xmm5,%xmm1
+ movdqa %xmm0,-64(%rax)
+ movdqa %xmm4,%xmm0
+
+ paddd %xmm2,%xmm3
+ pcmpeqd %xmm5,%xmm2
+ movdqa %xmm1,-48(%rax)
+ movdqa %xmm4,%xmm1
+
+ paddd %xmm3,%xmm0
+ pcmpeqd %xmm5,%xmm3
+ movdqa %xmm2,-32(%rax)
+ movdqa %xmm4,%xmm2
+ paddd %xmm0,%xmm1
+ pcmpeqd %xmm5,%xmm0
+ movdqa %xmm3,-16(%rax)
+ movdqa %xmm4,%xmm3
+
+ paddd %xmm1,%xmm2
+ pcmpeqd %xmm5,%xmm1
+ movdqa %xmm0,0(%rax)
+ movdqa %xmm4,%xmm0
+
+ paddd %xmm2,%xmm3
+ pcmpeqd %xmm5,%xmm2
+ movdqa %xmm1,16(%rax)
+ movdqa %xmm4,%xmm1
+
+ paddd %xmm3,%xmm0
+ pcmpeqd %xmm5,%xmm3
+ movdqa %xmm2,32(%rax)
+ movdqa %xmm4,%xmm2
+ paddd %xmm0,%xmm1
+ pcmpeqd %xmm5,%xmm0
+ movdqa %xmm3,48(%rax)
+ movdqa %xmm4,%xmm3
+
+ paddd %xmm1,%xmm2
+ pcmpeqd %xmm5,%xmm1
+ movdqa %xmm0,64(%rax)
+ movdqa %xmm4,%xmm0
+
+ paddd %xmm2,%xmm3
+ pcmpeqd %xmm5,%xmm2
+ movdqa %xmm1,80(%rax)
+ movdqa %xmm4,%xmm1
+
+ paddd %xmm3,%xmm0
+ pcmpeqd %xmm5,%xmm3
+ movdqa %xmm2,96(%rax)
+ movdqa %xmm4,%xmm2
+ movdqa %xmm3,112(%rax)
jmp L$gather
-.p2align 4
-L$gather:
- movq -128(%rdx),%xmm0
- movq -64(%rdx),%xmm1
- pand %xmm4,%xmm0
- movq 0(%rdx),%xmm2
- pand %xmm5,%xmm1
- movq 64(%rdx),%xmm3
- pand %xmm6,%xmm2
- por %xmm1,%xmm0
- pand %xmm7,%xmm3
-.byte 0x67,0x67
- por %xmm2,%xmm0
- leaq 256(%rdx),%rdx
- por %xmm3,%xmm0
+.p2align 5
+L$gather:
+ pxor %xmm4,%xmm4
+ pxor %xmm5,%xmm5
+ movdqa -128(%r11),%xmm0
+ movdqa -112(%r11),%xmm1
+ movdqa -96(%r11),%xmm2
+ pand -128(%rax),%xmm0
+ movdqa -80(%r11),%xmm3
+ pand -112(%rax),%xmm1
+ por %xmm0,%xmm4
+ pand -96(%rax),%xmm2
+ por %xmm1,%xmm5
+ pand -80(%rax),%xmm3
+ por %xmm2,%xmm4
+ por %xmm3,%xmm5
+ movdqa -64(%r11),%xmm0
+ movdqa -48(%r11),%xmm1
+ movdqa -32(%r11),%xmm2
+ pand -64(%rax),%xmm0
+ movdqa -16(%r11),%xmm3
+ pand -48(%rax),%xmm1
+ por %xmm0,%xmm4
+ pand -32(%rax),%xmm2
+ por %xmm1,%xmm5
+ pand -16(%rax),%xmm3
+ por %xmm2,%xmm4
+ por %xmm3,%xmm5
+ movdqa 0(%r11),%xmm0
+ movdqa 16(%r11),%xmm1
+ movdqa 32(%r11),%xmm2
+ pand 0(%rax),%xmm0
+ movdqa 48(%r11),%xmm3
+ pand 16(%rax),%xmm1
+ por %xmm0,%xmm4
+ pand 32(%rax),%xmm2
+ por %xmm1,%xmm5
+ pand 48(%rax),%xmm3
+ por %xmm2,%xmm4
+ por %xmm3,%xmm5
+ movdqa 64(%r11),%xmm0
+ movdqa 80(%r11),%xmm1
+ movdqa 96(%r11),%xmm2
+ pand 64(%rax),%xmm0
+ movdqa 112(%r11),%xmm3
+ pand 80(%rax),%xmm1
+ por %xmm0,%xmm4
+ pand 96(%rax),%xmm2
+ por %xmm1,%xmm5
+ pand 112(%rax),%xmm3
+ por %xmm2,%xmm4
+ por %xmm3,%xmm5
+ por %xmm5,%xmm4
+ leaq 256(%r11),%r11
+ pshufd $0x4e,%xmm4,%xmm0
+ por %xmm4,%xmm0
movq %xmm0,(%rdi)
leaq 8(%rdi),%rdi
subl $1,%esi
jnz L$gather
+
+ leaq (%r10),%rsp
.byte 0xf3,0xc3
L$SEH_end_bn_gather5:
.p2align 6
-L$magic_masks:
-.long 0,0, 0,0, 0,0, -1,-1
-.long 0,0, 0,0, 0,0, 0,0
+L$inc:
+.long 0,0, 1,1
+.long 2,2, 2,2
.byte 77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,119,105,116,104,32,115,99,97,116,116,101,114,47,103,97,116,104,101,114,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
#endif
diff --git a/mac-x86_64/crypto/chacha/chacha-x86_64.S b/mac-x86_64/crypto/chacha/chacha-x86_64.S
new file mode 100644
index 00000000..c3554c8d
--- /dev/null
+++ b/mac-x86_64/crypto/chacha/chacha-x86_64.S
@@ -0,0 +1,1584 @@
+#if defined(__x86_64__)
+.text
+
+
+
+.p2align 6
+L$zero:
+.long 0,0,0,0
+L$one:
+.long 1,0,0,0
+L$inc:
+.long 0,1,2,3
+L$four:
+.long 4,4,4,4
+L$incy:
+.long 0,2,4,6,1,3,5,7
+L$eight:
+.long 8,8,8,8,8,8,8,8
+L$rot16:
+.byte 0x2,0x3,0x0,0x1, 0x6,0x7,0x4,0x5, 0xa,0xb,0x8,0x9, 0xe,0xf,0xc,0xd
+L$rot24:
+.byte 0x3,0x0,0x1,0x2, 0x7,0x4,0x5,0x6, 0xb,0x8,0x9,0xa, 0xf,0xc,0xd,0xe
+L$sigma:
+.byte 101,120,112,97,110,100,32,51,50,45,98,121,116,101,32,107,0
+.byte 67,104,97,67,104,97,50,48,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+.globl _ChaCha20_ctr32
+.private_extern _ChaCha20_ctr32
+
+.p2align 6
+_ChaCha20_ctr32:
+ cmpq $0,%rdx
+ je L$no_data
+ movq _OPENSSL_ia32cap_P+4(%rip),%r10
+ testl $512,%r10d
+ jnz L$ChaCha20_ssse3
+
+ pushq %rbx
+ pushq %rbp
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
+ subq $64+24,%rsp
+
+
+ movdqu (%rcx),%xmm1
+ movdqu 16(%rcx),%xmm2
+ movdqu (%r8),%xmm3
+ movdqa L$one(%rip),%xmm4
+
+
+ movdqa %xmm1,16(%rsp)
+ movdqa %xmm2,32(%rsp)
+ movdqa %xmm3,48(%rsp)
+ movq %rdx,%rbp
+ jmp L$oop_outer
+
+.p2align 5
+L$oop_outer:
+ movl $0x61707865,%eax
+ movl $0x3320646e,%ebx
+ movl $0x79622d32,%ecx
+ movl $0x6b206574,%edx
+ movl 16(%rsp),%r8d
+ movl 20(%rsp),%r9d
+ movl 24(%rsp),%r10d
+ movl 28(%rsp),%r11d
+ movd %xmm3,%r12d
+ movl 52(%rsp),%r13d
+ movl 56(%rsp),%r14d
+ movl 60(%rsp),%r15d
+
+ movq %rbp,64+0(%rsp)
+ movl $10,%ebp
+ movq %rsi,64+8(%rsp)
+.byte 102,72,15,126,214
+ movq %rdi,64+16(%rsp)
+ movq %rsi,%rdi
+ shrq $32,%rdi
+ jmp L$oop
+
+.p2align 5
+L$oop:
+ addl %r8d,%eax
+ xorl %eax,%r12d
+ roll $16,%r12d
+ addl %r9d,%ebx
+ xorl %ebx,%r13d
+ roll $16,%r13d
+ addl %r12d,%esi
+ xorl %esi,%r8d
+ roll $12,%r8d
+ addl %r13d,%edi
+ xorl %edi,%r9d
+ roll $12,%r9d
+ addl %r8d,%eax
+ xorl %eax,%r12d
+ roll $8,%r12d
+ addl %r9d,%ebx
+ xorl %ebx,%r13d
+ roll $8,%r13d
+ addl %r12d,%esi
+ xorl %esi,%r8d
+ roll $7,%r8d
+ addl %r13d,%edi
+ xorl %edi,%r9d
+ roll $7,%r9d
+ movl %esi,32(%rsp)
+ movl %edi,36(%rsp)
+ movl 40(%rsp),%esi
+ movl 44(%rsp),%edi
+ addl %r10d,%ecx
+ xorl %ecx,%r14d
+ roll $16,%r14d
+ addl %r11d,%edx
+ xorl %edx,%r15d
+ roll $16,%r15d
+ addl %r14d,%esi
+ xorl %esi,%r10d
+ roll $12,%r10d
+ addl %r15d,%edi
+ xorl %edi,%r11d
+ roll $12,%r11d
+ addl %r10d,%ecx
+ xorl %ecx,%r14d
+ roll $8,%r14d
+ addl %r11d,%edx
+ xorl %edx,%r15d
+ roll $8,%r15d
+ addl %r14d,%esi
+ xorl %esi,%r10d
+ roll $7,%r10d
+ addl %r15d,%edi
+ xorl %edi,%r11d
+ roll $7,%r11d
+ addl %r9d,%eax
+ xorl %eax,%r15d
+ roll $16,%r15d
+ addl %r10d,%ebx
+ xorl %ebx,%r12d
+ roll $16,%r12d
+ addl %r15d,%esi
+ xorl %esi,%r9d
+ roll $12,%r9d
+ addl %r12d,%edi
+ xorl %edi,%r10d
+ roll $12,%r10d
+ addl %r9d,%eax
+ xorl %eax,%r15d
+ roll $8,%r15d
+ addl %r10d,%ebx
+ xorl %ebx,%r12d
+ roll $8,%r12d
+ addl %r15d,%esi
+ xorl %esi,%r9d
+ roll $7,%r9d
+ addl %r12d,%edi
+ xorl %edi,%r10d
+ roll $7,%r10d
+ movl %esi,40(%rsp)
+ movl %edi,44(%rsp)
+ movl 32(%rsp),%esi
+ movl 36(%rsp),%edi
+ addl %r11d,%ecx
+ xorl %ecx,%r13d
+ roll $16,%r13d
+ addl %r8d,%edx
+ xorl %edx,%r14d
+ roll $16,%r14d
+ addl %r13d,%esi
+ xorl %esi,%r11d
+ roll $12,%r11d
+ addl %r14d,%edi
+ xorl %edi,%r8d
+ roll $12,%r8d
+ addl %r11d,%ecx
+ xorl %ecx,%r13d
+ roll $8,%r13d
+ addl %r8d,%edx
+ xorl %edx,%r14d
+ roll $8,%r14d
+ addl %r13d,%esi
+ xorl %esi,%r11d
+ roll $7,%r11d
+ addl %r14d,%edi
+ xorl %edi,%r8d
+ roll $7,%r8d
+ decl %ebp
+ jnz L$oop
+ movl %edi,36(%rsp)
+ movl %esi,32(%rsp)
+ movq 64(%rsp),%rbp
+ movdqa %xmm2,%xmm1
+ movq 64+8(%rsp),%rsi
+ paddd %xmm4,%xmm3
+ movq 64+16(%rsp),%rdi
+
+ addl $0x61707865,%eax
+ addl $0x3320646e,%ebx
+ addl $0x79622d32,%ecx
+ addl $0x6b206574,%edx
+ addl 16(%rsp),%r8d
+ addl 20(%rsp),%r9d
+ addl 24(%rsp),%r10d
+ addl 28(%rsp),%r11d
+ addl 48(%rsp),%r12d
+ addl 52(%rsp),%r13d
+ addl 56(%rsp),%r14d
+ addl 60(%rsp),%r15d
+ paddd 32(%rsp),%xmm1
+
+ cmpq $64,%rbp
+ jb L$tail
+
+ xorl 0(%rsi),%eax
+ xorl 4(%rsi),%ebx
+ xorl 8(%rsi),%ecx
+ xorl 12(%rsi),%edx
+ xorl 16(%rsi),%r8d
+ xorl 20(%rsi),%r9d
+ xorl 24(%rsi),%r10d
+ xorl 28(%rsi),%r11d
+ movdqu 32(%rsi),%xmm0
+ xorl 48(%rsi),%r12d
+ xorl 52(%rsi),%r13d
+ xorl 56(%rsi),%r14d
+ xorl 60(%rsi),%r15d
+ leaq 64(%rsi),%rsi
+ pxor %xmm1,%xmm0
+
+ movdqa %xmm2,32(%rsp)
+ movd %xmm3,48(%rsp)
+
+ movl %eax,0(%rdi)
+ movl %ebx,4(%rdi)
+ movl %ecx,8(%rdi)
+ movl %edx,12(%rdi)
+ movl %r8d,16(%rdi)
+ movl %r9d,20(%rdi)
+ movl %r10d,24(%rdi)
+ movl %r11d,28(%rdi)
+ movdqu %xmm0,32(%rdi)
+ movl %r12d,48(%rdi)
+ movl %r13d,52(%rdi)
+ movl %r14d,56(%rdi)
+ movl %r15d,60(%rdi)
+ leaq 64(%rdi),%rdi
+
+ subq $64,%rbp
+ jnz L$oop_outer
+
+ jmp L$done
+
+.p2align 4
+L$tail:
+ movl %eax,0(%rsp)
+ movl %ebx,4(%rsp)
+ xorq %rbx,%rbx
+ movl %ecx,8(%rsp)
+ movl %edx,12(%rsp)
+ movl %r8d,16(%rsp)
+ movl %r9d,20(%rsp)
+ movl %r10d,24(%rsp)
+ movl %r11d,28(%rsp)
+ movdqa %xmm1,32(%rsp)
+ movl %r12d,48(%rsp)
+ movl %r13d,52(%rsp)
+ movl %r14d,56(%rsp)
+ movl %r15d,60(%rsp)
+
+L$oop_tail:
+ movzbl (%rsi,%rbx,1),%eax
+ movzbl (%rsp,%rbx,1),%edx
+ leaq 1(%rbx),%rbx
+ xorl %edx,%eax
+ movb %al,-1(%rdi,%rbx,1)
+ decq %rbp
+ jnz L$oop_tail
+
+L$done:
+ addq $64+24,%rsp
+ popq %r15
+ popq %r14
+ popq %r13
+ popq %r12
+ popq %rbp
+ popq %rbx
+L$no_data:
+ .byte 0xf3,0xc3
+
+
+.p2align 5
+ChaCha20_ssse3:
+L$ChaCha20_ssse3:
+ cmpq $128,%rdx
+ ja L$ChaCha20_4x
+
+L$do_sse3_after_all:
+ pushq %rbx
+ pushq %rbp
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
+
+ subq $64+24,%rsp
+ movdqa L$sigma(%rip),%xmm0
+ movdqu (%rcx),%xmm1
+ movdqu 16(%rcx),%xmm2
+ movdqu (%r8),%xmm3
+ movdqa L$rot16(%rip),%xmm6
+ movdqa L$rot24(%rip),%xmm7
+
+ movdqa %xmm0,0(%rsp)
+ movdqa %xmm1,16(%rsp)
+ movdqa %xmm2,32(%rsp)
+ movdqa %xmm3,48(%rsp)
+ movl $10,%ebp
+ jmp L$oop_ssse3
+
+.p2align 5
+L$oop_outer_ssse3:
+ movdqa L$one(%rip),%xmm3
+ movdqa 0(%rsp),%xmm0
+ movdqa 16(%rsp),%xmm1
+ movdqa 32(%rsp),%xmm2
+ paddd 48(%rsp),%xmm3
+ movl $10,%ebp
+ movdqa %xmm3,48(%rsp)
+ jmp L$oop_ssse3
+
+.p2align 5
+L$oop_ssse3:
+ paddd %xmm1,%xmm0
+ pxor %xmm0,%xmm3
+.byte 102,15,56,0,222
+ paddd %xmm3,%xmm2
+ pxor %xmm2,%xmm1
+ movdqa %xmm1,%xmm4
+ psrld $20,%xmm1
+ pslld $12,%xmm4
+ por %xmm4,%xmm1
+ paddd %xmm1,%xmm0
+ pxor %xmm0,%xmm3
+.byte 102,15,56,0,223
+ paddd %xmm3,%xmm2
+ pxor %xmm2,%xmm1
+ movdqa %xmm1,%xmm4
+ psrld $25,%xmm1
+ pslld $7,%xmm4
+ por %xmm4,%xmm1
+ pshufd $78,%xmm2,%xmm2
+ pshufd $57,%xmm1,%xmm1
+ pshufd $147,%xmm3,%xmm3
+ nop
+ paddd %xmm1,%xmm0
+ pxor %xmm0,%xmm3
+.byte 102,15,56,0,222
+ paddd %xmm3,%xmm2
+ pxor %xmm2,%xmm1
+ movdqa %xmm1,%xmm4
+ psrld $20,%xmm1
+ pslld $12,%xmm4
+ por %xmm4,%xmm1
+ paddd %xmm1,%xmm0
+ pxor %xmm0,%xmm3
+.byte 102,15,56,0,223
+ paddd %xmm3,%xmm2
+ pxor %xmm2,%xmm1
+ movdqa %xmm1,%xmm4
+ psrld $25,%xmm1
+ pslld $7,%xmm4
+ por %xmm4,%xmm1
+ pshufd $78,%xmm2,%xmm2
+ pshufd $147,%xmm1,%xmm1
+ pshufd $57,%xmm3,%xmm3
+ decl %ebp
+ jnz L$oop_ssse3
+ paddd 0(%rsp),%xmm0
+ paddd 16(%rsp),%xmm1
+ paddd 32(%rsp),%xmm2
+ paddd 48(%rsp),%xmm3
+
+ cmpq $64,%rdx
+ jb L$tail_ssse3
+
+ movdqu 0(%rsi),%xmm4
+ movdqu 16(%rsi),%xmm5
+ pxor %xmm4,%xmm0
+ movdqu 32(%rsi),%xmm4
+ pxor %xmm5,%xmm1
+ movdqu 48(%rsi),%xmm5
+ leaq 64(%rsi),%rsi
+ pxor %xmm4,%xmm2
+ pxor %xmm5,%xmm3
+
+ movdqu %xmm0,0(%rdi)
+ movdqu %xmm1,16(%rdi)
+ movdqu %xmm2,32(%rdi)
+ movdqu %xmm3,48(%rdi)
+ leaq 64(%rdi),%rdi
+
+ subq $64,%rdx
+ jnz L$oop_outer_ssse3
+
+ jmp L$done_ssse3
+
+.p2align 4
+L$tail_ssse3:
+ movdqa %xmm0,0(%rsp)
+ movdqa %xmm1,16(%rsp)
+ movdqa %xmm2,32(%rsp)
+ movdqa %xmm3,48(%rsp)
+ xorq %rbx,%rbx
+
+L$oop_tail_ssse3:
+ movzbl (%rsi,%rbx,1),%eax
+ movzbl (%rsp,%rbx,1),%ecx
+ leaq 1(%rbx),%rbx
+ xorl %ecx,%eax
+ movb %al,-1(%rdi,%rbx,1)
+ decq %rdx
+ jnz L$oop_tail_ssse3
+
+L$done_ssse3:
+ addq $64+24,%rsp
+ popq %r15
+ popq %r14
+ popq %r13
+ popq %r12
+ popq %rbp
+ popq %rbx
+ .byte 0xf3,0xc3
+
+
+.p2align 5
+ChaCha20_4x:
+L$ChaCha20_4x:
+ movq %r10,%r11
+ shrq $32,%r10
+ testq $32,%r10
+ jnz L$ChaCha20_8x
+ cmpq $192,%rdx
+ ja L$proceed4x
+
+ andq $71303168,%r11
+ cmpq $4194304,%r11
+ je L$do_sse3_after_all
+
+L$proceed4x:
+ leaq -120(%rsp),%r11
+ subq $0x148+0,%rsp
+ movdqa L$sigma(%rip),%xmm11
+ movdqu (%rcx),%xmm15
+ movdqu 16(%rcx),%xmm7
+ movdqu (%r8),%xmm3
+ leaq 256(%rsp),%rcx
+ leaq L$rot16(%rip),%r10
+ leaq L$rot24(%rip),%r11
+
+ pshufd $0x00,%xmm11,%xmm8
+ pshufd $0x55,%xmm11,%xmm9
+ movdqa %xmm8,64(%rsp)
+ pshufd $0xaa,%xmm11,%xmm10
+ movdqa %xmm9,80(%rsp)
+ pshufd $0xff,%xmm11,%xmm11
+ movdqa %xmm10,96(%rsp)
+ movdqa %xmm11,112(%rsp)
+
+ pshufd $0x00,%xmm15,%xmm12
+ pshufd $0x55,%xmm15,%xmm13
+ movdqa %xmm12,128-256(%rcx)
+ pshufd $0xaa,%xmm15,%xmm14
+ movdqa %xmm13,144-256(%rcx)
+ pshufd $0xff,%xmm15,%xmm15
+ movdqa %xmm14,160-256(%rcx)
+ movdqa %xmm15,176-256(%rcx)
+
+ pshufd $0x00,%xmm7,%xmm4
+ pshufd $0x55,%xmm7,%xmm5
+ movdqa %xmm4,192-256(%rcx)
+ pshufd $0xaa,%xmm7,%xmm6
+ movdqa %xmm5,208-256(%rcx)
+ pshufd $0xff,%xmm7,%xmm7
+ movdqa %xmm6,224-256(%rcx)
+ movdqa %xmm7,240-256(%rcx)
+
+ pshufd $0x00,%xmm3,%xmm0
+ pshufd $0x55,%xmm3,%xmm1
+ paddd L$inc(%rip),%xmm0
+ pshufd $0xaa,%xmm3,%xmm2
+ movdqa %xmm1,272-256(%rcx)
+ pshufd $0xff,%xmm3,%xmm3
+ movdqa %xmm2,288-256(%rcx)
+ movdqa %xmm3,304-256(%rcx)
+
+ jmp L$oop_enter4x
+
+.p2align 5
+L$oop_outer4x:
+ movdqa 64(%rsp),%xmm8
+ movdqa 80(%rsp),%xmm9
+ movdqa 96(%rsp),%xmm10
+ movdqa 112(%rsp),%xmm11
+ movdqa 128-256(%rcx),%xmm12
+ movdqa 144-256(%rcx),%xmm13
+ movdqa 160-256(%rcx),%xmm14
+ movdqa 176-256(%rcx),%xmm15
+ movdqa 192-256(%rcx),%xmm4
+ movdqa 208-256(%rcx),%xmm5
+ movdqa 224-256(%rcx),%xmm6
+ movdqa 240-256(%rcx),%xmm7
+ movdqa 256-256(%rcx),%xmm0
+ movdqa 272-256(%rcx),%xmm1
+ movdqa 288-256(%rcx),%xmm2
+ movdqa 304-256(%rcx),%xmm3
+ paddd L$four(%rip),%xmm0
+
+L$oop_enter4x:
+ movdqa %xmm6,32(%rsp)
+ movdqa %xmm7,48(%rsp)
+ movdqa (%r10),%xmm7
+ movl $10,%eax
+ movdqa %xmm0,256-256(%rcx)
+ jmp L$oop4x
+
+.p2align 5
+L$oop4x:
+ paddd %xmm12,%xmm8
+ paddd %xmm13,%xmm9
+ pxor %xmm8,%xmm0
+ pxor %xmm9,%xmm1
+.byte 102,15,56,0,199
+.byte 102,15,56,0,207
+ paddd %xmm0,%xmm4
+ paddd %xmm1,%xmm5
+ pxor %xmm4,%xmm12
+ pxor %xmm5,%xmm13
+ movdqa %xmm12,%xmm6
+ pslld $12,%xmm12
+ psrld $20,%xmm6
+ movdqa %xmm13,%xmm7
+ pslld $12,%xmm13
+ por %xmm6,%xmm12
+ psrld $20,%xmm7
+ movdqa (%r11),%xmm6
+ por %xmm7,%xmm13
+ paddd %xmm12,%xmm8
+ paddd %xmm13,%xmm9
+ pxor %xmm8,%xmm0
+ pxor %xmm9,%xmm1
+.byte 102,15,56,0,198
+.byte 102,15,56,0,206
+ paddd %xmm0,%xmm4
+ paddd %xmm1,%xmm5
+ pxor %xmm4,%xmm12
+ pxor %xmm5,%xmm13
+ movdqa %xmm12,%xmm7
+ pslld $7,%xmm12
+ psrld $25,%xmm7
+ movdqa %xmm13,%xmm6
+ pslld $7,%xmm13
+ por %xmm7,%xmm12
+ psrld $25,%xmm6
+ movdqa (%r10),%xmm7
+ por %xmm6,%xmm13
+ movdqa %xmm4,0(%rsp)
+ movdqa %xmm5,16(%rsp)
+ movdqa 32(%rsp),%xmm4
+ movdqa 48(%rsp),%xmm5
+ paddd %xmm14,%xmm10
+ paddd %xmm15,%xmm11
+ pxor %xmm10,%xmm2
+ pxor %xmm11,%xmm3
+.byte 102,15,56,0,215
+.byte 102,15,56,0,223
+ paddd %xmm2,%xmm4
+ paddd %xmm3,%xmm5
+ pxor %xmm4,%xmm14
+ pxor %xmm5,%xmm15
+ movdqa %xmm14,%xmm6
+ pslld $12,%xmm14
+ psrld $20,%xmm6
+ movdqa %xmm15,%xmm7
+ pslld $12,%xmm15
+ por %xmm6,%xmm14
+ psrld $20,%xmm7
+ movdqa (%r11),%xmm6
+ por %xmm7,%xmm15
+ paddd %xmm14,%xmm10
+ paddd %xmm15,%xmm11
+ pxor %xmm10,%xmm2
+ pxor %xmm11,%xmm3
+.byte 102,15,56,0,214
+.byte 102,15,56,0,222
+ paddd %xmm2,%xmm4
+ paddd %xmm3,%xmm5
+ pxor %xmm4,%xmm14
+ pxor %xmm5,%xmm15
+ movdqa %xmm14,%xmm7
+ pslld $7,%xmm14
+ psrld $25,%xmm7
+ movdqa %xmm15,%xmm6
+ pslld $7,%xmm15
+ por %xmm7,%xmm14
+ psrld $25,%xmm6
+ movdqa (%r10),%xmm7
+ por %xmm6,%xmm15
+ paddd %xmm13,%xmm8
+ paddd %xmm14,%xmm9
+ pxor %xmm8,%xmm3
+ pxor %xmm9,%xmm0
+.byte 102,15,56,0,223
+.byte 102,15,56,0,199
+ paddd %xmm3,%xmm4
+ paddd %xmm0,%xmm5
+ pxor %xmm4,%xmm13
+ pxor %xmm5,%xmm14
+ movdqa %xmm13,%xmm6
+ pslld $12,%xmm13
+ psrld $20,%xmm6
+ movdqa %xmm14,%xmm7
+ pslld $12,%xmm14
+ por %xmm6,%xmm13
+ psrld $20,%xmm7
+ movdqa (%r11),%xmm6
+ por %xmm7,%xmm14
+ paddd %xmm13,%xmm8
+ paddd %xmm14,%xmm9
+ pxor %xmm8,%xmm3
+ pxor %xmm9,%xmm0
+.byte 102,15,56,0,222
+.byte 102,15,56,0,198
+ paddd %xmm3,%xmm4
+ paddd %xmm0,%xmm5
+ pxor %xmm4,%xmm13
+ pxor %xmm5,%xmm14
+ movdqa %xmm13,%xmm7
+ pslld $7,%xmm13
+ psrld $25,%xmm7
+ movdqa %xmm14,%xmm6
+ pslld $7,%xmm14
+ por %xmm7,%xmm13
+ psrld $25,%xmm6
+ movdqa (%r10),%xmm7
+ por %xmm6,%xmm14
+ movdqa %xmm4,32(%rsp)
+ movdqa %xmm5,48(%rsp)
+ movdqa 0(%rsp),%xmm4
+ movdqa 16(%rsp),%xmm5
+ paddd %xmm15,%xmm10
+ paddd %xmm12,%xmm11
+ pxor %xmm10,%xmm1
+ pxor %xmm11,%xmm2
+.byte 102,15,56,0,207
+.byte 102,15,56,0,215
+ paddd %xmm1,%xmm4
+ paddd %xmm2,%xmm5
+ pxor %xmm4,%xmm15
+ pxor %xmm5,%xmm12
+ movdqa %xmm15,%xmm6
+ pslld $12,%xmm15
+ psrld $20,%xmm6
+ movdqa %xmm12,%xmm7
+ pslld $12,%xmm12
+ por %xmm6,%xmm15
+ psrld $20,%xmm7
+ movdqa (%r11),%xmm6
+ por %xmm7,%xmm12
+ paddd %xmm15,%xmm10
+ paddd %xmm12,%xmm11
+ pxor %xmm10,%xmm1
+ pxor %xmm11,%xmm2
+.byte 102,15,56,0,206
+.byte 102,15,56,0,214
+ paddd %xmm1,%xmm4
+ paddd %xmm2,%xmm5
+ pxor %xmm4,%xmm15
+ pxor %xmm5,%xmm12
+ movdqa %xmm15,%xmm7
+ pslld $7,%xmm15
+ psrld $25,%xmm7
+ movdqa %xmm12,%xmm6
+ pslld $7,%xmm12
+ por %xmm7,%xmm15
+ psrld $25,%xmm6
+ movdqa (%r10),%xmm7
+ por %xmm6,%xmm12
+ decl %eax
+ jnz L$oop4x
+
+ paddd 64(%rsp),%xmm8
+ paddd 80(%rsp),%xmm9
+ paddd 96(%rsp),%xmm10
+ paddd 112(%rsp),%xmm11
+
+ movdqa %xmm8,%xmm6
+ punpckldq %xmm9,%xmm8
+ movdqa %xmm10,%xmm7
+ punpckldq %xmm11,%xmm10
+ punpckhdq %xmm9,%xmm6
+ punpckhdq %xmm11,%xmm7
+ movdqa %xmm8,%xmm9
+ punpcklqdq %xmm10,%xmm8
+ movdqa %xmm6,%xmm11
+ punpcklqdq %xmm7,%xmm6
+ punpckhqdq %xmm10,%xmm9
+ punpckhqdq %xmm7,%xmm11
+ paddd 128-256(%rcx),%xmm12
+ paddd 144-256(%rcx),%xmm13
+ paddd 160-256(%rcx),%xmm14
+ paddd 176-256(%rcx),%xmm15
+
+ movdqa %xmm8,0(%rsp)
+ movdqa %xmm9,16(%rsp)
+ movdqa 32(%rsp),%xmm8
+ movdqa 48(%rsp),%xmm9
+
+ movdqa %xmm12,%xmm10
+ punpckldq %xmm13,%xmm12
+ movdqa %xmm14,%xmm7
+ punpckldq %xmm15,%xmm14
+ punpckhdq %xmm13,%xmm10
+ punpckhdq %xmm15,%xmm7
+ movdqa %xmm12,%xmm13
+ punpcklqdq %xmm14,%xmm12
+ movdqa %xmm10,%xmm15
+ punpcklqdq %xmm7,%xmm10
+ punpckhqdq %xmm14,%xmm13
+ punpckhqdq %xmm7,%xmm15
+ paddd 192-256(%rcx),%xmm4
+ paddd 208-256(%rcx),%xmm5
+ paddd 224-256(%rcx),%xmm8
+ paddd 240-256(%rcx),%xmm9
+
+ movdqa %xmm6,32(%rsp)
+ movdqa %xmm11,48(%rsp)
+
+ movdqa %xmm4,%xmm14
+ punpckldq %xmm5,%xmm4
+ movdqa %xmm8,%xmm7
+ punpckldq %xmm9,%xmm8
+ punpckhdq %xmm5,%xmm14
+ punpckhdq %xmm9,%xmm7
+ movdqa %xmm4,%xmm5
+ punpcklqdq %xmm8,%xmm4
+ movdqa %xmm14,%xmm9
+ punpcklqdq %xmm7,%xmm14
+ punpckhqdq %xmm8,%xmm5
+ punpckhqdq %xmm7,%xmm9
+ paddd 256-256(%rcx),%xmm0
+ paddd 272-256(%rcx),%xmm1
+ paddd 288-256(%rcx),%xmm2
+ paddd 304-256(%rcx),%xmm3
+
+ movdqa %xmm0,%xmm8
+ punpckldq %xmm1,%xmm0
+ movdqa %xmm2,%xmm7
+ punpckldq %xmm3,%xmm2
+ punpckhdq %xmm1,%xmm8
+ punpckhdq %xmm3,%xmm7
+ movdqa %xmm0,%xmm1
+ punpcklqdq %xmm2,%xmm0
+ movdqa %xmm8,%xmm3
+ punpcklqdq %xmm7,%xmm8
+ punpckhqdq %xmm2,%xmm1
+ punpckhqdq %xmm7,%xmm3
+ cmpq $256,%rdx
+ jb L$tail4x
+
+ movdqu 0(%rsi),%xmm6
+ movdqu 16(%rsi),%xmm11
+ movdqu 32(%rsi),%xmm2
+ movdqu 48(%rsi),%xmm7
+ pxor 0(%rsp),%xmm6
+ pxor %xmm12,%xmm11
+ pxor %xmm4,%xmm2
+ pxor %xmm0,%xmm7
+
+ movdqu %xmm6,0(%rdi)
+ movdqu 64(%rsi),%xmm6
+ movdqu %xmm11,16(%rdi)
+ movdqu 80(%rsi),%xmm11
+ movdqu %xmm2,32(%rdi)
+ movdqu 96(%rsi),%xmm2
+ movdqu %xmm7,48(%rdi)
+ movdqu 112(%rsi),%xmm7
+ leaq 128(%rsi),%rsi
+ pxor 16(%rsp),%xmm6
+ pxor %xmm13,%xmm11
+ pxor %xmm5,%xmm2
+ pxor %xmm1,%xmm7
+
+ movdqu %xmm6,64(%rdi)
+ movdqu 0(%rsi),%xmm6
+ movdqu %xmm11,80(%rdi)
+ movdqu 16(%rsi),%xmm11
+ movdqu %xmm2,96(%rdi)
+ movdqu 32(%rsi),%xmm2
+ movdqu %xmm7,112(%rdi)
+ leaq 128(%rdi),%rdi
+ movdqu 48(%rsi),%xmm7
+ pxor 32(%rsp),%xmm6
+ pxor %xmm10,%xmm11
+ pxor %xmm14,%xmm2
+ pxor %xmm8,%xmm7
+
+ movdqu %xmm6,0(%rdi)
+ movdqu 64(%rsi),%xmm6
+ movdqu %xmm11,16(%rdi)
+ movdqu 80(%rsi),%xmm11
+ movdqu %xmm2,32(%rdi)
+ movdqu 96(%rsi),%xmm2
+ movdqu %xmm7,48(%rdi)
+ movdqu 112(%rsi),%xmm7
+ leaq 128(%rsi),%rsi
+ pxor 48(%rsp),%xmm6
+ pxor %xmm15,%xmm11
+ pxor %xmm9,%xmm2
+ pxor %xmm3,%xmm7
+ movdqu %xmm6,64(%rdi)
+ movdqu %xmm11,80(%rdi)
+ movdqu %xmm2,96(%rdi)
+ movdqu %xmm7,112(%rdi)
+ leaq 128(%rdi),%rdi
+
+ subq $256,%rdx
+ jnz L$oop_outer4x
+
+ jmp L$done4x
+
+L$tail4x:
+ cmpq $192,%rdx
+ jae L$192_or_more4x
+ cmpq $128,%rdx
+ jae L$128_or_more4x
+ cmpq $64,%rdx
+ jae L$64_or_more4x
+
+
+ xorq %r10,%r10
+
+ movdqa %xmm12,16(%rsp)
+ movdqa %xmm4,32(%rsp)
+ movdqa %xmm0,48(%rsp)
+ jmp L$oop_tail4x
+
+.p2align 5
+L$64_or_more4x:
+ movdqu 0(%rsi),%xmm6
+ movdqu 16(%rsi),%xmm11
+ movdqu 32(%rsi),%xmm2
+ movdqu 48(%rsi),%xmm7
+ pxor 0(%rsp),%xmm6
+ pxor %xmm12,%xmm11
+ pxor %xmm4,%xmm2
+ pxor %xmm0,%xmm7
+ movdqu %xmm6,0(%rdi)
+ movdqu %xmm11,16(%rdi)
+ movdqu %xmm2,32(%rdi)
+ movdqu %xmm7,48(%rdi)
+ je L$done4x
+
+ movdqa 16(%rsp),%xmm6
+ leaq 64(%rsi),%rsi
+ xorq %r10,%r10
+ movdqa %xmm6,0(%rsp)
+ movdqa %xmm13,16(%rsp)
+ leaq 64(%rdi),%rdi
+ movdqa %xmm5,32(%rsp)
+ subq $64,%rdx
+ movdqa %xmm1,48(%rsp)
+ jmp L$oop_tail4x
+
+.p2align 5
+L$128_or_more4x:
+ movdqu 0(%rsi),%xmm6
+ movdqu 16(%rsi),%xmm11
+ movdqu 32(%rsi),%xmm2
+ movdqu 48(%rsi),%xmm7
+ pxor 0(%rsp),%xmm6
+ pxor %xmm12,%xmm11
+ pxor %xmm4,%xmm2
+ pxor %xmm0,%xmm7
+
+ movdqu %xmm6,0(%rdi)
+ movdqu 64(%rsi),%xmm6
+ movdqu %xmm11,16(%rdi)
+ movdqu 80(%rsi),%xmm11
+ movdqu %xmm2,32(%rdi)
+ movdqu 96(%rsi),%xmm2
+ movdqu %xmm7,48(%rdi)
+ movdqu 112(%rsi),%xmm7
+ pxor 16(%rsp),%xmm6
+ pxor %xmm13,%xmm11
+ pxor %xmm5,%xmm2
+ pxor %xmm1,%xmm7
+ movdqu %xmm6,64(%rdi)
+ movdqu %xmm11,80(%rdi)
+ movdqu %xmm2,96(%rdi)
+ movdqu %xmm7,112(%rdi)
+ je L$done4x
+
+ movdqa 32(%rsp),%xmm6
+ leaq 128(%rsi),%rsi
+ xorq %r10,%r10
+ movdqa %xmm6,0(%rsp)
+ movdqa %xmm10,16(%rsp)
+ leaq 128(%rdi),%rdi
+ movdqa %xmm14,32(%rsp)
+ subq $128,%rdx
+ movdqa %xmm8,48(%rsp)
+ jmp L$oop_tail4x
+
+.p2align 5
+L$192_or_more4x:
+ movdqu 0(%rsi),%xmm6
+ movdqu 16(%rsi),%xmm11
+ movdqu 32(%rsi),%xmm2
+ movdqu 48(%rsi),%xmm7
+ pxor 0(%rsp),%xmm6
+ pxor %xmm12,%xmm11
+ pxor %xmm4,%xmm2
+ pxor %xmm0,%xmm7
+
+ movdqu %xmm6,0(%rdi)
+ movdqu 64(%rsi),%xmm6
+ movdqu %xmm11,16(%rdi)
+ movdqu 80(%rsi),%xmm11
+ movdqu %xmm2,32(%rdi)
+ movdqu 96(%rsi),%xmm2
+ movdqu %xmm7,48(%rdi)
+ movdqu 112(%rsi),%xmm7
+ leaq 128(%rsi),%rsi
+ pxor 16(%rsp),%xmm6
+ pxor %xmm13,%xmm11
+ pxor %xmm5,%xmm2
+ pxor %xmm1,%xmm7
+
+ movdqu %xmm6,64(%rdi)
+ movdqu 0(%rsi),%xmm6
+ movdqu %xmm11,80(%rdi)
+ movdqu 16(%rsi),%xmm11
+ movdqu %xmm2,96(%rdi)
+ movdqu 32(%rsi),%xmm2
+ movdqu %xmm7,112(%rdi)
+ leaq 128(%rdi),%rdi
+ movdqu 48(%rsi),%xmm7
+ pxor 32(%rsp),%xmm6
+ pxor %xmm10,%xmm11
+ pxor %xmm14,%xmm2
+ pxor %xmm8,%xmm7
+ movdqu %xmm6,0(%rdi)
+ movdqu %xmm11,16(%rdi)
+ movdqu %xmm2,32(%rdi)
+ movdqu %xmm7,48(%rdi)
+ je L$done4x
+
+ movdqa 48(%rsp),%xmm6
+ leaq 64(%rsi),%rsi
+ xorq %r10,%r10
+ movdqa %xmm6,0(%rsp)
+ movdqa %xmm15,16(%rsp)
+ leaq 64(%rdi),%rdi
+ movdqa %xmm9,32(%rsp)
+ subq $192,%rdx
+ movdqa %xmm3,48(%rsp)
+
+L$oop_tail4x:
+ movzbl (%rsi,%r10,1),%eax
+ movzbl (%rsp,%r10,1),%ecx
+ leaq 1(%r10),%r10
+ xorl %ecx,%eax
+ movb %al,-1(%rdi,%r10,1)
+ decq %rdx
+ jnz L$oop_tail4x
+
+L$done4x:
+ addq $0x148+0,%rsp
+ .byte 0xf3,0xc3
+
+
+.p2align 5
+ChaCha20_8x:
+L$ChaCha20_8x:
+ movq %rsp,%r10
+ subq $0x280+8,%rsp
+ andq $-32,%rsp
+ vzeroupper
+ movq %r10,640(%rsp)
+
+
+
+
+
+
+
+
+
+
+ vbroadcasti128 L$sigma(%rip),%ymm11
+ vbroadcasti128 (%rcx),%ymm3
+ vbroadcasti128 16(%rcx),%ymm15
+ vbroadcasti128 (%r8),%ymm7
+ leaq 256(%rsp),%rcx
+ leaq 512(%rsp),%rax
+ leaq L$rot16(%rip),%r10
+ leaq L$rot24(%rip),%r11
+
+ vpshufd $0x00,%ymm11,%ymm8
+ vpshufd $0x55,%ymm11,%ymm9
+ vmovdqa %ymm8,128-256(%rcx)
+ vpshufd $0xaa,%ymm11,%ymm10
+ vmovdqa %ymm9,160-256(%rcx)
+ vpshufd $0xff,%ymm11,%ymm11
+ vmovdqa %ymm10,192-256(%rcx)
+ vmovdqa %ymm11,224-256(%rcx)
+
+ vpshufd $0x00,%ymm3,%ymm0
+ vpshufd $0x55,%ymm3,%ymm1
+ vmovdqa %ymm0,256-256(%rcx)
+ vpshufd $0xaa,%ymm3,%ymm2
+ vmovdqa %ymm1,288-256(%rcx)
+ vpshufd $0xff,%ymm3,%ymm3
+ vmovdqa %ymm2,320-256(%rcx)
+ vmovdqa %ymm3,352-256(%rcx)
+
+ vpshufd $0x00,%ymm15,%ymm12
+ vpshufd $0x55,%ymm15,%ymm13
+ vmovdqa %ymm12,384-512(%rax)
+ vpshufd $0xaa,%ymm15,%ymm14
+ vmovdqa %ymm13,416-512(%rax)
+ vpshufd $0xff,%ymm15,%ymm15
+ vmovdqa %ymm14,448-512(%rax)
+ vmovdqa %ymm15,480-512(%rax)
+
+ vpshufd $0x00,%ymm7,%ymm4
+ vpshufd $0x55,%ymm7,%ymm5
+ vpaddd L$incy(%rip),%ymm4,%ymm4
+ vpshufd $0xaa,%ymm7,%ymm6
+ vmovdqa %ymm5,544-512(%rax)
+ vpshufd $0xff,%ymm7,%ymm7
+ vmovdqa %ymm6,576-512(%rax)
+ vmovdqa %ymm7,608-512(%rax)
+
+ jmp L$oop_enter8x
+
+.p2align 5
+L$oop_outer8x:
+ vmovdqa 128-256(%rcx),%ymm8
+ vmovdqa 160-256(%rcx),%ymm9
+ vmovdqa 192-256(%rcx),%ymm10
+ vmovdqa 224-256(%rcx),%ymm11
+ vmovdqa 256-256(%rcx),%ymm0
+ vmovdqa 288-256(%rcx),%ymm1
+ vmovdqa 320-256(%rcx),%ymm2
+ vmovdqa 352-256(%rcx),%ymm3
+ vmovdqa 384-512(%rax),%ymm12
+ vmovdqa 416-512(%rax),%ymm13
+ vmovdqa 448-512(%rax),%ymm14
+ vmovdqa 480-512(%rax),%ymm15
+ vmovdqa 512-512(%rax),%ymm4
+ vmovdqa 544-512(%rax),%ymm5
+ vmovdqa 576-512(%rax),%ymm6
+ vmovdqa 608-512(%rax),%ymm7
+ vpaddd L$eight(%rip),%ymm4,%ymm4
+
+L$oop_enter8x:
+ vmovdqa %ymm14,64(%rsp)
+ vmovdqa %ymm15,96(%rsp)
+ vbroadcasti128 (%r10),%ymm15
+ vmovdqa %ymm4,512-512(%rax)
+ movl $10,%eax
+ jmp L$oop8x
+
+.p2align 5
+L$oop8x:
+ vpaddd %ymm0,%ymm8,%ymm8
+ vpxor %ymm4,%ymm8,%ymm4
+ vpshufb %ymm15,%ymm4,%ymm4
+ vpaddd %ymm1,%ymm9,%ymm9
+ vpxor %ymm5,%ymm9,%ymm5
+ vpshufb %ymm15,%ymm5,%ymm5
+ vpaddd %ymm4,%ymm12,%ymm12
+ vpxor %ymm0,%ymm12,%ymm0
+ vpslld $12,%ymm0,%ymm14
+ vpsrld $20,%ymm0,%ymm0
+ vpor %ymm0,%ymm14,%ymm0
+ vbroadcasti128 (%r11),%ymm14
+ vpaddd %ymm5,%ymm13,%ymm13
+ vpxor %ymm1,%ymm13,%ymm1
+ vpslld $12,%ymm1,%ymm15
+ vpsrld $20,%ymm1,%ymm1
+ vpor %ymm1,%ymm15,%ymm1
+ vpaddd %ymm0,%ymm8,%ymm8
+ vpxor %ymm4,%ymm8,%ymm4
+ vpshufb %ymm14,%ymm4,%ymm4
+ vpaddd %ymm1,%ymm9,%ymm9
+ vpxor %ymm5,%ymm9,%ymm5
+ vpshufb %ymm14,%ymm5,%ymm5
+ vpaddd %ymm4,%ymm12,%ymm12
+ vpxor %ymm0,%ymm12,%ymm0
+ vpslld $7,%ymm0,%ymm15
+ vpsrld $25,%ymm0,%ymm0
+ vpor %ymm0,%ymm15,%ymm0
+ vbroadcasti128 (%r10),%ymm15
+ vpaddd %ymm5,%ymm13,%ymm13
+ vpxor %ymm1,%ymm13,%ymm1
+ vpslld $7,%ymm1,%ymm14
+ vpsrld $25,%ymm1,%ymm1
+ vpor %ymm1,%ymm14,%ymm1
+ vmovdqa %ymm12,0(%rsp)
+ vmovdqa %ymm13,32(%rsp)
+ vmovdqa 64(%rsp),%ymm12
+ vmovdqa 96(%rsp),%ymm13
+ vpaddd %ymm2,%ymm10,%ymm10
+ vpxor %ymm6,%ymm10,%ymm6
+ vpshufb %ymm15,%ymm6,%ymm6
+ vpaddd %ymm3,%ymm11,%ymm11
+ vpxor %ymm7,%ymm11,%ymm7
+ vpshufb %ymm15,%ymm7,%ymm7
+ vpaddd %ymm6,%ymm12,%ymm12
+ vpxor %ymm2,%ymm12,%ymm2
+ vpslld $12,%ymm2,%ymm14
+ vpsrld $20,%ymm2,%ymm2
+ vpor %ymm2,%ymm14,%ymm2
+ vbroadcasti128 (%r11),%ymm14
+ vpaddd %ymm7,%ymm13,%ymm13
+ vpxor %ymm3,%ymm13,%ymm3
+ vpslld $12,%ymm3,%ymm15
+ vpsrld $20,%ymm3,%ymm3
+ vpor %ymm3,%ymm15,%ymm3
+ vpaddd %ymm2,%ymm10,%ymm10
+ vpxor %ymm6,%ymm10,%ymm6
+ vpshufb %ymm14,%ymm6,%ymm6
+ vpaddd %ymm3,%ymm11,%ymm11
+ vpxor %ymm7,%ymm11,%ymm7
+ vpshufb %ymm14,%ymm7,%ymm7
+ vpaddd %ymm6,%ymm12,%ymm12
+ vpxor %ymm2,%ymm12,%ymm2
+ vpslld $7,%ymm2,%ymm15
+ vpsrld $25,%ymm2,%ymm2
+ vpor %ymm2,%ymm15,%ymm2
+ vbroadcasti128 (%r10),%ymm15
+ vpaddd %ymm7,%ymm13,%ymm13
+ vpxor %ymm3,%ymm13,%ymm3
+ vpslld $7,%ymm3,%ymm14
+ vpsrld $25,%ymm3,%ymm3
+ vpor %ymm3,%ymm14,%ymm3
+ vpaddd %ymm1,%ymm8,%ymm8
+ vpxor %ymm7,%ymm8,%ymm7
+ vpshufb %ymm15,%ymm7,%ymm7
+ vpaddd %ymm2,%ymm9,%ymm9
+ vpxor %ymm4,%ymm9,%ymm4
+ vpshufb %ymm15,%ymm4,%ymm4
+ vpaddd %ymm7,%ymm12,%ymm12
+ vpxor %ymm1,%ymm12,%ymm1
+ vpslld $12,%ymm1,%ymm14
+ vpsrld $20,%ymm1,%ymm1
+ vpor %ymm1,%ymm14,%ymm1
+ vbroadcasti128 (%r11),%ymm14
+ vpaddd %ymm4,%ymm13,%ymm13
+ vpxor %ymm2,%ymm13,%ymm2
+ vpslld $12,%ymm2,%ymm15
+ vpsrld $20,%ymm2,%ymm2
+ vpor %ymm2,%ymm15,%ymm2
+ vpaddd %ymm1,%ymm8,%ymm8
+ vpxor %ymm7,%ymm8,%ymm7
+ vpshufb %ymm14,%ymm7,%ymm7
+ vpaddd %ymm2,%ymm9,%ymm9
+ vpxor %ymm4,%ymm9,%ymm4
+ vpshufb %ymm14,%ymm4,%ymm4
+ vpaddd %ymm7,%ymm12,%ymm12
+ vpxor %ymm1,%ymm12,%ymm1
+ vpslld $7,%ymm1,%ymm15
+ vpsrld $25,%ymm1,%ymm1
+ vpor %ymm1,%ymm15,%ymm1
+ vbroadcasti128 (%r10),%ymm15
+ vpaddd %ymm4,%ymm13,%ymm13
+ vpxor %ymm2,%ymm13,%ymm2
+ vpslld $7,%ymm2,%ymm14
+ vpsrld $25,%ymm2,%ymm2
+ vpor %ymm2,%ymm14,%ymm2
+ vmovdqa %ymm12,64(%rsp)
+ vmovdqa %ymm13,96(%rsp)
+ vmovdqa 0(%rsp),%ymm12
+ vmovdqa 32(%rsp),%ymm13
+ vpaddd %ymm3,%ymm10,%ymm10
+ vpxor %ymm5,%ymm10,%ymm5
+ vpshufb %ymm15,%ymm5,%ymm5
+ vpaddd %ymm0,%ymm11,%ymm11
+ vpxor %ymm6,%ymm11,%ymm6
+ vpshufb %ymm15,%ymm6,%ymm6
+ vpaddd %ymm5,%ymm12,%ymm12
+ vpxor %ymm3,%ymm12,%ymm3
+ vpslld $12,%ymm3,%ymm14
+ vpsrld $20,%ymm3,%ymm3
+ vpor %ymm3,%ymm14,%ymm3
+ vbroadcasti128 (%r11),%ymm14
+ vpaddd %ymm6,%ymm13,%ymm13
+ vpxor %ymm0,%ymm13,%ymm0
+ vpslld $12,%ymm0,%ymm15
+ vpsrld $20,%ymm0,%ymm0
+ vpor %ymm0,%ymm15,%ymm0
+ vpaddd %ymm3,%ymm10,%ymm10
+ vpxor %ymm5,%ymm10,%ymm5
+ vpshufb %ymm14,%ymm5,%ymm5
+ vpaddd %ymm0,%ymm11,%ymm11
+ vpxor %ymm6,%ymm11,%ymm6
+ vpshufb %ymm14,%ymm6,%ymm6
+ vpaddd %ymm5,%ymm12,%ymm12
+ vpxor %ymm3,%ymm12,%ymm3
+ vpslld $7,%ymm3,%ymm15
+ vpsrld $25,%ymm3,%ymm3
+ vpor %ymm3,%ymm15,%ymm3
+ vbroadcasti128 (%r10),%ymm15
+ vpaddd %ymm6,%ymm13,%ymm13
+ vpxor %ymm0,%ymm13,%ymm0
+ vpslld $7,%ymm0,%ymm14
+ vpsrld $25,%ymm0,%ymm0
+ vpor %ymm0,%ymm14,%ymm0
+ decl %eax
+ jnz L$oop8x
+
+ leaq 512(%rsp),%rax
+ vpaddd 128-256(%rcx),%ymm8,%ymm8
+ vpaddd 160-256(%rcx),%ymm9,%ymm9
+ vpaddd 192-256(%rcx),%ymm10,%ymm10
+ vpaddd 224-256(%rcx),%ymm11,%ymm11
+
+ vpunpckldq %ymm9,%ymm8,%ymm14
+ vpunpckldq %ymm11,%ymm10,%ymm15
+ vpunpckhdq %ymm9,%ymm8,%ymm8
+ vpunpckhdq %ymm11,%ymm10,%ymm10
+ vpunpcklqdq %ymm15,%ymm14,%ymm9
+ vpunpckhqdq %ymm15,%ymm14,%ymm14
+ vpunpcklqdq %ymm10,%ymm8,%ymm11
+ vpunpckhqdq %ymm10,%ymm8,%ymm8
+ vpaddd 256-256(%rcx),%ymm0,%ymm0
+ vpaddd 288-256(%rcx),%ymm1,%ymm1
+ vpaddd 320-256(%rcx),%ymm2,%ymm2
+ vpaddd 352-256(%rcx),%ymm3,%ymm3
+
+ vpunpckldq %ymm1,%ymm0,%ymm10
+ vpunpckldq %ymm3,%ymm2,%ymm15
+ vpunpckhdq %ymm1,%ymm0,%ymm0
+ vpunpckhdq %ymm3,%ymm2,%ymm2
+ vpunpcklqdq %ymm15,%ymm10,%ymm1
+ vpunpckhqdq %ymm15,%ymm10,%ymm10
+ vpunpcklqdq %ymm2,%ymm0,%ymm3
+ vpunpckhqdq %ymm2,%ymm0,%ymm0
+ vperm2i128 $0x20,%ymm1,%ymm9,%ymm15
+ vperm2i128 $0x31,%ymm1,%ymm9,%ymm1
+ vperm2i128 $0x20,%ymm10,%ymm14,%ymm9
+ vperm2i128 $0x31,%ymm10,%ymm14,%ymm10
+ vperm2i128 $0x20,%ymm3,%ymm11,%ymm14
+ vperm2i128 $0x31,%ymm3,%ymm11,%ymm3
+ vperm2i128 $0x20,%ymm0,%ymm8,%ymm11
+ vperm2i128 $0x31,%ymm0,%ymm8,%ymm0
+ vmovdqa %ymm15,0(%rsp)
+ vmovdqa %ymm9,32(%rsp)
+ vmovdqa 64(%rsp),%ymm15
+ vmovdqa 96(%rsp),%ymm9
+
+ vpaddd 384-512(%rax),%ymm12,%ymm12
+ vpaddd 416-512(%rax),%ymm13,%ymm13
+ vpaddd 448-512(%rax),%ymm15,%ymm15
+ vpaddd 480-512(%rax),%ymm9,%ymm9
+
+ vpunpckldq %ymm13,%ymm12,%ymm2
+ vpunpckldq %ymm9,%ymm15,%ymm8
+ vpunpckhdq %ymm13,%ymm12,%ymm12
+ vpunpckhdq %ymm9,%ymm15,%ymm15
+ vpunpcklqdq %ymm8,%ymm2,%ymm13
+ vpunpckhqdq %ymm8,%ymm2,%ymm2
+ vpunpcklqdq %ymm15,%ymm12,%ymm9
+ vpunpckhqdq %ymm15,%ymm12,%ymm12
+ vpaddd 512-512(%rax),%ymm4,%ymm4
+ vpaddd 544-512(%rax),%ymm5,%ymm5
+ vpaddd 576-512(%rax),%ymm6,%ymm6
+ vpaddd 608-512(%rax),%ymm7,%ymm7
+
+ vpunpckldq %ymm5,%ymm4,%ymm15
+ vpunpckldq %ymm7,%ymm6,%ymm8
+ vpunpckhdq %ymm5,%ymm4,%ymm4
+ vpunpckhdq %ymm7,%ymm6,%ymm6
+ vpunpcklqdq %ymm8,%ymm15,%ymm5
+ vpunpckhqdq %ymm8,%ymm15,%ymm15
+ vpunpcklqdq %ymm6,%ymm4,%ymm7
+ vpunpckhqdq %ymm6,%ymm4,%ymm4
+ vperm2i128 $0x20,%ymm5,%ymm13,%ymm8
+ vperm2i128 $0x31,%ymm5,%ymm13,%ymm5
+ vperm2i128 $0x20,%ymm15,%ymm2,%ymm13
+ vperm2i128 $0x31,%ymm15,%ymm2,%ymm15
+ vperm2i128 $0x20,%ymm7,%ymm9,%ymm2
+ vperm2i128 $0x31,%ymm7,%ymm9,%ymm7
+ vperm2i128 $0x20,%ymm4,%ymm12,%ymm9
+ vperm2i128 $0x31,%ymm4,%ymm12,%ymm4
+ vmovdqa 0(%rsp),%ymm6
+ vmovdqa 32(%rsp),%ymm12
+
+ cmpq $512,%rdx
+ jb L$tail8x
+
+ vpxor 0(%rsi),%ymm6,%ymm6
+ vpxor 32(%rsi),%ymm8,%ymm8
+ vpxor 64(%rsi),%ymm1,%ymm1
+ vpxor 96(%rsi),%ymm5,%ymm5
+ leaq 128(%rsi),%rsi
+ vmovdqu %ymm6,0(%rdi)
+ vmovdqu %ymm8,32(%rdi)
+ vmovdqu %ymm1,64(%rdi)
+ vmovdqu %ymm5,96(%rdi)
+ leaq 128(%rdi),%rdi
+
+ vpxor 0(%rsi),%ymm12,%ymm12
+ vpxor 32(%rsi),%ymm13,%ymm13
+ vpxor 64(%rsi),%ymm10,%ymm10
+ vpxor 96(%rsi),%ymm15,%ymm15
+ leaq 128(%rsi),%rsi
+ vmovdqu %ymm12,0(%rdi)
+ vmovdqu %ymm13,32(%rdi)
+ vmovdqu %ymm10,64(%rdi)
+ vmovdqu %ymm15,96(%rdi)
+ leaq 128(%rdi),%rdi
+
+ vpxor 0(%rsi),%ymm14,%ymm14
+ vpxor 32(%rsi),%ymm2,%ymm2
+ vpxor 64(%rsi),%ymm3,%ymm3
+ vpxor 96(%rsi),%ymm7,%ymm7
+ leaq 128(%rsi),%rsi
+ vmovdqu %ymm14,0(%rdi)
+ vmovdqu %ymm2,32(%rdi)
+ vmovdqu %ymm3,64(%rdi)
+ vmovdqu %ymm7,96(%rdi)
+ leaq 128(%rdi),%rdi
+
+ vpxor 0(%rsi),%ymm11,%ymm11
+ vpxor 32(%rsi),%ymm9,%ymm9
+ vpxor 64(%rsi),%ymm0,%ymm0
+ vpxor 96(%rsi),%ymm4,%ymm4
+ leaq 128(%rsi),%rsi
+ vmovdqu %ymm11,0(%rdi)
+ vmovdqu %ymm9,32(%rdi)
+ vmovdqu %ymm0,64(%rdi)
+ vmovdqu %ymm4,96(%rdi)
+ leaq 128(%rdi),%rdi
+
+ subq $512,%rdx
+ jnz L$oop_outer8x
+
+ jmp L$done8x
+
+L$tail8x:
+ cmpq $448,%rdx
+ jae L$448_or_more8x
+ cmpq $384,%rdx
+ jae L$384_or_more8x
+ cmpq $320,%rdx
+ jae L$320_or_more8x
+ cmpq $256,%rdx
+ jae L$256_or_more8x
+ cmpq $192,%rdx
+ jae L$192_or_more8x
+ cmpq $128,%rdx
+ jae L$128_or_more8x
+ cmpq $64,%rdx
+ jae L$64_or_more8x
+
+ xorq %r10,%r10
+ vmovdqa %ymm6,0(%rsp)
+ vmovdqa %ymm8,32(%rsp)
+ jmp L$oop_tail8x
+
+.p2align 5
+L$64_or_more8x:
+ vpxor 0(%rsi),%ymm6,%ymm6
+ vpxor 32(%rsi),%ymm8,%ymm8
+ vmovdqu %ymm6,0(%rdi)
+ vmovdqu %ymm8,32(%rdi)
+ je L$done8x
+
+ leaq 64(%rsi),%rsi
+ xorq %r10,%r10
+ vmovdqa %ymm1,0(%rsp)
+ leaq 64(%rdi),%rdi
+ subq $64,%rdx
+ vmovdqa %ymm5,32(%rsp)
+ jmp L$oop_tail8x
+
+.p2align 5
+L$128_or_more8x:
+ vpxor 0(%rsi),%ymm6,%ymm6
+ vpxor 32(%rsi),%ymm8,%ymm8
+ vpxor 64(%rsi),%ymm1,%ymm1
+ vpxor 96(%rsi),%ymm5,%ymm5
+ vmovdqu %ymm6,0(%rdi)
+ vmovdqu %ymm8,32(%rdi)
+ vmovdqu %ymm1,64(%rdi)
+ vmovdqu %ymm5,96(%rdi)
+ je L$done8x
+
+ leaq 128(%rsi),%rsi
+ xorq %r10,%r10
+ vmovdqa %ymm12,0(%rsp)
+ leaq 128(%rdi),%rdi
+ subq $128,%rdx
+ vmovdqa %ymm13,32(%rsp)
+ jmp L$oop_tail8x
+
+.p2align 5
+L$192_or_more8x:
+ vpxor 0(%rsi),%ymm6,%ymm6
+ vpxor 32(%rsi),%ymm8,%ymm8
+ vpxor 64(%rsi),%ymm1,%ymm1
+ vpxor 96(%rsi),%ymm5,%ymm5
+ vpxor 128(%rsi),%ymm12,%ymm12
+ vpxor 160(%rsi),%ymm13,%ymm13
+ vmovdqu %ymm6,0(%rdi)
+ vmovdqu %ymm8,32(%rdi)
+ vmovdqu %ymm1,64(%rdi)
+ vmovdqu %ymm5,96(%rdi)
+ vmovdqu %ymm12,128(%rdi)
+ vmovdqu %ymm13,160(%rdi)
+ je L$done8x
+
+ leaq 192(%rsi),%rsi
+ xorq %r10,%r10
+ vmovdqa %ymm10,0(%rsp)
+ leaq 192(%rdi),%rdi
+ subq $192,%rdx
+ vmovdqa %ymm15,32(%rsp)
+ jmp L$oop_tail8x
+
+.p2align 5
+L$256_or_more8x:
+ vpxor 0(%rsi),%ymm6,%ymm6
+ vpxor 32(%rsi),%ymm8,%ymm8
+ vpxor 64(%rsi),%ymm1,%ymm1
+ vpxor 96(%rsi),%ymm5,%ymm5
+ vpxor 128(%rsi),%ymm12,%ymm12
+ vpxor 160(%rsi),%ymm13,%ymm13
+ vpxor 192(%rsi),%ymm10,%ymm10
+ vpxor 224(%rsi),%ymm15,%ymm15
+ vmovdqu %ymm6,0(%rdi)
+ vmovdqu %ymm8,32(%rdi)
+ vmovdqu %ymm1,64(%rdi)
+ vmovdqu %ymm5,96(%rdi)
+ vmovdqu %ymm12,128(%rdi)
+ vmovdqu %ymm13,160(%rdi)
+ vmovdqu %ymm10,192(%rdi)
+ vmovdqu %ymm15,224(%rdi)
+ je L$done8x
+
+ leaq 256(%rsi),%rsi
+ xorq %r10,%r10
+ vmovdqa %ymm14,0(%rsp)
+ leaq 256(%rdi),%rdi
+ subq $256,%rdx
+ vmovdqa %ymm2,32(%rsp)
+ jmp L$oop_tail8x
+
+.p2align 5
+L$320_or_more8x:
+ vpxor 0(%rsi),%ymm6,%ymm6
+ vpxor 32(%rsi),%ymm8,%ymm8
+ vpxor 64(%rsi),%ymm1,%ymm1
+ vpxor 96(%rsi),%ymm5,%ymm5
+ vpxor 128(%rsi),%ymm12,%ymm12
+ vpxor 160(%rsi),%ymm13,%ymm13
+ vpxor 192(%rsi),%ymm10,%ymm10
+ vpxor 224(%rsi),%ymm15,%ymm15
+ vpxor 256(%rsi),%ymm14,%ymm14
+ vpxor 288(%rsi),%ymm2,%ymm2
+ vmovdqu %ymm6,0(%rdi)
+ vmovdqu %ymm8,32(%rdi)
+ vmovdqu %ymm1,64(%rdi)
+ vmovdqu %ymm5,96(%rdi)
+ vmovdqu %ymm12,128(%rdi)
+ vmovdqu %ymm13,160(%rdi)
+ vmovdqu %ymm10,192(%rdi)
+ vmovdqu %ymm15,224(%rdi)
+ vmovdqu %ymm14,256(%rdi)
+ vmovdqu %ymm2,288(%rdi)
+ je L$done8x
+
+ leaq 320(%rsi),%rsi
+ xorq %r10,%r10
+ vmovdqa %ymm3,0(%rsp)
+ leaq 320(%rdi),%rdi
+ subq $320,%rdx
+ vmovdqa %ymm7,32(%rsp)
+ jmp L$oop_tail8x
+
+.p2align 5
+L$384_or_more8x:
+ vpxor 0(%rsi),%ymm6,%ymm6
+ vpxor 32(%rsi),%ymm8,%ymm8
+ vpxor 64(%rsi),%ymm1,%ymm1
+ vpxor 96(%rsi),%ymm5,%ymm5
+ vpxor 128(%rsi),%ymm12,%ymm12
+ vpxor 160(%rsi),%ymm13,%ymm13
+ vpxor 192(%rsi),%ymm10,%ymm10
+ vpxor 224(%rsi),%ymm15,%ymm15
+ vpxor 256(%rsi),%ymm14,%ymm14
+ vpxor 288(%rsi),%ymm2,%ymm2
+ vpxor 320(%rsi),%ymm3,%ymm3
+ vpxor 352(%rsi),%ymm7,%ymm7
+ vmovdqu %ymm6,0(%rdi)
+ vmovdqu %ymm8,32(%rdi)
+ vmovdqu %ymm1,64(%rdi)
+ vmovdqu %ymm5,96(%rdi)
+ vmovdqu %ymm12,128(%rdi)
+ vmovdqu %ymm13,160(%rdi)
+ vmovdqu %ymm10,192(%rdi)
+ vmovdqu %ymm15,224(%rdi)
+ vmovdqu %ymm14,256(%rdi)
+ vmovdqu %ymm2,288(%rdi)
+ vmovdqu %ymm3,320(%rdi)
+ vmovdqu %ymm7,352(%rdi)
+ je L$done8x
+
+ leaq 384(%rsi),%rsi
+ xorq %r10,%r10
+ vmovdqa %ymm11,0(%rsp)
+ leaq 384(%rdi),%rdi
+ subq $384,%rdx
+ vmovdqa %ymm9,32(%rsp)
+ jmp L$oop_tail8x
+
+.p2align 5
+L$448_or_more8x:
+ vpxor 0(%rsi),%ymm6,%ymm6
+ vpxor 32(%rsi),%ymm8,%ymm8
+ vpxor 64(%rsi),%ymm1,%ymm1
+ vpxor 96(%rsi),%ymm5,%ymm5
+ vpxor 128(%rsi),%ymm12,%ymm12
+ vpxor 160(%rsi),%ymm13,%ymm13
+ vpxor 192(%rsi),%ymm10,%ymm10
+ vpxor 224(%rsi),%ymm15,%ymm15
+ vpxor 256(%rsi),%ymm14,%ymm14
+ vpxor 288(%rsi),%ymm2,%ymm2
+ vpxor 320(%rsi),%ymm3,%ymm3
+ vpxor 352(%rsi),%ymm7,%ymm7
+ vpxor 384(%rsi),%ymm11,%ymm11
+ vpxor 416(%rsi),%ymm9,%ymm9
+ vmovdqu %ymm6,0(%rdi)
+ vmovdqu %ymm8,32(%rdi)
+ vmovdqu %ymm1,64(%rdi)
+ vmovdqu %ymm5,96(%rdi)
+ vmovdqu %ymm12,128(%rdi)
+ vmovdqu %ymm13,160(%rdi)
+ vmovdqu %ymm10,192(%rdi)
+ vmovdqu %ymm15,224(%rdi)
+ vmovdqu %ymm14,256(%rdi)
+ vmovdqu %ymm2,288(%rdi)
+ vmovdqu %ymm3,320(%rdi)
+ vmovdqu %ymm7,352(%rdi)
+ vmovdqu %ymm11,384(%rdi)
+ vmovdqu %ymm9,416(%rdi)
+ je L$done8x
+
+ leaq 448(%rsi),%rsi
+ xorq %r10,%r10
+ vmovdqa %ymm0,0(%rsp)
+ leaq 448(%rdi),%rdi
+ subq $448,%rdx
+ vmovdqa %ymm4,32(%rsp)
+
+L$oop_tail8x:
+ movzbl (%rsi,%r10,1),%eax
+ movzbl (%rsp,%r10,1),%ecx
+ leaq 1(%r10),%r10
+ xorl %ecx,%eax
+ movb %al,-1(%rdi,%r10,1)
+ decq %rdx
+ jnz L$oop_tail8x
+
+L$done8x:
+ vzeroall
+ movq 640(%rsp),%rsp
+ .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
index bed11305..1cd0cc3f 100644
--- a/mac-x86_64/crypto/ec/p256-x86_64-asm.S
+++ b/mac-x86_64/crypto/ec/p256-x86_64-asm.S
@@ -893,6 +893,7 @@ _ecp_nistz256_point_double:
pushq %r15
subq $160+8,%rsp
+L$point_double_shortcutq:
movdqu 0(%rsi),%xmm0
movq %rsi,%rbx
movdqu 16(%rsi),%xmm1
@@ -1114,7 +1115,7 @@ _ecp_nistz256_point_add:
por %xmm1,%xmm3
movdqu 0(%rsi),%xmm0
- pshufd $177,%xmm3,%xmm5
+ pshufd $0xb1,%xmm3,%xmm5
movdqu 16(%rsi),%xmm1
movdqu 32(%rsi),%xmm2
por %xmm3,%xmm5
@@ -1124,7 +1125,7 @@ _ecp_nistz256_point_add:
movq 64+16(%rsi),%r15
movq 64+24(%rsi),%r8
movdqa %xmm0,480(%rsp)
- pshufd $30,%xmm5,%xmm4
+ pshufd $0x1e,%xmm5,%xmm4
movdqa %xmm1,480+16(%rsp)
por %xmm0,%xmm1
.byte 102,72,15,110,199
@@ -1144,10 +1145,10 @@ _ecp_nistz256_point_add:
call __ecp_nistz256_sqr_montq
pcmpeqd %xmm4,%xmm5
- pshufd $177,%xmm3,%xmm4
+ pshufd $0xb1,%xmm3,%xmm4
por %xmm3,%xmm4
pshufd $0,%xmm5,%xmm5
- pshufd $30,%xmm4,%xmm3
+ pshufd $0x1e,%xmm4,%xmm3
por %xmm3,%xmm4
pxor %xmm3,%xmm3
pcmpeqd %xmm3,%xmm4
@@ -1156,6 +1157,7 @@ _ecp_nistz256_point_add:
movq 64+8(%rbx),%r14
movq 64+16(%rbx),%r15
movq 64+24(%rbx),%r8
+.byte 102,72,15,110,203
leaq 64-0(%rbx),%rsi
leaq 32(%rsp),%rdi
@@ -1247,7 +1249,7 @@ _ecp_nistz256_point_add:
testq %r8,%r8
jnz L$add_proceedq
testq %r9,%r9
- jz L$add_proceedq
+ jz L$add_doubleq
.byte 102,72,15,126,199
pxor %xmm0,%xmm0
@@ -1260,6 +1262,13 @@ _ecp_nistz256_point_add:
jmp L$add_doneq
.p2align 5
+L$add_doubleq:
+.byte 102,72,15,126,206
+.byte 102,72,15,126,199
+ addq $416,%rsp
+ jmp L$point_double_shortcutq
+
+.p2align 5
L$add_proceedq:
movq 0+64(%rsp),%rax
movq 8+64(%rsp),%r14
@@ -1507,13 +1516,13 @@ _ecp_nistz256_point_add_affine:
por %xmm1,%xmm3
movdqu 0(%rbx),%xmm0
- pshufd $177,%xmm3,%xmm5
+ pshufd $0xb1,%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
+ pshufd $0x1e,%xmm5,%xmm4
movdqa %xmm1,416+16(%rsp)
por %xmm0,%xmm1
.byte 102,72,15,110,199
@@ -1529,13 +1538,13 @@ _ecp_nistz256_point_add_affine:
call __ecp_nistz256_sqr_montq
pcmpeqd %xmm4,%xmm5
- pshufd $177,%xmm3,%xmm4
+ pshufd $0xb1,%xmm3,%xmm4
movq 0(%rbx),%rax
movq %r12,%r9
por %xmm3,%xmm4
pshufd $0,%xmm5,%xmm5
- pshufd $30,%xmm4,%xmm3
+ pshufd $0x1e,%xmm4,%xmm3
movq %r13,%r10
por %xmm3,%xmm4
pxor %xmm3,%xmm3
diff --git a/mac-x86_64/crypto/md5/md5-x86_64.S b/mac-x86_64/crypto/md5/md5-x86_64.S
index 1e61479b..16fd2cce 100644
--- a/mac-x86_64/crypto/md5/md5-x86_64.S
+++ b/mac-x86_64/crypto/md5/md5-x86_64.S
@@ -495,14 +495,14 @@ L$loop:
movl %ecx,%r11d
addl %ecx,%ebx
movl 0(%rsi),%r10d
- movl $4294967295,%r11d
+ movl $0xffffffff,%r11d
xorl %edx,%r11d
leal -198630844(%rax,%r10,1),%eax
orl %ebx,%r11d
xorl %ecx,%r11d
addl %r11d,%eax
movl 28(%rsi),%r10d
- movl $4294967295,%r11d
+ movl $0xffffffff,%r11d
roll $6,%eax
xorl %ecx,%r11d
addl %ebx,%eax
@@ -511,7 +511,7 @@ L$loop:
xorl %ebx,%r11d
addl %r11d,%edx
movl 56(%rsi),%r10d
- movl $4294967295,%r11d
+ movl $0xffffffff,%r11d
roll $10,%edx
xorl %ebx,%r11d
addl %eax,%edx
@@ -520,7 +520,7 @@ L$loop:
xorl %eax,%r11d
addl %r11d,%ecx
movl 20(%rsi),%r10d
- movl $4294967295,%r11d
+ movl $0xffffffff,%r11d
roll $15,%ecx
xorl %eax,%r11d
addl %edx,%ecx
@@ -529,7 +529,7 @@ L$loop:
xorl %edx,%r11d
addl %r11d,%ebx
movl 48(%rsi),%r10d
- movl $4294967295,%r11d
+ movl $0xffffffff,%r11d
roll $21,%ebx
xorl %edx,%r11d
addl %ecx,%ebx
@@ -538,7 +538,7 @@ L$loop:
xorl %ecx,%r11d
addl %r11d,%eax
movl 12(%rsi),%r10d
- movl $4294967295,%r11d
+ movl $0xffffffff,%r11d
roll $6,%eax
xorl %ecx,%r11d
addl %ebx,%eax
@@ -547,7 +547,7 @@ L$loop:
xorl %ebx,%r11d
addl %r11d,%edx
movl 40(%rsi),%r10d
- movl $4294967295,%r11d
+ movl $0xffffffff,%r11d
roll $10,%edx
xorl %ebx,%r11d
addl %eax,%edx
@@ -556,7 +556,7 @@ L$loop:
xorl %eax,%r11d
addl %r11d,%ecx
movl 4(%rsi),%r10d
- movl $4294967295,%r11d
+ movl $0xffffffff,%r11d
roll $15,%ecx
xorl %eax,%r11d
addl %edx,%ecx
@@ -565,7 +565,7 @@ L$loop:
xorl %edx,%r11d
addl %r11d,%ebx
movl 32(%rsi),%r10d
- movl $4294967295,%r11d
+ movl $0xffffffff,%r11d
roll $21,%ebx
xorl %edx,%r11d
addl %ecx,%ebx
@@ -574,7 +574,7 @@ L$loop:
xorl %ecx,%r11d
addl %r11d,%eax
movl 60(%rsi),%r10d
- movl $4294967295,%r11d
+ movl $0xffffffff,%r11d
roll $6,%eax
xorl %ecx,%r11d
addl %ebx,%eax
@@ -583,7 +583,7 @@ L$loop:
xorl %ebx,%r11d
addl %r11d,%edx
movl 24(%rsi),%r10d
- movl $4294967295,%r11d
+ movl $0xffffffff,%r11d
roll $10,%edx
xorl %ebx,%r11d
addl %eax,%edx
@@ -592,7 +592,7 @@ L$loop:
xorl %eax,%r11d
addl %r11d,%ecx
movl 52(%rsi),%r10d
- movl $4294967295,%r11d
+ movl $0xffffffff,%r11d
roll $15,%ecx
xorl %eax,%r11d
addl %edx,%ecx
@@ -601,7 +601,7 @@ L$loop:
xorl %edx,%r11d
addl %r11d,%ebx
movl 16(%rsi),%r10d
- movl $4294967295,%r11d
+ movl $0xffffffff,%r11d
roll $21,%ebx
xorl %edx,%r11d
addl %ecx,%ebx
@@ -610,7 +610,7 @@ L$loop:
xorl %ecx,%r11d
addl %r11d,%eax
movl 44(%rsi),%r10d
- movl $4294967295,%r11d
+ movl $0xffffffff,%r11d
roll $6,%eax
xorl %ecx,%r11d
addl %ebx,%eax
@@ -619,7 +619,7 @@ L$loop:
xorl %ebx,%r11d
addl %r11d,%edx
movl 8(%rsi),%r10d
- movl $4294967295,%r11d
+ movl $0xffffffff,%r11d
roll $10,%edx
xorl %ebx,%r11d
addl %eax,%edx
@@ -628,7 +628,7 @@ L$loop:
xorl %eax,%r11d
addl %r11d,%ecx
movl 36(%rsi),%r10d
- movl $4294967295,%r11d
+ movl $0xffffffff,%r11d
roll $15,%ecx
xorl %eax,%r11d
addl %edx,%ecx
@@ -637,7 +637,7 @@ L$loop:
xorl %edx,%r11d
addl %r11d,%ebx
movl 0(%rsi),%r10d
- movl $4294967295,%r11d
+ movl $0xffffffff,%r11d
roll $21,%ebx
xorl %edx,%r11d
addl %ecx,%ebx
diff --git a/mac-x86_64/crypto/modes/ghash-x86_64.S b/mac-x86_64/crypto/modes/ghash-x86_64.S
index 305a91cb..1072c7fc 100644
--- a/mac-x86_64/crypto/modes/ghash-x86_64.S
+++ b/mac-x86_64/crypto/modes/ghash-x86_64.S
@@ -22,14 +22,14 @@ L$gmult_prologue:
movq $14,%rcx
movq 8(%rsi,%rax,1),%r8
movq (%rsi,%rax,1),%r9
- andb $240,%bl
+ andb $0xf0,%bl
movq %r8,%rdx
jmp L$oop1
.p2align 4
L$oop1:
shrq $4,%r8
- andq $15,%rdx
+ andq $0xf,%rdx
movq %r9,%r10
movb (%rdi,%rcx,1),%al
shrq $4,%r9
@@ -45,13 +45,13 @@ L$oop1:
js L$break1
shrq $4,%r8
- andq $15,%rdx
+ andq $0xf,%rdx
movq %r9,%r10
shrq $4,%r9
xorq 8(%rsi,%rax,1),%r8
shlq $60,%r10
xorq (%rsi,%rax,1),%r9
- andb $240,%bl
+ andb $0xf0,%bl
xorq (%r11,%rdx,8),%r9
movq %r8,%rdx
xorq %r10,%r8
@@ -60,19 +60,19 @@ L$oop1:
.p2align 4
L$break1:
shrq $4,%r8
- andq $15,%rdx
+ andq $0xf,%rdx
movq %r9,%r10
shrq $4,%r9
xorq 8(%rsi,%rax,1),%r8
shlq $60,%r10
xorq (%rsi,%rax,1),%r9
- andb $240,%bl
+ andb $0xf0,%bl
xorq (%r11,%rdx,8),%r9
movq %r8,%rdx
xorq %r10,%r8
shrq $4,%r8
- andq $15,%rdx
+ andq $0xf,%rdx
movq %r9,%r10
shrq $4,%r9
xorq 8(%rsi,%rbx,1),%r8
@@ -880,20 +880,20 @@ L$_ghash_clmul:
movdqu 32(%rsi),%xmm7
.byte 102,65,15,56,0,194
- subq $16,%rcx
+ subq $0x10,%rcx
jz L$odd_tail
movdqu 16(%rsi),%xmm6
movl _OPENSSL_ia32cap_P+4(%rip),%eax
- cmpq $48,%rcx
+ cmpq $0x30,%rcx
jb L$skip4x
andl $71303168,%eax
cmpl $4194304,%eax
je L$skip4x
- subq $48,%rcx
- movq $11547335547999543296,%rax
+ subq $0x30,%rcx
+ movq $0xA040608020C0E000,%rax
movdqu 48(%rsi),%xmm14
movdqu 64(%rsi),%xmm15
@@ -940,7 +940,7 @@ L$_ghash_clmul:
xorps %xmm13,%xmm5
leaq 64(%rdx),%rdx
- subq $64,%rcx
+ subq $0x40,%rcx
jc L$tail4x
jmp L$mod4_loop
@@ -1023,7 +1023,7 @@ L$mod4_loop:
xorps %xmm13,%xmm5
leaq 64(%rdx),%rdx
- subq $64,%rcx
+ subq $0x40,%rcx
jnc L$mod4_loop
L$tail4x:
@@ -1067,10 +1067,10 @@ L$tail4x:
pxor %xmm4,%xmm0
psrlq $1,%xmm0
pxor %xmm1,%xmm0
- addq $64,%rcx
+ addq $0x40,%rcx
jz L$done
movdqu 32(%rsi),%xmm7
- subq $16,%rcx
+ subq $0x10,%rcx
jz L$odd_tail
L$skip4x:
@@ -1093,7 +1093,7 @@ L$skip4x:
leaq 32(%rdx),%rdx
nop
- subq $32,%rcx
+ subq $0x20,%rcx
jbe L$even_tail
nop
jmp L$mod_loop
@@ -1156,7 +1156,7 @@ L$mod_loop:
.byte 102,15,58,68,231,0
pxor %xmm1,%xmm0
- subq $32,%rcx
+ subq $0x20,%rcx
ja L$mod_loop
L$even_tail:
diff --git a/sources.mk b/sources.mk
index e82f3d5c..1ffa6579 100644
--- a/sources.mk
+++ b/sources.mk
@@ -45,7 +45,6 @@ crypto_sources := \
src/crypto/asn1/f_int.c\
src/crypto/asn1/f_string.c\
src/crypto/asn1/t_bitst.c\
- src/crypto/asn1/t_pkey.c\
src/crypto/asn1/tasn_dec.c\
src/crypto/asn1/tasn_enc.c\
src/crypto/asn1/tasn_fre.c\
@@ -87,11 +86,11 @@ crypto_sources := \
src/crypto/bn/shift.c\
src/crypto/bn/sqrt.c\
src/crypto/buf/buf.c\
+ src/crypto/bytestring/asn1_compat.c\
src/crypto/bytestring/ber.c\
src/crypto/bytestring/cbb.c\
src/crypto/bytestring/cbs.c\
- src/crypto/chacha/chacha_generic.c\
- src/crypto/chacha/chacha_vec.c\
+ src/crypto/chacha/chacha.c\
src/crypto/cipher/aead.c\
src/crypto/cipher/cipher.c\
src/crypto/cipher/derive_key.c\
@@ -106,10 +105,13 @@ crypto_sources := \
src/crypto/cipher/tls_cbc.c\
src/crypto/cmac/cmac.c\
src/crypto/conf/conf.c\
+ src/crypto/cpu-aarch64-linux.c\
+ src/crypto/cpu-arm-linux.c\
src/crypto/cpu-arm.c\
src/crypto/cpu-intel.c\
src/crypto/crypto.c\
src/crypto/curve25519/curve25519.c\
+ src/crypto/curve25519/spake25519.c\
src/crypto/curve25519/x25519-x86_64.c\
src/crypto/des/des.c\
src/crypto/dh/check.c\
@@ -118,8 +120,6 @@ crypto_sources := \
src/crypto/dh/params.c\
src/crypto/digest/digest.c\
src/crypto/digest/digests.c\
- src/crypto/directory_posix.c\
- src/crypto/directory_win.c\
src/crypto/dsa/dsa.c\
src/crypto/dsa/dsa_asn1.c\
src/crypto/ec/ec.c\
@@ -138,7 +138,6 @@ crypto_sources := \
src/crypto/ecdsa/ecdsa_asn1.c\
src/crypto/engine/engine.c\
src/crypto/err/err.c\
- src/crypto/evp/algorithm.c\
src/crypto/evp/digestsign.c\
src/crypto/evp/evp.c\
src/crypto/evp/evp_asn1.c\
@@ -149,6 +148,7 @@ crypto_sources := \
src/crypto/evp/p_rsa.c\
src/crypto/evp/p_rsa_asn1.c\
src/crypto/evp/pbkdf.c\
+ src/crypto/evp/print.c\
src/crypto/evp/sign.c\
src/crypto/ex_data.c\
src/crypto/hkdf/hkdf.c\
@@ -162,6 +162,12 @@ crypto_sources := \
src/crypto/modes/ctr.c\
src/crypto/modes/gcm.c\
src/crypto/modes/ofb.c\
+ src/crypto/newhope/error_correction.c\
+ src/crypto/newhope/newhope.c\
+ src/crypto/newhope/ntt.c\
+ src/crypto/newhope/poly.c\
+ src/crypto/newhope/precomp.c\
+ src/crypto/newhope/reduce.c\
src/crypto/obj/obj.c\
src/crypto/obj/obj_xref.c\
src/crypto/pem/pem_all.c\
@@ -179,6 +185,7 @@ crypto_sources := \
src/crypto/poly1305/poly1305.c\
src/crypto/poly1305/poly1305_arm.c\
src/crypto/poly1305/poly1305_vec.c\
+ src/crypto/rand/deterministic.c\
src/crypto/rand/rand.c\
src/crypto/rand/urandom.c\
src/crypto/rand/windows.c\
@@ -203,11 +210,13 @@ crypto_sources := \
src/crypto/x509/a_sign.c\
src/crypto/x509/a_strex.c\
src/crypto/x509/a_verify.c\
+ src/crypto/x509/algorithm.c\
src/crypto/x509/asn1_gen.c\
src/crypto/x509/by_dir.c\
src/crypto/x509/by_file.c\
src/crypto/x509/i2d_pr.c\
src/crypto/x509/pkcs7.c\
+ src/crypto/x509/rsa_pss.c\
src/crypto/x509/t_crl.c\
src/crypto/x509/t_req.c\
src/crypto/x509/t_x509.c\
@@ -332,6 +341,7 @@ tool_sources := \
linux_aarch64_sources := \
linux-aarch64/crypto/aes/aesv8-armx64.S\
linux-aarch64/crypto/bn/armv8-mont.S\
+ linux-aarch64/crypto/chacha/chacha-armv8.S\
linux-aarch64/crypto/modes/ghashv8-armx64.S\
linux-aarch64/crypto/sha/sha1-armv8.S\
linux-aarch64/crypto/sha/sha256-armv8.S\
@@ -342,13 +352,12 @@ linux_arm_sources := \
linux-arm/crypto/aes/aesv8-armx32.S\
linux-arm/crypto/aes/bsaes-armv7.S\
linux-arm/crypto/bn/armv4-mont.S\
+ linux-arm/crypto/chacha/chacha-armv4.S\
linux-arm/crypto/modes/ghash-armv4.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\
@@ -359,6 +368,7 @@ 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/chacha/chacha-x86.S\
linux-x86/crypto/md5/md5-586.S\
linux-x86/crypto/modes/ghash-x86.S\
linux-x86/crypto/rc4/rc4-586.S\
@@ -375,6 +385,7 @@ 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/chacha/chacha-x86_64.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\
@@ -384,6 +395,7 @@ linux_x86_64_sources := \
linux-x86_64/crypto/sha/sha1-x86_64.S\
linux-x86_64/crypto/sha/sha256-x86_64.S\
linux-x86_64/crypto/sha/sha512-x86_64.S\
+ src/crypto/curve25519/asm/x25519-asm-x86_64.S\
mac_x86_sources := \
mac-x86/crypto/aes/aes-586.S\
@@ -392,6 +404,7 @@ 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/chacha/chacha-x86.S\
mac-x86/crypto/md5/md5-586.S\
mac-x86/crypto/modes/ghash-x86.S\
mac-x86/crypto/rc4/rc4-586.S\
@@ -408,6 +421,7 @@ 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/chacha/chacha-x86_64.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\
@@ -425,6 +439,7 @@ 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/chacha/chacha-x86.asm\
win-x86/crypto/md5/md5-586.asm\
win-x86/crypto/modes/ghash-x86.asm\
win-x86/crypto/rc4/rc4-586.asm\
@@ -441,6 +456,7 @@ 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/chacha/chacha-x86_64.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\
diff --git a/src/.clang-format b/src/.clang-format
index 43032d44..5865a706 100644
--- a/src/.clang-format
+++ b/src/.clang-format
@@ -2,3 +2,6 @@ BasedOnStyle: Google
MaxEmptyLinesToKeep: 3
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
+DerivePointerAlignment: false
+PointerAlignment: Right
+
diff --git a/src/.github/PULL_REQUEST_TEMPLATE b/src/.github/PULL_REQUEST_TEMPLATE
new file mode 100644
index 00000000..6c101eab
--- /dev/null
+++ b/src/.github/PULL_REQUEST_TEMPLATE
@@ -0,0 +1,7 @@
+Please do not send pull requests to the BoringSSL repository.
+
+We do, however, take contributions gladly.
+
+See https://boringssl.googlesource.com/boringssl/+/master/CONTRIBUTING.md
+
+Thanks!
diff --git a/src/BUILDING.md b/src/BUILDING.md
index 02f8f11f..e1113104 100644
--- a/src/BUILDING.md
+++ b/src/BUILDING.md
@@ -2,14 +2,18 @@
## Build Prerequisites
- * [CMake](http://www.cmake.org/download/) 2.8.8 or later is required.
+ * [CMake](https://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/)
+ [Active State Perl](http://www.activestate.com/activeperl/) has been
+ reported to work, as has MSYS Perl.
+ [Strawberry Perl](http://strawberryperl.com/) also works but it adds GCC
+ to `PATH`, which can confuse some build tools when identifying the compiler
+ (removing `C:\Strawberry\c\bin` from `PATH` should resolve any problems).
+ If Perl is not found by CMake, it may be configured explicitly by setting
+ `PERL_EXECUTABLE`.
+
+ * On Windows you currently must use [Ninja](https://ninja-build.org/)
to build; on other platforms, it is not required, but recommended, because
it makes builds faster.
@@ -21,22 +25,12 @@
`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.
+ with Platform SDK 8.1 or later are supported. Recent versions of GCC (4.8+)
+ 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):
@@ -58,7 +52,8 @@ 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.
+debugging—optimisation isn't enabled. Pass `-DCMAKE_BUILD_TYPE=Release` to
+`cmake` to configure a release build.
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
@@ -75,6 +70,9 @@ 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.
+See [CMake's documentation](https://cmake.org/cmake/help/v3.4/manual/cmake-variables.7.html)
+for other variables which may be used to configure the build.
+
### Building for Android
It's possible to build BoringSSL with the Android NDK using CMake. This has
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index e07be54d..adf2021d 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,6 +1,16 @@
cmake_minimum_required (VERSION 2.8.10)
-project (BoringSSL)
+# Defer enabling C and CXX languages.
+project (BoringSSL NONE)
+
+if(WIN32)
+ # On Windows, prefer cl over gcc if both are available. By default most of
+ # the CMake generators prefer gcc, even on Windows.
+ set(CMAKE_GENERATOR_CC cl)
+endif()
+
+enable_language(C)
+enable_language(CXX)
if(ANDROID)
# Android-NDK CMake files reconfigure the path and so Go and Perl won't be
@@ -17,8 +27,9 @@ 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 -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")
+ set(C_CXX_FLAGS "-Wall -Werror -Wformat=2 -Wsign-compare -Wmissing-field-initializers -ggdb -fvisibility=hidden")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${C_CXX_FLAGS} -Wmissing-prototypes")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x ${C_CXX_FLAGS} -Wmissing-declarations")
elseif(MSVC)
set(MSVC_DISABLED_WARNINGS_LIST
"C4100" # 'exarg' : unreferenced formal parameter
@@ -60,10 +71,25 @@ elseif(MSVC)
"C4996" # 'read': The POSIX name for this item is deprecated. Instead,
# use the ISO C++ conformant name: _read.
)
+ if(NOT(CMAKE_C_COMPILER_VERSION VERSION_LESS "19.0.23506"))
+ # MSVC 2015 Update 1.
+ set(MSVC_DISABLED_WARNINGS_LIST
+ ${MSVC_DISABLED_WARNINGS_LIST}
+ "C4464" # relative include path contains '..'
+ "C4623" # default constructor was implicitly defined as deleted
+ "C5027" # move assignment operator was implicitly defined as deleted
+ )
+ set(MSVC_LEVEL4_WARNINGS_LIST
+ # See https://connect.microsoft.com/VisualStudio/feedback/details/1217660/warning-c4265-when-using-functional-header
+ "C4265" # class has virtual functions, but destructor is not virtual
+ )
+ string(REPLACE "C" " -w4" MSVC_LEVEL4_WARNINGS_STR
+ ${MSVC_LEVEL4_WARNINGS_LIST})
+ endif()
string(REPLACE "C" " -wd" MSVC_DISABLED_WARNINGS_STR
${MSVC_DISABLED_WARNINGS_LIST})
- set(CMAKE_C_FLAGS "-Wall -WX ${MSVC_DISABLED_WARNINGS_STR}")
- set(CMAKE_CXX_FLAGS "-Wall -WX ${MSVC_DISABLED_WARNINGS_STR}")
+ set(CMAKE_C_FLAGS "-Wall -WX ${MSVC_DISABLED_WARNINGS_STR} ${MSVC_LEVEL4_WARNINGS_STR}")
+ set(CMAKE_CXX_FLAGS "-Wall -WX ${MSVC_DISABLED_WARNINGS_STR} ${MSVC_LEVEL4_WARNINGS_STR}")
add_definitions(-D_HAS_EXCEPTIONS=0)
add_definitions(-DWIN32_LEAN_AND_MEAN)
add_definitions(-DNOMINMAX)
@@ -85,8 +111,11 @@ if(FUZZ)
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")
+ add_definitions(-DBORINGSSL_UNSAFE_FUZZER_MODE)
+ set(RUNNER_ARGS "-fuzzer")
+
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fsanitize-coverage=edge,indirect-calls,8bit-counters")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fsanitize-coverage=edge,indirect-calls,8bit-counters")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address")
link_directories(.)
endif()
@@ -173,6 +202,7 @@ add_custom_target(
${CMAKE_BINARY_DIR}
COMMAND cd ssl/test/runner
COMMAND ${GO_EXECUTABLE} test -shim-path $<TARGET_FILE:bssl_shim>
+ ${RUNNER_ARGS}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
DEPENDS all_tests bssl_shim
${MAYBE_USES_TERMINAL})
diff --git a/src/CONTRIBUTING.md b/src/CONTRIBUTING.md
new file mode 100644
index 00000000..8907cc98
--- /dev/null
+++ b/src/CONTRIBUTING.md
@@ -0,0 +1,49 @@
+Want to contribute? Great! First, read this page (including the small print at the end).
+
+### Before you contribute
+Before we can use your code, you must sign the
+[Google Individual Contributor License Agreement](https://cla.developers.google.com/about/google-individual)
+(CLA), which you can do online. The CLA is necessary mainly because you own the
+copyright to your changes, even after your contribution becomes part of our
+codebase, so we need your permission to use and distribute your code. We also
+need to be sure of various other things—for instance that you'll tell us if you
+know that your code infringes on other people's patents. You don't have to sign
+the CLA until after you've submitted your code for review and a member has
+approved it, but you must do it before we can put your code into our codebase.
+Before you start working on a larger contribution, you should get in touch with
+us first via email with your idea so that we can help out and possibly guide
+you. Coordinating up front makes it much easier to avoid frustration later on.
+
+### Code reviews
+All submissions, including submissions by project members, require review. We
+use [Gerrit](https://boringssl-review.googlesource.com) for this purpose.
+
+#### Setup
+If you have not done so on this machine, you will need to set up a password for
+Gerrit. Sign in with a Google account, visit
+[this link](https://boringssl.googlesource.com/), and click the "Generate
+Password" link in the top right. You will also need to prepare your checkout to
+[add Change-Ids](https://gerrit-review.googlesource.com/Documentation/cmd-hook-commit-msg.html)
+on commit. Run:
+
+ curl -Lo .git/hooks/commit-msg https://boringssl-review.googlesource.com/tools/hooks/commit-msg
+ chmod u+x .git/hooks/commit-msg
+
+#### Uploading changes
+To upload a change, push it to the special `refs/for/master` target:
+
+ git push origin HEAD:refs/for/master
+
+The output will then give you a link to the change. Add `agl@google.com` and
+`davidben@google.com` as reviewers.
+
+Pushing a commit with the same Change-Id as an existing change will upload a new
+version of it. (Use the `git rebase` or `git commit --amend` commands.)
+
+For more detailed instructions, see the
+[Gerrit User Guide](https://gerrit-review.googlesource.com/Documentation/intro-user.html).
+
+### The small print
+Contributions made by corporations are covered by a different agreement than
+the one above, the
+[Software Grant and Corporate Contributor License Agreement](https://cla.developers.google.com/about/google-corporate).
diff --git a/src/FUZZING.md b/src/FUZZING.md
index 4bd15a37..86d09308 100644
--- a/src/FUZZING.md
+++ b/src/FUZZING.md
@@ -13,9 +13,9 @@ 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
+svn co http://llvm.org/svn/llvm-project/llvm/trunk/lib/Fuzzer
+clang++ -c -g -O2 -std=c++11 Fuzzer/*.cpp -IFuzzer
+ar ruv libFuzzer.a Fuzzer*.o
```
Then copy `libFuzzer.a` to the top-level of your BoringSSL source directory.
@@ -23,18 +23,41 @@ 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/
+./fuzz/cert -max_len=3072 -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.
+The arguments to `jobs` and `workers` should be the number of cores that you wish to dedicate to fuzzing. By default, libFuzzer uses the largest test in the corpus (or 64 if empty) as the maximum test case length. The `max_len` argument overrides this.
-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.
+The recommended values of `max_len` for each test are:
| Test | `max_len` value |
|-----------|-----------------|
-| `privkey` | 2048 |
| `cert` | 3072 |
-| `server` | 1024 |
-| `client` | 4096 |
+| `client` | 20000 |
+| `pkcs8` | 2048 |
+| `privkey` | 2048 |
+| `server` | 4096 |
+| `spki` | 1024 |
+
+
+These were determined by rounding up the length of the largest case in the corpus.
+
+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.)
+
+## Minimising the corpuses
+
+When a large number of new seeds are available, it's a good idea to minimise the corpus so that different seeds that trigger the same code paths can be deduplicated.
+
+In order to minimise all the corpuses, build for fuzzing and run `./fuzz/minimise_corpuses.sh`. Note that minimisation is, oddly, often not idempotent for unknown reasons.
+
+## Fuzzer mode
+
+When `-DFUZZ=1` is passed into CMake, BoringSSL builds with `BORINGSSL_UNSAFE_FUZZER_MODE` defined. This modifies the library, particularly the TLS stack, to be more friendly to fuzzers. It will:
+
+* Replace `RAND_bytes` with a deterministic PRNG. Call `RAND_reset_for_fuzzing()` at the start of fuzzers which use `RAND_bytes` to reset the PRNG state.
+
+* Modify the TLS stack to perform all signature checks (CertificateVerify and ServerKeyExchange) and the Finished check, but always act as if the check succeeded.
+
+* Treat every cipher as the NULL cipher.
+
+This is to prevent the fuzzer from getting stuck at a cryptographic invariant in the protocol.
diff --git a/src/INCORPORATING.md b/src/INCORPORATING.md
new file mode 100644
index 00000000..58f37db9
--- /dev/null
+++ b/src/INCORPORATING.md
@@ -0,0 +1,85 @@
+# Incorporating BoringSSL into a project
+
+**Note**: if your target project is not a Google project then first read the
+[main README](/README.md) about the purpose of BoringSSL.
+
+## Directory layout
+
+Typically projects create a `third_party/boringssl` directory to put
+BoringSSL-specific files into. The source code of BoringSSL itself goes into
+`third_party/boringssl/src`, either by copying or as a
+[submodule](https://git-scm.com/docs/git-submodule).
+
+It's generally a mistake to put BoringSSL's source code into
+`third_party/boringssl` directly because pre-built files and custom build files
+need to go somewhere and merging these with the BoringSSL source code makes
+updating things more complex.
+
+## Build support
+
+BoringSSL is designed to work with many different build systems. Currently,
+different projects use [GYP](https://gyp.gsrc.io/),
+[GN](https://chromium.googlesource.com/chromium/src/+/master/tools/gn/docs/quick_start.md),
+[Bazel](http://bazel.io/) and [Make](https://www.gnu.org/software/make/) to
+build BoringSSL, without too much pain.
+
+The development build system is CMake and the CMake build knows how to
+automatically generate the intermediate files that BoringSSL needs. However,
+outside of the CMake environment, these intermediates are generated once and
+checked into the incorporating project's source repository. This avoids
+incorporating projects needing to support Perl and Go in their build systems.
+
+The script [`util/generate_build_files.py`](/util/generate_build_files.py)
+expects to be run from the `third_party/boringssl` directory and to find the
+BoringSSL source code in `src/`. You should pass it a single argument: the name
+of the build system that you're using. If you don't use any of the supported
+build systems then you should augment `generate_build_files.py` with support
+for it.
+
+The script will pregenerate the intermediate files (see
+[BUILDING.md](/BUILDING.md) for details about which tools will need to be
+installed) and output helper files for that build system. It doesn't generate a
+complete build script, just file and test lists, which change often. For
+example, see the
+[file](https://code.google.com/p/chromium/codesearch#chromium/src/third_party/boringssl/BUILD.generated.gni)
+and
+[test](https://code.google.com/p/chromium/codesearch#chromium/src/third_party/boringssl/BUILD.generated_tests.gni)
+lists generated for GN in Chromium.
+
+## Defines
+
+BoringSSL does not present a lot of configurability in order to reduce the
+number of configurations that need to be tested. But there are a couple of
+\#defines that you may wish to set:
+
+`OPENSSL_NO_ASM` prevents the use of assembly code (although it's up to you to
+ensure that the build system doesn't link it in if you wish to reduce binary
+size). This will have a significant performance impact but can be useful if you
+wish to use tools like
+[AddressSanitizer](http://clang.llvm.org/docs/AddressSanitizer.html) that
+interact poorly with assembly code.
+
+`OPENSSL_SMALL` removes some code that is especially large at some performance
+cost.
+
+## Symbols
+
+You cannot link multiple versions of BoringSSL or OpenSSL into a single binary
+without dealing with symbol conflicts. If you are statically linking multiple
+versions together, there's not a lot that can be done because C doesn't have a
+module system.
+
+If you are using multiple versions in a single binary, in different shared
+objects, ensure you build BoringSSL with `-fvisibility=hidden` and do not
+export any of BoringSSL's symbols. This will prevent any collisions with other
+verisons that may be included in other shared objects. Note that this requires
+that all callers of BoringSSL APIs live in the same shared object as BoringSSL.
+
+If you require that BoringSSL APIs be used across shared object boundaries,
+continue to build with `-fvisibility=hidden` but define
+`BORINGSSL_SHARED_LIBRARY` in both BoringSSL and consumers. BoringSSL's own
+source files (but *not* consumers' source files) must also build with
+`BORINGSSL_IMPLEMENTATION` defined. This will export BoringSSL's public symbols
+in the resulting shared object while hiding private symbols. However note that,
+as with a static link, this precludes dynamically linking with another version
+of BoringSSL or OpenSSL.
diff --git a/src/LICENSE b/src/LICENSE
index b242dcb1..a25996f7 100644
--- a/src/LICENSE
+++ b/src/LICENSE
@@ -14,6 +14,13 @@ for the actual license texts. Actually both licenses are BSD-style Open Source
licenses. In case of any license issues related to OpenSSL please contact
openssl-core@openssl.org.
+The following are Google-internal bug numbers where explicit permission from
+some authors is recorded for use of their work. (This is purely for our own
+record keeping.)
+ 27287199
+ 27287880
+ 27287883
+
OpenSSL License
---------------
diff --git a/src/PORTING.md b/src/PORTING.md
index b3e50d7e..f953e746 100644
--- a/src/PORTING.md
+++ b/src/PORTING.md
@@ -130,6 +130,23 @@ BoringSSL's `BN_bn2hex` function uses lowercase hexadecimal digits instead of
uppercase. Some code may require changes to avoid being sensitive to this
difference.
+### Legacy ASN.1 functions
+
+OpenSSL's ASN.1 stack uses `d2i` functions for parsing. They have the form:
+
+ RSA *d2i_RSAPrivateKey(RSA **out, const uint8_t **inp, long len);
+
+In addition to returning the result, OpenSSL places it in `*out` if `out` is
+not `NULL`. On input, if `*out` is not `NULL`, OpenSSL will usually (but not
+always) reuse that object rather than allocating a new one. In BoringSSL, these
+functions are compatibility wrappers over a newer ASN.1 stack. Even if `*out`
+is not `NULL`, these wrappers will always allocate a new object and free the
+previous one.
+
+Ensure that callers do not rely on this object reuse behavior. It is
+recommended to avoid the `out` parameter completely and always pass in `NULL`.
+Note that less error-prone APIs are available for BoringSSL-specific code (see
+below).
## Optional BoringSSL-specific simplifications
@@ -162,3 +179,9 @@ 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.
+
+### ASN.1
+
+BoringSSL is in the process of deprecating OpenSSL's `d2i` and `i2d` in favor of
+new functions using the much less error-prone `CBS` and `CBB` types.
+BoringSSL-only code should use those functions where available.
diff --git a/src/README.md b/src/README.md
index d8a65c22..4caedb76 100644
--- a/src/README.md
+++ b/src/README.md
@@ -25,6 +25,8 @@ 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
+ * [INCORPORATING.md](/INCORPORATING.md): how to incorporate BoringSSL into a project.
* [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.
+ * [CONTRIBUTING.md](/CONTRIBUTING.md): how to contribute to BoringSSL.
diff --git a/src/crypto/CMakeLists.txt b/src/crypto/CMakeLists.txt
index 6651f293..3b4413cb 100644
--- a/src/crypto/CMakeLists.txt
+++ b/src/crypto/CMakeLists.txt
@@ -22,6 +22,7 @@ elseif(UNIX)
endif()
set(ASM_EXT S)
enable_language(ASM)
+ set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -Wa,--noexecstack")
else()
if (CMAKE_CL_64)
message("Using nasm")
@@ -53,39 +54,6 @@ function(perlasm dest src)
)
endfunction()
-if (${ARCH} STREQUAL "x86_64")
- set(
- CRYPTO_ARCH_SOURCES
-
- cpu-intel.c
- )
-endif()
-
-if (${ARCH} STREQUAL "x86")
- set(
- CRYPTO_ARCH_SOURCES
-
- cpu-intel.c
- )
-endif()
-
-if (${ARCH} STREQUAL "arm")
- set(
- CRYPTO_ARCH_SOURCES
-
- cpu-arm.c
- cpu-arm-asm.S
- )
-endif()
-
-if (${ARCH} STREQUAL "aarch64")
- set(
- CRYPTO_ARCH_SOURCES
-
- cpu-arm.c
- )
-endif()
-
# Level 0.1 - depends on nothing outside this set.
add_subdirectory(stack)
add_subdirectory(lhash)
@@ -106,6 +74,7 @@ add_subdirectory(conf)
add_subdirectory(chacha)
add_subdirectory(poly1305)
add_subdirectory(curve25519)
+add_subdirectory(newhope)
# Level 1, depends only on 0.*
add_subdirectory(digest)
@@ -143,9 +112,11 @@ add_subdirectory(test)
add_library(
crypto
+ cpu-aarch64-linux.c
+ cpu-arm.c
+ cpu-arm-linux.c
+ cpu-intel.c
crypto.c
- directory_posix.c
- directory_win.c
ex_data.c
mem.c
refcount_c11.c
@@ -156,8 +127,6 @@ add_library(
thread_win.c
time_support.c
- ${CRYPTO_ARCH_SOURCES}
-
$<TARGET_OBJECTS:stack>
$<TARGET_OBJECTS:lhash>
$<TARGET_OBJECTS:err>
@@ -196,7 +165,8 @@ add_library(
$<TARGET_OBJECTS:pem>
$<TARGET_OBJECTS:x509>
$<TARGET_OBJECTS:x509v3>
- $<TARGET_OBJECTS:pkcs8>
+ $<TARGET_OBJECTS:pkcs8_lib>
+ $<TARGET_OBJECTS:newhope>
)
if(NOT MSVC AND NOT ANDROID)
diff --git a/src/crypto/aes/asm/aes-armv4.pl b/src/crypto/aes/asm/aes-armv4.pl
index 882017a6..a60ed4cf 100644
--- a/src/crypto/aes/asm/aes-armv4.pl
+++ b/src/crypto/aes/asm/aes-armv4.pl
@@ -191,7 +191,6 @@ AES_Te:
@ void asm_AES_encrypt(const unsigned char *in, unsigned char *out,
@ const AES_KEY *key) {
.global asm_AES_encrypt
-.hidden asm_AES_encrypt
.type asm_AES_encrypt,%function
.align 5
asm_AES_encrypt:
@@ -441,7 +440,6 @@ _armv4_AES_encrypt:
.size _armv4_AES_encrypt,.-_armv4_AES_encrypt
.global asm_AES_set_encrypt_key
-.hidden asm_AES_set_encrypt_key
.type asm_AES_set_encrypt_key,%function
.align 5
asm_AES_set_encrypt_key:
@@ -748,7 +746,6 @@ _armv4_AES_set_encrypt_key:
.size asm_AES_set_encrypt_key,.-asm_AES_set_encrypt_key
.global asm_AES_set_decrypt_key
-.hidden asm_AES_set_decrypt_key
.type asm_AES_set_decrypt_key,%function
.align 5
asm_AES_set_decrypt_key:
@@ -765,7 +762,6 @@ asm_AES_set_decrypt_key:
@ void AES_set_enc2dec_key(const AES_KEY *inp,AES_KEY *out)
.global AES_set_enc2dec_key
-.hidden AES_set_enc2dec_key
.type AES_set_enc2dec_key,%function
.align 5
AES_set_enc2dec_key:
@@ -971,7 +967,6 @@ AES_Td:
@ void asm_AES_decrypt(const unsigned char *in, unsigned char *out,
@ const AES_KEY *key) {
.global asm_AES_decrypt
-.hidden asm_AES_decrypt
.type asm_AES_decrypt,%function
.align 5
asm_AES_decrypt:
diff --git a/src/crypto/aes/asm/bsaes-armv7.pl b/src/crypto/aes/asm/bsaes-armv7.pl
index 2617fef7..22362f51 100644
--- a/src/crypto/aes/asm/bsaes-armv7.pl
+++ b/src/crypto/aes/asm/bsaes-armv7.pl
@@ -1006,7 +1006,6 @@ if (0) { # following four functions are unsupported interface
# used for benchmarking...
$code.=<<___;
.globl bsaes_enc_key_convert
-.hidden bsaes_enc_key_convert
.type bsaes_enc_key_convert,%function
.align 4
bsaes_enc_key_convert:
@@ -1025,7 +1024,6 @@ bsaes_enc_key_convert:
.size bsaes_enc_key_convert,.-bsaes_enc_key_convert
.globl bsaes_encrypt_128
-.hidden bsaes_encrypt_128
.type bsaes_encrypt_128,%function
.align 4
bsaes_encrypt_128:
@@ -1056,7 +1054,6 @@ bsaes_encrypt_128:
.size bsaes_encrypt_128,.-bsaes_encrypt_128
.globl bsaes_dec_key_convert
-.hidden bsaes_dec_key_convert
.type bsaes_dec_key_convert,%function
.align 4
bsaes_dec_key_convert:
@@ -1077,7 +1074,6 @@ bsaes_dec_key_convert:
.size bsaes_dec_key_convert,.-bsaes_dec_key_convert
.globl bsaes_decrypt_128
-.hidden bsaes_decrypt_128
.type bsaes_decrypt_128,%function
.align 4
bsaes_decrypt_128:
@@ -1117,7 +1113,6 @@ $code.=<<___;
.extern AES_decrypt
.global bsaes_cbc_encrypt
-.hidden bsaes_cbc_encrypt
.type bsaes_cbc_encrypt,%function
.align 5
bsaes_cbc_encrypt:
@@ -1393,7 +1388,6 @@ my $keysched = "sp";
$code.=<<___;
.extern AES_encrypt
.global bsaes_ctr32_encrypt_blocks
-.hidden bsaes_ctr32_encrypt_blocks
.type bsaes_ctr32_encrypt_blocks,%function
.align 5
bsaes_ctr32_encrypt_blocks:
@@ -1635,7 +1629,6 @@ my @T=@XMM[6..7];
$code.=<<___;
.globl bsaes_xts_encrypt
-.hidden bsaes_xts_encrypt
.type bsaes_xts_encrypt,%function
.align 4
bsaes_xts_encrypt:
@@ -2050,7 +2043,6 @@ $code.=<<___;
.size bsaes_xts_encrypt,.-bsaes_xts_encrypt
.globl bsaes_xts_decrypt
-.hidden bsaes_xts_decrypt
.type bsaes_xts_decrypt,%function
.align 4
bsaes_xts_decrypt:
diff --git a/src/crypto/aes/mode_wrappers.c b/src/crypto/aes/mode_wrappers.c
index dc657dcd..4929920f 100644
--- a/src/crypto/aes/mode_wrappers.c
+++ b/src/crypto/aes/mode_wrappers.c
@@ -96,13 +96,17 @@ void AES_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len,
void AES_ofb128_encrypt(const uint8_t *in, uint8_t *out, size_t length,
const AES_KEY *key, uint8_t *ivec, int *num) {
- CRYPTO_ofb128_encrypt(in, out, length, key, ivec, num,
+ unsigned num_u = (unsigned)(*num);
+ CRYPTO_ofb128_encrypt(in, out, length, key, ivec, &num_u,
(block128_f)AES_encrypt);
+ *num = (int)num_u;
}
void AES_cfb128_encrypt(const uint8_t *in, uint8_t *out, size_t length,
const AES_KEY *key, uint8_t *ivec, int *num,
int enc) {
- CRYPTO_cfb128_encrypt(in, out, length, key, ivec, num, enc,
+ unsigned num_u = (unsigned)(*num);
+ CRYPTO_cfb128_encrypt(in, out, length, key, ivec, &num_u, enc,
(block128_f)AES_encrypt);
+ *num = (int)num_u;
}
diff --git a/src/crypto/asn1/CMakeLists.txt b/src/crypto/asn1/CMakeLists.txt
index 41e31224..f0667fcd 100644
--- a/src/crypto/asn1/CMakeLists.txt
+++ b/src/crypto/asn1/CMakeLists.txt
@@ -32,7 +32,6 @@ add_library(
f_int.c
f_string.c
t_bitst.c
- t_pkey.c
tasn_dec.c
tasn_enc.c
tasn_fre.c
@@ -43,3 +42,14 @@ add_library(
x_bignum.c
x_long.c
)
+
+add_executable(
+ asn1_test
+
+ asn1_test.cc
+
+ $<TARGET_OBJECTS:test_support>
+)
+
+target_link_libraries(asn1_test crypto)
+add_dependencies(all_tests asn1_test)
diff --git a/src/crypto/asn1/a_bitstr.c b/src/crypto/asn1/a_bitstr.c
index 8bad3394..2705ea56 100644
--- a/src/crypto/asn1/a_bitstr.c
+++ b/src/crypto/asn1/a_bitstr.c
@@ -33,7 +33,7 @@
* 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
+ * 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)"
*
@@ -61,195 +61,203 @@
#include <openssl/err.h>
#include <openssl/mem.h>
-
int ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len)
-{ return M_ASN1_BIT_STRING_set(x, d, len); }
+{
+ return M_ASN1_BIT_STRING_set(x, d, len);
+}
int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp)
- {
- int ret,j,bits,len;
- unsigned char *p,*d;
-
- if (a == NULL) return(0);
-
- len=a->length;
-
- if (len > 0)
- {
- if (a->flags & ASN1_STRING_FLAG_BITS_LEFT)
- {
- bits=(int)a->flags&0x07;
- }
- else
- {
- for ( ; len > 0; len--)
- {
- if (a->data[len-1]) break;
- }
- j=a->data[len-1];
- if (j & 0x01) bits=0;
- else if (j & 0x02) bits=1;
- else if (j & 0x04) bits=2;
- else if (j & 0x08) bits=3;
- else if (j & 0x10) bits=4;
- else if (j & 0x20) bits=5;
- else if (j & 0x40) bits=6;
- else if (j & 0x80) bits=7;
- else bits=0; /* should not happen */
- }
- }
- else
- bits=0;
-
- ret=1+len;
- if (pp == NULL) return(ret);
-
- p= *pp;
-
- *(p++)=(unsigned char)bits;
- d=a->data;
- memcpy(p,d,len);
- p+=len;
- if (len > 0) p[-1]&=(0xff<<bits);
- *pp=p;
- return(ret);
- }
+{
+ int ret, j, bits, len;
+ unsigned char *p, *d;
+
+ if (a == NULL)
+ return (0);
+
+ len = a->length;
+
+ if (len > 0) {
+ if (a->flags & ASN1_STRING_FLAG_BITS_LEFT) {
+ bits = (int)a->flags & 0x07;
+ } else {
+ for (; len > 0; len--) {
+ if (a->data[len - 1])
+ break;
+ }
+ j = a->data[len - 1];
+ if (j & 0x01)
+ bits = 0;
+ else if (j & 0x02)
+ bits = 1;
+ else if (j & 0x04)
+ bits = 2;
+ else if (j & 0x08)
+ bits = 3;
+ else if (j & 0x10)
+ bits = 4;
+ else if (j & 0x20)
+ bits = 5;
+ else if (j & 0x40)
+ bits = 6;
+ else if (j & 0x80)
+ bits = 7;
+ else
+ bits = 0; /* should not happen */
+ }
+ } else
+ bits = 0;
+
+ ret = 1 + len;
+ if (pp == NULL)
+ return (ret);
+
+ p = *pp;
+
+ *(p++) = (unsigned char)bits;
+ d = a->data;
+ memcpy(p, d, len);
+ p += len;
+ if (len > 0)
+ p[-1] &= (0xff << bits);
+ *pp = p;
+ return (ret);
+}
ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
- const unsigned char **pp, long len)
- {
- ASN1_BIT_STRING *ret=NULL;
- const unsigned char *p;
- unsigned char *s;
- int padding;
-
- if (len < 1)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_SHORT);
- goto err;
- }
-
- if ((a == NULL) || ((*a) == NULL))
- {
- if ((ret=M_ASN1_BIT_STRING_new()) == NULL) return(NULL);
- }
- else
- ret=(*a);
-
- p= *pp;
- padding = *(p++);
- if (padding > 7)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
- goto err;
- }
-
- /* We do this to preserve the settings. If we modify
- * the settings, via the _set_bit function, we will recalculate
- * on output */
- ret->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear */
- ret->flags|=(ASN1_STRING_FLAG_BITS_LEFT|padding); /* set */
-
- if (len-- > 1) /* using one because of the bits left byte */
- {
- s=(unsigned char *)OPENSSL_malloc((int)len);
- if (s == NULL)
- {
- OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- memcpy(s,p,(int)len);
- s[len-1]&=(0xff<<padding);
- p+=len;
- }
- else
- s=NULL;
-
- ret->length=(int)len;
- if (ret->data != NULL) OPENSSL_free(ret->data);
- ret->data=s;
- ret->type=V_ASN1_BIT_STRING;
- if (a != NULL) (*a)=ret;
- *pp=p;
- return(ret);
-err:
- if ((ret != NULL) && ((a == NULL) || (*a != ret)))
- M_ASN1_BIT_STRING_free(ret);
- return(NULL);
- }
-
-/* These next 2 functions from Goetz Babin-Ebell <babinebell@trustcenter.de>
+ const unsigned char **pp, long len)
+{
+ ASN1_BIT_STRING *ret = NULL;
+ const unsigned char *p;
+ unsigned char *s;
+ int padding;
+
+ if (len < 1) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_SHORT);
+ goto err;
+ }
+
+ if ((a == NULL) || ((*a) == NULL)) {
+ if ((ret = M_ASN1_BIT_STRING_new()) == NULL)
+ return (NULL);
+ } else
+ ret = (*a);
+
+ p = *pp;
+ padding = *(p++);
+ if (padding > 7) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
+ goto err;
+ }
+
+ /*
+ * We do this to preserve the settings. If we modify the settings, via
+ * the _set_bit function, we will recalculate on output
+ */
+ ret->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear */
+ ret->flags |= (ASN1_STRING_FLAG_BITS_LEFT | padding); /* set */
+
+ if (len-- > 1) { /* using one because of the bits left byte */
+ s = (unsigned char *)OPENSSL_malloc((int)len);
+ if (s == NULL) {
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ memcpy(s, p, (int)len);
+ s[len - 1] &= (0xff << padding);
+ p += len;
+ } else
+ s = NULL;
+
+ ret->length = (int)len;
+ if (ret->data != NULL)
+ OPENSSL_free(ret->data);
+ ret->data = s;
+ ret->type = V_ASN1_BIT_STRING;
+ if (a != NULL)
+ (*a) = ret;
+ *pp = p;
+ return (ret);
+ err:
+ if ((ret != NULL) && ((a == NULL) || (*a != ret)))
+ M_ASN1_BIT_STRING_free(ret);
+ return (NULL);
+}
+
+/*
+ * These next 2 functions from Goetz Babin-Ebell <babinebell@trustcenter.de>
*/
int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value)
- {
- int w,v,iv;
- unsigned char *c;
-
- w=n/8;
- v=1<<(7-(n&0x07));
- iv= ~v;
- if (!value) v=0;
-
- if (a == NULL)
- return 0;
-
- a->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear, set on write */
-
- if ((a->length < (w+1)) || (a->data == NULL))
- {
- if (!value) return(1); /* Don't need to set */
- if (a->data == NULL)
- c=(unsigned char *)OPENSSL_malloc(w+1);
- else
- c=(unsigned char *)OPENSSL_realloc_clean(a->data,
- a->length,
- w+1);
- if (c == NULL)
- {
- 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);
- a->data=c;
- a->length=w+1;
- }
- a->data[w]=((a->data[w])&iv)|v;
- while ((a->length > 0) && (a->data[a->length-1] == 0))
- a->length--;
- return(1);
- }
+{
+ int w, v, iv;
+ unsigned char *c;
+
+ w = n / 8;
+ v = 1 << (7 - (n & 0x07));
+ iv = ~v;
+ if (!value)
+ v = 0;
+
+ if (a == NULL)
+ return 0;
+
+ a->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear, set on write */
+
+ if ((a->length < (w + 1)) || (a->data == NULL)) {
+ if (!value)
+ return (1); /* Don't need to set */
+ if (a->data == NULL)
+ c = (unsigned char *)OPENSSL_malloc(w + 1);
+ else
+ c = (unsigned char *)OPENSSL_realloc_clean(a->data,
+ a->length, w + 1);
+ if (c == NULL) {
+ 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);
+ a->data = c;
+ a->length = w + 1;
+ }
+ a->data[w] = ((a->data[w]) & iv) | v;
+ while ((a->length > 0) && (a->data[a->length - 1] == 0))
+ a->length--;
+ return (1);
+}
int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n)
- {
- int w,v;
+{
+ int w, v;
- w=n/8;
- v=1<<(7-(n&0x07));
- if ((a == NULL) || (a->length < (w+1)) || (a->data == NULL))
- return(0);
- return((a->data[w]&v) != 0);
- }
+ w = n / 8;
+ v = 1 << (7 - (n & 0x07));
+ if ((a == NULL) || (a->length < (w + 1)) || (a->data == NULL))
+ return (0);
+ return ((a->data[w] & v) != 0);
+}
/*
- * Checks if the given bit string contains only bits specified by
+ * Checks if the given bit string contains only bits specified by
* the flags vector. Returns 0 if there is at least one bit set in 'a'
* which is not specified in 'flags', 1 otherwise.
* 'len' is the length of 'flags'.
*/
int ASN1_BIT_STRING_check(ASN1_BIT_STRING *a,
- unsigned char *flags, int flags_len)
- {
- int i, ok;
- /* Check if there is one bit set at all. */
- if (!a || !a->data) return 1;
-
- /* Check each byte of the internal representation of the bit string. */
- ok = 1;
- for (i = 0; i < a->length && ok; ++i)
- {
- unsigned char mask = i < flags_len ? ~flags[i] : 0xff;
- /* We are done if there is an unneeded bit set. */
- ok = (a->data[i] & mask) == 0;
- }
- return ok;
- }
+ unsigned char *flags, int flags_len)
+{
+ int i, ok;
+ /* Check if there is one bit set at all. */
+ if (!a || !a->data)
+ return 1;
+
+ /*
+ * Check each byte of the internal representation of the bit string.
+ */
+ ok = 1;
+ for (i = 0; i < a->length && ok; ++i) {
+ unsigned char mask = i < flags_len ? ~flags[i] : 0xff;
+ /* We are done if there is an unneeded bit set. */
+ ok = (a->data[i] & mask) == 0;
+ }
+ return ok;
+}
diff --git a/src/crypto/asn1/a_bool.c b/src/crypto/asn1/a_bool.c
index 826bcf43..64a079ec 100644
--- a/src/crypto/asn1/a_bool.c
+++ b/src/crypto/asn1/a_bool.c
@@ -33,7 +33,7 @@
* 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
+ * 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)"
*
@@ -59,54 +59,52 @@
#include <openssl/err.h>
#include <openssl/mem.h>
-
int i2d_ASN1_BOOLEAN(int a, unsigned char **pp)
- {
- int r;
- unsigned char *p;
+{
+ int r;
+ unsigned char *p;
- r=ASN1_object_size(0,1,V_ASN1_BOOLEAN);
- if (pp == NULL) return(r);
- p= *pp;
+ r = ASN1_object_size(0, 1, V_ASN1_BOOLEAN);
+ if (pp == NULL)
+ return (r);
+ p = *pp;
- ASN1_put_object(&p,0,1,V_ASN1_BOOLEAN,V_ASN1_UNIVERSAL);
- *(p++)= (unsigned char)a;
- *pp=p;
- return(r);
- }
+ ASN1_put_object(&p, 0, 1, V_ASN1_BOOLEAN, V_ASN1_UNIVERSAL);
+ *(p++) = (unsigned char)a;
+ *pp = p;
+ return (r);
+}
int d2i_ASN1_BOOLEAN(int *a, const unsigned char **pp, long length)
- {
- int ret= -1;
- const unsigned char *p;
- long len;
- int inf,tag,xclass;
- int i=0;
+{
+ int ret = -1;
+ const unsigned char *p;
+ long len;
+ int inf, tag, xclass;
+ int i = 0;
- p= *pp;
- inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
- if (inf & 0x80)
- {
- i=ASN1_R_BAD_OBJECT_HEADER;
- goto err;
- }
+ p = *pp;
+ inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
+ if (inf & 0x80) {
+ i = ASN1_R_BAD_OBJECT_HEADER;
+ goto err;
+ }
- if (tag != V_ASN1_BOOLEAN)
- {
- i=ASN1_R_EXPECTING_A_BOOLEAN;
- goto err;
- }
+ if (tag != V_ASN1_BOOLEAN) {
+ i = ASN1_R_EXPECTING_A_BOOLEAN;
+ goto err;
+ }
- if (len != 1)
- {
- i=ASN1_R_BOOLEAN_IS_WRONG_LENGTH;
- goto err;
- }
- ret= (int)*(p++);
- if (a != NULL) (*a)=ret;
- *pp=p;
- return(ret);
-err:
- OPENSSL_PUT_ERROR(ASN1, i);
- return(ret);
- }
+ if (len != 1) {
+ i = ASN1_R_BOOLEAN_IS_WRONG_LENGTH;
+ goto err;
+ }
+ ret = (int)*(p++);
+ if (a != NULL)
+ (*a) = ret;
+ *pp = p;
+ return (ret);
+ err:
+ OPENSSL_PUT_ERROR(ASN1, i);
+ return (ret);
+}
diff --git a/src/crypto/asn1/a_bytes.c b/src/crypto/asn1/a_bytes.c
index 19043755..7e2f85dc 100644
--- a/src/crypto/asn1/a_bytes.c
+++ b/src/crypto/asn1/a_bytes.c
@@ -62,256 +62,247 @@
#include <openssl/err.h>
#include <openssl/mem.h>
-
static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c);
-/* type is a 'bitmap' of acceptable string types.
+/*
+ * type is a 'bitmap' of acceptable string types.
*/
ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a, const unsigned char **pp,
- long length, int type)
- {
- ASN1_STRING *ret=NULL;
- const unsigned char *p;
- unsigned char *s;
- long len;
- int inf,tag,xclass;
- int i=0;
-
- p= *pp;
- inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
- if (inf & 0x80) goto err;
-
- if (tag >= 32)
- {
- i=ASN1_R_TAG_VALUE_TOO_HIGH;
- goto err;
- }
- if (!(ASN1_tag2bit(tag) & type))
- {
- i=ASN1_R_WRONG_TYPE;
- goto err;
- }
-
- /* If a bit-string, exit early */
- if (tag == V_ASN1_BIT_STRING)
- return(d2i_ASN1_BIT_STRING(a,pp,length));
-
- if ((a == NULL) || ((*a) == NULL))
- {
- if ((ret=ASN1_STRING_new()) == NULL) return(NULL);
- }
- else
- ret=(*a);
-
- if (len != 0)
- {
- s=(unsigned char *)OPENSSL_malloc((int)len+1);
- if (s == NULL)
- {
- i=ERR_R_MALLOC_FAILURE;
- goto err;
- }
- memcpy(s,p,(int)len);
- s[len]='\0';
- p+=len;
- }
- else
- s=NULL;
-
- if (ret->data != NULL) OPENSSL_free(ret->data);
- ret->length=(int)len;
- ret->data=s;
- ret->type=tag;
- if (a != NULL) (*a)=ret;
- *pp=p;
- return(ret);
-err:
- OPENSSL_PUT_ERROR(ASN1, i);
- if ((ret != NULL) && ((a == NULL) || (*a != ret)))
- ASN1_STRING_free(ret);
- return(NULL);
- }
+ long length, int type)
+{
+ ASN1_STRING *ret = NULL;
+ const unsigned char *p;
+ unsigned char *s;
+ long len;
+ int inf, tag, xclass;
+ int i = 0;
+
+ p = *pp;
+ inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
+ if (inf & 0x80)
+ goto err;
+
+ if (tag >= 32) {
+ i = ASN1_R_TAG_VALUE_TOO_HIGH;
+ goto err;
+ }
+ if (!(ASN1_tag2bit(tag) & type)) {
+ i = ASN1_R_WRONG_TYPE;
+ goto err;
+ }
+
+ /* If a bit-string, exit early */
+ if (tag == V_ASN1_BIT_STRING)
+ return (d2i_ASN1_BIT_STRING(a, pp, length));
+
+ if ((a == NULL) || ((*a) == NULL)) {
+ if ((ret = ASN1_STRING_new()) == NULL)
+ return (NULL);
+ } else
+ ret = (*a);
+
+ if (len != 0) {
+ s = (unsigned char *)OPENSSL_malloc((int)len + 1);
+ if (s == NULL) {
+ i = ERR_R_MALLOC_FAILURE;
+ goto err;
+ }
+ memcpy(s, p, (int)len);
+ s[len] = '\0';
+ p += len;
+ } else
+ s = NULL;
+
+ if (ret->data != NULL)
+ OPENSSL_free(ret->data);
+ ret->length = (int)len;
+ ret->data = s;
+ ret->type = tag;
+ if (a != NULL)
+ (*a) = ret;
+ *pp = p;
+ return (ret);
+ err:
+ OPENSSL_PUT_ERROR(ASN1, i);
+ if ((ret != NULL) && ((a == NULL) || (*a != ret)))
+ ASN1_STRING_free(ret);
+ return (NULL);
+}
int i2d_ASN1_bytes(ASN1_STRING *a, unsigned char **pp, int tag, int xclass)
- {
- int ret,r,constructed;
- unsigned char *p;
-
- if (a == NULL) return(0);
-
- if (tag == V_ASN1_BIT_STRING)
- return(i2d_ASN1_BIT_STRING(a,pp));
-
- ret=a->length;
- r=ASN1_object_size(0,ret,tag);
- if (pp == NULL) return(r);
- p= *pp;
-
- if ((tag == V_ASN1_SEQUENCE) || (tag == V_ASN1_SET))
- constructed=1;
- else
- constructed=0;
- ASN1_put_object(&p,constructed,ret,tag,xclass);
- memcpy(p,a->data,a->length);
- p+=a->length;
- *pp= p;
- return(r);
- }
+{
+ int ret, r, constructed;
+ unsigned char *p;
+
+ if (a == NULL)
+ return (0);
+
+ if (tag == V_ASN1_BIT_STRING)
+ return (i2d_ASN1_BIT_STRING(a, pp));
+
+ ret = a->length;
+ r = ASN1_object_size(0, ret, tag);
+ if (pp == NULL)
+ return (r);
+ p = *pp;
+
+ if ((tag == V_ASN1_SEQUENCE) || (tag == V_ASN1_SET))
+ constructed = 1;
+ else
+ constructed = 0;
+ ASN1_put_object(&p, constructed, ret, tag, xclass);
+ memcpy(p, a->data, a->length);
+ p += a->length;
+ *pp = p;
+ return (r);
+}
ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp,
- long length, int Ptag, int Pclass)
- {
- ASN1_STRING *ret=NULL;
- const unsigned char *p;
- unsigned char *s;
- long len;
- int inf,tag,xclass;
- int i=0;
-
- if ((a == NULL) || ((*a) == NULL))
- {
- if ((ret=ASN1_STRING_new()) == NULL) return(NULL);
- }
- else
- ret=(*a);
-
- p= *pp;
- inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
- if (inf & 0x80)
- {
- i=ASN1_R_BAD_OBJECT_HEADER;
- goto err;
- }
-
- if (tag != Ptag)
- {
- i=ASN1_R_WRONG_TAG;
- goto err;
- }
-
- if (inf & V_ASN1_CONSTRUCTED)
- {
- ASN1_const_CTX c;
-
- c.pp=pp;
- c.p=p;
- c.inf=inf;
- c.slen=len;
- c.tag=Ptag;
- c.xclass=Pclass;
- c.max=(length == 0)?0:(p+length);
- if (!asn1_collate_primitive(ret,&c))
- goto err;
- else
- {
- p=c.p;
- }
- }
- else
- {
- if (len != 0)
- {
- if ((ret->length < len) || (ret->data == NULL))
- {
- if (ret->data != NULL) OPENSSL_free(ret->data);
- s=(unsigned char *)OPENSSL_malloc((int)len + 1);
- if (s == NULL)
- {
- i=ERR_R_MALLOC_FAILURE;
- goto err;
- }
- }
- else
- s=ret->data;
- memcpy(s,p,(int)len);
- s[len] = '\0';
- p+=len;
- }
- else
- {
- s=NULL;
- if (ret->data != NULL) OPENSSL_free(ret->data);
- }
-
- ret->length=(int)len;
- ret->data=s;
- ret->type=Ptag;
- }
-
- if (a != NULL) (*a)=ret;
- *pp=p;
- return(ret);
-err:
- if ((ret != NULL) && ((a == NULL) || (*a != ret)))
- ASN1_STRING_free(ret);
- OPENSSL_PUT_ERROR(ASN1, i);
- return(NULL);
- }
-
-
-/* We are about to parse 0..n d2i_ASN1_bytes objects, we are to collapse
- * them into the one structure that is then returned */
-/* There have been a few bug fixes for this function from
- * Paul Keogh <paul.keogh@sse.ie>, many thanks to him */
+ long length, int Ptag, int Pclass)
+{
+ ASN1_STRING *ret = NULL;
+ const unsigned char *p;
+ unsigned char *s;
+ long len;
+ int inf, tag, xclass;
+ int i = 0;
+
+ if ((a == NULL) || ((*a) == NULL)) {
+ if ((ret = ASN1_STRING_new()) == NULL)
+ return (NULL);
+ } else
+ ret = (*a);
+
+ p = *pp;
+ inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
+ if (inf & 0x80) {
+ i = ASN1_R_BAD_OBJECT_HEADER;
+ goto err;
+ }
+
+ if (tag != Ptag) {
+ i = ASN1_R_WRONG_TAG;
+ goto err;
+ }
+
+ if (inf & V_ASN1_CONSTRUCTED) {
+ ASN1_const_CTX c;
+
+ c.pp = pp;
+ c.p = p;
+ c.inf = inf;
+ c.slen = len;
+ c.tag = Ptag;
+ c.xclass = Pclass;
+ c.max = (length == 0) ? 0 : (p + length);
+ if (!asn1_collate_primitive(ret, &c))
+ goto err;
+ else {
+ p = c.p;
+ }
+ } else {
+ if (len != 0) {
+ if ((ret->length < len) || (ret->data == NULL)) {
+ if (ret->data != NULL)
+ OPENSSL_free(ret->data);
+ s = (unsigned char *)OPENSSL_malloc((int)len + 1);
+ if (s == NULL) {
+ i = ERR_R_MALLOC_FAILURE;
+ goto err;
+ }
+ } else
+ s = ret->data;
+ memcpy(s, p, (int)len);
+ s[len] = '\0';
+ p += len;
+ } else {
+ s = NULL;
+ if (ret->data != NULL)
+ OPENSSL_free(ret->data);
+ }
+
+ ret->length = (int)len;
+ ret->data = s;
+ ret->type = Ptag;
+ }
+
+ if (a != NULL)
+ (*a) = ret;
+ *pp = p;
+ return (ret);
+ err:
+ if ((ret != NULL) && ((a == NULL) || (*a != ret)))
+ ASN1_STRING_free(ret);
+ OPENSSL_PUT_ERROR(ASN1, i);
+ return (NULL);
+}
+
+/*
+ * We are about to parse 0..n d2i_ASN1_bytes objects, we are to collapse them
+ * into the one structure that is then returned
+ */
+/*
+ * There have been a few bug fixes for this function from Paul Keogh
+ * <paul.keogh@sse.ie>, many thanks to him
+ */
static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c)
- {
- ASN1_STRING *os=NULL;
- BUF_MEM b;
- int num;
-
- b.length=0;
- b.max=0;
- b.data=NULL;
-
- if (a == NULL)
- {
- c->error=ERR_R_PASSED_NULL_PARAMETER;
- goto err;
- }
-
- num=0;
- for (;;)
- {
- if (c->inf & 1)
- {
- c->eos=ASN1_const_check_infinite_end(&c->p,
- (long)(c->max-c->p));
- if (c->eos) break;
- }
- else
- {
- if (c->slen <= 0) break;
- }
-
- c->q=c->p;
- if (d2i_ASN1_bytes(&os,&c->p,c->max-c->p,c->tag,c->xclass)
- == NULL)
- {
- c->error=ERR_R_ASN1_LIB;
- goto err;
- }
-
- if (!BUF_MEM_grow_clean(&b,num+os->length))
- {
- c->error=ERR_R_BUF_LIB;
- goto err;
- }
- memcpy(&(b.data[num]),os->data,os->length);
- if (!(c->inf & 1))
- c->slen-=(c->p-c->q);
- num+=os->length;
- }
-
- if (!asn1_const_Finish(c)) goto err;
-
- a->length=num;
- if (a->data != NULL) OPENSSL_free(a->data);
- a->data=(unsigned char *)b.data;
- if (os != NULL) ASN1_STRING_free(os);
- return(1);
-err:
- OPENSSL_PUT_ERROR(ASN1, c->error);
- if (os != NULL) ASN1_STRING_free(os);
- if (b.data != NULL) OPENSSL_free(b.data);
- return(0);
- }
-
+{
+ ASN1_STRING *os = NULL;
+ BUF_MEM b;
+ int num;
+
+ b.length = 0;
+ b.max = 0;
+ b.data = NULL;
+
+ if (a == NULL) {
+ c->error = ERR_R_PASSED_NULL_PARAMETER;
+ goto err;
+ }
+
+ num = 0;
+ for (;;) {
+ if (c->inf & 1) {
+ c->eos = ASN1_const_check_infinite_end(&c->p,
+ (long)(c->max - c->p));
+ if (c->eos)
+ break;
+ } else {
+ if (c->slen <= 0)
+ break;
+ }
+
+ c->q = c->p;
+ if (d2i_ASN1_bytes(&os, &c->p, c->max - c->p, c->tag, c->xclass)
+ == NULL) {
+ c->error = ERR_R_ASN1_LIB;
+ goto err;
+ }
+
+ if (!BUF_MEM_grow_clean(&b, num + os->length)) {
+ c->error = ERR_R_BUF_LIB;
+ goto err;
+ }
+ memcpy(&(b.data[num]), os->data, os->length);
+ if (!(c->inf & 1))
+ c->slen -= (c->p - c->q);
+ num += os->length;
+ }
+
+ if (!asn1_const_Finish(c))
+ goto err;
+
+ a->length = num;
+ if (a->data != NULL)
+ OPENSSL_free(a->data);
+ a->data = (unsigned char *)b.data;
+ if (os != NULL)
+ ASN1_STRING_free(os);
+ return (1);
+ err:
+ 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 97ec75b5..b5449719 100644
--- a/src/crypto/asn1/a_d2i_fp.c
+++ b/src/crypto/asn1/a_d2i_fp.c
@@ -62,225 +62,221 @@
#include <openssl/err.h>
#include <openssl/mem.h>
-
static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb);
#ifndef NO_OLD_ASN1
-#ifndef OPENSSL_NO_FP_API
+# ifndef OPENSSL_NO_FP_API
-void *ASN1_d2i_fp(void *(*xnew)(void), d2i_of_void *d2i, FILE *in, void **x)
- {
- BIO *b;
- void *ret;
+void *ASN1_d2i_fp(void *(*xnew) (void), d2i_of_void *d2i, FILE *in, void **x)
+{
+ BIO *b;
+ void *ret;
- if ((b=BIO_new(BIO_s_file())) == NULL)
- {
- OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
- return(NULL);
- }
- BIO_set_fp(b,in,BIO_NOCLOSE);
- ret=ASN1_d2i_bio(xnew,d2i,b,x);
- BIO_free(b);
- return(ret);
- }
-#endif
+ if ((b = BIO_new(BIO_s_file())) == NULL) {
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
+ return (NULL);
+ }
+ BIO_set_fp(b, in, BIO_NOCLOSE);
+ ret = ASN1_d2i_bio(xnew, d2i, b, x);
+ BIO_free(b);
+ return (ret);
+}
+# endif
-void *ASN1_d2i_bio(void *(*xnew)(void), d2i_of_void *d2i, BIO *in, void **x)
- {
- BUF_MEM *b = NULL;
- const unsigned char *p;
- void *ret=NULL;
- int len;
+void *ASN1_d2i_bio(void *(*xnew) (void), d2i_of_void *d2i, BIO *in, void **x)
+{
+ BUF_MEM *b = NULL;
+ const unsigned char *p;
+ void *ret = NULL;
+ int len;
- len = asn1_d2i_read_bio(in, &b);
- if(len < 0) goto err;
+ len = asn1_d2i_read_bio(in, &b);
+ if (len < 0)
+ goto err;
- p=(unsigned char *)b->data;
- ret=d2i(x,&p,len);
-err:
- if (b != NULL) BUF_MEM_free(b);
- return(ret);
- }
+ p = (unsigned char *)b->data;
+ ret = d2i(x, &p, len);
+ err:
+ if (b != NULL)
+ BUF_MEM_free(b);
+ return (ret);
+}
#endif
void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x)
- {
- BUF_MEM *b = NULL;
- const unsigned char *p;
- void *ret=NULL;
- int len;
+{
+ BUF_MEM *b = NULL;
+ const unsigned char *p;
+ void *ret = NULL;
+ int len;
- len = asn1_d2i_read_bio(in, &b);
- if(len < 0) goto err;
+ len = asn1_d2i_read_bio(in, &b);
+ if (len < 0)
+ goto err;
- p=(const unsigned char *)b->data;
- ret=ASN1_item_d2i(x,&p,len, it);
-err:
- if (b != NULL) BUF_MEM_free(b);
- return(ret);
- }
+ p = (const unsigned char *)b->data;
+ ret = ASN1_item_d2i(x, &p, len, it);
+ err:
+ if (b != NULL)
+ BUF_MEM_free(b);
+ return (ret);
+}
#ifndef OPENSSL_NO_FP_API
void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x)
- {
- BIO *b;
- char *ret;
+{
+ BIO *b;
+ char *ret;
- if ((b=BIO_new(BIO_s_file())) == NULL)
- {
- OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
- return(NULL);
- }
- BIO_set_fp(b,in,BIO_NOCLOSE);
- ret=ASN1_item_d2i_bio(it,b,x);
- BIO_free(b);
- return(ret);
- }
+ if ((b = BIO_new(BIO_s_file())) == NULL) {
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
+ return (NULL);
+ }
+ BIO_set_fp(b, in, BIO_NOCLOSE);
+ ret = ASN1_item_d2i_bio(it, b, x);
+ BIO_free(b);
+ return (ret);
+}
#endif
#define HEADER_SIZE 8
+#define ASN1_CHUNK_INITIAL_SIZE (16 * 1024)
static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
- {
- BUF_MEM *b;
- unsigned char *p;
- int i;
- ASN1_const_CTX c;
- size_t want=HEADER_SIZE;
- int eos=0;
- size_t off=0;
- size_t len=0;
+{
+ BUF_MEM *b;
+ unsigned char *p;
+ int i;
+ ASN1_const_CTX c;
+ size_t want = HEADER_SIZE;
+ int eos = 0;
+ size_t off = 0;
+ size_t len = 0;
- b=BUF_MEM_new();
- if (b == NULL)
- {
- OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
- return -1;
- }
+ b = BUF_MEM_new();
+ if (b == NULL) {
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
- ERR_clear_error();
- for (;;)
- {
- if (want >= (len-off))
- {
- want-=(len-off);
+ ERR_clear_error();
+ for (;;) {
+ if (want >= (len - off)) {
+ want -= (len - off);
- if (len + want < len || !BUF_MEM_grow_clean(b,len+want))
- {
- 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_R_NOT_ENOUGH_DATA);
- goto err;
- }
- if (i > 0)
- {
- if (len+i < len)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
- goto err;
- }
- len+=i;
- }
- }
- /* else data already loaded */
+ if (len + want < len || !BUF_MEM_grow_clean(b, len + want)) {
+ 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_R_NOT_ENOUGH_DATA);
+ goto err;
+ }
+ if (i > 0) {
+ if (len + i < len) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
+ goto err;
+ }
+ len += i;
+ }
+ }
+ /* else data already loaded */
+
+ p = (unsigned char *)&(b->data[off]);
+ c.p = p;
+ c.inf = ASN1_get_object(&(c.p), &(c.slen), &(c.tag), &(c.xclass),
+ len - off);
+ if (c.inf & 0x80) {
+ uint32_t e;
- p=(unsigned char *)&(b->data[off]);
- c.p=p;
- c.inf=ASN1_get_object(&(c.p),&(c.slen),&(c.tag),&(c.xclass),
- len-off);
- if (c.inf & 0x80)
- {
- uint32_t e;
+ e = ERR_GET_REASON(ERR_peek_error());
+ if (e != ASN1_R_TOO_LONG)
+ goto err;
+ else
+ ERR_clear_error(); /* clear error */
+ }
+ i = c.p - p; /* header length */
+ off += i; /* end of data */
- e=ERR_GET_REASON(ERR_peek_error());
- if (e != ASN1_R_TOO_LONG)
- goto err;
- else
- ERR_clear_error(); /* clear error */
- }
- i=c.p-p;/* header length */
- off+=i; /* end of data */
+ if (c.inf & 1) {
+ /* no data body so go round again */
+ eos++;
+ if (eos < 0) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_HEADER_TOO_LONG);
+ goto err;
+ }
+ want = HEADER_SIZE;
+ } else if (eos && (c.slen == 0) && (c.tag == V_ASN1_EOC)) {
+ /* eos value, so go back and read another header */
+ eos--;
+ if (eos <= 0)
+ break;
+ else
+ want = HEADER_SIZE;
+ } else {
+ /* suck in c.slen bytes of data */
+ want = c.slen;
+ if (want > (len - off)) {
+ size_t chunk_max = ASN1_CHUNK_INITIAL_SIZE;
+ want -= (len - off);
+ if (want > INT_MAX /* BIO_read takes an int length */ ||
+ len + want < len) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
+ goto err;
+ }
+ while (want > 0) {
+ /*
+ * Read content in chunks of increasing size
+ * so we can return an error for EOF without
+ * having to allocate the entire content length
+ * in one go.
+ */
+ size_t chunk = want > chunk_max ? chunk_max : want;
- if (c.inf & 1)
- {
- /* no data body so go round again */
- eos++;
- if (eos < 0)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_HEADER_TOO_LONG);
- goto err;
- }
- want=HEADER_SIZE;
- }
- else if (eos && (c.slen == 0) && (c.tag == V_ASN1_EOC))
- {
- /* eos value, so go back and read another header */
- eos--;
- if (eos <= 0)
- break;
- else
- want=HEADER_SIZE;
- }
- else
- {
- /* suck in c.slen bytes of data */
- want=c.slen;
- if (want > (len-off))
- {
- want-=(len-off);
- if (want > INT_MAX /* BIO_read takes an int length */ ||
- len+want < len)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
- goto err;
- }
- if (!BUF_MEM_grow_clean(b,len+want))
- {
- OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- while (want > 0)
- {
- i=BIO_read(in,&(b->data[len]),want);
- if (i <= 0)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ENOUGH_DATA);
- goto err;
- }
- /* This can't overflow because
- * |len+want| didn't overflow. */
- len+=i;
- want-=i;
- }
- }
- if (off + c.slen < off)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
- goto err;
- }
- off+=c.slen;
- if (eos <= 0)
- {
- break;
- }
- else
- want=HEADER_SIZE;
- }
- }
+ if (!BUF_MEM_grow_clean(b, len + chunk)) {
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ want -= chunk;
+ while (chunk > 0) {
+ i = BIO_read(in, &(b->data[len]), chunk);
+ if (i <= 0) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ENOUGH_DATA);
+ goto err;
+ }
+ /*
+ * This can't overflow because |len+want| didn't
+ * overflow.
+ */
+ len += i;
+ chunk -= i;
+ }
+ if (chunk_max < INT_MAX/2)
+ chunk_max *= 2;
+ }
+ }
+ if (off + c.slen < off) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
+ goto err;
+ }
+ off += c.slen;
+ if (eos <= 0) {
+ break;
+ } else
+ want = HEADER_SIZE;
+ }
+ }
- if (off > INT_MAX)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
- goto err;
- }
+ if (off > INT_MAX) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
+ goto err;
+ }
- *pb = b;
- return off;
-err:
- if (b != NULL) BUF_MEM_free(b);
- return -1;
- }
+ *pb = b;
+ return off;
+ err:
+ if (b != NULL)
+ BUF_MEM_free(b);
+ return -1;
+}
diff --git a/src/crypto/asn1/a_dup.c b/src/crypto/asn1/a_dup.c
index 5e87457c..57394f58 100644
--- a/src/crypto/asn1/a_dup.c
+++ b/src/crypto/asn1/a_dup.c
@@ -59,45 +59,53 @@
#include <openssl/err.h>
#include <openssl/mem.h>
-
void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x)
- {
- unsigned char *b,*p;
- const unsigned char *p2;
- int i;
- char *ret;
+{
+ unsigned char *b, *p;
+ const unsigned char *p2;
+ int i;
+ char *ret;
- if (x == NULL) return(NULL);
+ if (x == NULL)
+ return (NULL);
- i=i2d(x,NULL);
- b=OPENSSL_malloc(i+10);
- if (b == NULL)
- { OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); return(NULL); }
- p= b;
- i=i2d(x,&p);
- p2= b;
- ret=d2i(NULL,&p2,i);
- OPENSSL_free(b);
- return(ret);
- }
+ i = i2d(x, NULL);
+ b = OPENSSL_malloc(i + 10);
+ if (b == NULL) {
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+ p = b;
+ i = i2d(x, &p);
+ p2 = b;
+ ret = d2i(NULL, &p2, i);
+ OPENSSL_free(b);
+ return (ret);
+}
-/* ASN1_ITEM version of dup: this follows the model above except we don't need
- * to allocate the buffer. At some point this could be rewritten to directly dup
- * the underlying structure instead of doing and encode and decode. */
+/*
+ * ASN1_ITEM version of dup: this follows the model above except we don't
+ * need to allocate the buffer. At some point this could be rewritten to
+ * directly dup the underlying structure instead of doing and encode and
+ * decode.
+ */
void *ASN1_item_dup(const ASN1_ITEM *it, void *x)
- {
- unsigned char *b = NULL;
- const unsigned char *p;
- long i;
- void *ret;
+{
+ unsigned char *b = NULL;
+ const unsigned char *p;
+ long i;
+ void *ret;
- if (x == NULL) return(NULL);
+ if (x == NULL)
+ return (NULL);
- i=ASN1_item_i2d(x,&b,it);
- if (b == NULL)
- { OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); return(NULL); }
- p= b;
- ret=ASN1_item_d2i(NULL,&p,i, it);
- OPENSSL_free(b);
- return(ret);
- }
+ i = ASN1_item_i2d(x, &b, it);
+ if (b == NULL) {
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+ p = b;
+ ret = ASN1_item_d2i(NULL, &p, i, it);
+ OPENSSL_free(b);
+ return (ret);
+}
diff --git a/src/crypto/asn1/a_enum.c b/src/crypto/asn1/a_enum.c
index 579dafd3..0b95fc95 100644
--- a/src/crypto/asn1/a_enum.c
+++ b/src/crypto/asn1/a_enum.c
@@ -61,123 +61,121 @@
#include <openssl/err.h>
#include <openssl/mem.h>
-
-/*
+/*
* Code for ENUMERATED type: identical to INTEGER apart from a different tag.
* for comments on encoding see a_int.c
*/
int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v)
- {
- int j,k;
- unsigned int i;
- unsigned char buf[sizeof(long)+1];
- long d;
-
- a->type=V_ASN1_ENUMERATED;
- if (a->length < (int)(sizeof(long)+1))
- {
- if (a->data != NULL)
- OPENSSL_free(a->data);
- if ((a->data=(unsigned char *)OPENSSL_malloc(sizeof(long)+1)) != NULL)
- memset((char *)a->data,0,sizeof(long)+1);
- }
- if (a->data == NULL)
- {
- OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
- return(0);
- }
- d=v;
- if (d < 0)
- {
- d= -d;
- a->type=V_ASN1_NEG_ENUMERATED;
- }
-
- for (i=0; i<sizeof(long); i++)
- {
- if (d == 0) break;
- buf[i]=(int)d&0xff;
- d>>=8;
- }
- j=0;
- for (k=i-1; k >=0; k--)
- a->data[j++]=buf[k];
- a->length=j;
- return(1);
- }
+{
+ int j, k;
+ unsigned int i;
+ unsigned char buf[sizeof(long) + 1];
+ long d;
+
+ a->type = V_ASN1_ENUMERATED;
+ if (a->length < (int)(sizeof(long) + 1)) {
+ if (a->data != NULL)
+ OPENSSL_free(a->data);
+ if ((a->data =
+ (unsigned char *)OPENSSL_malloc(sizeof(long) + 1)) != NULL)
+ memset((char *)a->data, 0, sizeof(long) + 1);
+ }
+ if (a->data == NULL) {
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+ return (0);
+ }
+ d = v;
+ if (d < 0) {
+ d = -d;
+ a->type = V_ASN1_NEG_ENUMERATED;
+ }
+
+ for (i = 0; i < sizeof(long); i++) {
+ if (d == 0)
+ break;
+ buf[i] = (int)d & 0xff;
+ d >>= 8;
+ }
+ j = 0;
+ for (k = i - 1; k >= 0; k--)
+ a->data[j++] = buf[k];
+ a->length = j;
+ return (1);
+}
long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a)
- {
- int neg=0,i;
- long r=0;
-
- if (a == NULL) return(0L);
- i=a->type;
- if (i == V_ASN1_NEG_ENUMERATED)
- neg=1;
- else if (i != V_ASN1_ENUMERATED)
- return -1;
-
- if (a->length > (int)sizeof(long))
- {
- /* hmm... a bit ugly */
- return(0xffffffffL);
- }
- if (a->data == NULL)
- return 0;
-
- for (i=0; i<a->length; i++)
- {
- r<<=8;
- r|=(unsigned char)a->data[i];
- }
- if (neg) r= -r;
- return(r);
- }
+{
+ int neg = 0, i;
+ long r = 0;
+
+ if (a == NULL)
+ return (0L);
+ i = a->type;
+ if (i == V_ASN1_NEG_ENUMERATED)
+ neg = 1;
+ else if (i != V_ASN1_ENUMERATED)
+ return -1;
+
+ if (a->length > (int)sizeof(long)) {
+ /* hmm... a bit ugly */
+ return (0xffffffffL);
+ }
+ if (a->data == NULL)
+ return 0;
+
+ for (i = 0; i < a->length; i++) {
+ r <<= 8;
+ r |= (unsigned char)a->data[i];
+ }
+ if (neg)
+ r = -r;
+ return (r);
+}
ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai)
- {
- ASN1_ENUMERATED *ret;
- int len,j;
-
- if (ai == NULL)
- ret=M_ASN1_ENUMERATED_new();
- else
- ret=ai;
- if (ret == NULL)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
- goto err;
- }
- if(BN_is_negative(bn)) ret->type = V_ASN1_NEG_ENUMERATED;
- else ret->type=V_ASN1_ENUMERATED;
- j=BN_num_bits(bn);
- len=((j == 0)?0:((j/8)+1));
- if (ret->length < len+4)
- {
- unsigned char *new_data=OPENSSL_realloc(ret->data, len+4);
- if (!new_data)
- {
- OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- ret->data=new_data;
- }
-
- ret->length=BN_bn2bin(bn,ret->data);
- return(ret);
-err:
- if (ret != ai) M_ASN1_ENUMERATED_free(ret);
- return(NULL);
- }
+{
+ ASN1_ENUMERATED *ret;
+ int len, j;
+
+ if (ai == NULL)
+ ret = M_ASN1_ENUMERATED_new();
+ else
+ ret = ai;
+ if (ret == NULL) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
+ goto err;
+ }
+ if (BN_is_negative(bn))
+ ret->type = V_ASN1_NEG_ENUMERATED;
+ else
+ ret->type = V_ASN1_ENUMERATED;
+ j = BN_num_bits(bn);
+ len = ((j == 0) ? 0 : ((j / 8) + 1));
+ if (ret->length < len + 4) {
+ unsigned char *new_data = OPENSSL_realloc(ret->data, len + 4);
+ if (!new_data) {
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ ret->data = new_data;
+ }
+
+ ret->length = BN_bn2bin(bn, ret->data);
+ return (ret);
+ err:
+ if (ret != ai)
+ M_ASN1_ENUMERATED_free(ret);
+ return (NULL);
+}
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_R_BN_LIB);
- else if(ai->type == V_ASN1_NEG_ENUMERATED) BN_set_negative(ret,1);
- return(ret);
- }
+{
+ BIGNUM *ret;
+
+ if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL)
+ 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 7cb18a95..ee6b3db5 100644
--- a/src/crypto/asn1/a_gentm.c
+++ b/src/crypto/asn1/a_gentm.c
@@ -63,193 +63,194 @@
#include <openssl/mem.h>
#include <openssl/time_support.h>
+#include "asn1_locl.h"
int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d)
- {
- static const int min[9]={ 0, 0, 1, 1, 0, 0, 0, 0, 0};
- static const int max[9]={99, 99,12,31,23,59,59,12,59};
- char *a;
- int n,i,l,o;
-
- if (d->type != V_ASN1_GENERALIZEDTIME) return(0);
- l=d->length;
- a=(char *)d->data;
- o=0;
- /* GENERALIZEDTIME is similar to UTCTIME except the year is
- * represented as YYYY. This stuff treats everything as a two digit
- * field so make first two fields 00 to 99
- */
- if (l < 13) goto err;
- for (i=0; i<7; i++)
- {
- if ((i == 6) && ((a[o] == 'Z') ||
- (a[o] == '+') || (a[o] == '-')))
- {
- i++;
- if (tm)
- tm->tm_sec = 0;
- break;
- }
- if ((a[o] < '0') || (a[o] > '9')) goto err;
- n= a[o]-'0';
- if (++o > l) goto err;
-
- if ((a[o] < '0') || (a[o] > '9')) goto err;
- n=(n*10)+ a[o]-'0';
- if (++o > l) goto err;
-
- if ((n < min[i]) || (n > max[i])) goto err;
- if (tm)
- {
- switch(i)
- {
- case 0:
- tm->tm_year = n * 100 - 1900;
- break;
- case 1:
- tm->tm_year += n;
- break;
- case 2:
- tm->tm_mon = n - 1;
- break;
- case 3:
- tm->tm_mday = n;
- break;
- case 4:
- tm->tm_hour = n;
- break;
- case 5:
- tm->tm_min = n;
- break;
- case 6:
- tm->tm_sec = n;
- break;
- }
- }
- }
- /* Optional fractional seconds: decimal point followed by one
- * or more digits.
- */
- if (a[o] == '.')
- {
- if (++o > l) goto err;
- i = o;
- while ((a[o] >= '0') && (a[o] <= '9') && (o <= l))
- o++;
- /* Must have at least one digit after decimal point */
- if (i == o) goto err;
- }
-
- if (a[o] == 'Z')
- o++;
- else if ((a[o] == '+') || (a[o] == '-'))
- {
- int offsign = a[o] == '-' ? -1 : 1, offset = 0;
- o++;
- if (o+4 > l) goto err;
- for (i=7; i<9; i++)
- {
- if ((a[o] < '0') || (a[o] > '9')) goto err;
- n= a[o]-'0';
- o++;
- if ((a[o] < '0') || (a[o] > '9')) goto err;
- n=(n*10)+ a[o]-'0';
- if ((n < min[i]) || (n > max[i])) goto err;
- if (tm)
- {
- if (i == 7)
- offset = n * 3600;
- else if (i == 8)
- offset += n * 60;
- }
- o++;
- }
- if (offset && !OPENSSL_gmtime_adj(tm, 0, offset * offsign))
- return 0;
- }
- else if (a[o])
- {
- /* Missing time zone information. */
- goto err;
- }
- return(o == l);
-err:
- return(0);
- }
+{
+ static const int min[9] = { 0, 0, 1, 1, 0, 0, 0, 0, 0 };
+ static const int max[9] = { 99, 99, 12, 31, 23, 59, 59, 12, 59 };
+ char *a;
+ int n, i, l, o;
+
+ if (d->type != V_ASN1_GENERALIZEDTIME)
+ return (0);
+ l = d->length;
+ a = (char *)d->data;
+ o = 0;
+ /*
+ * GENERALIZEDTIME is similar to UTCTIME except the year is represented
+ * as YYYY. This stuff treats everything as a two digit field so make
+ * first two fields 00 to 99
+ */
+ if (l < 13)
+ goto err;
+ for (i = 0; i < 7; i++) {
+ if ((i == 6) && ((a[o] == 'Z') || (a[o] == '+') || (a[o] == '-'))) {
+ i++;
+ if (tm)
+ tm->tm_sec = 0;
+ break;
+ }
+ if ((a[o] < '0') || (a[o] > '9'))
+ goto err;
+ n = a[o] - '0';
+ if (++o > l)
+ goto err;
+
+ if ((a[o] < '0') || (a[o] > '9'))
+ goto err;
+ n = (n * 10) + a[o] - '0';
+ if (++o > l)
+ goto err;
+
+ if ((n < min[i]) || (n > max[i]))
+ goto err;
+ if (tm) {
+ switch (i) {
+ case 0:
+ tm->tm_year = n * 100 - 1900;
+ break;
+ case 1:
+ tm->tm_year += n;
+ break;
+ case 2:
+ tm->tm_mon = n - 1;
+ break;
+ case 3:
+ tm->tm_mday = n;
+ break;
+ case 4:
+ tm->tm_hour = n;
+ break;
+ case 5:
+ tm->tm_min = n;
+ break;
+ case 6:
+ tm->tm_sec = n;
+ break;
+ }
+ }
+ }
+ /*
+ * Optional fractional seconds: decimal point followed by one or more
+ * digits.
+ */
+ if (a[o] == '.') {
+ if (++o > l)
+ goto err;
+ i = o;
+ while ((a[o] >= '0') && (a[o] <= '9') && (o <= l))
+ o++;
+ /* Must have at least one digit after decimal point */
+ if (i == o)
+ goto err;
+ }
+
+ if (a[o] == 'Z')
+ o++;
+ else if ((a[o] == '+') || (a[o] == '-')) {
+ int offsign = a[o] == '-' ? -1 : 1, offset = 0;
+ o++;
+ if (o + 4 > l)
+ goto err;
+ for (i = 7; i < 9; i++) {
+ if ((a[o] < '0') || (a[o] > '9'))
+ goto err;
+ n = a[o] - '0';
+ o++;
+ if ((a[o] < '0') || (a[o] > '9'))
+ goto err;
+ n = (n * 10) + a[o] - '0';
+ if ((n < min[i]) || (n > max[i]))
+ goto err;
+ if (tm) {
+ if (i == 7)
+ offset = n * 3600;
+ else if (i == 8)
+ offset += n * 60;
+ }
+ o++;
+ }
+ if (offset && !OPENSSL_gmtime_adj(tm, 0, offset * offsign))
+ return 0;
+ } else if (a[o]) {
+ /* Missing time zone information. */
+ goto err;
+ }
+ return (o == l);
+ err:
+ return (0);
+}
int ASN1_GENERALIZEDTIME_check(const ASN1_GENERALIZEDTIME *d)
- {
- return asn1_generalizedtime_to_tm(NULL, d);
- }
+{
+ return asn1_generalizedtime_to_tm(NULL, d);
+}
int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str)
- {
- ASN1_GENERALIZEDTIME t;
-
- t.type=V_ASN1_GENERALIZEDTIME;
- t.length=strlen(str);
- t.data=(unsigned char *)str;
- if (ASN1_GENERALIZEDTIME_check(&t))
- {
- if (s != NULL)
- {
- if (!ASN1_STRING_set((ASN1_STRING *)s,
- (unsigned char *)str,t.length))
- return 0;
- s->type=V_ASN1_GENERALIZEDTIME;
- }
- return(1);
- }
- else
- return(0);
- }
+{
+ ASN1_GENERALIZEDTIME t;
+
+ t.type = V_ASN1_GENERALIZEDTIME;
+ t.length = strlen(str);
+ t.data = (unsigned char *)str;
+ if (ASN1_GENERALIZEDTIME_check(&t)) {
+ if (s != NULL) {
+ if (!ASN1_STRING_set((ASN1_STRING *)s,
+ (unsigned char *)str, t.length))
+ return 0;
+ s->type = V_ASN1_GENERALIZEDTIME;
+ }
+ return (1);
+ } else
+ return (0);
+}
ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s,
- time_t t)
- {
- return ASN1_GENERALIZEDTIME_adj(s, t, 0, 0);
- }
+ time_t t)
+{
+ return ASN1_GENERALIZEDTIME_adj(s, t, 0, 0);
+}
ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s,
- time_t t, int offset_day, long offset_sec)
- {
- char *p;
- struct tm *ts;
- struct tm data;
- size_t len = 20;
-
- if (s == NULL)
- s=M_ASN1_GENERALIZEDTIME_new();
- if (s == NULL)
- return(NULL);
-
- ts=OPENSSL_gmtime(&t, &data);
- if (ts == NULL)
- return(NULL);
-
- if (offset_day || offset_sec)
- {
- if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
- return NULL;
- }
-
- p=(char *)s->data;
- if ((p == NULL) || ((size_t)s->length < len))
- {
- p=OPENSSL_malloc(len);
- if (p == NULL)
- {
- OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
- return(NULL);
- }
- if (s->data != NULL)
- OPENSSL_free(s->data);
- s->data=(unsigned char *)p;
- }
-
- BIO_snprintf(p,len,"%04d%02d%02d%02d%02d%02dZ",ts->tm_year + 1900,
- ts->tm_mon+1,ts->tm_mday,ts->tm_hour,ts->tm_min,ts->tm_sec);
- s->length=strlen(p);
- s->type=V_ASN1_GENERALIZEDTIME;
- return(s);
- }
+ time_t t, int offset_day,
+ long offset_sec)
+{
+ char *p;
+ struct tm *ts;
+ struct tm data;
+ size_t len = 20;
+
+ if (s == NULL)
+ s = M_ASN1_GENERALIZEDTIME_new();
+ if (s == NULL)
+ return (NULL);
+
+ ts = OPENSSL_gmtime(&t, &data);
+ if (ts == NULL)
+ return (NULL);
+
+ if (offset_day || offset_sec) {
+ if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
+ return NULL;
+ }
+
+ p = (char *)s->data;
+ if ((p == NULL) || ((size_t)s->length < len)) {
+ p = OPENSSL_malloc(len);
+ if (p == NULL) {
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+ if (s->data != NULL)
+ OPENSSL_free(s->data);
+ s->data = (unsigned char *)p;
+ }
+
+ BIO_snprintf(p, len, "%04d%02d%02d%02d%02d%02dZ", ts->tm_year + 1900,
+ ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, ts->tm_min,
+ ts->tm_sec);
+ s->length = strlen(p);
+ s->type = V_ASN1_GENERALIZEDTIME;
+ return (s);
+}
diff --git a/src/crypto/asn1/a_i2d_fp.c b/src/crypto/asn1/a_i2d_fp.c
index 74ded78b..486207ed 100644
--- a/src/crypto/asn1/a_i2d_fp.c
+++ b/src/crypto/asn1/a_i2d_fp.c
@@ -59,96 +59,89 @@
#include <openssl/err.h>
#include <openssl/mem.h>
-
int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x)
- {
- BIO *b;
- int ret;
+{
+ BIO *b;
+ int ret;
- if ((b=BIO_new(BIO_s_file())) == NULL)
- {
- OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
- return(0);
- }
- BIO_set_fp(b,out,BIO_NOCLOSE);
- ret=ASN1_i2d_bio(i2d,b,x);
- BIO_free(b);
- return(ret);
- }
+ if ((b = BIO_new(BIO_s_file())) == NULL) {
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
+ return (0);
+ }
+ BIO_set_fp(b, out, BIO_NOCLOSE);
+ ret = ASN1_i2d_bio(i2d, b, x);
+ BIO_free(b);
+ return (ret);
+}
int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, void *x)
- {
- char *b;
- unsigned char *p;
- int i,j=0,n,ret=1;
+{
+ char *b;
+ unsigned char *p;
+ int i, j = 0, n, ret = 1;
+
+ n = i2d(x, NULL);
+ b = (char *)OPENSSL_malloc(n);
+ if (b == NULL) {
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+ return (0);
+ }
- n=i2d(x,NULL);
- b=(char *)OPENSSL_malloc(n);
- if (b == NULL)
- {
- OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
- return(0);
- }
+ p = (unsigned char *)b;
+ i2d(x, &p);
- p=(unsigned char *)b;
- i2d(x,&p);
-
- for (;;)
- {
- i=BIO_write(out,&(b[j]),n);
- if (i == n) break;
- if (i <= 0)
- {
- ret=0;
- break;
- }
- j+=i;
- n-=i;
- }
- OPENSSL_free(b);
- return(ret);
- }
+ for (;;) {
+ i = BIO_write(out, &(b[j]), n);
+ if (i == n)
+ break;
+ if (i <= 0) {
+ ret = 0;
+ break;
+ }
+ j += i;
+ n -= i;
+ }
+ OPENSSL_free(b);
+ return (ret);
+}
int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x)
- {
- BIO *b;
- int ret;
+{
+ BIO *b;
+ int ret;
- if ((b=BIO_new(BIO_s_file())) == NULL)
- {
- OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
- return(0);
- }
- BIO_set_fp(b,out,BIO_NOCLOSE);
- ret=ASN1_item_i2d_bio(it,b,x);
- BIO_free(b);
- return(ret);
- }
+ if ((b = BIO_new(BIO_s_file())) == NULL) {
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
+ return (0);
+ }
+ BIO_set_fp(b, out, BIO_NOCLOSE);
+ ret = ASN1_item_i2d_bio(it, b, x);
+ BIO_free(b);
+ return (ret);
+}
int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x)
- {
- unsigned char *b = NULL;
- int i,j=0,n,ret=1;
+{
+ unsigned char *b = NULL;
+ int i, j = 0, n, ret = 1;
- n = ASN1_item_i2d(x, &b, it);
- if (b == NULL)
- {
- OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
- return(0);
- }
+ n = ASN1_item_i2d(x, &b, it);
+ if (b == NULL) {
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+ return (0);
+ }
- for (;;)
- {
- i=BIO_write(out,&(b[j]),n);
- if (i == n) break;
- if (i <= 0)
- {
- ret=0;
- break;
- }
- j+=i;
- n-=i;
- }
- OPENSSL_free(b);
- return(ret);
- }
+ for (;;) {
+ i = BIO_write(out, &(b[j]), n);
+ if (i == n)
+ break;
+ if (i <= 0) {
+ ret = 0;
+ break;
+ }
+ j += i;
+ n -= i;
+ }
+ OPENSSL_free(b);
+ return (ret);
+}
diff --git a/src/crypto/asn1/a_int.c b/src/crypto/asn1/a_int.c
index 9a565343..38a01bcb 100644
--- a/src/crypto/asn1/a_int.c
+++ b/src/crypto/asn1/a_int.c
@@ -61,47 +61,46 @@
#include <openssl/err.h>
#include <openssl/mem.h>
-
ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x)
-{ return M_ASN1_INTEGER_dup(x);}
+{
+ return M_ASN1_INTEGER_dup(x);
+}
int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y)
- {
- int neg, ret;
- /* Compare signs */
- neg = x->type & V_ASN1_NEG;
- if (neg != (y->type & V_ASN1_NEG))
- {
- if (neg)
- return -1;
- else
- return 1;
- }
-
- ret = ASN1_STRING_cmp(x, y);
-
- if (neg)
- return -ret;
- else
- return ret;
- }
-
-
-/*
+{
+ int neg, ret;
+ /* Compare signs */
+ neg = x->type & V_ASN1_NEG;
+ if (neg != (y->type & V_ASN1_NEG)) {
+ if (neg)
+ return -1;
+ else
+ return 1;
+ }
+
+ ret = ASN1_STRING_cmp(x, y);
+
+ if (neg)
+ return -ret;
+ else
+ return ret;
+}
+
+/*
* This converts an ASN1 INTEGER into its content encoding.
* The internal representation is an ASN1_STRING whose data is a big endian
* representation of the value, ignoring the sign. The sign is determined by
- * the type: V_ASN1_INTEGER for positive and V_ASN1_NEG_INTEGER for negative.
+ * the type: V_ASN1_INTEGER for positive and V_ASN1_NEG_INTEGER for negative.
*
* Positive integers are no problem: they are almost the same as the DER
* encoding, except if the first byte is >= 0x80 we need to add a zero pad.
*
* Negative integers are a bit trickier...
* The DER representation of negative integers is in 2s complement form.
- * The internal form is converted by complementing each octet and finally
+ * The internal form is converted by complementing each octet and finally
* adding one to the result. This can be done less messily with a little trick.
* If the internal form has trailing zeroes then they will become FF by the
- * complement and 0 by the add one (due to carry) so just copy as many trailing
+ * complement and 0 by the add one (due to carry) so just copy as many trailing
* zeros to the destination as there are in the source. The carry will add one
* to the last none zero octet: so complement this octet and add one and finally
* complement any left over until you get to the start of the string.
@@ -113,344 +112,349 @@ int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y)
*/
int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp)
- {
- int pad=0,ret,i,neg;
- unsigned char *p,*n,pb=0;
-
- if (a == NULL) return(0);
- neg=a->type & V_ASN1_NEG;
- if (a->length == 0)
- ret=1;
- else
- {
- ret=a->length;
- i=a->data[0];
- if (!neg && (i > 127)) {
- pad=1;
- pb=0;
- } else if(neg) {
- if(i>128) {
- pad=1;
- pb=0xFF;
- } else if(i == 128) {
- /*
- * Special case: if any other bytes non zero we pad:
- * otherwise we don't.
- */
- for(i = 1; i < a->length; i++) if(a->data[i]) {
- pad=1;
- pb=0xFF;
- break;
- }
- }
- }
- ret+=pad;
- }
- if (pp == NULL) return(ret);
- p= *pp;
-
- if (pad) *(p++)=pb;
- if (a->length == 0) *(p++)=0;
- else if (!neg) memcpy(p,a->data,(unsigned int)a->length);
- else {
- /* Begin at the end of the encoding */
- n=a->data + a->length - 1;
- p += a->length - 1;
- i = a->length;
- /* Copy zeros to destination as long as source is zero */
- while(!*n) {
- *(p--) = 0;
- n--;
- i--;
- }
- /* Complement and increment next octet */
- *(p--) = ((*(n--)) ^ 0xff) + 1;
- i--;
- /* Complement any octets left */
- for(;i > 0; i--) *(p--) = *(n--) ^ 0xff;
- }
-
- *pp+=ret;
- return(ret);
- }
+{
+ int pad = 0, ret, i, neg;
+ unsigned char *p, *n, pb = 0;
+
+ if (a == NULL)
+ return (0);
+ neg = a->type & V_ASN1_NEG;
+ if (a->length == 0)
+ ret = 1;
+ else {
+ ret = a->length;
+ i = a->data[0];
+ if (ret == 1 && i == 0)
+ neg = 0;
+ if (!neg && (i > 127)) {
+ pad = 1;
+ pb = 0;
+ } else if (neg) {
+ if (i > 128) {
+ pad = 1;
+ pb = 0xFF;
+ } else if (i == 128) {
+ /*
+ * Special case: if any other bytes non zero we pad:
+ * otherwise we don't.
+ */
+ for (i = 1; i < a->length; i++)
+ if (a->data[i]) {
+ pad = 1;
+ pb = 0xFF;
+ break;
+ }
+ }
+ }
+ ret += pad;
+ }
+ if (pp == NULL)
+ return (ret);
+ p = *pp;
+
+ if (pad)
+ *(p++) = pb;
+ if (a->length == 0)
+ *(p++) = 0;
+ else if (!neg)
+ memcpy(p, a->data, (unsigned int)a->length);
+ else {
+ /* Begin at the end of the encoding */
+ n = a->data + a->length - 1;
+ p += a->length - 1;
+ i = a->length;
+ /* Copy zeros to destination as long as source is zero */
+ while (!*n && i > 1) {
+ *(p--) = 0;
+ n--;
+ i--;
+ }
+ /* Complement and increment next octet */
+ *(p--) = ((*(n--)) ^ 0xff) + 1;
+ i--;
+ /* Complement any octets left */
+ for (; i > 0; i--)
+ *(p--) = *(n--) ^ 0xff;
+ }
+
+ *pp += ret;
+ return (ret);
+}
/* Convert just ASN1 INTEGER content octets to ASN1_INTEGER structure */
ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp,
- long len)
- {
- ASN1_INTEGER *ret=NULL;
- const unsigned char *p, *pend;
- unsigned char *to,*s;
- int i;
-
- if ((a == NULL) || ((*a) == NULL))
- {
- if ((ret=M_ASN1_INTEGER_new()) == NULL) return(NULL);
- ret->type=V_ASN1_INTEGER;
- }
- else
- ret=(*a);
-
- p= *pp;
- pend = p + len;
-
- /* We must OPENSSL_malloc stuff, even for 0 bytes otherwise it
- * signifies a missing NULL parameter. */
- s=(unsigned char *)OPENSSL_malloc((int)len+1);
- if (s == NULL)
- {
- i=ERR_R_MALLOC_FAILURE;
- goto err;
- }
- to=s;
- if(!len) {
- /* Strictly speaking this is an illegal INTEGER but we
- * tolerate it.
- */
- ret->type=V_ASN1_INTEGER;
- } else if (*p & 0x80) /* a negative number */
- {
- ret->type=V_ASN1_NEG_INTEGER;
- if ((*p == 0xff) && (len != 1)) {
- p++;
- len--;
- }
- i = len;
- p += i - 1;
- to += i - 1;
- while((!*p) && i) {
- *(to--) = 0;
- i--;
- p--;
- }
- /* Special case: if all zeros then the number will be of
- * the form FF followed by n zero bytes: this corresponds to
- * 1 followed by n zero bytes. We've already written n zeros
- * so we just append an extra one and set the first byte to
- * a 1. This is treated separately because it is the only case
- * where the number of bytes is larger than len.
- */
- if(!i) {
- *s = 1;
- s[len] = 0;
- len++;
- } else {
- *(to--) = (*(p--) ^ 0xff) + 1;
- i--;
- for(;i > 0; i--) *(to--) = *(p--) ^ 0xff;
- }
- } else {
- ret->type=V_ASN1_INTEGER;
- if ((*p == 0) && (len != 1))
- {
- p++;
- len--;
- }
- memcpy(s,p,(int)len);
- }
-
- if (ret->data != NULL) OPENSSL_free(ret->data);
- ret->data=s;
- ret->length=(int)len;
- if (a != NULL) (*a)=ret;
- *pp=pend;
- return(ret);
-err:
- OPENSSL_PUT_ERROR(ASN1, i);
- if ((ret != NULL) && ((a == NULL) || (*a != ret)))
- M_ASN1_INTEGER_free(ret);
- return(NULL);
- }
-
-
-/* This is a version of d2i_ASN1_INTEGER that ignores the sign bit of
- * ASN1 integers: some broken software can encode a positive INTEGER
- * with its MSB set as negative (it doesn't add a padding zero).
+ long len)
+{
+ ASN1_INTEGER *ret = NULL;
+ const unsigned char *p, *pend;
+ unsigned char *to, *s;
+ int i;
+
+ if ((a == NULL) || ((*a) == NULL)) {
+ if ((ret = M_ASN1_INTEGER_new()) == NULL)
+ return (NULL);
+ ret->type = V_ASN1_INTEGER;
+ } else
+ ret = (*a);
+
+ p = *pp;
+ pend = p + len;
+
+ /*
+ * We must OPENSSL_malloc stuff, even for 0 bytes otherwise it signifies
+ * a missing NULL parameter.
+ */
+ s = (unsigned char *)OPENSSL_malloc((int)len + 1);
+ if (s == NULL) {
+ i = ERR_R_MALLOC_FAILURE;
+ goto err;
+ }
+ to = s;
+ if (!len) {
+ /*
+ * Strictly speaking this is an illegal INTEGER but we tolerate it.
+ */
+ ret->type = V_ASN1_INTEGER;
+ } else if (*p & 0x80) { /* a negative number */
+ ret->type = V_ASN1_NEG_INTEGER;
+ if ((*p == 0xff) && (len != 1)) {
+ p++;
+ len--;
+ }
+ i = len;
+ p += i - 1;
+ to += i - 1;
+ while ((!*p) && i) {
+ *(to--) = 0;
+ i--;
+ p--;
+ }
+ /*
+ * Special case: if all zeros then the number will be of the form FF
+ * followed by n zero bytes: this corresponds to 1 followed by n zero
+ * bytes. We've already written n zeros so we just append an extra
+ * one and set the first byte to a 1. This is treated separately
+ * because it is the only case where the number of bytes is larger
+ * than len.
+ */
+ if (!i) {
+ *s = 1;
+ s[len] = 0;
+ len++;
+ } else {
+ *(to--) = (*(p--) ^ 0xff) + 1;
+ i--;
+ for (; i > 0; i--)
+ *(to--) = *(p--) ^ 0xff;
+ }
+ } else {
+ ret->type = V_ASN1_INTEGER;
+ if ((*p == 0) && (len != 1)) {
+ p++;
+ len--;
+ }
+ memcpy(s, p, (int)len);
+ }
+
+ if (ret->data != NULL)
+ OPENSSL_free(ret->data);
+ ret->data = s;
+ ret->length = (int)len;
+ if (a != NULL)
+ (*a) = ret;
+ *pp = pend;
+ return (ret);
+ err:
+ OPENSSL_PUT_ERROR(ASN1, i);
+ if ((ret != NULL) && ((a == NULL) || (*a != ret)))
+ M_ASN1_INTEGER_free(ret);
+ return (NULL);
+}
+
+/*
+ * This is a version of d2i_ASN1_INTEGER that ignores the sign bit of ASN1
+ * integers: some broken software can encode a positive INTEGER with its MSB
+ * set as negative (it doesn't add a padding zero).
*/
ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp,
- long length)
- {
- ASN1_INTEGER *ret=NULL;
- const unsigned char *p;
- unsigned char *s;
- long len;
- int inf,tag,xclass;
- int i;
-
- if ((a == NULL) || ((*a) == NULL))
- {
- if ((ret=M_ASN1_INTEGER_new()) == NULL) return(NULL);
- ret->type=V_ASN1_INTEGER;
- }
- else
- ret=(*a);
-
- p= *pp;
- inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
- if (inf & 0x80)
- {
- i=ASN1_R_BAD_OBJECT_HEADER;
- goto err;
- }
-
- if (tag != V_ASN1_INTEGER)
- {
- i=ASN1_R_EXPECTING_AN_INTEGER;
- goto err;
- }
-
- /* We must OPENSSL_malloc stuff, even for 0 bytes otherwise it
- * signifies a missing NULL parameter. */
- s=(unsigned char *)OPENSSL_malloc((int)len+1);
- if (s == NULL)
- {
- i=ERR_R_MALLOC_FAILURE;
- goto err;
- }
- ret->type=V_ASN1_INTEGER;
- if(len) {
- if ((*p == 0) && (len != 1))
- {
- p++;
- len--;
- }
- memcpy(s,p,(int)len);
- p+=len;
- }
-
- if (ret->data != NULL) OPENSSL_free(ret->data);
- ret->data=s;
- ret->length=(int)len;
- if (a != NULL) (*a)=ret;
- *pp=p;
- return(ret);
-err:
- OPENSSL_PUT_ERROR(ASN1, i);
- if ((ret != NULL) && ((a == NULL) || (*a != ret)))
- M_ASN1_INTEGER_free(ret);
- return(NULL);
- }
+ long length)
+{
+ ASN1_INTEGER *ret = NULL;
+ const unsigned char *p;
+ unsigned char *s;
+ long len;
+ int inf, tag, xclass;
+ int i;
+
+ if ((a == NULL) || ((*a) == NULL)) {
+ if ((ret = M_ASN1_INTEGER_new()) == NULL)
+ return (NULL);
+ ret->type = V_ASN1_INTEGER;
+ } else
+ ret = (*a);
+
+ p = *pp;
+ inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
+ if (inf & 0x80) {
+ i = ASN1_R_BAD_OBJECT_HEADER;
+ goto err;
+ }
+
+ if (tag != V_ASN1_INTEGER) {
+ i = ASN1_R_EXPECTING_AN_INTEGER;
+ goto err;
+ }
+
+ /*
+ * We must OPENSSL_malloc stuff, even for 0 bytes otherwise it signifies
+ * a missing NULL parameter.
+ */
+ s = (unsigned char *)OPENSSL_malloc((int)len + 1);
+ if (s == NULL) {
+ i = ERR_R_MALLOC_FAILURE;
+ goto err;
+ }
+ ret->type = V_ASN1_INTEGER;
+ if (len) {
+ if ((*p == 0) && (len != 1)) {
+ p++;
+ len--;
+ }
+ memcpy(s, p, (int)len);
+ p += len;
+ }
+
+ if (ret->data != NULL)
+ OPENSSL_free(ret->data);
+ ret->data = s;
+ ret->length = (int)len;
+ if (a != NULL)
+ (*a) = ret;
+ *pp = p;
+ return (ret);
+ err:
+ OPENSSL_PUT_ERROR(ASN1, i);
+ if ((ret != NULL) && ((a == NULL) || (*a != ret)))
+ M_ASN1_INTEGER_free(ret);
+ return (NULL);
+}
int ASN1_INTEGER_set(ASN1_INTEGER *a, long v)
- {
- int j,k;
- unsigned int i;
- unsigned char buf[sizeof(long)+1];
- long d;
-
- a->type=V_ASN1_INTEGER;
- if (a->length < (int)(sizeof(long)+1))
- {
- if (a->data != NULL)
- OPENSSL_free(a->data);
- if ((a->data=(unsigned char *)OPENSSL_malloc(sizeof(long)+1)) != NULL)
- memset((char *)a->data,0,sizeof(long)+1);
- }
- if (a->data == NULL)
- {
- OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
- return(0);
- }
- d=v;
- if (d < 0)
- {
- d= -d;
- a->type=V_ASN1_NEG_INTEGER;
- }
-
- for (i=0; i<sizeof(long); i++)
- {
- if (d == 0) break;
- buf[i]=(int)d&0xff;
- d>>=8;
- }
- j=0;
- for (k=i-1; k >=0; k--)
- a->data[j++]=buf[k];
- a->length=j;
- return(1);
- }
+{
+ int j, k;
+ unsigned int i;
+ unsigned char buf[sizeof(long) + 1];
+ long d;
+
+ a->type = V_ASN1_INTEGER;
+ if (a->length < (int)(sizeof(long) + 1)) {
+ if (a->data != NULL)
+ OPENSSL_free(a->data);
+ if ((a->data =
+ (unsigned char *)OPENSSL_malloc(sizeof(long) + 1)) != NULL)
+ memset((char *)a->data, 0, sizeof(long) + 1);
+ }
+ if (a->data == NULL) {
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+ return (0);
+ }
+ d = v;
+ if (d < 0) {
+ d = -d;
+ a->type = V_ASN1_NEG_INTEGER;
+ }
+
+ for (i = 0; i < sizeof(long); i++) {
+ if (d == 0)
+ break;
+ buf[i] = (int)d & 0xff;
+ d >>= 8;
+ }
+ j = 0;
+ for (k = i - 1; k >= 0; k--)
+ a->data[j++] = buf[k];
+ a->length = j;
+ return (1);
+}
long ASN1_INTEGER_get(const ASN1_INTEGER *a)
- {
- int neg=0,i;
- long r=0;
-
- if (a == NULL) return(0L);
- i=a->type;
- if (i == V_ASN1_NEG_INTEGER)
- neg=1;
- else if (i != V_ASN1_INTEGER)
- return -1;
-
- if (a->length > (int)sizeof(long))
- {
- /* hmm... a bit ugly, return all ones */
- return -1;
- }
- if (a->data == NULL)
- return 0;
-
- for (i=0; i<a->length; i++)
- {
- r<<=8;
- r|=(unsigned char)a->data[i];
- }
- if (neg) r= -r;
- return(r);
- }
+{
+ int neg = 0, i;
+ long r = 0;
+
+ if (a == NULL)
+ return (0L);
+ i = a->type;
+ if (i == V_ASN1_NEG_INTEGER)
+ neg = 1;
+ else if (i != V_ASN1_INTEGER)
+ return -1;
+
+ if (a->length > (int)sizeof(long)) {
+ /* hmm... a bit ugly, return all ones */
+ return -1;
+ }
+ if (a->data == NULL)
+ return 0;
+
+ for (i = 0; i < a->length; i++) {
+ r <<= 8;
+ r |= (unsigned char)a->data[i];
+ }
+ if (neg)
+ r = -r;
+ return (r);
+}
ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai)
- {
- ASN1_INTEGER *ret;
- int len,j;
-
- if (ai == NULL)
- ret=M_ASN1_INTEGER_new();
- else
- ret=ai;
- if (ret == NULL)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
- goto err;
- }
- if (BN_is_negative(bn) && !BN_is_zero(bn))
- ret->type = V_ASN1_NEG_INTEGER;
- else ret->type=V_ASN1_INTEGER;
- j=BN_num_bits(bn);
- len=((j == 0)?0:((j/8)+1));
- if (ret->length < len+4)
- {
- unsigned char *new_data=OPENSSL_realloc(ret->data, len+4);
- if (!new_data)
- {
- OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- ret->data=new_data;
- }
- ret->length=BN_bn2bin(bn,ret->data);
- /* Correct zero case */
- if(!ret->length)
- {
- ret->data[0] = 0;
- ret->length = 1;
- }
- return(ret);
-err:
- if (ret != ai) M_ASN1_INTEGER_free(ret);
- return(NULL);
- }
+{
+ ASN1_INTEGER *ret;
+ int len, j;
+
+ if (ai == NULL)
+ ret = M_ASN1_INTEGER_new();
+ else
+ ret = ai;
+ if (ret == NULL) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
+ goto err;
+ }
+ if (BN_is_negative(bn) && !BN_is_zero(bn))
+ ret->type = V_ASN1_NEG_INTEGER;
+ else
+ ret->type = V_ASN1_INTEGER;
+ j = BN_num_bits(bn);
+ len = ((j == 0) ? 0 : ((j / 8) + 1));
+ if (ret->length < len + 4) {
+ unsigned char *new_data = OPENSSL_realloc(ret->data, len + 4);
+ if (!new_data) {
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ ret->data = new_data;
+ }
+ ret->length = BN_bn2bin(bn, ret->data);
+ /* Correct zero case */
+ if (!ret->length) {
+ ret->data[0] = 0;
+ ret->length = 1;
+ }
+ return (ret);
+ err:
+ if (ret != ai)
+ M_ASN1_INTEGER_free(ret);
+ return (NULL);
+}
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_R_BN_LIB);
- else if(ai->type == V_ASN1_NEG_INTEGER)
- BN_set_negative(ret, 1);
- return(ret);
- }
+{
+ BIGNUM *ret;
+
+ if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL)
+ 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 42806d1a..30fff82a 100644
--- a/src/crypto/asn1/a_mbstr.c
+++ b/src/crypto/asn1/a_mbstr.c
@@ -61,9 +61,9 @@
#include <openssl/err.h>
#include <openssl/mem.h>
-
static int traverse_string(const unsigned char *p, int len, int inform,
- int (*rfunc)(unsigned long value, void *in), void *arg);
+ int (*rfunc) (unsigned long value, void *in),
+ void *arg);
static int in_utf8(unsigned long value, void *arg);
static int out_utf8(unsigned long value, void *arg);
static int type_str(unsigned long value, void *arg);
@@ -73,208 +73,219 @@ static int cpy_univ(unsigned long value, void *arg);
static int cpy_utf8(unsigned long value, void *arg);
static int is_printable(unsigned long value);
-/* These functions take a string in UTF8, ASCII or multibyte form and
- * a mask of permissible ASN1 string types. It then works out the minimal
- * type (using the order Printable < IA5 < T61 < BMP < Universal < UTF8)
- * and creates a string of the correct type with the supplied data.
- * Yes this is horrible: it has to be :-(
- * The 'ncopy' form checks minimum and maximum size limits too.
+/*
+ * These functions take a string in UTF8, ASCII or multibyte form and a mask
+ * of permissible ASN1 string types. It then works out the minimal type
+ * (using the order Printable < IA5 < T61 < BMP < Universal < UTF8) and
+ * creates a string of the correct type with the supplied data. Yes this is
+ * horrible: it has to be :-( The 'ncopy' form checks minimum and maximum
+ * size limits too.
*/
int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len,
- int inform, unsigned long mask)
+ int inform, unsigned long mask)
{
- return ASN1_mbstring_ncopy(out, in, len, inform, mask, 0, 0);
+ return ASN1_mbstring_ncopy(out, in, len, inform, mask, 0, 0);
}
int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
- int inform, unsigned long mask,
- long minsize, long maxsize)
+ int inform, unsigned long mask,
+ long minsize, long maxsize)
{
- int str_type;
- int ret;
- char free_out;
- int outform, outlen = 0;
- ASN1_STRING *dest;
- unsigned char *p;
- int nchar;
- char strbuf[32];
- int (*cpyfunc)(unsigned long,void *) = NULL;
- if(len == -1) len = strlen((const char *)in);
- if(!mask) mask = DIRSTRING_TYPE;
-
- /* First do a string check and work out the number of characters */
- switch(inform) {
-
- case MBSTRING_BMP:
- if(len & 1) {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BMPSTRING_LENGTH);
- return -1;
- }
- nchar = len >> 1;
- break;
-
- case MBSTRING_UNIV:
- if(len & 3) {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_UNIVERSALSTRING_LENGTH);
- return -1;
- }
- nchar = len >> 2;
- break;
-
- case MBSTRING_UTF8:
- nchar = 0;
- /* 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_R_INVALID_UTF8STRING);
- return -1;
- }
- break;
-
- case MBSTRING_ASC:
- nchar = len;
- break;
-
- default:
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_FORMAT);
- return -1;
- }
-
- if((minsize > 0) && (nchar < minsize)) {
- 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_R_STRING_TOO_LONG);
- BIO_snprintf(strbuf, sizeof strbuf, "%ld", maxsize);
- ERR_add_error_data(2, "maxsize=", strbuf);
- return -1;
- }
-
- /* Now work out minimal type (if any) */
- if(traverse_string(in, len, inform, type_str, &mask) < 0) {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_CHARACTERS);
- return -1;
- }
-
-
- /* Now work out output format and string type */
- outform = MBSTRING_ASC;
- if(mask & B_ASN1_PRINTABLESTRING) str_type = V_ASN1_PRINTABLESTRING;
- else if(mask & B_ASN1_IA5STRING) str_type = V_ASN1_IA5STRING;
- else if(mask & B_ASN1_T61STRING) str_type = V_ASN1_T61STRING;
- else if(mask & B_ASN1_BMPSTRING) {
- str_type = V_ASN1_BMPSTRING;
- outform = MBSTRING_BMP;
- } else if(mask & B_ASN1_UNIVERSALSTRING) {
- str_type = V_ASN1_UNIVERSALSTRING;
- outform = MBSTRING_UNIV;
- } else {
- str_type = V_ASN1_UTF8STRING;
- outform = MBSTRING_UTF8;
- }
- if(!out) return str_type;
- if(*out) {
- free_out = 0;
- dest = *out;
- if(dest->data) {
- dest->length = 0;
- OPENSSL_free(dest->data);
- dest->data = NULL;
- }
- dest->type = str_type;
- } else {
- free_out = 1;
- dest = ASN1_STRING_type_new(str_type);
- if(!dest) {
- OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
- return -1;
- }
- *out = dest;
- }
- /* If both the same type just copy across */
- if(inform == outform) {
- if(!ASN1_STRING_set(dest, in, len)) {
- OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
- return -1;
- }
- return str_type;
- }
-
- /* Work out how much space the destination will need */
- switch(outform) {
- case MBSTRING_ASC:
- outlen = nchar;
- cpyfunc = cpy_asc;
- break;
-
- case MBSTRING_BMP:
- outlen = nchar << 1;
- cpyfunc = cpy_bmp;
- break;
-
- case MBSTRING_UNIV:
- outlen = nchar << 2;
- cpyfunc = cpy_univ;
- break;
-
- case MBSTRING_UTF8:
- outlen = 0;
- traverse_string(in, len, inform, out_utf8, &outlen);
- cpyfunc = cpy_utf8;
- break;
- }
- if(!(p = OPENSSL_malloc(outlen + 1))) {
- if(free_out) ASN1_STRING_free(dest);
- OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
- return -1;
- }
- dest->length = outlen;
- dest->data = p;
- p[outlen] = 0;
- traverse_string(in, len, inform, cpyfunc, &p);
- return str_type;
+ int str_type;
+ int ret;
+ char free_out;
+ int outform, outlen = 0;
+ ASN1_STRING *dest;
+ unsigned char *p;
+ int nchar;
+ char strbuf[32];
+ int (*cpyfunc) (unsigned long, void *) = NULL;
+ if (len == -1)
+ len = strlen((const char *)in);
+ if (!mask)
+ mask = DIRSTRING_TYPE;
+
+ /* First do a string check and work out the number of characters */
+ switch (inform) {
+
+ case MBSTRING_BMP:
+ if (len & 1) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BMPSTRING_LENGTH);
+ return -1;
+ }
+ nchar = len >> 1;
+ break;
+
+ case MBSTRING_UNIV:
+ if (len & 3) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_UNIVERSALSTRING_LENGTH);
+ return -1;
+ }
+ nchar = len >> 2;
+ break;
+
+ case MBSTRING_UTF8:
+ nchar = 0;
+ /* 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_R_INVALID_UTF8STRING);
+ return -1;
+ }
+ break;
+
+ case MBSTRING_ASC:
+ nchar = len;
+ break;
+
+ default:
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_FORMAT);
+ return -1;
+ }
+
+ if ((minsize > 0) && (nchar < minsize)) {
+ 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_R_STRING_TOO_LONG);
+ BIO_snprintf(strbuf, sizeof strbuf, "%ld", maxsize);
+ ERR_add_error_data(2, "maxsize=", strbuf);
+ return -1;
+ }
+
+ /* Now work out minimal type (if any) */
+ if (traverse_string(in, len, inform, type_str, &mask) < 0) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_CHARACTERS);
+ return -1;
+ }
+
+ /* Now work out output format and string type */
+ outform = MBSTRING_ASC;
+ if (mask & B_ASN1_PRINTABLESTRING)
+ str_type = V_ASN1_PRINTABLESTRING;
+ else if (mask & B_ASN1_IA5STRING)
+ str_type = V_ASN1_IA5STRING;
+ else if (mask & B_ASN1_T61STRING)
+ str_type = V_ASN1_T61STRING;
+ else if (mask & B_ASN1_BMPSTRING) {
+ str_type = V_ASN1_BMPSTRING;
+ outform = MBSTRING_BMP;
+ } else if (mask & B_ASN1_UNIVERSALSTRING) {
+ str_type = V_ASN1_UNIVERSALSTRING;
+ outform = MBSTRING_UNIV;
+ } else {
+ str_type = V_ASN1_UTF8STRING;
+ outform = MBSTRING_UTF8;
+ }
+ if (!out)
+ return str_type;
+ if (*out) {
+ free_out = 0;
+ dest = *out;
+ if (dest->data) {
+ dest->length = 0;
+ OPENSSL_free(dest->data);
+ dest->data = NULL;
+ }
+ dest->type = str_type;
+ } else {
+ free_out = 1;
+ dest = ASN1_STRING_type_new(str_type);
+ if (!dest) {
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+ *out = dest;
+ }
+ /* If both the same type just copy across */
+ if (inform == outform) {
+ if (!ASN1_STRING_set(dest, in, len)) {
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+ return str_type;
+ }
+
+ /* Work out how much space the destination will need */
+ switch (outform) {
+ case MBSTRING_ASC:
+ outlen = nchar;
+ cpyfunc = cpy_asc;
+ break;
+
+ case MBSTRING_BMP:
+ outlen = nchar << 1;
+ cpyfunc = cpy_bmp;
+ break;
+
+ case MBSTRING_UNIV:
+ outlen = nchar << 2;
+ cpyfunc = cpy_univ;
+ break;
+
+ case MBSTRING_UTF8:
+ outlen = 0;
+ traverse_string(in, len, inform, out_utf8, &outlen);
+ cpyfunc = cpy_utf8;
+ break;
+ }
+ if (!(p = OPENSSL_malloc(outlen + 1))) {
+ if (free_out)
+ ASN1_STRING_free(dest);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+ dest->length = outlen;
+ dest->data = p;
+ p[outlen] = 0;
+ traverse_string(in, len, inform, cpyfunc, &p);
+ return str_type;
}
-/* This function traverses a string and passes the value of each character
- * to an optional function along with a void * argument.
+/*
+ * This function traverses a string and passes the value of each character to
+ * an optional function along with a void * argument.
*/
static int traverse_string(const unsigned char *p, int len, int inform,
- int (*rfunc)(unsigned long value, void *in), void *arg)
+ int (*rfunc) (unsigned long value, void *in),
+ void *arg)
{
- unsigned long value;
- int ret;
- while(len) {
- if(inform == MBSTRING_ASC) {
- value = *p++;
- len--;
- } else if(inform == MBSTRING_BMP) {
- value = *p++ << 8;
- value |= *p++;
- len -= 2;
- } else if(inform == MBSTRING_UNIV) {
- value = ((unsigned long)*p++) << 24;
- value |= ((unsigned long)*p++) << 16;
- value |= *p++ << 8;
- value |= *p++;
- len -= 4;
- } else {
- ret = UTF8_getc(p, len, &value);
- if(ret < 0) return -1;
- len -= ret;
- p += ret;
- }
- if(rfunc) {
- ret = rfunc(value, arg);
- if(ret <= 0) return ret;
- }
- }
- return 1;
+ unsigned long value;
+ int ret;
+ while (len) {
+ if (inform == MBSTRING_ASC) {
+ value = *p++;
+ len--;
+ } else if (inform == MBSTRING_BMP) {
+ value = *p++ << 8;
+ value |= *p++;
+ len -= 2;
+ } else if (inform == MBSTRING_UNIV) {
+ value = ((unsigned long)*p++) << 24;
+ value |= ((unsigned long)*p++) << 16;
+ value |= *p++ << 8;
+ value |= *p++;
+ len -= 4;
+ } else {
+ ret = UTF8_getc(p, len, &value);
+ if (ret < 0)
+ return -1;
+ len -= ret;
+ p += ret;
+ }
+ if (rfunc) {
+ ret = rfunc(value, arg);
+ if (ret <= 0)
+ return ret;
+ }
+ }
+ return 1;
}
/* Various utility functions for traverse_string */
@@ -283,108 +294,116 @@ static int traverse_string(const unsigned char *p, int len, int inform,
static int in_utf8(unsigned long value, void *arg)
{
- int *nchar;
- nchar = arg;
- (*nchar)++;
- return 1;
+ int *nchar;
+ nchar = arg;
+ (*nchar)++;
+ return 1;
}
/* Determine size of output as a UTF8 String */
static int out_utf8(unsigned long value, void *arg)
{
- int *outlen;
- outlen = arg;
- *outlen += UTF8_putc(NULL, -1, value);
- return 1;
+ int *outlen;
+ outlen = arg;
+ *outlen += UTF8_putc(NULL, -1, value);
+ return 1;
}
-/* Determine the "type" of a string: check each character against a
- * supplied "mask".
+/*
+ * Determine the "type" of a string: check each character against a supplied
+ * "mask".
*/
static int type_str(unsigned long value, void *arg)
{
- unsigned long types;
- types = *((unsigned long *)arg);
- if((types & B_ASN1_PRINTABLESTRING) && !is_printable(value))
- types &= ~B_ASN1_PRINTABLESTRING;
- if((types & B_ASN1_IA5STRING) && (value > 127))
- types &= ~B_ASN1_IA5STRING;
- if((types & B_ASN1_T61STRING) && (value > 0xff))
- types &= ~B_ASN1_T61STRING;
- if((types & B_ASN1_BMPSTRING) && (value > 0xffff))
- types &= ~B_ASN1_BMPSTRING;
- if(!types) return -1;
- *((unsigned long *)arg) = types;
- return 1;
+ unsigned long types;
+ types = *((unsigned long *)arg);
+ if ((types & B_ASN1_PRINTABLESTRING) && !is_printable(value))
+ types &= ~B_ASN1_PRINTABLESTRING;
+ if ((types & B_ASN1_IA5STRING) && (value > 127))
+ types &= ~B_ASN1_IA5STRING;
+ if ((types & B_ASN1_T61STRING) && (value > 0xff))
+ types &= ~B_ASN1_T61STRING;
+ if ((types & B_ASN1_BMPSTRING) && (value > 0xffff))
+ types &= ~B_ASN1_BMPSTRING;
+ if (!types)
+ return -1;
+ *((unsigned long *)arg) = types;
+ return 1;
}
/* Copy one byte per character ASCII like strings */
static int cpy_asc(unsigned long value, void *arg)
{
- unsigned char **p, *q;
- p = arg;
- q = *p;
- *q = (unsigned char) value;
- (*p)++;
- return 1;
+ unsigned char **p, *q;
+ p = arg;
+ q = *p;
+ *q = (unsigned char)value;
+ (*p)++;
+ return 1;
}
/* Copy two byte per character BMPStrings */
static int cpy_bmp(unsigned long value, void *arg)
{
- unsigned char **p, *q;
- p = arg;
- q = *p;
- *q++ = (unsigned char) ((value >> 8) & 0xff);
- *q = (unsigned char) (value & 0xff);
- *p += 2;
- return 1;
+ unsigned char **p, *q;
+ p = arg;
+ q = *p;
+ *q++ = (unsigned char)((value >> 8) & 0xff);
+ *q = (unsigned char)(value & 0xff);
+ *p += 2;
+ return 1;
}
/* Copy four byte per character UniversalStrings */
static int cpy_univ(unsigned long value, void *arg)
{
- unsigned char **p, *q;
- p = arg;
- q = *p;
- *q++ = (unsigned char) ((value >> 24) & 0xff);
- *q++ = (unsigned char) ((value >> 16) & 0xff);
- *q++ = (unsigned char) ((value >> 8) & 0xff);
- *q = (unsigned char) (value & 0xff);
- *p += 4;
- return 1;
+ unsigned char **p, *q;
+ p = arg;
+ q = *p;
+ *q++ = (unsigned char)((value >> 24) & 0xff);
+ *q++ = (unsigned char)((value >> 16) & 0xff);
+ *q++ = (unsigned char)((value >> 8) & 0xff);
+ *q = (unsigned char)(value & 0xff);
+ *p += 4;
+ return 1;
}
/* Copy to a UTF8String */
static int cpy_utf8(unsigned long value, void *arg)
{
- unsigned char **p;
- int ret;
- p = arg;
- /* We already know there is enough room so pass 0xff as the length */
- ret = UTF8_putc(*p, 0xff, value);
- *p += ret;
- return 1;
+ unsigned char **p;
+ int ret;
+ p = arg;
+ /* We already know there is enough room so pass 0xff as the length */
+ ret = UTF8_putc(*p, 0xff, value);
+ *p += ret;
+ return 1;
}
/* Return 1 if the character is permitted in a PrintableString */
static int is_printable(unsigned long value)
{
- int ch;
- if(value > 0x7f) return 0;
- ch = (int) value;
- /* Note: we can't use 'isalnum' because certain accented
- * characters may count as alphanumeric in some environments.
- */
- if((ch >= 'a') && (ch <= 'z')) return 1;
- if((ch >= 'A') && (ch <= 'Z')) return 1;
- if((ch >= '0') && (ch <= '9')) return 1;
- if ((ch == ' ') || strchr("'()+,-./:=?", ch)) return 1;
- return 0;
+ int ch;
+ if (value > 0x7f)
+ return 0;
+ ch = (int)value;
+ /*
+ * Note: we can't use 'isalnum' because certain accented characters may
+ * count as alphanumeric in some environments.
+ */
+ if ((ch >= 'a') && (ch <= 'z'))
+ return 1;
+ if ((ch >= 'A') && (ch <= 'Z'))
+ return 1;
+ if ((ch >= '0') && (ch <= '9'))
+ return 1;
+ if ((ch == ' ') || strchr("'()+,-./:=?", ch))
+ return 1;
+ return 0;
}
diff --git a/src/crypto/asn1/a_object.c b/src/crypto/asn1/a_object.c
index 6ddfca92..10f38398 100644
--- a/src/crypto/asn1/a_object.c
+++ b/src/crypto/asn1/a_object.c
@@ -63,350 +63,334 @@
#include <openssl/mem.h>
#include <openssl/obj.h>
-
int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp)
- {
- unsigned char *p;
- int objsize;
+{
+ unsigned char *p;
+ int objsize;
- if ((a == NULL) || (a->data == NULL)) return(0);
+ if ((a == NULL) || (a->data == NULL))
+ return (0);
- objsize = ASN1_object_size(0,a->length,V_ASN1_OBJECT);
- if (pp == NULL) return objsize;
+ objsize = ASN1_object_size(0, a->length, V_ASN1_OBJECT);
+ if (pp == NULL)
+ return objsize;
- p= *pp;
- ASN1_put_object(&p,0,a->length,V_ASN1_OBJECT,V_ASN1_UNIVERSAL);
- memcpy(p,a->data,a->length);
- p+=a->length;
+ p = *pp;
+ ASN1_put_object(&p, 0, a->length, V_ASN1_OBJECT, V_ASN1_UNIVERSAL);
+ memcpy(p, a->data, a->length);
+ p += a->length;
- *pp=p;
- return(objsize);
- }
+ *pp = p;
+ return (objsize);
+}
int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
- {
- int i,first,len=0,c, use_bn;
- char ftmp[24], *tmp = ftmp;
- int tmpsize = sizeof ftmp;
- const char *p;
- unsigned long l;
- BIGNUM *bl = NULL;
+{
+ int i, first, len = 0, c, use_bn;
+ char ftmp[24], *tmp = ftmp;
+ int tmpsize = sizeof ftmp;
+ const char *p;
+ unsigned long l;
+ BIGNUM *bl = NULL;
- if (num == 0)
- return(0);
- else if (num == -1)
- num=strlen(buf);
+ if (num == 0)
+ return (0);
+ else if (num == -1)
+ num = strlen(buf);
- p=buf;
- c= *(p++);
- num--;
- if ((c >= '0') && (c <= '2'))
- {
- first= c-'0';
- }
- else
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_FIRST_NUM_TOO_LARGE);
- goto err;
- }
+ p = buf;
+ c = *(p++);
+ num--;
+ if ((c >= '0') && (c <= '2')) {
+ first = c - '0';
+ } else {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_FIRST_NUM_TOO_LARGE);
+ goto err;
+ }
- if (num <= 0)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_SECOND_NUMBER);
- goto err;
- }
- c= *(p++);
- num--;
- for (;;)
- {
- if (num <= 0) break;
- if ((c != '.') && (c != ' '))
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_SEPARATOR);
- goto err;
- }
- l=0;
- use_bn = 0;
- for (;;)
- {
- if (num <= 0) break;
- num--;
- c= *(p++);
- if ((c == ' ') || (c == '.'))
- break;
- if ((c < '0') || (c > '9'))
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_DIGIT);
- goto err;
- }
- if (!use_bn && l >= ((ULONG_MAX - 80) / 10L))
- {
- use_bn = 1;
- if (!bl)
- bl = BN_new();
- if (!bl || !BN_set_word(bl, l))
- goto err;
- }
- if (use_bn)
- {
- if (!BN_mul_word(bl, 10L)
- || !BN_add_word(bl, c-'0'))
- goto err;
- }
- else
- l=l*10L+(long)(c-'0');
- }
- if (len == 0)
- {
- if ((first < 2) && (l >= 40))
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_SECOND_NUMBER_TOO_LARGE);
- goto err;
- }
- if (use_bn)
- {
- if (!BN_add_word(bl, first * 40))
- goto err;
- }
- else
- l+=(long)first*40;
- }
- i=0;
- if (use_bn)
- {
- int blsize;
- blsize = BN_num_bits(bl);
- blsize = (blsize + 6)/7;
- if (blsize > tmpsize)
- {
- if (tmp != ftmp)
- OPENSSL_free(tmp);
- tmpsize = blsize + 32;
- tmp = OPENSSL_malloc(tmpsize);
- if (!tmp)
- goto err;
- }
- while(blsize--)
- tmp[i++] = (unsigned char)BN_div_word(bl, 0x80L);
- }
- else
- {
-
- for (;;)
- {
- tmp[i++]=(unsigned char)l&0x7f;
- l>>=7L;
- if (l == 0L) break;
- }
+ if (num <= 0) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_SECOND_NUMBER);
+ goto err;
+ }
+ c = *(p++);
+ num--;
+ for (;;) {
+ if (num <= 0)
+ break;
+ if ((c != '.') && (c != ' ')) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_SEPARATOR);
+ goto err;
+ }
+ l = 0;
+ use_bn = 0;
+ for (;;) {
+ if (num <= 0)
+ break;
+ num--;
+ c = *(p++);
+ if ((c == ' ') || (c == '.'))
+ break;
+ if ((c < '0') || (c > '9')) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_DIGIT);
+ goto err;
+ }
+ if (!use_bn && l >= ((ULONG_MAX - 80) / 10L)) {
+ use_bn = 1;
+ if (!bl)
+ bl = BN_new();
+ if (!bl || !BN_set_word(bl, l))
+ goto err;
+ }
+ if (use_bn) {
+ if (!BN_mul_word(bl, 10L)
+ || !BN_add_word(bl, c - '0'))
+ goto err;
+ } else
+ l = l * 10L + (long)(c - '0');
+ }
+ if (len == 0) {
+ if ((first < 2) && (l >= 40)) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_SECOND_NUMBER_TOO_LARGE);
+ goto err;
+ }
+ if (use_bn) {
+ if (!BN_add_word(bl, first * 40))
+ goto err;
+ } else
+ l += (long)first *40;
+ }
+ i = 0;
+ if (use_bn) {
+ int blsize;
+ blsize = BN_num_bits(bl);
+ blsize = (blsize + 6) / 7;
+ if (blsize > tmpsize) {
+ if (tmp != ftmp)
+ OPENSSL_free(tmp);
+ tmpsize = blsize + 32;
+ tmp = OPENSSL_malloc(tmpsize);
+ if (!tmp)
+ goto err;
+ }
+ while (blsize--)
+ tmp[i++] = (unsigned char)BN_div_word(bl, 0x80L);
+ } else {
- }
- if (out != NULL)
- {
- if (len+i > olen)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_BUFFER_TOO_SMALL);
- goto err;
- }
- while (--i > 0)
- out[len++]=tmp[i]|0x80;
- out[len++]=tmp[0];
- }
- else
- len+=i;
- }
- if (tmp != ftmp)
- OPENSSL_free(tmp);
- if (bl)
- BN_free(bl);
- return(len);
-err:
- if (tmp != ftmp)
- OPENSSL_free(tmp);
- if (bl)
- BN_free(bl);
- return(0);
- }
+ for (;;) {
+ tmp[i++] = (unsigned char)l & 0x7f;
+ l >>= 7L;
+ if (l == 0L)
+ break;
+ }
+
+ }
+ if (out != NULL) {
+ if (len + i > olen) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_BUFFER_TOO_SMALL);
+ goto err;
+ }
+ while (--i > 0)
+ out[len++] = tmp[i] | 0x80;
+ out[len++] = tmp[0];
+ } else
+ len += i;
+ }
+ if (tmp != ftmp)
+ OPENSSL_free(tmp);
+ if (bl)
+ BN_free(bl);
+ return (len);
+ err:
+ if (tmp != ftmp)
+ OPENSSL_free(tmp);
+ if (bl)
+ BN_free(bl);
+ return (0);
+}
int i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *a)
{
- return OBJ_obj2txt(buf, buf_len, a, 0);
+ return OBJ_obj2txt(buf, buf_len, a, 0);
}
int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a)
- {
- char buf[80], *p = buf;
- int i;
+{
+ char buf[80], *p = buf;
+ int i;
- if ((a == NULL) || (a->data == NULL))
- return(BIO_write(bp,"NULL",4));
- i=i2t_ASN1_OBJECT(buf,sizeof buf,a);
- if (i > (int)(sizeof(buf) - 1))
- {
- p = OPENSSL_malloc(i + 1);
- if (!p)
- return -1;
- i2t_ASN1_OBJECT(p,i + 1,a);
- }
- if (i <= 0)
- return BIO_write(bp, "<INVALID>", 9);
- BIO_write(bp,p,i);
- if (p != buf)
- OPENSSL_free(p);
- return(i);
- }
+ if ((a == NULL) || (a->data == NULL))
+ return (BIO_write(bp, "NULL", 4));
+ i = i2t_ASN1_OBJECT(buf, sizeof buf, a);
+ if (i > (int)(sizeof(buf) - 1)) {
+ p = OPENSSL_malloc(i + 1);
+ if (!p)
+ return -1;
+ i2t_ASN1_OBJECT(p, i + 1, a);
+ }
+ if (i <= 0)
+ return BIO_write(bp, "<INVALID>", 9);
+ BIO_write(bp, p, i);
+ if (p != buf)
+ OPENSSL_free(p);
+ return (i);
+}
ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
- long length)
+ long length)
{
- const unsigned char *p;
- long len;
- int tag,xclass;
- int inf,i;
- ASN1_OBJECT *ret = NULL;
- p= *pp;
- inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
- if (inf & 0x80)
- {
- i=ASN1_R_BAD_OBJECT_HEADER;
- goto err;
- }
+ const unsigned char *p;
+ long len;
+ int tag, xclass;
+ int inf, i;
+ ASN1_OBJECT *ret = NULL;
+ p = *pp;
+ inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
+ if (inf & 0x80) {
+ i = ASN1_R_BAD_OBJECT_HEADER;
+ goto err;
+ }
- if (tag != V_ASN1_OBJECT)
- {
- i=ASN1_R_EXPECTING_AN_OBJECT;
- goto err;
- }
- ret = c2i_ASN1_OBJECT(a, &p, len);
- if(ret) *pp = p;
- return ret;
-err:
- OPENSSL_PUT_ERROR(ASN1, i);
- return(NULL);
+ if (tag != V_ASN1_OBJECT) {
+ i = ASN1_R_EXPECTING_AN_OBJECT;
+ goto err;
+ }
+ ret = c2i_ASN1_OBJECT(a, &p, len);
+ if (ret)
+ *pp = p;
+ return ret;
+ err:
+ OPENSSL_PUT_ERROR(ASN1, i);
+ return (NULL);
}
ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
- long len)
- {
- ASN1_OBJECT *ret=NULL;
- const unsigned char *p;
- unsigned char *data;
- int i, length;
+ long len)
+{
+ ASN1_OBJECT *ret = NULL;
+ const unsigned char *p;
+ unsigned char *data;
+ int i, length;
- /* Sanity check OID encoding.
- * Need at least one content octet.
- * MSB must be clear in the last octet.
- * can't have leading 0x80 in subidentifiers, see: X.690 8.19.2
- */
- if (len <= 0 || len > INT_MAX || pp == NULL || (p = *pp) == NULL ||
- p[len - 1] & 0x80)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING);
- return NULL;
- }
- /* Now 0 < len <= INT_MAX, so the cast is safe. */
- length = (int)len;
- for (i = 0; i < length; i++, p++)
- {
- if (*p == 0x80 && (!i || !(p[-1] & 0x80)))
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING);
- return NULL;
- }
- }
+ /*
+ * Sanity check OID encoding. Need at least one content octet. MSB must
+ * be clear in the last octet. can't have leading 0x80 in subidentifiers,
+ * see: X.690 8.19.2
+ */
+ if (len <= 0 || len > INT_MAX || pp == NULL || (p = *pp) == NULL ||
+ p[len - 1] & 0x80) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING);
+ return NULL;
+ }
+ /* Now 0 < len <= INT_MAX, so the cast is safe. */
+ length = (int)len;
+ for (i = 0; i < length; i++, p++) {
+ if (*p == 0x80 && (!i || !(p[-1] & 0x80))) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING);
+ return NULL;
+ }
+ }
- /* only the ASN1_OBJECTs from the 'table' will have values
- * for ->sn or ->ln */
- if ((a == NULL) || ((*a) == NULL) ||
- !((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC))
- {
- if ((ret=ASN1_OBJECT_new()) == NULL) return(NULL);
- }
- else ret=(*a);
+ /*
+ * only the ASN1_OBJECTs from the 'table' will have values for ->sn or
+ * ->ln
+ */
+ if ((a == NULL) || ((*a) == NULL) ||
+ !((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC)) {
+ if ((ret = ASN1_OBJECT_new()) == NULL)
+ return (NULL);
+ } else
+ ret = (*a);
- p= *pp;
- /* detach data from object */
- data = (unsigned char *)ret->data;
- ret->data = NULL;
- /* once detached we can change it */
- if ((data == NULL) || (ret->length < length))
- {
- ret->length=0;
- if (data != NULL) OPENSSL_free(data);
- data=(unsigned char *)OPENSSL_malloc(length);
- if (data == NULL)
- { i=ERR_R_MALLOC_FAILURE; goto err; }
- ret->flags|=ASN1_OBJECT_FLAG_DYNAMIC_DATA;
- }
- memcpy(data,p,length);
- /* reattach data to object, after which it remains const */
- ret->data =data;
- ret->length=length;
- ret->sn=NULL;
- ret->ln=NULL;
- /* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */
- p+=length;
+ p = *pp;
+ /* detach data from object */
+ data = (unsigned char *)ret->data;
+ ret->data = NULL;
+ /* once detached we can change it */
+ if ((data == NULL) || (ret->length < length)) {
+ ret->length = 0;
+ if (data != NULL)
+ OPENSSL_free(data);
+ data = (unsigned char *)OPENSSL_malloc(length);
+ if (data == NULL) {
+ i = ERR_R_MALLOC_FAILURE;
+ goto err;
+ }
+ ret->flags |= ASN1_OBJECT_FLAG_DYNAMIC_DATA;
+ }
+ memcpy(data, p, length);
+ /* reattach data to object, after which it remains const */
+ ret->data = data;
+ ret->length = length;
+ ret->sn = NULL;
+ ret->ln = NULL;
+ /* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */
+ p += length;
- if (a != NULL) (*a)=ret;
- *pp=p;
- return(ret);
-err:
- OPENSSL_PUT_ERROR(ASN1, i);
- if ((ret != NULL) && ((a == NULL) || (*a != ret)))
- ASN1_OBJECT_free(ret);
- return(NULL);
- }
+ if (a != NULL)
+ (*a) = ret;
+ *pp = p;
+ return (ret);
+ err:
+ OPENSSL_PUT_ERROR(ASN1, i);
+ if ((ret != NULL) && ((a == NULL) || (*a != ret)))
+ ASN1_OBJECT_free(ret);
+ return (NULL);
+}
ASN1_OBJECT *ASN1_OBJECT_new(void)
- {
- ASN1_OBJECT *ret;
+{
+ ASN1_OBJECT *ret;
- ret=(ASN1_OBJECT *)OPENSSL_malloc(sizeof(ASN1_OBJECT));
- if (ret == NULL)
- {
- OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
- return(NULL);
- }
- ret->length=0;
- ret->data=NULL;
- ret->nid=0;
- ret->sn=NULL;
- ret->ln=NULL;
- ret->flags=ASN1_OBJECT_FLAG_DYNAMIC;
- return(ret);
- }
+ ret = (ASN1_OBJECT *)OPENSSL_malloc(sizeof(ASN1_OBJECT));
+ if (ret == NULL) {
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+ ret->length = 0;
+ ret->data = NULL;
+ ret->nid = 0;
+ ret->sn = NULL;
+ ret->ln = NULL;
+ ret->flags = ASN1_OBJECT_FLAG_DYNAMIC;
+ return (ret);
+}
void ASN1_OBJECT_free(ASN1_OBJECT *a)
- {
- if (a == NULL) return;
- if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS)
- {
-#ifndef CONST_STRICT /* disable purely for compile-time strict const checking. Doing this on a "real" compile will cause memory leaks */
- if (a->sn != NULL) OPENSSL_free((void *)a->sn);
- if (a->ln != NULL) OPENSSL_free((void *)a->ln);
+{
+ if (a == NULL)
+ return;
+ if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS) {
+#ifndef CONST_STRICT /* disable purely for compile-time strict
+ * const checking. Doing this on a "real"
+ * compile will cause memory leaks */
+ if (a->sn != NULL)
+ OPENSSL_free((void *)a->sn);
+ if (a->ln != NULL)
+ OPENSSL_free((void *)a->ln);
#endif
- a->sn=a->ln=NULL;
- }
- if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA)
- {
- if (a->data != NULL) OPENSSL_free((void *)a->data);
- a->data=NULL;
- a->length=0;
- }
- if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC)
- OPENSSL_free(a);
- }
+ a->sn = a->ln = NULL;
+ }
+ if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA) {
+ if (a->data != NULL)
+ OPENSSL_free((void *)a->data);
+ a->data = NULL;
+ a->length = 0;
+ }
+ if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC)
+ OPENSSL_free(a);
+}
ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len,
- const char *sn, const char *ln)
- {
- ASN1_OBJECT o;
+ const char *sn, const char *ln)
+{
+ ASN1_OBJECT o;
- o.sn=sn;
- o.ln=ln;
- o.data=data;
- o.nid=nid;
- o.length=len;
- o.flags=ASN1_OBJECT_FLAG_DYNAMIC|ASN1_OBJECT_FLAG_DYNAMIC_STRINGS|
- ASN1_OBJECT_FLAG_DYNAMIC_DATA;
- return(OBJ_dup(&o));
- }
+ o.sn = sn;
+ o.ln = ln;
+ o.data = data;
+ o.nid = nid;
+ o.length = len;
+ o.flags = ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS |
+ ASN1_OBJECT_FLAG_DYNAMIC_DATA;
+ return (OBJ_dup(&o));
+}
diff --git a/src/crypto/asn1/a_octet.c b/src/crypto/asn1/a_octet.c
index 583c9e9d..2e74d6bf 100644
--- a/src/crypto/asn1/a_octet.c
+++ b/src/crypto/asn1/a_octet.c
@@ -59,12 +59,19 @@
#include <openssl/err.h>
#include <openssl/mem.h>
-
ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *x)
-{ return M_ASN1_OCTET_STRING_dup(x); }
+{
+ return M_ASN1_OCTET_STRING_dup(x);
+}
-int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a, const ASN1_OCTET_STRING *b)
-{ return M_ASN1_OCTET_STRING_cmp(a, b); }
+int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a,
+ const ASN1_OCTET_STRING *b)
+{
+ return M_ASN1_OCTET_STRING_cmp(a, b);
+}
-int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *x, const unsigned char *d, int len)
-{ return M_ASN1_OCTET_STRING_set(x, d, len); }
+int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *x, const unsigned char *d,
+ int len)
+{
+ return M_ASN1_OCTET_STRING_set(x, d, len);
+}
diff --git a/src/crypto/asn1/a_print.c b/src/crypto/asn1/a_print.c
index 3b6be10b..aee54fa4 100644
--- a/src/crypto/asn1/a_print.c
+++ b/src/crypto/asn1/a_print.c
@@ -59,61 +59,63 @@
#include <openssl/err.h>
#include <openssl/mem.h>
-
int ASN1_PRINTABLE_type(const unsigned char *s, int len)
- {
- int c;
- int ia5=0;
- int t61=0;
+{
+ int c;
+ int ia5 = 0;
+ int t61 = 0;
- if (len <= 0) len= -1;
- if (s == NULL) return(V_ASN1_PRINTABLESTRING);
+ if (len <= 0)
+ len = -1;
+ if (s == NULL)
+ return (V_ASN1_PRINTABLESTRING);
- while ((*s) && (len-- != 0))
- {
- c= *(s++);
- if (!( ((c >= 'a') && (c <= 'z')) ||
- ((c >= 'A') && (c <= 'Z')) ||
- (c == ' ') ||
- ((c >= '0') && (c <= '9')) ||
- (c == ' ') || (c == '\'') ||
- (c == '(') || (c == ')') ||
- (c == '+') || (c == ',') ||
- (c == '-') || (c == '.') ||
- (c == '/') || (c == ':') ||
- (c == '=') || (c == '?')))
- ia5=1;
- if (c&0x80)
- t61=1;
- }
- if (t61) return(V_ASN1_T61STRING);
- if (ia5) return(V_ASN1_IA5STRING);
- return(V_ASN1_PRINTABLESTRING);
- }
+ while ((*s) && (len-- != 0)) {
+ c = *(s++);
+ if (!(((c >= 'a') && (c <= 'z')) ||
+ ((c >= 'A') && (c <= 'Z')) ||
+ (c == ' ') ||
+ ((c >= '0') && (c <= '9')) ||
+ (c == ' ') || (c == '\'') ||
+ (c == '(') || (c == ')') ||
+ (c == '+') || (c == ',') ||
+ (c == '-') || (c == '.') ||
+ (c == '/') || (c == ':') || (c == '=') || (c == '?')))
+ ia5 = 1;
+ if (c & 0x80)
+ t61 = 1;
+ }
+ if (t61)
+ return (V_ASN1_T61STRING);
+ if (ia5)
+ return (V_ASN1_IA5STRING);
+ return (V_ASN1_PRINTABLESTRING);
+}
int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s)
- {
- int i;
- unsigned char *p;
+{
+ int i;
+ unsigned char *p;
- if (s->type != V_ASN1_UNIVERSALSTRING) return(0);
- if ((s->length%4) != 0) return(0);
- p=s->data;
- for (i=0; i<s->length; i+=4)
- {
- if ((p[0] != '\0') || (p[1] != '\0') || (p[2] != '\0'))
- break;
- else
- p+=4;
- }
- if (i < s->length) return(0);
- p=s->data;
- for (i=3; i<s->length; i+=4)
- {
- *(p++)=s->data[i];
- }
- *(p)='\0';
- s->length/=4;
- s->type=ASN1_PRINTABLE_type(s->data,s->length);
- return(1);
- }
+ if (s->type != V_ASN1_UNIVERSALSTRING)
+ return (0);
+ if ((s->length % 4) != 0)
+ return (0);
+ p = s->data;
+ for (i = 0; i < s->length; i += 4) {
+ if ((p[0] != '\0') || (p[1] != '\0') || (p[2] != '\0'))
+ break;
+ else
+ p += 4;
+ }
+ if (i < s->length)
+ return (0);
+ p = s->data;
+ for (i = 3; i < s->length; i += 4) {
+ *(p++) = s->data[i];
+ }
+ *(p) = '\0';
+ s->length /= 4;
+ s->type = ASN1_PRINTABLE_type(s->data, s->length);
+ return (1);
+}
diff --git a/src/crypto/asn1/a_strnid.c b/src/crypto/asn1/a_strnid.c
index d4316f72..ba1224ef 100644
--- a/src/crypto/asn1/a_strnid.c
+++ b/src/crypto/asn1/a_strnid.c
@@ -56,231 +56,253 @@
#include <openssl/asn1.h>
-#include <stdlib.h> /* For bsearch */
+#include <stdlib.h> /* For bsearch */
#include <string.h>
#include <openssl/err.h>
#include <openssl/mem.h>
#include <openssl/obj.h>
-
static STACK_OF(ASN1_STRING_TABLE) *stable = NULL;
static void st_free(ASN1_STRING_TABLE *tbl);
-/* This is the global mask for the mbstring functions: this is use to
- * mask out certain types (such as BMPString and UTF8String) because
- * certain software (e.g. Netscape) has problems with them.
+/*
+ * This is the global mask for the mbstring functions: this is use to mask
+ * out certain types (such as BMPString and UTF8String) because certain
+ * software (e.g. Netscape) has problems with them.
*/
static unsigned long global_mask = B_ASN1_UTF8STRING;
void ASN1_STRING_set_default_mask(unsigned long mask)
{
- global_mask = mask;
+ global_mask = mask;
}
unsigned long ASN1_STRING_get_default_mask(void)
{
- return global_mask;
+ return global_mask;
}
-/* This function sets the default to various "flavours" of configuration.
- * based on an ASCII string. Currently this is:
- * MASK:XXXX : a numerical mask value.
- * nobmp : Don't use BMPStrings (just Printable, T61).
- * pkix : PKIX recommendation in RFC2459.
- * utf8only : only use UTF8Strings (RFC2459 recommendation for 2004).
- * default: the default value, Printable, T61, BMP.
+/*
+ * This function sets the default to various "flavours" of configuration.
+ * based on an ASCII string. Currently this is: MASK:XXXX : a numerical mask
+ * value. nobmp : Don't use BMPStrings (just Printable, T61). pkix : PKIX
+ * recommendation in RFC2459. utf8only : only use UTF8Strings (RFC2459
+ * recommendation for 2004). default: the default value, Printable, T61, BMP.
*/
int ASN1_STRING_set_default_mask_asc(const char *p)
{
- unsigned long mask;
- char *end;
- if(!strncmp(p, "MASK:", 5)) {
- if(!p[5]) return 0;
- mask = strtoul(p + 5, &end, 0);
- if(*end) return 0;
- } else if(!strcmp(p, "nombstr"))
- mask = ~((unsigned long)(B_ASN1_BMPSTRING|B_ASN1_UTF8STRING));
- else if(!strcmp(p, "pkix"))
- mask = ~((unsigned long)B_ASN1_T61STRING);
- else if(!strcmp(p, "utf8only")) mask = B_ASN1_UTF8STRING;
- else if(!strcmp(p, "default"))
- mask = 0xFFFFFFFFL;
- else return 0;
- ASN1_STRING_set_default_mask(mask);
- return 1;
+ unsigned long mask;
+ char *end;
+ if (!strncmp(p, "MASK:", 5)) {
+ if (!p[5])
+ return 0;
+ mask = strtoul(p + 5, &end, 0);
+ if (*end)
+ return 0;
+ } else if (!strcmp(p, "nombstr"))
+ mask = ~((unsigned long)(B_ASN1_BMPSTRING | B_ASN1_UTF8STRING));
+ else if (!strcmp(p, "pkix"))
+ mask = ~((unsigned long)B_ASN1_T61STRING);
+ else if (!strcmp(p, "utf8only"))
+ mask = B_ASN1_UTF8STRING;
+ else if (!strcmp(p, "default"))
+ mask = 0xFFFFFFFFL;
+ else
+ return 0;
+ ASN1_STRING_set_default_mask(mask);
+ return 1;
}
-/* The following function generates an ASN1_STRING based on limits in a table.
- * Frequently the types and length of an ASN1_STRING are restricted by a
- * corresponding OID. For example certificates and certificate requests.
+/*
+ * The following function generates an ASN1_STRING based on limits in a
+ * table. Frequently the types and length of an ASN1_STRING are restricted by
+ * a corresponding OID. For example certificates and certificate requests.
*/
-ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, const unsigned char *in,
- int inlen, int inform, int nid)
+ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out,
+ const unsigned char *in, int inlen,
+ int inform, int nid)
{
- ASN1_STRING_TABLE *tbl;
- ASN1_STRING *str = NULL;
- unsigned long mask;
- int ret;
- if(!out) out = &str;
- tbl = ASN1_STRING_TABLE_get(nid);
- if(tbl) {
- mask = tbl->mask;
- if(!(tbl->flags & STABLE_NO_MASK)) mask &= global_mask;
- ret = ASN1_mbstring_ncopy(out, in, inlen, inform, mask,
- tbl->minsize, tbl->maxsize);
- } else ret = ASN1_mbstring_copy(out, in, inlen, inform, DIRSTRING_TYPE & global_mask);
- if(ret <= 0) return NULL;
- return *out;
+ ASN1_STRING_TABLE *tbl;
+ ASN1_STRING *str = NULL;
+ unsigned long mask;
+ int ret;
+ if (!out)
+ out = &str;
+ tbl = ASN1_STRING_TABLE_get(nid);
+ if (tbl) {
+ mask = tbl->mask;
+ if (!(tbl->flags & STABLE_NO_MASK))
+ mask &= global_mask;
+ ret = ASN1_mbstring_ncopy(out, in, inlen, inform, mask,
+ tbl->minsize, tbl->maxsize);
+ } else
+ ret =
+ ASN1_mbstring_copy(out, in, inlen, inform,
+ DIRSTRING_TYPE & global_mask);
+ if (ret <= 0)
+ return NULL;
+ return *out;
}
-/* Now the tables and helper functions for the string table:
+/*
+ * Now the tables and helper functions for the string table:
*/
/* size limits: this stuff is taken straight from RFC3280 */
-#define ub_name 32768
-#define ub_common_name 64
-#define ub_locality_name 128
-#define ub_state_name 128
-#define ub_organization_name 64
-#define ub_organization_unit_name 64
-#define ub_title 64
-#define ub_email_address 128
-#define ub_serial_number 64
-
+#define ub_name 32768
+#define ub_common_name 64
+#define ub_locality_name 128
+#define ub_state_name 128
+#define ub_organization_name 64
+#define ub_organization_unit_name 64
+#define ub_title 64
+#define ub_email_address 128
+#define ub_serial_number 64
/* This table must be kept in NID order */
static const ASN1_STRING_TABLE tbl_standard[] = {
-{NID_commonName, 1, ub_common_name, DIRSTRING_TYPE, 0},
-{NID_countryName, 2, 2, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
-{NID_localityName, 1, ub_locality_name, DIRSTRING_TYPE, 0},
-{NID_stateOrProvinceName, 1, ub_state_name, DIRSTRING_TYPE, 0},
-{NID_organizationName, 1, ub_organization_name, DIRSTRING_TYPE, 0},
-{NID_organizationalUnitName, 1, ub_organization_unit_name, DIRSTRING_TYPE, 0},
-{NID_pkcs9_emailAddress, 1, ub_email_address, B_ASN1_IA5STRING, STABLE_NO_MASK},
-{NID_pkcs9_unstructuredName, 1, -1, PKCS9STRING_TYPE, 0},
-{NID_pkcs9_challengePassword, 1, -1, PKCS9STRING_TYPE, 0},
-{NID_pkcs9_unstructuredAddress, 1, -1, DIRSTRING_TYPE, 0},
-{NID_givenName, 1, ub_name, DIRSTRING_TYPE, 0},
-{NID_surname, 1, ub_name, DIRSTRING_TYPE, 0},
-{NID_initials, 1, ub_name, DIRSTRING_TYPE, 0},
-{NID_serialNumber, 1, ub_serial_number, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
-{NID_friendlyName, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK},
-{NID_name, 1, ub_name, DIRSTRING_TYPE, 0},
-{NID_dnQualifier, -1, -1, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
-{NID_domainComponent, 1, -1, B_ASN1_IA5STRING, STABLE_NO_MASK},
-{NID_ms_csp_name, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK}
+ {NID_commonName, 1, ub_common_name, DIRSTRING_TYPE, 0},
+ {NID_countryName, 2, 2, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
+ {NID_localityName, 1, ub_locality_name, DIRSTRING_TYPE, 0},
+ {NID_stateOrProvinceName, 1, ub_state_name, DIRSTRING_TYPE, 0},
+ {NID_organizationName, 1, ub_organization_name, DIRSTRING_TYPE, 0},
+ {NID_organizationalUnitName, 1, ub_organization_unit_name, DIRSTRING_TYPE,
+ 0},
+ {NID_pkcs9_emailAddress, 1, ub_email_address, B_ASN1_IA5STRING,
+ STABLE_NO_MASK},
+ {NID_pkcs9_unstructuredName, 1, -1, PKCS9STRING_TYPE, 0},
+ {NID_pkcs9_challengePassword, 1, -1, PKCS9STRING_TYPE, 0},
+ {NID_pkcs9_unstructuredAddress, 1, -1, DIRSTRING_TYPE, 0},
+ {NID_givenName, 1, ub_name, DIRSTRING_TYPE, 0},
+ {NID_surname, 1, ub_name, DIRSTRING_TYPE, 0},
+ {NID_initials, 1, ub_name, DIRSTRING_TYPE, 0},
+ {NID_serialNumber, 1, ub_serial_number, B_ASN1_PRINTABLESTRING,
+ STABLE_NO_MASK},
+ {NID_friendlyName, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK},
+ {NID_name, 1, ub_name, DIRSTRING_TYPE, 0},
+ {NID_dnQualifier, -1, -1, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
+ {NID_domainComponent, 1, -1, B_ASN1_IA5STRING, STABLE_NO_MASK},
+ {NID_ms_csp_name, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK}
};
static int sk_table_cmp(const ASN1_STRING_TABLE **a,
- const ASN1_STRING_TABLE **b)
+ const ASN1_STRING_TABLE **b)
{
- return (*a)->nid - (*b)->nid;
+ return (*a)->nid - (*b)->nid;
}
static int table_cmp(const void *in_a, const void *in_b)
{
- const ASN1_STRING_TABLE *a = in_a;
- const ASN1_STRING_TABLE *b = in_b;
- return a->nid - b->nid;
+ const ASN1_STRING_TABLE *a = in_a;
+ const ASN1_STRING_TABLE *b = in_b;
+ return a->nid - b->nid;
}
ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid)
{
- int found;
- size_t idx;
- ASN1_STRING_TABLE *ttmp;
- ASN1_STRING_TABLE fnd;
- fnd.nid = nid;
-
- ttmp = bsearch(&fnd, tbl_standard, sizeof(tbl_standard)/sizeof(ASN1_STRING_TABLE), sizeof(ASN1_STRING_TABLE), table_cmp);
- if(ttmp) return ttmp;
- if(!stable) return NULL;
- found = sk_ASN1_STRING_TABLE_find(stable, &idx, &fnd);
- if (!found) return NULL;
- return sk_ASN1_STRING_TABLE_value(stable, idx);
+ int found;
+ size_t idx;
+ ASN1_STRING_TABLE *ttmp;
+ ASN1_STRING_TABLE fnd;
+ fnd.nid = nid;
+
+ ttmp =
+ bsearch(&fnd, tbl_standard,
+ sizeof(tbl_standard) / sizeof(ASN1_STRING_TABLE),
+ sizeof(ASN1_STRING_TABLE), table_cmp);
+ if (ttmp)
+ return ttmp;
+ if (!stable)
+ return NULL;
+ found = sk_ASN1_STRING_TABLE_find(stable, &idx, &fnd);
+ if (!found)
+ return NULL;
+ return sk_ASN1_STRING_TABLE_value(stable, idx);
}
-
+
int ASN1_STRING_TABLE_add(int nid,
- long minsize, long maxsize, unsigned long mask,
- unsigned long flags)
+ long minsize, long maxsize, unsigned long mask,
+ unsigned long flags)
{
- ASN1_STRING_TABLE *tmp;
- char new_nid = 0;
- flags &= ~STABLE_FLAGS_MALLOC;
- if(!stable) stable = sk_ASN1_STRING_TABLE_new(sk_table_cmp);
- if(!stable) {
- 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, ERR_R_MALLOC_FAILURE);
- return 0;
- }
- tmp->flags = flags | STABLE_FLAGS_MALLOC;
- tmp->nid = nid;
- new_nid = 1;
- } else tmp->flags = (tmp->flags & STABLE_FLAGS_MALLOC) | flags;
- if(minsize != -1) tmp->minsize = minsize;
- if(maxsize != -1) tmp->maxsize = maxsize;
- tmp->mask = mask;
- if(new_nid) sk_ASN1_STRING_TABLE_push(stable, tmp);
- return 1;
+ ASN1_STRING_TABLE *tmp;
+ char new_nid = 0;
+ flags &= ~STABLE_FLAGS_MALLOC;
+ if (!stable)
+ stable = sk_ASN1_STRING_TABLE_new(sk_table_cmp);
+ if (!stable) {
+ 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, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ tmp->flags = flags | STABLE_FLAGS_MALLOC;
+ tmp->nid = nid;
+ new_nid = 1;
+ } else
+ tmp->flags = (tmp->flags & STABLE_FLAGS_MALLOC) | flags;
+ if (minsize != -1)
+ tmp->minsize = minsize;
+ if (maxsize != -1)
+ tmp->maxsize = maxsize;
+ tmp->mask = mask;
+ if (new_nid)
+ sk_ASN1_STRING_TABLE_push(stable, tmp);
+ return 1;
}
void ASN1_STRING_TABLE_cleanup(void)
{
- STACK_OF(ASN1_STRING_TABLE) *tmp;
- tmp = stable;
- if(!tmp) return;
- stable = NULL;
- sk_ASN1_STRING_TABLE_pop_free(tmp, st_free);
+ STACK_OF(ASN1_STRING_TABLE) *tmp;
+ tmp = stable;
+ if (!tmp)
+ return;
+ stable = NULL;
+ sk_ASN1_STRING_TABLE_pop_free(tmp, st_free);
}
static void st_free(ASN1_STRING_TABLE *tbl)
{
- if(tbl->flags & STABLE_FLAGS_MALLOC) OPENSSL_free(tbl);
+ if (tbl->flags & STABLE_FLAGS_MALLOC)
+ OPENSSL_free(tbl);
}
-
#ifdef STRING_TABLE_TEST
-int
-main(void)
+int main(void)
{
- ASN1_STRING_TABLE *tmp;
- int i, last_nid = -1;
-
- for (tmp = tbl_standard, i = 0;
- i < sizeof(tbl_standard)/sizeof(ASN1_STRING_TABLE); i++, tmp++)
- {
- if (tmp->nid < last_nid)
- {
- last_nid = 0;
- break;
- }
- last_nid = tmp->nid;
- }
-
- if (last_nid != 0)
- {
- printf("Table order OK\n");
- exit(0);
- }
-
- for (tmp = tbl_standard, i = 0;
- i < sizeof(tbl_standard)/sizeof(ASN1_STRING_TABLE); i++, tmp++)
- printf("Index %d, NID %d, Name=%s\n", i, tmp->nid,
- OBJ_nid2ln(tmp->nid));
-
- return 0;
+ ASN1_STRING_TABLE *tmp;
+ int i, last_nid = -1;
+
+ for (tmp = tbl_standard, i = 0;
+ i < sizeof(tbl_standard) / sizeof(ASN1_STRING_TABLE); i++, tmp++) {
+ if (tmp->nid < last_nid) {
+ last_nid = 0;
+ break;
+ }
+ last_nid = tmp->nid;
+ }
+
+ if (last_nid != 0) {
+ printf("Table order OK\n");
+ exit(0);
+ }
+
+ for (tmp = tbl_standard, i = 0;
+ i < sizeof(tbl_standard) / sizeof(ASN1_STRING_TABLE); i++, tmp++)
+ printf("Index %d, NID %d, Name=%s\n", i, tmp->nid,
+ OBJ_nid2ln(tmp->nid));
+
+ return 0;
}
#endif
diff --git a/src/crypto/asn1/a_time.c b/src/crypto/asn1/a_time.c
index ac2cb485..4391092a 100644
--- a/src/crypto/asn1/a_time.c
+++ b/src/crypto/asn1/a_time.c
@@ -67,12 +67,10 @@
#include "asn1_locl.h"
-
-/* This is an implementation of the ASN1 Time structure which is:
- * Time ::= CHOICE {
- * utcTime UTCTime,
- * generalTime GeneralizedTime }
- * written by Steve Henson.
+/*
+ * This is an implementation of the ASN1 Time structure which is: Time ::=
+ * CHOICE { utcTime UTCTime, generalTime GeneralizedTime } written by Steve
+ * Henson.
*/
IMPLEMENT_ASN1_MSTRING(ASN1_TIME, B_ASN1_TIME)
@@ -81,141 +79,139 @@ IMPLEMENT_ASN1_FUNCTIONS(ASN1_TIME)
#if 0
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, ASN1_R_EXPECTING_A_TIME);
- return -1;
- }
+{
+ 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, ASN1_R_EXPECTING_A_TIME);
+ return -1;
+}
#endif
-
ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t)
- {
- return ASN1_TIME_adj(s, t, 0, 0);
- }
+{
+ return ASN1_TIME_adj(s, t, 0, 0);
+}
ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t,
- int offset_day, long offset_sec)
- {
- struct tm *ts;
- struct tm data;
-
- ts=OPENSSL_gmtime(&t,&data);
- if (ts == NULL)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_ERROR_GETTING_TIME);
- return NULL;
- }
- if (offset_day || offset_sec)
- {
- if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
- return NULL;
- }
- if((ts->tm_year >= 50) && (ts->tm_year < 150))
- return ASN1_UTCTIME_adj(s, t, offset_day, offset_sec);
- return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec);
- }
+ int offset_day, long offset_sec)
+{
+ struct tm *ts;
+ struct tm data;
+
+ ts = OPENSSL_gmtime(&t, &data);
+ if (ts == NULL) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ERROR_GETTING_TIME);
+ return NULL;
+ }
+ if (offset_day || offset_sec) {
+ if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
+ return NULL;
+ }
+ if ((ts->tm_year >= 50) && (ts->tm_year < 150))
+ return ASN1_UTCTIME_adj(s, t, offset_day, offset_sec);
+ return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec);
+}
int ASN1_TIME_check(ASN1_TIME *t)
- {
- if (t->type == V_ASN1_GENERALIZEDTIME)
- return ASN1_GENERALIZEDTIME_check(t);
- else if (t->type == V_ASN1_UTCTIME)
- return ASN1_UTCTIME_check(t);
- return 0;
- }
+{
+ if (t->type == V_ASN1_GENERALIZEDTIME)
+ return ASN1_GENERALIZEDTIME_check(t);
+ else if (t->type == V_ASN1_UTCTIME)
+ return ASN1_UTCTIME_check(t);
+ return 0;
+}
/* Convert an ASN1_TIME structure to GeneralizedTime */
-ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME **out)
- {
- ASN1_GENERALIZEDTIME *ret;
- char *str;
- int newlen;
-
- if (!ASN1_TIME_check(t)) return NULL;
-
- if (!out || !*out)
- {
- if (!(ret = ASN1_GENERALIZEDTIME_new ()))
- return NULL;
- if (out) *out = ret;
- }
- else ret = *out;
-
- /* If already GeneralizedTime just copy across */
- if (t->type == V_ASN1_GENERALIZEDTIME)
- {
- if(!ASN1_STRING_set(ret, t->data, t->length))
- return NULL;
- return ret;
- }
-
- /* grow the string */
- if (!ASN1_STRING_set(ret, NULL, t->length + 2))
- return NULL;
- /* ASN1_STRING_set() allocated 'len + 1' bytes. */
- newlen = t->length + 2 + 1;
- str = (char *)ret->data;
- /* Work out the century and prepend */
- if (t->data[0] >= '5') BUF_strlcpy(str, "19", newlen);
- else BUF_strlcpy(str, "20", newlen);
-
- BUF_strlcat(str, (char *)t->data, newlen);
-
- return ret;
- }
+ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t,
+ ASN1_GENERALIZEDTIME **out)
+{
+ ASN1_GENERALIZEDTIME *ret;
+ char *str;
+ int newlen;
+
+ if (!ASN1_TIME_check(t))
+ return NULL;
+
+ if (!out || !*out) {
+ if (!(ret = ASN1_GENERALIZEDTIME_new()))
+ return NULL;
+ if (out)
+ *out = ret;
+ } else
+ ret = *out;
+
+ /* If already GeneralizedTime just copy across */
+ if (t->type == V_ASN1_GENERALIZEDTIME) {
+ if (!ASN1_STRING_set(ret, t->data, t->length))
+ return NULL;
+ return ret;
+ }
+
+ /* grow the string */
+ if (!ASN1_STRING_set(ret, NULL, t->length + 2))
+ return NULL;
+ /* ASN1_STRING_set() allocated 'len + 1' bytes. */
+ newlen = t->length + 2 + 1;
+ str = (char *)ret->data;
+ /* Work out the century and prepend */
+ if (t->data[0] >= '5')
+ BUF_strlcpy(str, "19", newlen);
+ else
+ BUF_strlcpy(str, "20", newlen);
+
+ BUF_strlcat(str, (char *)t->data, newlen);
+
+ return ret;
+}
int ASN1_TIME_set_string(ASN1_TIME *s, const char *str)
- {
- ASN1_TIME t;
-
- t.length = strlen(str);
- t.data = (unsigned char *)str;
- t.flags = 0;
-
- t.type = V_ASN1_UTCTIME;
-
- if (!ASN1_TIME_check(&t))
- {
- t.type = V_ASN1_GENERALIZEDTIME;
- if (!ASN1_TIME_check(&t))
- return 0;
- }
-
- if (s && !ASN1_STRING_copy((ASN1_STRING *)s, (ASN1_STRING *)&t))
- return 0;
-
- return 1;
- }
+{
+ ASN1_TIME t;
+
+ t.length = strlen(str);
+ t.data = (unsigned char *)str;
+ t.flags = 0;
+
+ t.type = V_ASN1_UTCTIME;
+
+ if (!ASN1_TIME_check(&t)) {
+ t.type = V_ASN1_GENERALIZEDTIME;
+ if (!ASN1_TIME_check(&t))
+ return 0;
+ }
+
+ if (s && !ASN1_STRING_copy((ASN1_STRING *)s, (ASN1_STRING *)&t))
+ return 0;
+
+ return 1;
+}
static int asn1_time_to_tm(struct tm *tm, const ASN1_TIME *t)
- {
- if (t == NULL)
- {
- time_t now_t;
- time(&now_t);
- if (OPENSSL_gmtime(&now_t, tm))
- return 1;
- return 0;
- }
-
- if (t->type == V_ASN1_UTCTIME)
- return asn1_utctime_to_tm(tm, t);
- else if (t->type == V_ASN1_GENERALIZEDTIME)
- return asn1_generalizedtime_to_tm(tm, t);
-
- return 0;
- }
+{
+ if (t == NULL) {
+ time_t now_t;
+ time(&now_t);
+ if (OPENSSL_gmtime(&now_t, tm))
+ return 1;
+ return 0;
+ }
+
+ if (t->type == V_ASN1_UTCTIME)
+ return asn1_utctime_to_tm(tm, t);
+ else if (t->type == V_ASN1_GENERALIZEDTIME)
+ return asn1_generalizedtime_to_tm(tm, t);
+
+ return 0;
+}
int ASN1_TIME_diff(int *pday, int *psec,
- const ASN1_TIME *from, const ASN1_TIME *to)
- {
- struct tm tm_from, tm_to;
- if (!asn1_time_to_tm(&tm_from, from))
- return 0;
- if (!asn1_time_to_tm(&tm_to, to))
- return 0;
- return OPENSSL_gmtime_diff(pday, psec, &tm_from, &tm_to);
- }
+ const ASN1_TIME *from, const ASN1_TIME *to)
+{
+ struct tm tm_from, tm_to;
+ if (!asn1_time_to_tm(&tm_from, from))
+ return 0;
+ if (!asn1_time_to_tm(&tm_to, to))
+ return 0;
+ return OPENSSL_gmtime_diff(pday, psec, &tm_from, &tm_to);
+}
diff --git a/src/crypto/asn1/a_type.c b/src/crypto/asn1/a_type.c
index fd3d5b11..ecd47342 100644
--- a/src/crypto/asn1/a_type.c
+++ b/src/crypto/asn1/a_type.c
@@ -61,100 +61,93 @@
#include <openssl/mem.h>
#include <openssl/obj.h>
-
int ASN1_TYPE_get(ASN1_TYPE *a)
- {
- if ((a->value.ptr != NULL) || (a->type == V_ASN1_NULL))
- return(a->type);
- else
- return(0);
- }
+{
+ if ((a->value.ptr != NULL) || (a->type == V_ASN1_NULL))
+ return (a->type);
+ else
+ return (0);
+}
void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value)
- {
- if (a->value.ptr != NULL)
- {
- ASN1_TYPE **tmp_a = &a;
- ASN1_primitive_free((ASN1_VALUE **)tmp_a, NULL);
- }
- a->type=type;
- if (type == V_ASN1_BOOLEAN)
- a->value.boolean = value ? 0xff : 0;
- else
- a->value.ptr=value;
- }
+{
+ if (a->value.ptr != NULL) {
+ ASN1_TYPE **tmp_a = &a;
+ ASN1_primitive_free((ASN1_VALUE **)tmp_a, NULL);
+ }
+ a->type = type;
+ if (type == V_ASN1_BOOLEAN)
+ a->value.boolean = value ? 0xff : 0;
+ else
+ a->value.ptr = value;
+}
int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value)
- {
- if (!value || (type == V_ASN1_BOOLEAN))
- {
- void *p = (void *)value;
- ASN1_TYPE_set(a, type, p);
- }
- else if (type == V_ASN1_OBJECT)
- {
- ASN1_OBJECT *odup;
- odup = OBJ_dup(value);
- if (!odup)
- return 0;
- ASN1_TYPE_set(a, type, odup);
- }
- else
- {
- ASN1_STRING *sdup;
- sdup = ASN1_STRING_dup(value);
- if (!sdup)
- return 0;
- ASN1_TYPE_set(a, type, sdup);
- }
- return 1;
- }
+{
+ if (!value || (type == V_ASN1_BOOLEAN)) {
+ void *p = (void *)value;
+ ASN1_TYPE_set(a, type, p);
+ } else if (type == V_ASN1_OBJECT) {
+ ASN1_OBJECT *odup;
+ odup = OBJ_dup(value);
+ if (!odup)
+ return 0;
+ ASN1_TYPE_set(a, type, odup);
+ } else {
+ ASN1_STRING *sdup;
+ sdup = ASN1_STRING_dup(value);
+ if (!sdup)
+ return 0;
+ ASN1_TYPE_set(a, type, sdup);
+ }
+ return 1;
+}
/* Returns 0 if they are equal, != 0 otherwise. */
int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b)
- {
- int result = -1;
+{
+ int result = -1;
- if (!a || !b || a->type != b->type) return -1;
+ if (!a || !b || a->type != b->type)
+ return -1;
- switch (a->type)
- {
- case V_ASN1_OBJECT:
- result = OBJ_cmp(a->value.object, b->value.object);
- break;
- case V_ASN1_NULL:
- result = 0; /* They do not have content. */
- break;
- case V_ASN1_BOOLEAN:
- result = a->value.boolean - b->value.boolean;
- break;
- case V_ASN1_INTEGER:
- case V_ASN1_NEG_INTEGER:
- case V_ASN1_ENUMERATED:
- case V_ASN1_NEG_ENUMERATED:
- case V_ASN1_BIT_STRING:
- case V_ASN1_OCTET_STRING:
- case V_ASN1_SEQUENCE:
- case V_ASN1_SET:
- case V_ASN1_NUMERICSTRING:
- case V_ASN1_PRINTABLESTRING:
- case V_ASN1_T61STRING:
- case V_ASN1_VIDEOTEXSTRING:
- case V_ASN1_IA5STRING:
- case V_ASN1_UTCTIME:
- case V_ASN1_GENERALIZEDTIME:
- case V_ASN1_GRAPHICSTRING:
- case V_ASN1_VISIBLESTRING:
- case V_ASN1_GENERALSTRING:
- case V_ASN1_UNIVERSALSTRING:
- case V_ASN1_BMPSTRING:
- case V_ASN1_UTF8STRING:
- case V_ASN1_OTHER:
- default:
- result = ASN1_STRING_cmp((ASN1_STRING *) a->value.ptr,
- (ASN1_STRING *) b->value.ptr);
- break;
- }
+ switch (a->type) {
+ case V_ASN1_OBJECT:
+ result = OBJ_cmp(a->value.object, b->value.object);
+ break;
+ case V_ASN1_NULL:
+ result = 0; /* They do not have content. */
+ break;
+ case V_ASN1_BOOLEAN:
+ result = a->value.boolean - b->value.boolean;
+ break;
+ case V_ASN1_INTEGER:
+ case V_ASN1_NEG_INTEGER:
+ case V_ASN1_ENUMERATED:
+ case V_ASN1_NEG_ENUMERATED:
+ case V_ASN1_BIT_STRING:
+ case V_ASN1_OCTET_STRING:
+ case V_ASN1_SEQUENCE:
+ case V_ASN1_SET:
+ case V_ASN1_NUMERICSTRING:
+ case V_ASN1_PRINTABLESTRING:
+ case V_ASN1_T61STRING:
+ case V_ASN1_VIDEOTEXSTRING:
+ case V_ASN1_IA5STRING:
+ case V_ASN1_UTCTIME:
+ case V_ASN1_GENERALIZEDTIME:
+ case V_ASN1_GRAPHICSTRING:
+ case V_ASN1_VISIBLESTRING:
+ case V_ASN1_GENERALSTRING:
+ case V_ASN1_UNIVERSALSTRING:
+ case V_ASN1_BMPSTRING:
+ case V_ASN1_UTF8STRING:
+ case V_ASN1_OTHER:
+ default:
+ result = ASN1_STRING_cmp((ASN1_STRING *)a->value.ptr,
+ (ASN1_STRING *)b->value.ptr);
+ break;
+ }
- return result;
- }
+ return result;
+}
diff --git a/src/crypto/asn1/a_utctm.c b/src/crypto/asn1/a_utctm.c
index dbbbecb4..5a55bd24 100644
--- a/src/crypto/asn1/a_utctm.c
+++ b/src/crypto/asn1/a_utctm.c
@@ -63,280 +63,273 @@
#include <openssl/mem.h>
#include <openssl/time_support.h>
+#include "asn1_locl.h"
#if 0
int i2d_ASN1_UTCTIME(ASN1_UTCTIME *a, unsigned char **pp)
- {
- return(i2d_ASN1_bytes((ASN1_STRING *)a,pp,
- V_ASN1_UTCTIME,V_ASN1_UNIVERSAL));
- }
-
+{
+ return (i2d_ASN1_bytes((ASN1_STRING *)a, pp,
+ V_ASN1_UTCTIME, V_ASN1_UNIVERSAL));
+}
ASN1_UTCTIME *d2i_ASN1_UTCTIME(ASN1_UTCTIME **a, unsigned char **pp,
- long length)
- {
- ASN1_UTCTIME *ret=NULL;
-
- ret=(ASN1_UTCTIME *)d2i_ASN1_bytes((ASN1_STRING **)a,pp,length,
- V_ASN1_UTCTIME,V_ASN1_UNIVERSAL);
- if (ret == NULL)
- {
- OPENSSL_PUT_ERROR(ASN1, ERR_R_NESTED_ASN1_ERROR);
- return(NULL);
- }
- if (!ASN1_UTCTIME_check(ret))
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_TIME_FORMAT);
- goto err;
- }
-
- return(ret);
-err:
- if ((ret != NULL) && ((a == NULL) || (*a != ret)))
- M_ASN1_UTCTIME_free(ret);
- return(NULL);
- }
+ long length)
+{
+ ASN1_UTCTIME *ret = NULL;
+
+ ret = (ASN1_UTCTIME *)d2i_ASN1_bytes((ASN1_STRING **)a, pp, length,
+ V_ASN1_UTCTIME, V_ASN1_UNIVERSAL);
+ if (ret == NULL) {
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_NESTED_ASN1_ERROR);
+ return (NULL);
+ }
+ if (!ASN1_UTCTIME_check(ret)) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_TIME_FORMAT);
+ goto err;
+ }
+
+ return (ret);
+ err:
+ if ((ret != NULL) && ((a == NULL) || (*a != ret)))
+ M_ASN1_UTCTIME_free(ret);
+ return (NULL);
+}
#endif
int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d)
- {
- static const int min[8]={ 0, 1, 1, 0, 0, 0, 0, 0};
- static const int max[8]={99,12,31,23,59,59,12,59};
- char *a;
- int n,i,l,o;
-
- if (d->type != V_ASN1_UTCTIME) return(0);
- l=d->length;
- a=(char *)d->data;
- o=0;
-
- if (l < 11) goto err;
- for (i=0; i<6; i++)
- {
- if ((i == 5) && ((a[o] == 'Z') ||
- (a[o] == '+') || (a[o] == '-')))
- {
- i++;
- if (tm)
- tm->tm_sec = 0;
- break;
- }
- if ((a[o] < '0') || (a[o] > '9')) goto err;
- n= a[o]-'0';
- if (++o > l) goto err;
-
- if ((a[o] < '0') || (a[o] > '9')) goto err;
- n=(n*10)+ a[o]-'0';
- if (++o > l) goto err;
-
- if ((n < min[i]) || (n > max[i])) goto err;
- if (tm)
- {
- switch(i)
- {
- case 0:
- tm->tm_year = n < 50 ? n + 100 : n;
- break;
- case 1:
- tm->tm_mon = n - 1;
- break;
- case 2:
- tm->tm_mday = n;
- break;
- case 3:
- tm->tm_hour = n;
- break;
- case 4:
- tm->tm_min = n;
- break;
- case 5:
- tm->tm_sec = n;
- break;
- }
- }
- }
- if (a[o] == 'Z')
- o++;
- else if ((a[o] == '+') || (a[o] == '-'))
- {
- int offsign = a[o] == '-' ? -1 : 1, offset = 0;
- o++;
- if (o+4 > l) goto err;
- for (i=6; i<8; i++)
- {
- if ((a[o] < '0') || (a[o] > '9')) goto err;
- n= a[o]-'0';
- o++;
- if ((a[o] < '0') || (a[o] > '9')) goto err;
- n=(n*10)+ a[o]-'0';
- if ((n < min[i]) || (n > max[i])) goto err;
- if (tm)
- {
- if (i == 6)
- offset = n * 3600;
- else if (i == 7)
- offset += n * 60;
- }
- o++;
- }
- if (offset && !OPENSSL_gmtime_adj(tm, 0, offset * offsign))
- return 0;
- }
- return o == l;
-err:
- return 0;
- }
+{
+ static const int min[8] = { 0, 1, 1, 0, 0, 0, 0, 0 };
+ static const int max[8] = { 99, 12, 31, 23, 59, 59, 12, 59 };
+ char *a;
+ int n, i, l, o;
+
+ if (d->type != V_ASN1_UTCTIME)
+ return (0);
+ l = d->length;
+ a = (char *)d->data;
+ o = 0;
+
+ if (l < 11)
+ goto err;
+ for (i = 0; i < 6; i++) {
+ if ((i == 5) && ((a[o] == 'Z') || (a[o] == '+') || (a[o] == '-'))) {
+ i++;
+ if (tm)
+ tm->tm_sec = 0;
+ break;
+ }
+ if ((a[o] < '0') || (a[o] > '9'))
+ goto err;
+ n = a[o] - '0';
+ if (++o > l)
+ goto err;
+
+ if ((a[o] < '0') || (a[o] > '9'))
+ goto err;
+ n = (n * 10) + a[o] - '0';
+ if (++o > l)
+ goto err;
+
+ if ((n < min[i]) || (n > max[i]))
+ goto err;
+ if (tm) {
+ switch (i) {
+ case 0:
+ tm->tm_year = n < 50 ? n + 100 : n;
+ break;
+ case 1:
+ tm->tm_mon = n - 1;
+ break;
+ case 2:
+ tm->tm_mday = n;
+ break;
+ case 3:
+ tm->tm_hour = n;
+ break;
+ case 4:
+ tm->tm_min = n;
+ break;
+ case 5:
+ tm->tm_sec = n;
+ break;
+ }
+ }
+ }
+ if (a[o] == 'Z')
+ o++;
+ else if ((a[o] == '+') || (a[o] == '-')) {
+ int offsign = a[o] == '-' ? -1 : 1, offset = 0;
+ o++;
+ if (o + 4 > l)
+ goto err;
+ for (i = 6; i < 8; i++) {
+ if ((a[o] < '0') || (a[o] > '9'))
+ goto err;
+ n = a[o] - '0';
+ o++;
+ if ((a[o] < '0') || (a[o] > '9'))
+ goto err;
+ n = (n * 10) + a[o] - '0';
+ if ((n < min[i]) || (n > max[i]))
+ goto err;
+ if (tm) {
+ if (i == 6)
+ offset = n * 3600;
+ else if (i == 7)
+ offset += n * 60;
+ }
+ o++;
+ }
+ if (offset && !OPENSSL_gmtime_adj(tm, 0, offset * offsign))
+ return 0;
+ }
+ return o == l;
+ err:
+ return 0;
+}
int ASN1_UTCTIME_check(const ASN1_UTCTIME *d)
- {
- return asn1_utctime_to_tm(NULL, d);
- }
+{
+ return asn1_utctime_to_tm(NULL, d);
+}
int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str)
- {
- ASN1_UTCTIME t;
-
- t.type=V_ASN1_UTCTIME;
- t.length=strlen(str);
- t.data=(unsigned char *)str;
- if (ASN1_UTCTIME_check(&t))
- {
- if (s != NULL)
- {
- if (!ASN1_STRING_set((ASN1_STRING *)s,
- (unsigned char *)str,t.length))
- return 0;
- s->type = V_ASN1_UTCTIME;
- }
- return(1);
- }
- else
- return(0);
- }
+{
+ ASN1_UTCTIME t;
+
+ t.type = V_ASN1_UTCTIME;
+ t.length = strlen(str);
+ t.data = (unsigned char *)str;
+ if (ASN1_UTCTIME_check(&t)) {
+ if (s != NULL) {
+ if (!ASN1_STRING_set((ASN1_STRING *)s,
+ (unsigned char *)str, t.length))
+ return 0;
+ s->type = V_ASN1_UTCTIME;
+ }
+ return (1);
+ } else
+ return (0);
+}
ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t)
- {
- return ASN1_UTCTIME_adj(s, t, 0, 0);
- }
+{
+ return ASN1_UTCTIME_adj(s, t, 0, 0);
+}
ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t,
- int offset_day, long offset_sec)
- {
- char *p;
- struct tm *ts;
- struct tm data;
- size_t len = 20;
- int free_s = 0;
-
- if (s == NULL)
- {
- free_s = 1;
- s=M_ASN1_UTCTIME_new();
- }
- if (s == NULL)
- goto err;
-
-
- ts=OPENSSL_gmtime(&t, &data);
- if (ts == NULL)
- goto err;
-
- if (offset_day || offset_sec)
- {
- if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
- goto err;
- }
-
- if((ts->tm_year < 50) || (ts->tm_year >= 150))
- goto err;
-
- p=(char *)s->data;
- if ((p == NULL) || ((size_t)s->length < len))
- {
- p=OPENSSL_malloc(len);
- if (p == NULL)
- {
- OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- if (s->data != NULL)
- OPENSSL_free(s->data);
- s->data=(unsigned char *)p;
- }
-
- BIO_snprintf(p,len,"%02d%02d%02d%02d%02d%02dZ",ts->tm_year%100,
- ts->tm_mon+1,ts->tm_mday,ts->tm_hour,ts->tm_min,ts->tm_sec);
- s->length=strlen(p);
- s->type=V_ASN1_UTCTIME;
- return(s);
- err:
- if (free_s && s)
- M_ASN1_UTCTIME_free(s);
- return NULL;
- }
-
+ int offset_day, long offset_sec)
+{
+ char *p;
+ struct tm *ts;
+ struct tm data;
+ size_t len = 20;
+ int free_s = 0;
+
+ if (s == NULL) {
+ free_s = 1;
+ s = M_ASN1_UTCTIME_new();
+ }
+ if (s == NULL)
+ goto err;
+
+ ts = OPENSSL_gmtime(&t, &data);
+ if (ts == NULL)
+ goto err;
+
+ if (offset_day || offset_sec) {
+ if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
+ goto err;
+ }
+
+ if ((ts->tm_year < 50) || (ts->tm_year >= 150))
+ goto err;
+
+ p = (char *)s->data;
+ if ((p == NULL) || ((size_t)s->length < len)) {
+ p = OPENSSL_malloc(len);
+ if (p == NULL) {
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if (s->data != NULL)
+ OPENSSL_free(s->data);
+ s->data = (unsigned char *)p;
+ }
+
+ BIO_snprintf(p, len, "%02d%02d%02d%02d%02d%02dZ", ts->tm_year % 100,
+ ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, ts->tm_min,
+ ts->tm_sec);
+ s->length = strlen(p);
+ s->type = V_ASN1_UTCTIME;
+ return (s);
+ err:
+ if (free_s && s)
+ M_ASN1_UTCTIME_free(s);
+ return NULL;
+}
int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t)
- {
- struct tm stm, ttm;
- int day, sec;
-
- if (!asn1_utctime_to_tm(&stm, s))
- return -2;
-
- if (!OPENSSL_gmtime(&t, &ttm))
- return -2;
-
- if (!OPENSSL_gmtime_diff(&day, &sec, &ttm, &stm))
- return -2;
-
- if (day > 0)
- return 1;
- if (day < 0)
- return -1;
- if (sec > 0)
- return 1;
- if (sec < 0)
- return -1;
- return 0;
- }
-
+{
+ struct tm stm, ttm;
+ int day, sec;
+
+ if (!asn1_utctime_to_tm(&stm, s))
+ return -2;
+
+ if (!OPENSSL_gmtime(&t, &ttm))
+ return -2;
+
+ if (!OPENSSL_gmtime_diff(&day, &sec, &ttm, &stm))
+ return -2;
+
+ if (day > 0)
+ return 1;
+ if (day < 0)
+ return -1;
+ if (sec > 0)
+ return 1;
+ if (sec < 0)
+ return -1;
+ return 0;
+}
#if 0
time_t ASN1_UTCTIME_get(const ASN1_UTCTIME *s)
- {
- struct tm tm;
- int offset;
-
- memset(&tm,'\0',sizeof tm);
-
-#define g2(p) (((p)[0]-'0')*10+(p)[1]-'0')
- tm.tm_year=g2(s->data);
- if(tm.tm_year < 50)
- tm.tm_year+=100;
- tm.tm_mon=g2(s->data+2)-1;
- tm.tm_mday=g2(s->data+4);
- tm.tm_hour=g2(s->data+6);
- tm.tm_min=g2(s->data+8);
- tm.tm_sec=g2(s->data+10);
- if(s->data[12] == 'Z')
- offset=0;
- else
- {
- offset=g2(s->data+13)*60+g2(s->data+15);
- if(s->data[12] == '-')
- offset= -offset;
- }
-#undef g2
-
- return mktime(&tm)-offset*60; /* FIXME: mktime assumes the current timezone
- * instead of UTC, and unless we rewrite OpenSSL
- * in Lisp we cannot locally change the timezone
- * without possibly interfering with other parts
- * of the program. timegm, which uses UTC, is
- * non-standard.
- * Also time_t is inappropriate for general
- * UTC times because it may a 32 bit type. */
- }
+{
+ struct tm tm;
+ int offset;
+
+ memset(&tm, '\0', sizeof tm);
+
+# define g2(p) (((p)[0]-'0')*10+(p)[1]-'0')
+ tm.tm_year = g2(s->data);
+ if (tm.tm_year < 50)
+ tm.tm_year += 100;
+ tm.tm_mon = g2(s->data + 2) - 1;
+ tm.tm_mday = g2(s->data + 4);
+ tm.tm_hour = g2(s->data + 6);
+ tm.tm_min = g2(s->data + 8);
+ tm.tm_sec = g2(s->data + 10);
+ if (s->data[12] == 'Z')
+ offset = 0;
+ else {
+ offset = g2(s->data + 13) * 60 + g2(s->data + 15);
+ if (s->data[12] == '-')
+ offset = -offset;
+ }
+# undef g2
+
+ return mktime(&tm) - offset * 60; /* FIXME: mktime assumes the current
+ * timezone instead of UTC, and unless
+ * we rewrite OpenSSL in Lisp we cannot
+ * locally change the timezone without
+ * possibly interfering with other
+ * parts of the program. timegm, which
+ * uses UTC, is non-standard. Also
+ * time_t is inappropriate for general
+ * UTC times because it may a 32 bit
+ * type. */
+}
#endif
diff --git a/src/crypto/asn1/a_utf8.c b/src/crypto/asn1/a_utf8.c
index ed6e98d3..17027686 100644
--- a/src/crypto/asn1/a_utf8.c
+++ b/src/crypto/asn1/a_utf8.c
@@ -59,152 +59,176 @@
#include <openssl/err.h>
#include <openssl/mem.h>
-
/* UTF8 utilities */
-/* This parses a UTF8 string one character at a time. It is passed a pointer
- * to the string and the length of the string. It sets 'value' to the value of
- * the current character. It returns the number of characters read or a
- * negative error code:
- * -1 = string too short
- * -2 = illegal character
- * -3 = subsequent characters not of the form 10xxxxxx
- * -4 = character encoded incorrectly (not minimal length).
+/*
+ * This parses a UTF8 string one character at a time. It is passed a pointer
+ * to the string and the length of the string. It sets 'value' to the value
+ * of the current character. It returns the number of characters read or a
+ * negative error code: -1 = string too short -2 = illegal character -3 =
+ * subsequent characters not of the form 10xxxxxx -4 = character encoded
+ * incorrectly (not minimal length).
*/
int UTF8_getc(const unsigned char *str, int len, unsigned long *val)
{
- const unsigned char *p;
- unsigned long value;
- int ret;
- if(len <= 0) return 0;
- p = str;
+ const unsigned char *p;
+ unsigned long value;
+ int ret;
+ if (len <= 0)
+ return 0;
+ p = str;
- /* Check syntax and work out the encoded value (if correct) */
- if((*p & 0x80) == 0) {
- value = *p++ & 0x7f;
- ret = 1;
- } else if((*p & 0xe0) == 0xc0) {
- if(len < 2) return -1;
- if((p[1] & 0xc0) != 0x80) return -3;
- value = (*p++ & 0x1f) << 6;
- value |= *p++ & 0x3f;
- if(value < 0x80) return -4;
- ret = 2;
- } else if((*p & 0xf0) == 0xe0) {
- if(len < 3) return -1;
- if( ((p[1] & 0xc0) != 0x80)
- || ((p[2] & 0xc0) != 0x80) ) return -3;
- value = (*p++ & 0xf) << 12;
- value |= (*p++ & 0x3f) << 6;
- value |= *p++ & 0x3f;
- if(value < 0x800) return -4;
- ret = 3;
- } else if((*p & 0xf8) == 0xf0) {
- if(len < 4) return -1;
- if( ((p[1] & 0xc0) != 0x80)
- || ((p[2] & 0xc0) != 0x80)
- || ((p[3] & 0xc0) != 0x80) ) return -3;
- value = ((unsigned long)(*p++ & 0x7)) << 18;
- value |= (*p++ & 0x3f) << 12;
- value |= (*p++ & 0x3f) << 6;
- value |= *p++ & 0x3f;
- if(value < 0x10000) return -4;
- ret = 4;
- } else if((*p & 0xfc) == 0xf8) {
- if(len < 5) return -1;
- if( ((p[1] & 0xc0) != 0x80)
- || ((p[2] & 0xc0) != 0x80)
- || ((p[3] & 0xc0) != 0x80)
- || ((p[4] & 0xc0) != 0x80) ) return -3;
- value = ((unsigned long)(*p++ & 0x3)) << 24;
- value |= ((unsigned long)(*p++ & 0x3f)) << 18;
- value |= ((unsigned long)(*p++ & 0x3f)) << 12;
- value |= (*p++ & 0x3f) << 6;
- value |= *p++ & 0x3f;
- if(value < 0x200000) return -4;
- ret = 5;
- } else if((*p & 0xfe) == 0xfc) {
- if(len < 6) return -1;
- if( ((p[1] & 0xc0) != 0x80)
- || ((p[2] & 0xc0) != 0x80)
- || ((p[3] & 0xc0) != 0x80)
- || ((p[4] & 0xc0) != 0x80)
- || ((p[5] & 0xc0) != 0x80) ) return -3;
- value = ((unsigned long)(*p++ & 0x1)) << 30;
- value |= ((unsigned long)(*p++ & 0x3f)) << 24;
- value |= ((unsigned long)(*p++ & 0x3f)) << 18;
- value |= ((unsigned long)(*p++ & 0x3f)) << 12;
- value |= (*p++ & 0x3f) << 6;
- value |= *p++ & 0x3f;
- if(value < 0x4000000) return -4;
- ret = 6;
- } else return -2;
- *val = value;
- return ret;
+ /* Check syntax and work out the encoded value (if correct) */
+ if ((*p & 0x80) == 0) {
+ value = *p++ & 0x7f;
+ ret = 1;
+ } else if ((*p & 0xe0) == 0xc0) {
+ if (len < 2)
+ return -1;
+ if ((p[1] & 0xc0) != 0x80)
+ return -3;
+ value = (*p++ & 0x1f) << 6;
+ value |= *p++ & 0x3f;
+ if (value < 0x80)
+ return -4;
+ ret = 2;
+ } else if ((*p & 0xf0) == 0xe0) {
+ if (len < 3)
+ return -1;
+ if (((p[1] & 0xc0) != 0x80)
+ || ((p[2] & 0xc0) != 0x80))
+ return -3;
+ value = (*p++ & 0xf) << 12;
+ value |= (*p++ & 0x3f) << 6;
+ value |= *p++ & 0x3f;
+ if (value < 0x800)
+ return -4;
+ ret = 3;
+ } else if ((*p & 0xf8) == 0xf0) {
+ if (len < 4)
+ return -1;
+ if (((p[1] & 0xc0) != 0x80)
+ || ((p[2] & 0xc0) != 0x80)
+ || ((p[3] & 0xc0) != 0x80))
+ return -3;
+ value = ((unsigned long)(*p++ & 0x7)) << 18;
+ value |= (*p++ & 0x3f) << 12;
+ value |= (*p++ & 0x3f) << 6;
+ value |= *p++ & 0x3f;
+ if (value < 0x10000)
+ return -4;
+ ret = 4;
+ } else if ((*p & 0xfc) == 0xf8) {
+ if (len < 5)
+ return -1;
+ if (((p[1] & 0xc0) != 0x80)
+ || ((p[2] & 0xc0) != 0x80)
+ || ((p[3] & 0xc0) != 0x80)
+ || ((p[4] & 0xc0) != 0x80))
+ return -3;
+ value = ((unsigned long)(*p++ & 0x3)) << 24;
+ value |= ((unsigned long)(*p++ & 0x3f)) << 18;
+ value |= ((unsigned long)(*p++ & 0x3f)) << 12;
+ value |= (*p++ & 0x3f) << 6;
+ value |= *p++ & 0x3f;
+ if (value < 0x200000)
+ return -4;
+ ret = 5;
+ } else if ((*p & 0xfe) == 0xfc) {
+ if (len < 6)
+ return -1;
+ if (((p[1] & 0xc0) != 0x80)
+ || ((p[2] & 0xc0) != 0x80)
+ || ((p[3] & 0xc0) != 0x80)
+ || ((p[4] & 0xc0) != 0x80)
+ || ((p[5] & 0xc0) != 0x80))
+ return -3;
+ value = ((unsigned long)(*p++ & 0x1)) << 30;
+ value |= ((unsigned long)(*p++ & 0x3f)) << 24;
+ value |= ((unsigned long)(*p++ & 0x3f)) << 18;
+ value |= ((unsigned long)(*p++ & 0x3f)) << 12;
+ value |= (*p++ & 0x3f) << 6;
+ value |= *p++ & 0x3f;
+ if (value < 0x4000000)
+ return -4;
+ ret = 6;
+ } else
+ return -2;
+ *val = value;
+ return ret;
}
-/* This takes a character 'value' and writes the UTF8 encoded value in
- * 'str' where 'str' is a buffer containing 'len' characters. Returns
- * the number of characters written or -1 if 'len' is too small. 'str' can
- * be set to NULL in which case it just returns the number of characters.
- * It will need at most 6 characters.
+/*
+ * This takes a character 'value' and writes the UTF8 encoded value in 'str'
+ * where 'str' is a buffer containing 'len' characters. Returns the number of
+ * characters written or -1 if 'len' is too small. 'str' can be set to NULL
+ * in which case it just returns the number of characters. It will need at
+ * most 6 characters.
*/
int UTF8_putc(unsigned char *str, int len, unsigned long value)
{
- if(!str) len = 6; /* Maximum we will need */
- else if(len <= 0) return -1;
- if(value < 0x80) {
- if(str) *str = (unsigned char)value;
- return 1;
- }
- if(value < 0x800) {
- if(len < 2) return -1;
- if(str) {
- *str++ = (unsigned char)(((value >> 6) & 0x1f) | 0xc0);
- *str = (unsigned char)((value & 0x3f) | 0x80);
- }
- return 2;
- }
- if(value < 0x10000) {
- if(len < 3) return -1;
- if(str) {
- *str++ = (unsigned char)(((value >> 12) & 0xf) | 0xe0);
- *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
- *str = (unsigned char)((value & 0x3f) | 0x80);
- }
- return 3;
- }
- if(value < 0x200000) {
- if(len < 4) return -1;
- if(str) {
- *str++ = (unsigned char)(((value >> 18) & 0x7) | 0xf0);
- *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
- *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
- *str = (unsigned char)((value & 0x3f) | 0x80);
- }
- return 4;
- }
- if(value < 0x4000000) {
- if(len < 5) return -1;
- if(str) {
- *str++ = (unsigned char)(((value >> 24) & 0x3) | 0xf8);
- *str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80);
- *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
- *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
- *str = (unsigned char)((value & 0x3f) | 0x80);
- }
- return 5;
- }
- if(len < 6) return -1;
- if(str) {
- *str++ = (unsigned char)(((value >> 30) & 0x1) | 0xfc);
- *str++ = (unsigned char)(((value >> 24) & 0x3f) | 0x80);
- *str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80);
- *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
- *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
- *str = (unsigned char)((value & 0x3f) | 0x80);
- }
- return 6;
+ if (!str)
+ len = 6; /* Maximum we will need */
+ else if (len <= 0)
+ return -1;
+ if (value < 0x80) {
+ if (str)
+ *str = (unsigned char)value;
+ return 1;
+ }
+ if (value < 0x800) {
+ if (len < 2)
+ return -1;
+ if (str) {
+ *str++ = (unsigned char)(((value >> 6) & 0x1f) | 0xc0);
+ *str = (unsigned char)((value & 0x3f) | 0x80);
+ }
+ return 2;
+ }
+ if (value < 0x10000) {
+ if (len < 3)
+ return -1;
+ if (str) {
+ *str++ = (unsigned char)(((value >> 12) & 0xf) | 0xe0);
+ *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
+ *str = (unsigned char)((value & 0x3f) | 0x80);
+ }
+ return 3;
+ }
+ if (value < 0x200000) {
+ if (len < 4)
+ return -1;
+ if (str) {
+ *str++ = (unsigned char)(((value >> 18) & 0x7) | 0xf0);
+ *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
+ *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
+ *str = (unsigned char)((value & 0x3f) | 0x80);
+ }
+ return 4;
+ }
+ if (value < 0x4000000) {
+ if (len < 5)
+ return -1;
+ if (str) {
+ *str++ = (unsigned char)(((value >> 24) & 0x3) | 0xf8);
+ *str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80);
+ *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
+ *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
+ *str = (unsigned char)((value & 0x3f) | 0x80);
+ }
+ return 5;
+ }
+ if (len < 6)
+ return -1;
+ if (str) {
+ *str++ = (unsigned char)(((value >> 30) & 0x1) | 0xfc);
+ *str++ = (unsigned char)(((value >> 24) & 0x3f) | 0x80);
+ *str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80);
+ *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
+ *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
+ *str = (unsigned char)((value & 0x3f) | 0x80);
+ }
+ return 6;
}
diff --git a/src/crypto/asn1/asn1_lib.c b/src/crypto/asn1/asn1_lib.c
index 0f2ce505..b637e795 100644
--- a/src/crypto/asn1/asn1_lib.c
+++ b/src/crypto/asn1/asn1_lib.c
@@ -63,12 +63,19 @@
#include <openssl/err.h>
#include <openssl/mem.h>
-
-/* Cross-module errors from crypto/x509/i2d_pr.c */
+/* Cross-module errors from crypto/x509/i2d_pr.c. */
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. */
+/* Cross-module errors from crypto/x509/algorithm.c. */
+OPENSSL_DECLARE_ERROR_REASON(ASN1, CONTEXT_NOT_INITIALISED);
+OPENSSL_DECLARE_ERROR_REASON(ASN1, DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
+OPENSSL_DECLARE_ERROR_REASON(ASN1, UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
+OPENSSL_DECLARE_ERROR_REASON(ASN1, UNKNOWN_SIGNATURE_ALGORITHM);
+OPENSSL_DECLARE_ERROR_REASON(ASN1, WRONG_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_REASON(ASN1, DEPTH_EXCEEDED);
OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_BITSTRING_FORMAT);
OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_BOOLEAN);
@@ -93,414 +100,406 @@ OPENSSL_DECLARE_ERROR_REASON(ASN1, UNKNOWN_FORMAT);
OPENSSL_DECLARE_ERROR_REASON(ASN1, UNKNOWN_TAG);
OPENSSL_DECLARE_ERROR_REASON(ASN1, UNSUPPORTED_TYPE);
-static int asn1_get_length(const unsigned char **pp,int *inf,long *rl,int max);
+static int asn1_get_length(const unsigned char **pp, int *inf, long *rl,
+ long max);
static void asn1_put_length(unsigned char **pp, int length);
static int _asn1_check_infinite_end(const unsigned char **p, long len)
- {
- /* If there is 0 or 1 byte left, the length check should pick
- * things up */
- if (len <= 0)
- return(1);
- else if ((len >= 2) && ((*p)[0] == 0) && ((*p)[1] == 0))
- {
- (*p)+=2;
- return(1);
- }
- return(0);
- }
+{
+ /*
+ * If there is 0 or 1 byte left, the length check should pick things up
+ */
+ if (len <= 0)
+ return (1);
+ else if ((len >= 2) && ((*p)[0] == 0) && ((*p)[1] == 0)) {
+ (*p) += 2;
+ return (1);
+ }
+ return (0);
+}
int ASN1_check_infinite_end(unsigned char **p, long len)
- {
- return _asn1_check_infinite_end((const unsigned char **)p, len);
- }
+{
+ return _asn1_check_infinite_end((const unsigned char **)p, len);
+}
int ASN1_const_check_infinite_end(const unsigned char **p, long len)
- {
- return _asn1_check_infinite_end(p, len);
- }
-
+{
+ return _asn1_check_infinite_end(p, len);
+}
int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
- int *pclass, long omax)
- {
- int i,ret;
- long l;
- const unsigned char *p= *pp;
- int tag,xclass,inf;
- long max=omax;
-
- if (!max) goto err;
- ret=(*p&V_ASN1_CONSTRUCTED);
- xclass=(*p&V_ASN1_PRIVATE);
- i= *p&V_ASN1_PRIMITIVE_TAG;
- if (i == V_ASN1_PRIMITIVE_TAG)
- { /* high-tag */
- p++;
- if (--max == 0) goto err;
- l=0;
- while (*p&0x80)
- {
- l<<=7L;
- l|= *(p++)&0x7f;
- if (--max == 0) goto err;
- if (l > (INT_MAX >> 7L)) goto err;
- }
- l<<=7L;
- l|= *(p++)&0x7f;
- tag=(int)l;
- if (--max == 0) goto err;
- }
- else
- {
- tag=i;
- p++;
- if (--max == 0) goto err;
- }
- *ptag=tag;
- *pclass=xclass;
- if (!asn1_get_length(&p,&inf,plength,(int)max)) goto err;
-
- if (inf && !(ret & V_ASN1_CONSTRUCTED))
- goto err;
+ int *pclass, long omax)
+{
+ int i, ret;
+ long l;
+ const unsigned char *p = *pp;
+ int tag, xclass, inf;
+ long max = omax;
+
+ if (!max)
+ goto err;
+ ret = (*p & V_ASN1_CONSTRUCTED);
+ xclass = (*p & V_ASN1_PRIVATE);
+ i = *p & V_ASN1_PRIMITIVE_TAG;
+ if (i == V_ASN1_PRIMITIVE_TAG) { /* high-tag */
+ p++;
+ if (--max == 0)
+ goto err;
+ l = 0;
+ while (*p & 0x80) {
+ l <<= 7L;
+ l |= *(p++) & 0x7f;
+ if (--max == 0)
+ goto err;
+ if (l > (INT_MAX >> 7L))
+ goto err;
+ }
+ l <<= 7L;
+ l |= *(p++) & 0x7f;
+ tag = (int)l;
+ if (--max == 0)
+ goto err;
+ } else {
+ tag = i;
+ p++;
+ if (--max == 0)
+ goto err;
+ }
+
+ /* To avoid ambiguity with V_ASN1_NEG, impose a limit on universal tags. */
+ if (xclass == V_ASN1_UNIVERSAL && tag > V_ASN1_MAX_UNIVERSAL)
+ goto err;
+
+ *ptag = tag;
+ *pclass = xclass;
+ if (!asn1_get_length(&p, &inf, plength, max))
+ goto err;
+
+ if (inf && !(ret & V_ASN1_CONSTRUCTED))
+ goto err;
#if 0
- fprintf(stderr,"p=%d + *plength=%ld > omax=%ld + *pp=%d (%d > %d)\n",
- (int)p,*plength,omax,(int)*pp,(int)(p+ *plength),
- (int)(omax+ *pp));
+ fprintf(stderr, "p=%d + *plength=%ld > omax=%ld + *pp=%d (%d > %d)\n",
+ (int)p, *plength, omax, (int)*pp, (int)(p + *plength),
+ (int)(omax + *pp));
#endif
- if (*plength > (omax - (p - *pp)))
- {
- 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;
- }
- *pp=p;
- return(ret|inf);
-err:
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_HEADER_TOO_LONG);
- return(0x80);
- }
-
-static int asn1_get_length(const unsigned char **pp, int *inf, long *rl, int max)
- {
- const unsigned char *p= *pp;
- unsigned long ret=0;
- unsigned int i;
-
- if (max-- < 1) return(0);
- if (*p == 0x80)
- {
- *inf=1;
- ret=0;
- p++;
- }
- else
- {
- *inf=0;
- i= *p&0x7f;
- if (*(p++) & 0x80)
- {
- if (i > sizeof(long))
- return 0;
- if (max-- == 0) return(0);
- while (i-- > 0)
- {
- ret<<=8L;
- ret|= *(p++);
- if (max-- == 0) return(0);
- }
- }
- else
- ret=i;
- }
- if (ret > LONG_MAX)
- return 0;
- *pp=p;
- *rl=(long)ret;
- return(1);
- }
-
-/* class 0 is constructed
- * constructed == 2 for indefinite length constructed */
+ if (*plength > (omax - (p - *pp))) {
+ 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;
+ }
+ *pp = p;
+ return (ret | inf);
+ err:
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_HEADER_TOO_LONG);
+ return (0x80);
+}
+
+static int asn1_get_length(const unsigned char **pp, int *inf, long *rl,
+ long max)
+{
+ const unsigned char *p = *pp;
+ unsigned long ret = 0;
+ unsigned long i;
+
+ if (max-- < 1)
+ return 0;
+ if (*p == 0x80) {
+ *inf = 1;
+ ret = 0;
+ p++;
+ } else {
+ *inf = 0;
+ i = *p & 0x7f;
+ if (*(p++) & 0x80) {
+ if (i > sizeof(ret) || max < (long)i)
+ return 0;
+ while (i-- > 0) {
+ ret <<= 8L;
+ ret |= *(p++);
+ }
+ } else
+ ret = i;
+ }
+ if (ret > LONG_MAX)
+ return 0;
+ *pp = p;
+ *rl = (long)ret;
+ return 1;
+}
+
+/*
+ * class 0 is constructed constructed == 2 for indefinite length constructed
+ */
void ASN1_put_object(unsigned char **pp, int constructed, int length, int tag,
- int xclass)
- {
- unsigned char *p= *pp;
- int i, ttag;
-
- i=(constructed)?V_ASN1_CONSTRUCTED:0;
- i|=(xclass&V_ASN1_PRIVATE);
- if (tag < 31)
- *(p++)=i|(tag&V_ASN1_PRIMITIVE_TAG);
- else
- {
- *(p++)=i|V_ASN1_PRIMITIVE_TAG;
- for(i = 0, ttag = tag; ttag > 0; i++) ttag >>=7;
- ttag = i;
- while(i-- > 0)
- {
- p[i] = tag & 0x7f;
- if(i != (ttag - 1)) p[i] |= 0x80;
- tag >>= 7;
- }
- p += ttag;
- }
- if (constructed == 2)
- *(p++)=0x80;
- else
- asn1_put_length(&p,length);
- *pp=p;
- }
+ int xclass)
+{
+ unsigned char *p = *pp;
+ int i, ttag;
+
+ i = (constructed) ? V_ASN1_CONSTRUCTED : 0;
+ i |= (xclass & V_ASN1_PRIVATE);
+ if (tag < 31)
+ *(p++) = i | (tag & V_ASN1_PRIMITIVE_TAG);
+ else {
+ *(p++) = i | V_ASN1_PRIMITIVE_TAG;
+ for (i = 0, ttag = tag; ttag > 0; i++)
+ ttag >>= 7;
+ ttag = i;
+ while (i-- > 0) {
+ p[i] = tag & 0x7f;
+ if (i != (ttag - 1))
+ p[i] |= 0x80;
+ tag >>= 7;
+ }
+ p += ttag;
+ }
+ if (constructed == 2)
+ *(p++) = 0x80;
+ else
+ asn1_put_length(&p, length);
+ *pp = p;
+}
int ASN1_put_eoc(unsigned char **pp)
- {
- unsigned char *p = *pp;
- *p++ = 0;
- *p++ = 0;
- *pp = p;
- return 2;
- }
+{
+ unsigned char *p = *pp;
+ *p++ = 0;
+ *p++ = 0;
+ *pp = p;
+ return 2;
+}
static void asn1_put_length(unsigned char **pp, int length)
- {
- unsigned char *p= *pp;
- int i,l;
- if (length <= 127)
- *(p++)=(unsigned char)length;
- else
- {
- l=length;
- for (i=0; l > 0; i++)
- l>>=8;
- *(p++)=i|0x80;
- l=i;
- while (i-- > 0)
- {
- p[i]=length&0xff;
- length>>=8;
- }
- p+=l;
- }
- *pp=p;
- }
+{
+ unsigned char *p = *pp;
+ int i, l;
+ if (length <= 127)
+ *(p++) = (unsigned char)length;
+ else {
+ l = length;
+ for (i = 0; l > 0; i++)
+ l >>= 8;
+ *(p++) = i | 0x80;
+ l = i;
+ while (i-- > 0) {
+ p[i] = length & 0xff;
+ length >>= 8;
+ }
+ p += l;
+ }
+ *pp = p;
+}
int ASN1_object_size(int constructed, int length, int tag)
- {
- int ret;
-
- ret=length;
- ret++;
- if (tag >= 31)
- {
- while (tag > 0)
- {
- tag>>=7;
- ret++;
- }
- }
- if (constructed == 2)
- return ret + 3;
- ret++;
- if (length > 127)
- {
- while (length > 0)
- {
- length>>=8;
- ret++;
- }
- }
- return(ret);
- }
+{
+ int ret;
+
+ ret = length;
+ ret++;
+ if (tag >= 31) {
+ while (tag > 0) {
+ tag >>= 7;
+ ret++;
+ }
+ }
+ if (constructed == 2)
+ return ret + 3;
+ ret++;
+ if (length > 127) {
+ while (length > 0) {
+ length >>= 8;
+ ret++;
+ }
+ }
+ return (ret);
+}
static int _asn1_Finish(ASN1_const_CTX *c)
- {
- if ((c->inf == (1|V_ASN1_CONSTRUCTED)) && (!c->eos))
- {
- if (!ASN1_const_check_infinite_end(&c->p,c->slen))
- {
- c->error=ASN1_R_MISSING_ASN1_EOS;
- return(0);
- }
- }
- if ( ((c->slen != 0) && !(c->inf & 1)) ||
- ((c->slen < 0) && (c->inf & 1)))
- {
- c->error=ASN1_R_ASN1_LENGTH_MISMATCH;
- return(0);
- }
- return(1);
- }
+{
+ if ((c->inf == (1 | V_ASN1_CONSTRUCTED)) && (!c->eos)) {
+ if (!ASN1_const_check_infinite_end(&c->p, c->slen)) {
+ c->error = ASN1_R_MISSING_ASN1_EOS;
+ return (0);
+ }
+ }
+ if (((c->slen != 0) && !(c->inf & 1)) || ((c->slen < 0) && (c->inf & 1))) {
+ c->error = ASN1_R_ASN1_LENGTH_MISMATCH;
+ return (0);
+ }
+ return (1);
+}
int asn1_Finish(ASN1_CTX *c)
- {
- return _asn1_Finish((ASN1_const_CTX *)c);
- }
+{
+ return _asn1_Finish((ASN1_const_CTX *)c);
+}
int asn1_const_Finish(ASN1_const_CTX *c)
- {
- return _asn1_Finish(c);
- }
+{
+ return _asn1_Finish(c);
+}
int asn1_GetSequence(ASN1_const_CTX *c, long *length)
- {
- const unsigned char *q;
-
- q=c->p;
- c->inf=ASN1_get_object(&(c->p),&(c->slen),&(c->tag),&(c->xclass),
- *length);
- if (c->inf & 0x80)
- {
- c->error=ASN1_R_BAD_GET_ASN1_OBJECT_CALL;
- return(0);
- }
- if (c->tag != V_ASN1_SEQUENCE)
- {
- c->error=ASN1_R_EXPECTING_AN_ASN1_SEQUENCE;
- return(0);
- }
- (*length)-=(c->p-q);
- if (c->max && (*length < 0))
- {
- c->error=ASN1_R_ASN1_LENGTH_MISMATCH;
- return(0);
- }
- if (c->inf == (1|V_ASN1_CONSTRUCTED))
- c->slen= *length+ *(c->pp)-c->p;
- c->eos=0;
- return(1);
- }
+{
+ const unsigned char *q;
+
+ q = c->p;
+ c->inf = ASN1_get_object(&(c->p), &(c->slen), &(c->tag), &(c->xclass),
+ *length);
+ if (c->inf & 0x80) {
+ c->error = ASN1_R_BAD_GET_ASN1_OBJECT_CALL;
+ return (0);
+ }
+ if (c->tag != V_ASN1_SEQUENCE) {
+ c->error = ASN1_R_EXPECTING_AN_ASN1_SEQUENCE;
+ return (0);
+ }
+ (*length) -= (c->p - q);
+ if (c->max && (*length < 0)) {
+ c->error = ASN1_R_ASN1_LENGTH_MISMATCH;
+ return (0);
+ }
+ if (c->inf == (1 | V_ASN1_CONSTRUCTED))
+ c->slen = *length + *(c->pp) - c->p;
+ c->eos = 0;
+ return (1);
+}
int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str)
- {
- if (str == NULL)
- return 0;
- dst->type = str->type;
- if (!ASN1_STRING_set(dst,str->data,str->length))
- return 0;
- dst->flags = str->flags;
- return 1;
- }
+{
+ if (str == NULL)
+ return 0;
+ dst->type = str->type;
+ if (!ASN1_STRING_set(dst, str->data, str->length))
+ return 0;
+ dst->flags = str->flags;
+ return 1;
+}
ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *str)
- {
- ASN1_STRING *ret;
- if (!str)
- return NULL;
- ret=ASN1_STRING_new();
- if (!ret)
- return NULL;
- if (!ASN1_STRING_copy(ret,str))
- {
- ASN1_STRING_free(ret);
- return NULL;
- }
- return ret;
- }
+{
+ ASN1_STRING *ret;
+ if (!str)
+ return NULL;
+ ret = ASN1_STRING_new();
+ if (!ret)
+ return NULL;
+ if (!ASN1_STRING_copy(ret, str)) {
+ ASN1_STRING_free(ret);
+ return NULL;
+ }
+ return ret;
+}
int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len)
- {
- unsigned char *c;
- const char *data=_data;
-
- if (len < 0)
- {
- if (data == NULL)
- return(0);
- else
- len=strlen(data);
- }
- if ((str->length < len) || (str->data == NULL))
- {
- c=str->data;
- if (c == NULL)
- str->data=OPENSSL_malloc(len+1);
- else
- str->data=OPENSSL_realloc(c,len+1);
-
- if (str->data == NULL)
- {
- OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
- str->data=c;
- return(0);
- }
- }
- str->length=len;
- if (data != NULL)
- {
- memcpy(str->data,data,len);
- /* an allowance for strings :-) */
- str->data[len]='\0';
- }
- return(1);
- }
+{
+ unsigned char *c;
+ const char *data = _data;
+
+ if (len < 0) {
+ if (data == NULL)
+ return (0);
+ else
+ len = strlen(data);
+ }
+ if ((str->length < len) || (str->data == NULL)) {
+ c = str->data;
+ if (c == NULL)
+ str->data = OPENSSL_malloc(len + 1);
+ else
+ str->data = OPENSSL_realloc(c, len + 1);
+
+ if (str->data == NULL) {
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+ str->data = c;
+ return (0);
+ }
+ }
+ str->length = len;
+ if (data != NULL) {
+ memcpy(str->data, data, len);
+ /* an allowance for strings :-) */
+ str->data[len] = '\0';
+ }
+ return (1);
+}
void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len)
- {
- if (str->data)
- OPENSSL_free(str->data);
- str->data = data;
- str->length = len;
- }
+{
+ if (str->data)
+ OPENSSL_free(str->data);
+ str->data = data;
+ str->length = len;
+}
ASN1_STRING *ASN1_STRING_new(void)
- {
- return(ASN1_STRING_type_new(V_ASN1_OCTET_STRING));
- }
-
+{
+ return (ASN1_STRING_type_new(V_ASN1_OCTET_STRING));
+}
ASN1_STRING *ASN1_STRING_type_new(int type)
- {
- ASN1_STRING *ret;
-
- ret=(ASN1_STRING *)OPENSSL_malloc(sizeof(ASN1_STRING));
- if (ret == NULL)
- {
- OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
- return(NULL);
- }
- ret->length=0;
- ret->type=type;
- ret->data=NULL;
- ret->flags=0;
- return(ret);
- }
+{
+ ASN1_STRING *ret;
+
+ ret = (ASN1_STRING *)OPENSSL_malloc(sizeof(ASN1_STRING));
+ if (ret == NULL) {
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+ ret->length = 0;
+ ret->type = type;
+ ret->data = NULL;
+ ret->flags = 0;
+ return (ret);
+}
void ASN1_STRING_free(ASN1_STRING *a)
- {
- if (a == NULL) return;
- if (a->data && !(a->flags & ASN1_STRING_FLAG_NDEF))
- OPENSSL_free(a->data);
- OPENSSL_free(a);
- }
+{
+ if (a == NULL)
+ return;
+ if (a->data && !(a->flags & ASN1_STRING_FLAG_NDEF))
+ OPENSSL_free(a->data);
+ OPENSSL_free(a);
+}
int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
- {
- int i;
-
- i=(a->length-b->length);
- if (i == 0)
- {
- i=memcmp(a->data,b->data,a->length);
- if (i == 0)
- return(a->type-b->type);
- else
- return(i);
- }
- else
- return(i);
- }
+{
+ int i;
+
+ i = (a->length - b->length);
+ if (i == 0) {
+ i = memcmp(a->data, b->data, a->length);
+ if (i == 0)
+ return (a->type - b->type);
+ else
+ return (i);
+ } else
+ return (i);
+}
int ASN1_STRING_length(const ASN1_STRING *x)
-{ return M_ASN1_STRING_length(x); }
+{
+ return M_ASN1_STRING_length(x);
+}
void ASN1_STRING_length_set(ASN1_STRING *x, int len)
-{ M_ASN1_STRING_length_set(x, len); return; }
+{
+ M_ASN1_STRING_length_set(x, len);
+ return;
+}
int ASN1_STRING_type(ASN1_STRING *x)
-{ return M_ASN1_STRING_type(x); }
-
-unsigned char * ASN1_STRING_data(ASN1_STRING *x)
-{ return M_ASN1_STRING_data(x); }
+{
+ return M_ASN1_STRING_type(x);
+}
+
+unsigned char *ASN1_STRING_data(ASN1_STRING *x)
+{
+ return M_ASN1_STRING_data(x);
+}
diff --git a/src/crypto/asn1/asn1_locl.h b/src/crypto/asn1/asn1_locl.h
index ca5f6120..49eceb6b 100644
--- a/src/crypto/asn1/asn1_locl.h
+++ b/src/crypto/asn1/asn1_locl.h
@@ -1,6 +1,7 @@
/* asn1t.h */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2006.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2006.
*/
/* ====================================================================
* Copyright (c) 2006 The OpenSSL Project. All rights reserved.
@@ -10,7 +11,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -63,11 +64,10 @@ int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d);
/* ASN1 print context structure */
-struct asn1_pctx_st
- {
- unsigned long flags;
- unsigned long nm_flags;
- unsigned long cert_flags;
- unsigned long oid_flags;
- unsigned long str_flags;
- } /* ASN1_PCTX */;
+struct asn1_pctx_st {
+ unsigned long flags;
+ unsigned long nm_flags;
+ unsigned long cert_flags;
+ unsigned long oid_flags;
+ unsigned long str_flags;
+} /* ASN1_PCTX */ ;
diff --git a/src/crypto/asn1/asn1_par.c b/src/crypto/asn1/asn1_par.c
index e04aa1e7..d1f66402 100644
--- a/src/crypto/asn1/asn1_par.c
+++ b/src/crypto/asn1/asn1_par.c
@@ -60,385 +60,352 @@
#include <openssl/err.h>
#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_print_info(BIO *bp, int tag, int xclass, int constructed,
+ int indent);
static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
- int offset, int depth, int indent, int dump);
+ int offset, int depth, int indent, int dump);
static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed,
- int indent)
- {
- static const char fmt[]="%-18s";
- char str[128];
- const char *p;
+ int indent)
+{
+ static const char fmt[] = "%-18s";
+ char str[128];
+ const char *p;
- if (constructed & V_ASN1_CONSTRUCTED)
- p="cons: ";
- else
- p="prim: ";
- if (BIO_write(bp,p,6) < 6) goto err;
- BIO_indent(bp,indent,128);
+ if (constructed & V_ASN1_CONSTRUCTED)
+ p = "cons: ";
+ else
+ p = "prim: ";
+ if (BIO_write(bp, p, 6) < 6)
+ goto err;
+ BIO_indent(bp, indent, 128);
- p=str;
- if ((xclass & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
- BIO_snprintf(str,sizeof str,"priv [ %d ] ",tag);
- else if ((xclass & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
- BIO_snprintf(str,sizeof str,"cont [ %d ]",tag);
- else if ((xclass & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
- BIO_snprintf(str,sizeof str,"appl [ %d ]",tag);
- else if (tag > 30)
- BIO_snprintf(str,sizeof str,"<ASN1 %d>",tag);
- else
- p = ASN1_tag2str(tag);
+ p = str;
+ if ((xclass & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
+ BIO_snprintf(str, sizeof str, "priv [ %d ] ", tag);
+ else if ((xclass & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
+ BIO_snprintf(str, sizeof str, "cont [ %d ]", tag);
+ else if ((xclass & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
+ BIO_snprintf(str, sizeof str, "appl [ %d ]", tag);
+ else if (tag > 30)
+ BIO_snprintf(str, sizeof str, "<ASN1 %d>", tag);
+ else
+ p = ASN1_tag2str(tag);
- if (BIO_printf(bp,fmt,p) <= 0)
- goto err;
- return(1);
-err:
- return(0);
- }
+ if (BIO_printf(bp, fmt, p) <= 0)
+ goto err;
+ return (1);
+ err:
+ return (0);
+}
int ASN1_parse(BIO *bp, const unsigned char *pp, long len, int indent)
- {
- return(asn1_parse2(bp,&pp,len,0,0,indent,0));
- }
+{
+ return (asn1_parse2(bp, &pp, len, 0, 0, indent, 0));
+}
-int ASN1_parse_dump(BIO *bp, const unsigned char *pp, long len, int indent, int dump)
- {
- return(asn1_parse2(bp,&pp,len,0,0,indent,dump));
- }
+int ASN1_parse_dump(BIO *bp, const unsigned char *pp, long len, int indent,
+ int dump)
+{
+ return (asn1_parse2(bp, &pp, len, 0, 0, indent, dump));
+}
-static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offset,
- int depth, int indent, int dump)
- {
- const unsigned char *p,*ep,*tot,*op,*opp;
- long len;
- int tag,xclass,ret=0;
- int nl,hl,j,r;
- ASN1_OBJECT *o=NULL;
- ASN1_OCTET_STRING *os=NULL;
- /* ASN1_BMPSTRING *bmp=NULL;*/
- int dump_indent;
+static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
+ int offset, int depth, int indent, int dump)
+{
+ const unsigned char *p, *ep, *tot, *op, *opp;
+ long len;
+ int tag, xclass, ret = 0;
+ int nl, hl, j, r;
+ ASN1_OBJECT *o = NULL;
+ ASN1_OCTET_STRING *os = NULL;
+ /* ASN1_BMPSTRING *bmp=NULL; */
+ int dump_indent;
#if 0
- dump_indent = indent;
+ dump_indent = indent;
#else
- dump_indent = 6; /* Because we know BIO_dump_indent() */
+ dump_indent = 6; /* Because we know BIO_dump_indent() */
#endif
- if (depth > ASN1_PARSE_MAXDEPTH)
- {
- BIO_puts(bp, "BAD RECURSION DEPTH\n");
- return 0;
- }
+ if (depth > ASN1_PARSE_MAXDEPTH) {
+ BIO_puts(bp, "BAD RECURSION DEPTH\n");
+ return 0;
+ }
- p= *pp;
- tot=p+length;
- op=p-1;
- while ((p < tot) && (op < p))
- {
- op=p;
- j=ASN1_get_object(&p,&len,&tag,&xclass,length);
+ p = *pp;
+ tot = p + length;
+ op = p - 1;
+ while ((p < tot) && (op < p)) {
+ op = p;
+ j = ASN1_get_object(&p, &len, &tag, &xclass, length);
#ifdef LINT
- j=j;
+ j = j;
#endif
- if (j & 0x80)
- {
- if (BIO_puts(bp, "Error in encoding\n") <= 0)
- goto end;
- ret=0;
- goto end;
- }
- hl=(p-op);
- length-=hl;
- /* if j == 0x21 it is a constructed indefinite length object */
- if (BIO_printf(bp,"%5ld:",(long)offset+(long)(op- *pp))
- <= 0) goto end;
+ if (j & 0x80) {
+ if (BIO_puts(bp, "Error in encoding\n") <= 0)
+ goto end;
+ ret = 0;
+ goto end;
+ }
+ hl = (p - op);
+ length -= hl;
+ /*
+ * if j == 0x21 it is a constructed indefinite length object
+ */
+ if (BIO_printf(bp, "%5ld:", (long)offset + (long)(op - *pp))
+ <= 0)
+ goto end;
+
+ if (j != (V_ASN1_CONSTRUCTED | 1)) {
+ if (BIO_printf(bp, "d=%-2d hl=%ld l=%4ld ",
+ depth, (long)hl, len) <= 0)
+ goto end;
+ } else {
+ if (BIO_printf(bp, "d=%-2d hl=%ld l=inf ", depth, (long)hl) <= 0)
+ goto end;
+ }
+ if (!asn1_print_info(bp, tag, xclass, j, (indent) ? depth : 0))
+ goto end;
+ if (j & V_ASN1_CONSTRUCTED) {
+ const unsigned char *sp;
- if (j != (V_ASN1_CONSTRUCTED | 1))
- {
- if (BIO_printf(bp,"d=%-2d hl=%ld l=%4ld ",
- depth,(long)hl,len) <= 0)
- goto end;
- }
- else
- {
- if (BIO_printf(bp,"d=%-2d hl=%ld l=inf ",
- depth,(long)hl) <= 0)
- goto end;
- }
- if (!asn1_print_info(bp,tag,xclass,j,(indent)?depth:0))
- goto end;
- if (j & V_ASN1_CONSTRUCTED)
- {
- ep=p+len;
- if (BIO_puts(bp, "\n") <= 0) goto end;
- if (len > length)
- {
- BIO_printf(bp,
- "length is greater than %ld\n",length);
- ret=0;
- goto end;
- }
- if ((j == 0x21) && (len == 0))
- {
- for (;;)
- {
- r=asn1_parse2(bp,&p,(long)(tot-p),
- offset+(p - *pp),depth+1,
- indent,dump);
- if (r == 0) { ret=0; goto end; }
- if ((r == 2) || (p >= tot)) break;
- }
- }
- else
- while (p < ep)
- {
- r=asn1_parse2(bp,&p,(long)len,
- offset+(p - *pp),depth+1,
- indent,dump);
- if (r == 0) { ret=0; goto end; }
- }
- }
- else if (xclass != 0)
- {
- p+=len;
- if (BIO_puts(bp, "\n") <= 0) goto end;
- }
- else
- {
- nl=0;
- if ( (tag == V_ASN1_PRINTABLESTRING) ||
- (tag == V_ASN1_T61STRING) ||
- (tag == V_ASN1_IA5STRING) ||
- (tag == V_ASN1_VISIBLESTRING) ||
- (tag == V_ASN1_NUMERICSTRING) ||
- (tag == V_ASN1_UTF8STRING) ||
- (tag == V_ASN1_UTCTIME) ||
- (tag == V_ASN1_GENERALIZEDTIME))
- {
- if (BIO_puts(bp, ":") <= 0) goto end;
- if ((len > 0) &&
- BIO_write(bp,(const char *)p,(int)len)
- != (int)len)
- goto end;
- }
- else if (tag == V_ASN1_OBJECT)
- {
- opp=op;
- if (d2i_ASN1_OBJECT(&o,&opp,len+hl) != NULL)
- {
- if (BIO_puts(bp, ":") <= 0) goto end;
- i2a_ASN1_OBJECT(bp,o);
- }
- else
- {
- if (BIO_puts(bp, ":BAD OBJECT") <= 0)
- goto end;
- }
- }
- else if (tag == V_ASN1_BOOLEAN)
- {
- int ii;
+ ep = p + len;
+ if (BIO_puts(bp, "\n") <= 0)
+ goto end;
+ if (len > length) {
+ BIO_printf(bp, "length is greater than %ld\n", length);
+ ret = 0;
+ goto end;
+ }
+ if ((j == 0x21) && (len == 0)) {
+ sp = p;
+ for (;;) {
+ r = asn1_parse2(bp, &p, (long)(tot - p),
+ offset + (p - *pp), depth + 1,
+ indent, dump);
+ if (r == 0) {
+ ret = 0;
+ goto end;
+ }
+ if ((r == 2) || (p >= tot)) {
+ len = p - sp;
+ break;
+ }
+ }
+ } else {
+ long tmp = len;
- opp=op;
- ii=d2i_ASN1_BOOLEAN(NULL,&opp,len+hl);
- if (ii < 0)
- {
- if (BIO_puts(bp, "Bad boolean\n") <= 0)
- goto end;
- }
- BIO_printf(bp,":%d",ii);
- }
- else if (tag == V_ASN1_BMPSTRING)
- {
- /* do the BMP thang */
- }
- else if (tag == V_ASN1_OCTET_STRING)
- {
- int i,printable=1;
+ while (p < ep) {
+ sp = p;
+ r = asn1_parse2(bp, &p, tmp, offset + (p - *pp), depth + 1,
+ indent, dump);
+ if (r == 0) {
+ ret = 0;
+ goto end;
+ }
+ tmp -= p - sp;
+ }
+ }
+ } else if (xclass != 0) {
+ p += len;
+ if (BIO_puts(bp, "\n") <= 0)
+ goto end;
+ } else {
+ nl = 0;
+ if ((tag == V_ASN1_PRINTABLESTRING) ||
+ (tag == V_ASN1_T61STRING) ||
+ (tag == V_ASN1_IA5STRING) ||
+ (tag == V_ASN1_VISIBLESTRING) ||
+ (tag == V_ASN1_NUMERICSTRING) ||
+ (tag == V_ASN1_UTF8STRING) ||
+ (tag == V_ASN1_UTCTIME) || (tag == V_ASN1_GENERALIZEDTIME)) {
+ if (BIO_puts(bp, ":") <= 0)
+ goto end;
+ if ((len > 0) && BIO_write(bp, (const char *)p, (int)len)
+ != (int)len)
+ goto end;
+ } else if (tag == V_ASN1_OBJECT) {
+ opp = op;
+ if (d2i_ASN1_OBJECT(&o, &opp, len + hl) != NULL) {
+ if (BIO_puts(bp, ":") <= 0)
+ goto end;
+ i2a_ASN1_OBJECT(bp, o);
+ } else {
+ if (BIO_puts(bp, ":BAD OBJECT") <= 0)
+ goto end;
+ }
+ } else if (tag == V_ASN1_BOOLEAN) {
+ int ii;
- opp=op;
- os=d2i_ASN1_OCTET_STRING(NULL,&opp,len+hl);
- if (os != NULL && os->length > 0)
- {
- opp = os->data;
- /* testing whether the octet string is
- * printable */
- for (i=0; i<os->length; i++)
- {
- if (( (opp[i] < ' ') &&
- (opp[i] != '\n') &&
- (opp[i] != '\r') &&
- (opp[i] != '\t')) ||
- (opp[i] > '~'))
- {
- printable=0;
- break;
- }
- }
- if (printable)
- /* printable string */
- {
- if (BIO_puts(bp, ":") <= 0)
- goto end;
- if (BIO_write(bp,(const char *)opp,
- os->length) <= 0)
- goto end;
- }
- else if (!dump)
- /* not printable => print octet string
- * as hex dump */
- {
- if (BIO_puts(bp, "[HEX DUMP]:") <= 0)
- goto end;
- for (i=0; i<os->length; i++)
- {
- if (BIO_printf(bp,"%02X"
- , opp[i]) <= 0)
- goto end;
- }
- }
- else
- /* print the normal dump */
- {
- if (!nl)
- {
- if (BIO_puts(bp, "\n") <= 0)
- goto end;
- }
- if (!BIO_hexdump(bp, opp,
- ((dump == -1 || dump >
- os->length)?os->length:dump),
- dump_indent))
- goto end;
- nl=1;
- }
- }
- if (os != NULL)
- {
- M_ASN1_OCTET_STRING_free(os);
- os=NULL;
- }
- }
- else if (tag == V_ASN1_INTEGER)
- {
- ASN1_INTEGER *bs;
- int i;
+ opp = op;
+ ii = d2i_ASN1_BOOLEAN(NULL, &opp, len + hl);
+ if (ii < 0) {
+ if (BIO_puts(bp, "Bad boolean\n") <= 0)
+ goto end;
+ }
+ BIO_printf(bp, ":%d", ii);
+ } else if (tag == V_ASN1_BMPSTRING) {
+ /* do the BMP thang */
+ } else if (tag == V_ASN1_OCTET_STRING) {
+ int i, printable = 1;
- opp=op;
- bs=d2i_ASN1_INTEGER(NULL,&opp,len+hl);
- if (bs != NULL)
- {
- if (BIO_puts(bp, ":") <= 0) goto end;
- if (bs->type == V_ASN1_NEG_INTEGER)
- if (BIO_puts(bp, "-") <= 0)
- goto end;
- for (i=0; i<bs->length; i++)
- {
- if (BIO_printf(bp,"%02X",
- bs->data[i]) <= 0)
- goto end;
- }
- if (bs->length == 0)
- {
- if (BIO_puts(bp, "00") <= 0)
- goto end;
- }
- }
- else
- {
- if (BIO_puts(bp, "BAD INTEGER") <= 0)
- goto end;
- }
- M_ASN1_INTEGER_free(bs);
- }
- else if (tag == V_ASN1_ENUMERATED)
- {
- ASN1_ENUMERATED *bs;
- int i;
+ opp = op;
+ os = d2i_ASN1_OCTET_STRING(NULL, &opp, len + hl);
+ if (os != NULL && os->length > 0) {
+ opp = os->data;
+ /*
+ * testing whether the octet string is printable
+ */
+ for (i = 0; i < os->length; i++) {
+ if (((opp[i] < ' ') &&
+ (opp[i] != '\n') &&
+ (opp[i] != '\r') &&
+ (opp[i] != '\t')) || (opp[i] > '~')) {
+ printable = 0;
+ break;
+ }
+ }
+ if (printable)
+ /* printable string */
+ {
+ if (BIO_puts(bp, ":") <= 0)
+ goto end;
+ if (BIO_write(bp, (const char *)opp, os->length) <= 0)
+ goto end;
+ } else if (!dump)
+ /*
+ * not printable => print octet string as hex dump
+ */
+ {
+ if (BIO_puts(bp, "[HEX DUMP]:") <= 0)
+ goto end;
+ for (i = 0; i < os->length; i++) {
+ if (BIO_printf(bp, "%02X", opp[i]) <= 0)
+ goto end;
+ }
+ } else
+ /* print the normal dump */
+ {
+ if (!nl) {
+ if (BIO_puts(bp, "\n") <= 0)
+ goto end;
+ }
+ if (!BIO_hexdump(bp, opp,
+ ((dump == -1 || dump >
+ os->length) ? os->length : dump),
+ dump_indent))
+ goto end;
+ nl = 1;
+ }
+ }
+ if (os != NULL) {
+ M_ASN1_OCTET_STRING_free(os);
+ os = NULL;
+ }
+ } else if (tag == V_ASN1_INTEGER) {
+ ASN1_INTEGER *bs;
+ int i;
- opp=op;
- bs=d2i_ASN1_ENUMERATED(NULL,&opp,len+hl);
- if (bs != NULL)
- {
- if (BIO_puts(bp, ":") <= 0) goto end;
- if (bs->type == V_ASN1_NEG_ENUMERATED)
- if (BIO_puts(bp, "-") <= 0)
- goto end;
- for (i=0; i<bs->length; i++)
- {
- if (BIO_printf(bp,"%02X",
- bs->data[i]) <= 0)
- goto end;
- }
- if (bs->length == 0)
- {
- if (BIO_puts(bp, "00") <= 0)
- goto end;
- }
- }
- else
- {
- if (BIO_puts(bp, "BAD ENUMERATED") <= 0)
- goto end;
- }
- M_ASN1_ENUMERATED_free(bs);
- }
- else if (len > 0 && dump)
- {
- if (!nl)
- {
- if (BIO_puts(bp, "\n") <= 0)
- goto end;
- }
- if (!BIO_hexdump(bp,p,
- ((dump == -1 || dump > len)?len:dump),
- dump_indent))
- goto end;
- nl=1;
- }
+ opp = op;
+ bs = d2i_ASN1_INTEGER(NULL, &opp, len + hl);
+ if (bs != NULL) {
+ if (BIO_puts(bp, ":") <= 0)
+ goto end;
+ if (bs->type == V_ASN1_NEG_INTEGER)
+ if (BIO_puts(bp, "-") <= 0)
+ goto end;
+ for (i = 0; i < bs->length; i++) {
+ if (BIO_printf(bp, "%02X", bs->data[i]) <= 0)
+ goto end;
+ }
+ if (bs->length == 0) {
+ if (BIO_puts(bp, "00") <= 0)
+ goto end;
+ }
+ } else {
+ if (BIO_puts(bp, "BAD INTEGER") <= 0)
+ goto end;
+ }
+ M_ASN1_INTEGER_free(bs);
+ } else if (tag == V_ASN1_ENUMERATED) {
+ ASN1_ENUMERATED *bs;
+ int i;
- if (!nl)
- {
- if (BIO_puts(bp, "\n") <= 0) goto end;
- }
- p+=len;
- if ((tag == V_ASN1_EOC) && (xclass == 0))
- {
- ret=2; /* End of sequence */
- goto end;
- }
- }
- length-=len;
- }
- ret=1;
-end:
- if (o != NULL) ASN1_OBJECT_free(o);
- if (os != NULL) M_ASN1_OCTET_STRING_free(os);
- *pp=p;
- return(ret);
- }
+ opp = op;
+ bs = d2i_ASN1_ENUMERATED(NULL, &opp, len + hl);
+ if (bs != NULL) {
+ if (BIO_puts(bp, ":") <= 0)
+ goto end;
+ if (bs->type == V_ASN1_NEG_ENUMERATED)
+ if (BIO_puts(bp, "-") <= 0)
+ goto end;
+ for (i = 0; i < bs->length; i++) {
+ if (BIO_printf(bp, "%02X", bs->data[i]) <= 0)
+ goto end;
+ }
+ if (bs->length == 0) {
+ if (BIO_puts(bp, "00") <= 0)
+ goto end;
+ }
+ } else {
+ if (BIO_puts(bp, "BAD ENUMERATED") <= 0)
+ goto end;
+ }
+ M_ASN1_ENUMERATED_free(bs);
+ } else if (len > 0 && dump) {
+ if (!nl) {
+ if (BIO_puts(bp, "\n") <= 0)
+ goto end;
+ }
+ if (!BIO_hexdump(bp, p,
+ ((dump == -1 || dump > len) ? len : dump),
+ dump_indent))
+ goto end;
+ nl = 1;
+ }
+
+ if (!nl) {
+ if (BIO_puts(bp, "\n") <= 0)
+ goto end;
+ }
+ p += len;
+ if ((tag == V_ASN1_EOC) && (xclass == 0)) {
+ ret = 2; /* End of sequence */
+ goto end;
+ }
+ }
+ length -= len;
+ }
+ ret = 1;
+ end:
+ if (o != NULL)
+ ASN1_OBJECT_free(o);
+ if (os != NULL)
+ M_ASN1_OCTET_STRING_free(os);
+ *pp = p;
+ return (ret);
+}
const char *ASN1_tag2str(int tag)
{
- static const char * const tag2str[] = {
- "EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING", /* 0-4 */
- "NULL", "OBJECT", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL", /* 5-9 */
- "ENUMERATED", "<ASN1 11>", "UTF8STRING", "<ASN1 13>", /* 10-13 */
- "<ASN1 14>", "<ASN1 15>", "SEQUENCE", "SET", /* 15-17 */
- "NUMERICSTRING", "PRINTABLESTRING", "T61STRING", /* 18-20 */
- "VIDEOTEXSTRING", "IA5STRING", "UTCTIME","GENERALIZEDTIME", /* 21-24 */
- "GRAPHICSTRING", "VISIBLESTRING", "GENERALSTRING", /* 25-27 */
- "UNIVERSALSTRING", "<ASN1 29>", "BMPSTRING" /* 28-30 */
- };
+ static const char *const tag2str[] = {
+ "EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING", /* 0-4 */
+ "NULL", "OBJECT", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL", /* 5-9 */
+ "ENUMERATED", "<ASN1 11>", "UTF8STRING", "<ASN1 13>", /* 10-13 */
+ "<ASN1 14>", "<ASN1 15>", "SEQUENCE", "SET", /* 15-17 */
+ "NUMERICSTRING", "PRINTABLESTRING", "T61STRING", /* 18-20 */
+ "VIDEOTEXSTRING", "IA5STRING", "UTCTIME", "GENERALIZEDTIME", /* 21-24
+ */
+ "GRAPHICSTRING", "VISIBLESTRING", "GENERALSTRING", /* 25-27 */
+ "UNIVERSALSTRING", "<ASN1 29>", "BMPSTRING" /* 28-30 */
+ };
- if((tag == V_ASN1_NEG_INTEGER) || (tag == V_ASN1_NEG_ENUMERATED))
- tag &= ~0x100;
+ if ((tag == V_ASN1_NEG_INTEGER) || (tag == V_ASN1_NEG_ENUMERATED))
+ tag &= ~0x100;
- if(tag < 0 || tag > 30) return "(unknown)";
- return tag2str[tag];
+ if (tag < 0 || tag > 30)
+ return "(unknown)";
+ return tag2str[tag];
}
-
diff --git a/src/crypto/asn1/asn1_test.cc b/src/crypto/asn1/asn1_test.cc
new file mode 100644
index 00000000..8b024427
--- /dev/null
+++ b/src/crypto/asn1/asn1_test.cc
@@ -0,0 +1,81 @@
+/* Copyright (c) 2016, 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 <openssl/asn1.h>
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+
+#include "../test/scoped_types.h"
+
+
+// kTag128 is an ASN.1 structure with a universal tag with number 128.
+static const uint8_t kTag128[] = {
+ 0x1f, 0x81, 0x00, 0x01, 0x00,
+};
+
+// kTag258 is an ASN.1 structure with a universal tag with number 258.
+static const uint8_t kTag258[] = {
+ 0x1f, 0x82, 0x02, 0x01, 0x00,
+};
+
+static_assert(V_ASN1_NEG_INTEGER == 258,
+ "V_ASN1_NEG_INTEGER changed. Update kTag258 to collide with it.");
+
+// kTagOverflow is an ASN.1 structure with a universal tag with number 2^35-1,
+// which will not fit in an int.
+static const uint8_t kTagOverflow[] = {
+ 0x1f, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x01, 0x00,
+};
+
+static bool TestLargeTags() {
+ const uint8_t *p = kTag258;
+ ScopedASN1_TYPE obj(d2i_ASN1_TYPE(NULL, &p, sizeof(kTag258)));
+ if (obj) {
+ fprintf(stderr, "Parsed value with illegal tag (type = %d).\n", obj->type);
+ return false;
+ }
+ ERR_clear_error();
+
+ p = kTagOverflow;
+ obj.reset(d2i_ASN1_TYPE(NULL, &p, sizeof(kTagOverflow)));
+ if (obj) {
+ fprintf(stderr, "Parsed value with tag overflow (type = %d).\n", obj->type);
+ return false;
+ }
+ ERR_clear_error();
+
+ p = kTag128;
+ obj.reset(d2i_ASN1_TYPE(NULL, &p, sizeof(kTag128)));
+ if (!obj || obj->type != 128 || obj->value.asn1_string->length != 1 ||
+ obj->value.asn1_string->data[0] != 0) {
+ fprintf(stderr, "Failed to parse value with tag 128.\n");
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ return true;
+}
+
+int main() {
+ CRYPTO_library_init();
+
+ if (!TestLargeTags()) {
+ return 1;
+ }
+
+ printf("PASS\n");
+ return 0;
+}
diff --git a/src/crypto/asn1/asn_pack.c b/src/crypto/asn1/asn_pack.c
index e842a10d..eff54e55 100644
--- a/src/crypto/asn1/asn_pack.c
+++ b/src/crypto/asn1/asn_pack.c
@@ -59,46 +59,47 @@
#include <openssl/err.h>
#include <openssl/mem.h>
-
/* ASN1_ITEM versions of the above */
ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_STRING **oct)
{
- ASN1_STRING *octmp;
+ ASN1_STRING *octmp;
+
+ if (!oct || !*oct) {
+ if (!(octmp = ASN1_STRING_new())) {
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ if (oct)
+ *oct = octmp;
+ } else
+ octmp = *oct;
- if (!oct || !*oct) {
- if (!(octmp = ASN1_STRING_new ())) {
- OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
- if (oct) *oct = octmp;
- } else octmp = *oct;
+ if (octmp->data) {
+ OPENSSL_free(octmp->data);
+ octmp->data = NULL;
+ }
- if(octmp->data) {
- OPENSSL_free(octmp->data);
- octmp->data = NULL;
- }
-
- if (!(octmp->length = ASN1_item_i2d(obj, &octmp->data, it))) {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_ENCODE_ERROR);
- return NULL;
- }
- if (!octmp->data) {
- OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
- return octmp;
+ if (!(octmp->length = ASN1_item_i2d(obj, &octmp->data, it))) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ENCODE_ERROR);
+ return NULL;
+ }
+ if (!octmp->data) {
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ return octmp;
}
/* Extract an ASN1 object from an ASN1_STRING */
void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it)
{
- const unsigned char *p;
- void *ret;
+ const unsigned char *p;
+ void *ret;
- p = oct->data;
- if(!(ret = ASN1_item_d2i(NULL, &p, oct->length, it)))
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR);
- return ret;
+ p = oct->data;
+ if (!(ret = ASN1_item_d2i(NULL, &p, oct->length, it)))
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR);
+ return ret;
}
diff --git a/src/crypto/asn1/bio_asn1.c b/src/crypto/asn1/bio_asn1.c
index 15f233be..03cc9a6e 100644
--- a/src/crypto/asn1/bio_asn1.c
+++ b/src/crypto/asn1/bio_asn1.c
@@ -62,53 +62,48 @@
#include <openssl/bio.h>
#include <openssl/mem.h>
-
/* Must be large enough for biggest tag+length */
#define DEFAULT_ASN1_BUF_SIZE 20
-typedef enum
- {
- ASN1_STATE_START,
- ASN1_STATE_PRE_COPY,
- ASN1_STATE_HEADER,
- ASN1_STATE_HEADER_COPY,
- ASN1_STATE_DATA_COPY,
- ASN1_STATE_POST_COPY,
- ASN1_STATE_DONE
- } asn1_bio_state_t;
-
-typedef struct BIO_ASN1_EX_FUNCS_st
- {
- asn1_ps_func *ex_func;
- asn1_ps_func *ex_free_func;
- } BIO_ASN1_EX_FUNCS;
-
-typedef struct BIO_ASN1_BUF_CTX_t
- {
- /* Internal state */
- asn1_bio_state_t state;
- /* Internal buffer */
- unsigned char *buf;
- /* Size of buffer */
- int bufsize;
- /* Current position in buffer */
- int bufpos;
- /* Current buffer length */
- int buflen;
- /* Amount of data to copy */
- int copylen;
- /* Class and tag to use */
- int asn1_class, asn1_tag;
- asn1_ps_func *prefix, *prefix_free, *suffix, *suffix_free;
- /* Extra buffer for prefix and suffix data */
- unsigned char *ex_buf;
- int ex_len;
- int ex_pos;
- void *ex_arg;
- } BIO_ASN1_BUF_CTX;
-
-
-static int asn1_bio_write(BIO *h, const char *buf,int num);
+typedef enum {
+ ASN1_STATE_START,
+ ASN1_STATE_PRE_COPY,
+ ASN1_STATE_HEADER,
+ ASN1_STATE_HEADER_COPY,
+ ASN1_STATE_DATA_COPY,
+ ASN1_STATE_POST_COPY,
+ ASN1_STATE_DONE
+} asn1_bio_state_t;
+
+typedef struct BIO_ASN1_EX_FUNCS_st {
+ asn1_ps_func *ex_func;
+ asn1_ps_func *ex_free_func;
+} BIO_ASN1_EX_FUNCS;
+
+typedef struct BIO_ASN1_BUF_CTX_t {
+ /* Internal state */
+ asn1_bio_state_t state;
+ /* Internal buffer */
+ unsigned char *buf;
+ /* Size of buffer */
+ int bufsize;
+ /* Current position in buffer */
+ int bufpos;
+ /* Current buffer length */
+ int buflen;
+ /* Amount of data to copy */
+ int copylen;
+ /* Class and tag to use */
+ int asn1_class, asn1_tag;
+ asn1_ps_func *prefix, *prefix_free, *suffix, *suffix_free;
+ /* Extra buffer for prefix and suffix data */
+ unsigned char *ex_buf;
+ int ex_len;
+ int ex_pos;
+ void *ex_arg;
+} BIO_ASN1_BUF_CTX;
+
+static int asn1_bio_write(BIO *h, const char *buf, int num);
static int asn1_bio_read(BIO *h, char *buf, int size);
static int asn1_bio_puts(BIO *h, const char *str);
static int asn1_bio_gets(BIO *h, char *str, int size);
@@ -119,378 +114,364 @@ static long asn1_bio_callback_ctrl(BIO *h, int cmd, bio_info_cb fp);
static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size);
static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
- asn1_ps_func *cleanup, asn1_bio_state_t next);
+ asn1_ps_func *cleanup, asn1_bio_state_t next);
static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
- asn1_ps_func *setup,
- asn1_bio_state_t ex_state,
- asn1_bio_state_t other_state);
-
-static const BIO_METHOD methods_asn1=
- {
- BIO_TYPE_ASN1,
- "asn1",
- asn1_bio_write,
- asn1_bio_read,
- asn1_bio_puts,
- asn1_bio_gets,
- asn1_bio_ctrl,
- asn1_bio_new,
- asn1_bio_free,
- asn1_bio_callback_ctrl,
- };
+ asn1_ps_func *setup,
+ asn1_bio_state_t ex_state,
+ asn1_bio_state_t other_state);
+
+static const BIO_METHOD methods_asn1 = {
+ BIO_TYPE_ASN1,
+ "asn1",
+ asn1_bio_write,
+ asn1_bio_read,
+ asn1_bio_puts,
+ asn1_bio_gets,
+ asn1_bio_ctrl,
+ asn1_bio_new,
+ asn1_bio_free,
+ asn1_bio_callback_ctrl,
+};
const BIO_METHOD *BIO_f_asn1(void)
- {
- return(&methods_asn1);
- }
-
+{
+ return (&methods_asn1);
+}
static int asn1_bio_new(BIO *b)
- {
- BIO_ASN1_BUF_CTX *ctx;
- ctx = OPENSSL_malloc(sizeof(BIO_ASN1_BUF_CTX));
- if (!ctx)
- return 0;
- if (!asn1_bio_init(ctx, DEFAULT_ASN1_BUF_SIZE))
- {
- OPENSSL_free(ctx);
- return 0;
- }
- b->init = 1;
- b->ptr = (char *)ctx;
- b->flags = 0;
- return 1;
- }
+{
+ BIO_ASN1_BUF_CTX *ctx;
+ ctx = OPENSSL_malloc(sizeof(BIO_ASN1_BUF_CTX));
+ if (!ctx)
+ return 0;
+ if (!asn1_bio_init(ctx, DEFAULT_ASN1_BUF_SIZE)) {
+ OPENSSL_free(ctx);
+ return 0;
+ }
+ b->init = 1;
+ b->ptr = (char *)ctx;
+ b->flags = 0;
+ return 1;
+}
static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size)
- {
- ctx->buf = OPENSSL_malloc(size);
- if (!ctx->buf)
- return 0;
- ctx->bufsize = size;
- ctx->bufpos = 0;
- ctx->buflen = 0;
- ctx->copylen = 0;
- ctx->asn1_class = V_ASN1_UNIVERSAL;
- ctx->asn1_tag = V_ASN1_OCTET_STRING;
- ctx->ex_buf = 0;
- ctx->ex_pos = 0;
- ctx->ex_len = 0;
- ctx->state = ASN1_STATE_START;
- return 1;
- }
+{
+ ctx->buf = OPENSSL_malloc(size);
+ if (!ctx->buf)
+ return 0;
+ ctx->bufsize = size;
+ ctx->bufpos = 0;
+ ctx->buflen = 0;
+ ctx->copylen = 0;
+ ctx->asn1_class = V_ASN1_UNIVERSAL;
+ ctx->asn1_tag = V_ASN1_OCTET_STRING;
+ ctx->ex_buf = 0;
+ ctx->ex_pos = 0;
+ ctx->ex_len = 0;
+ ctx->state = ASN1_STATE_START;
+ return 1;
+}
static int asn1_bio_free(BIO *b)
- {
- BIO_ASN1_BUF_CTX *ctx;
- ctx = (BIO_ASN1_BUF_CTX *) b->ptr;
- if (ctx == NULL)
- return 0;
- if (ctx->buf)
- OPENSSL_free(ctx->buf);
- OPENSSL_free(ctx);
- b->init = 0;
- b->ptr = NULL;
- b->flags = 0;
- return 1;
- }
-
-static int asn1_bio_write(BIO *b, const char *in , int inl)
- {
- BIO_ASN1_BUF_CTX *ctx;
- int wrmax, wrlen, ret;
- unsigned char *p;
- if (!in || (inl < 0) || (b->next_bio == NULL))
- return 0;
- ctx = (BIO_ASN1_BUF_CTX *) b->ptr;
- if (ctx == NULL)
- return 0;
-
- wrlen = 0;
- ret = -1;
-
- for(;;)
- {
- switch (ctx->state)
- {
-
- /* Setup prefix data, call it */
- case ASN1_STATE_START:
- if (!asn1_bio_setup_ex(b, ctx, ctx->prefix,
- ASN1_STATE_PRE_COPY, ASN1_STATE_HEADER))
- return 0;
- break;
-
- /* Copy any pre data first */
- case ASN1_STATE_PRE_COPY:
-
- ret = asn1_bio_flush_ex(b, ctx, ctx->prefix_free,
- ASN1_STATE_HEADER);
-
- if (ret <= 0)
- goto done;
-
- break;
-
- case ASN1_STATE_HEADER:
- ctx->buflen =
- ASN1_object_size(0, inl, ctx->asn1_tag) - inl;
- assert(ctx->buflen <= ctx->bufsize);
- p = ctx->buf;
- ASN1_put_object(&p, 0, inl,
- ctx->asn1_tag, ctx->asn1_class);
- ctx->copylen = inl;
- ctx->state = ASN1_STATE_HEADER_COPY;
-
- break;
-
- case ASN1_STATE_HEADER_COPY:
- ret = BIO_write(b->next_bio,
- ctx->buf + ctx->bufpos, ctx->buflen);
- if (ret <= 0)
- goto done;
-
- ctx->buflen -= ret;
- if (ctx->buflen)
- ctx->bufpos += ret;
- else
- {
- ctx->bufpos = 0;
- ctx->state = ASN1_STATE_DATA_COPY;
- }
-
- break;
-
- case ASN1_STATE_DATA_COPY:
-
- if (inl > ctx->copylen)
- wrmax = ctx->copylen;
- else
- wrmax = inl;
- ret = BIO_write(b->next_bio, in, wrmax);
- if (ret <= 0)
- break;
- wrlen += ret;
- ctx->copylen -= ret;
- in += ret;
- inl -= ret;
-
- if (ctx->copylen == 0)
- ctx->state = ASN1_STATE_HEADER;
-
- if (inl == 0)
- goto done;
-
- break;
-
- default:
- BIO_clear_retry_flags(b);
- return 0;
-
- }
-
- }
-
- done:
- BIO_clear_retry_flags(b);
- BIO_copy_next_retry(b);
-
- return (wrlen > 0) ? wrlen : ret;
-
- }
+{
+ BIO_ASN1_BUF_CTX *ctx;
+ ctx = (BIO_ASN1_BUF_CTX *)b->ptr;
+ if (ctx == NULL)
+ return 0;
+ if (ctx->buf)
+ OPENSSL_free(ctx->buf);
+ OPENSSL_free(ctx);
+ b->init = 0;
+ b->ptr = NULL;
+ b->flags = 0;
+ return 1;
+}
+
+static int asn1_bio_write(BIO *b, const char *in, int inl)
+{
+ BIO_ASN1_BUF_CTX *ctx;
+ int wrmax, wrlen, ret;
+ unsigned char *p;
+ if (!in || (inl < 0) || (b->next_bio == NULL))
+ return 0;
+ ctx = (BIO_ASN1_BUF_CTX *)b->ptr;
+ if (ctx == NULL)
+ return 0;
+
+ wrlen = 0;
+ ret = -1;
+
+ for (;;) {
+ switch (ctx->state) {
+
+ /* Setup prefix data, call it */
+ case ASN1_STATE_START:
+ if (!asn1_bio_setup_ex(b, ctx, ctx->prefix,
+ ASN1_STATE_PRE_COPY, ASN1_STATE_HEADER))
+ return 0;
+ break;
+
+ /* Copy any pre data first */
+ case ASN1_STATE_PRE_COPY:
+
+ ret = asn1_bio_flush_ex(b, ctx, ctx->prefix_free,
+ ASN1_STATE_HEADER);
+
+ if (ret <= 0)
+ goto done;
+
+ break;
+
+ case ASN1_STATE_HEADER:
+ ctx->buflen = ASN1_object_size(0, inl, ctx->asn1_tag) - inl;
+ assert(ctx->buflen <= ctx->bufsize);
+ p = ctx->buf;
+ ASN1_put_object(&p, 0, inl, ctx->asn1_tag, ctx->asn1_class);
+ ctx->copylen = inl;
+ ctx->state = ASN1_STATE_HEADER_COPY;
+
+ break;
+
+ case ASN1_STATE_HEADER_COPY:
+ ret = BIO_write(b->next_bio, ctx->buf + ctx->bufpos, ctx->buflen);
+ if (ret <= 0)
+ goto done;
+
+ ctx->buflen -= ret;
+ if (ctx->buflen)
+ ctx->bufpos += ret;
+ else {
+ ctx->bufpos = 0;
+ ctx->state = ASN1_STATE_DATA_COPY;
+ }
+
+ break;
+
+ case ASN1_STATE_DATA_COPY:
+
+ if (inl > ctx->copylen)
+ wrmax = ctx->copylen;
+ else
+ wrmax = inl;
+ ret = BIO_write(b->next_bio, in, wrmax);
+ if (ret <= 0)
+ break;
+ wrlen += ret;
+ ctx->copylen -= ret;
+ in += ret;
+ inl -= ret;
+
+ if (ctx->copylen == 0)
+ ctx->state = ASN1_STATE_HEADER;
+
+ if (inl == 0)
+ goto done;
+
+ break;
+
+ default:
+ BIO_clear_retry_flags(b);
+ return 0;
+
+ }
+
+ }
+
+ done:
+ BIO_clear_retry_flags(b);
+ BIO_copy_next_retry(b);
+
+ return (wrlen > 0) ? wrlen : ret;
+
+}
static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
- asn1_ps_func *cleanup, asn1_bio_state_t next)
- {
- int ret;
- if (ctx->ex_len <= 0)
- return 1;
- for(;;)
- {
- ret = BIO_write(b->next_bio, ctx->ex_buf + ctx->ex_pos,
- ctx->ex_len);
- if (ret <= 0)
- break;
- ctx->ex_len -= ret;
- if (ctx->ex_len > 0)
- ctx->ex_pos += ret;
- else
- {
- if(cleanup)
- cleanup(b, &ctx->ex_buf, &ctx->ex_len,
- &ctx->ex_arg);
- ctx->state = next;
- ctx->ex_pos = 0;
- break;
- }
- }
- return ret;
- }
+ asn1_ps_func *cleanup, asn1_bio_state_t next)
+{
+ int ret;
+ if (ctx->ex_len <= 0)
+ return 1;
+ for (;;) {
+ ret = BIO_write(b->next_bio, ctx->ex_buf + ctx->ex_pos, ctx->ex_len);
+ if (ret <= 0)
+ break;
+ ctx->ex_len -= ret;
+ if (ctx->ex_len > 0)
+ ctx->ex_pos += ret;
+ else {
+ if (cleanup)
+ cleanup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg);
+ ctx->state = next;
+ ctx->ex_pos = 0;
+ break;
+ }
+ }
+ return ret;
+}
static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
- asn1_ps_func *setup,
- asn1_bio_state_t ex_state,
- asn1_bio_state_t other_state)
- {
- if (setup && !setup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg))
- {
- BIO_clear_retry_flags(b);
- return 0;
- }
- if (ctx->ex_len > 0)
- ctx->state = ex_state;
- else
- ctx->state = other_state;
- return 1;
- }
-
-static int asn1_bio_read(BIO *b, char *in , int inl)
- {
- if (!b->next_bio)
- return 0;
- return BIO_read(b->next_bio, in , inl);
- }
+ asn1_ps_func *setup,
+ asn1_bio_state_t ex_state,
+ asn1_bio_state_t other_state)
+{
+ if (setup && !setup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg)) {
+ BIO_clear_retry_flags(b);
+ return 0;
+ }
+ if (ctx->ex_len > 0)
+ ctx->state = ex_state;
+ else
+ ctx->state = other_state;
+ return 1;
+}
+
+static int asn1_bio_read(BIO *b, char *in, int inl)
+{
+ if (!b->next_bio)
+ return 0;
+ return BIO_read(b->next_bio, in, inl);
+}
static int asn1_bio_puts(BIO *b, const char *str)
- {
- return asn1_bio_write(b, str, strlen(str));
- }
+{
+ return asn1_bio_write(b, str, strlen(str));
+}
static int asn1_bio_gets(BIO *b, char *str, int size)
- {
- if (!b->next_bio)
- return 0;
- return BIO_gets(b->next_bio, str , size);
- }
+{
+ if (!b->next_bio)
+ return 0;
+ return BIO_gets(b->next_bio, str, size);
+}
static long asn1_bio_callback_ctrl(BIO *b, int cmd, bio_info_cb fp)
- {
- if (b->next_bio == NULL) return(0);
- return BIO_callback_ctrl(b->next_bio,cmd,fp);
- }
+{
+ if (b->next_bio == NULL)
+ return (0);
+ return BIO_callback_ctrl(b->next_bio, cmd, fp);
+}
static long asn1_bio_ctrl(BIO *b, int cmd, long arg1, void *arg2)
- {
- BIO_ASN1_BUF_CTX *ctx;
- BIO_ASN1_EX_FUNCS *ex_func;
- long ret = 1;
- ctx = (BIO_ASN1_BUF_CTX *) b->ptr;
- if (ctx == NULL)
- return 0;
- switch(cmd)
- {
-
- case BIO_C_SET_PREFIX:
- ex_func = arg2;
- ctx->prefix = ex_func->ex_func;
- ctx->prefix_free = ex_func->ex_free_func;
- break;
-
- case BIO_C_GET_PREFIX:
- ex_func = arg2;
- ex_func->ex_func = ctx->prefix;
- ex_func->ex_free_func = ctx->prefix_free;
- break;
-
- case BIO_C_SET_SUFFIX:
- ex_func = arg2;
- ctx->suffix = ex_func->ex_func;
- ctx->suffix_free = ex_func->ex_free_func;
- break;
-
- case BIO_C_GET_SUFFIX:
- ex_func = arg2;
- ex_func->ex_func = ctx->suffix;
- ex_func->ex_free_func = ctx->suffix_free;
- break;
-
- case BIO_C_SET_EX_ARG:
- ctx->ex_arg = arg2;
- break;
-
- case BIO_C_GET_EX_ARG:
- *(void **)arg2 = ctx->ex_arg;
- break;
-
- case BIO_CTRL_FLUSH:
- if (!b->next_bio)
- return 0;
-
- /* Call post function if possible */
- if (ctx->state == ASN1_STATE_HEADER)
- {
- if (!asn1_bio_setup_ex(b, ctx, ctx->suffix,
- ASN1_STATE_POST_COPY, ASN1_STATE_DONE))
- return 0;
- }
-
- if (ctx->state == ASN1_STATE_POST_COPY)
- {
- ret = asn1_bio_flush_ex(b, ctx, ctx->suffix_free,
- ASN1_STATE_DONE);
- if (ret <= 0)
- return ret;
- }
-
- if (ctx->state == ASN1_STATE_DONE)
- return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
- else
- {
- BIO_clear_retry_flags(b);
- return 0;
- }
- break;
-
-
- default:
- if (!b->next_bio)
- return 0;
- return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
-
- }
-
- return ret;
- }
+{
+ BIO_ASN1_BUF_CTX *ctx;
+ BIO_ASN1_EX_FUNCS *ex_func;
+ long ret = 1;
+ ctx = (BIO_ASN1_BUF_CTX *)b->ptr;
+ if (ctx == NULL)
+ return 0;
+ switch (cmd) {
+
+ case BIO_C_SET_PREFIX:
+ ex_func = arg2;
+ ctx->prefix = ex_func->ex_func;
+ ctx->prefix_free = ex_func->ex_free_func;
+ break;
+
+ case BIO_C_GET_PREFIX:
+ ex_func = arg2;
+ ex_func->ex_func = ctx->prefix;
+ ex_func->ex_free_func = ctx->prefix_free;
+ break;
+
+ case BIO_C_SET_SUFFIX:
+ ex_func = arg2;
+ ctx->suffix = ex_func->ex_func;
+ ctx->suffix_free = ex_func->ex_free_func;
+ break;
+
+ case BIO_C_GET_SUFFIX:
+ ex_func = arg2;
+ ex_func->ex_func = ctx->suffix;
+ ex_func->ex_free_func = ctx->suffix_free;
+ break;
+
+ case BIO_C_SET_EX_ARG:
+ ctx->ex_arg = arg2;
+ break;
+
+ case BIO_C_GET_EX_ARG:
+ *(void **)arg2 = ctx->ex_arg;
+ break;
+
+ case BIO_CTRL_FLUSH:
+ if (!b->next_bio)
+ return 0;
+
+ /* Call post function if possible */
+ if (ctx->state == ASN1_STATE_HEADER) {
+ if (!asn1_bio_setup_ex(b, ctx, ctx->suffix,
+ ASN1_STATE_POST_COPY, ASN1_STATE_DONE))
+ return 0;
+ }
+
+ if (ctx->state == ASN1_STATE_POST_COPY) {
+ ret = asn1_bio_flush_ex(b, ctx, ctx->suffix_free,
+ ASN1_STATE_DONE);
+ if (ret <= 0)
+ return ret;
+ }
+
+ if (ctx->state == ASN1_STATE_DONE)
+ return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
+ else {
+ BIO_clear_retry_flags(b);
+ return 0;
+ }
+ break;
+
+ default:
+ if (!b->next_bio)
+ return 0;
+ return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
+
+ }
+
+ return ret;
+}
static int asn1_bio_set_ex(BIO *b, int cmd,
- asn1_ps_func *ex_func, asn1_ps_func *ex_free_func)
- {
- BIO_ASN1_EX_FUNCS extmp;
- extmp.ex_func = ex_func;
- extmp.ex_free_func = ex_free_func;
- return BIO_ctrl(b, cmd, 0, &extmp);
- }
+ asn1_ps_func *ex_func, asn1_ps_func *ex_free_func)
+{
+ BIO_ASN1_EX_FUNCS extmp;
+ extmp.ex_func = ex_func;
+ extmp.ex_free_func = ex_free_func;
+ return BIO_ctrl(b, cmd, 0, &extmp);
+}
static int asn1_bio_get_ex(BIO *b, int cmd,
- asn1_ps_func **ex_func, asn1_ps_func **ex_free_func)
- {
- BIO_ASN1_EX_FUNCS extmp;
- int ret;
- ret = BIO_ctrl(b, cmd, 0, &extmp);
- if (ret > 0)
- {
- *ex_func = extmp.ex_func;
- *ex_free_func = extmp.ex_free_func;
- }
- return ret;
- }
-
-int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix, asn1_ps_func *prefix_free)
- {
- return asn1_bio_set_ex(b, BIO_C_SET_PREFIX, prefix, prefix_free);
- }
-
-int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix, asn1_ps_func **pprefix_free)
- {
- return asn1_bio_get_ex(b, BIO_C_GET_PREFIX, pprefix, pprefix_free);
- }
-
-int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix, asn1_ps_func *suffix_free)
- {
- return asn1_bio_set_ex(b, BIO_C_SET_SUFFIX, suffix, suffix_free);
- }
-
-int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix, asn1_ps_func **psuffix_free)
- {
- return asn1_bio_get_ex(b, BIO_C_GET_SUFFIX, psuffix, psuffix_free);
- }
+ asn1_ps_func **ex_func,
+ asn1_ps_func **ex_free_func)
+{
+ BIO_ASN1_EX_FUNCS extmp;
+ int ret;
+ ret = BIO_ctrl(b, cmd, 0, &extmp);
+ if (ret > 0) {
+ *ex_func = extmp.ex_func;
+ *ex_free_func = extmp.ex_free_func;
+ }
+ return ret;
+}
+
+int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix,
+ asn1_ps_func *prefix_free)
+{
+ return asn1_bio_set_ex(b, BIO_C_SET_PREFIX, prefix, prefix_free);
+}
+
+int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix,
+ asn1_ps_func **pprefix_free)
+{
+ return asn1_bio_get_ex(b, BIO_C_GET_PREFIX, pprefix, pprefix_free);
+}
+
+int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix,
+ asn1_ps_func *suffix_free)
+{
+ return asn1_bio_set_ex(b, BIO_C_SET_SUFFIX, suffix, suffix_free);
+}
+
+int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix,
+ asn1_ps_func **psuffix_free)
+{
+ return asn1_bio_get_ex(b, BIO_C_GET_SUFFIX, psuffix, psuffix_free);
+}
diff --git a/src/crypto/asn1/bio_ndef.c b/src/crypto/asn1/bio_ndef.c
index f07d3de7..81a8aa7c 100644
--- a/src/crypto/asn1/bio_ndef.c
+++ b/src/crypto/asn1/bio_ndef.c
@@ -63,192 +63,189 @@
#include <openssl/err.h>
#include <openssl/mem.h>
-
/* Experimental NDEF ASN1 BIO support routines */
-/* The usage is quite simple, initialize an ASN1 structure,
- * get a BIO from it then any data written through the BIO
- * will end up translated to approptiate format on the fly.
- * The data is streamed out and does *not* need to be
- * all held in memory at once.
- *
- * When the BIO is flushed the output is finalized and any
- * signatures etc written out.
- *
- * The BIO is a 'proper' BIO and can handle non blocking I/O
- * correctly.
- *
- * The usage is simple. The implementation is *not*...
+/*
+ * The usage is quite simple, initialize an ASN1 structure, get a BIO from it
+ * then any data written through the BIO will end up translated to
+ * approptiate format on the fly. The data is streamed out and does *not*
+ * need to be all held in memory at once. When the BIO is flushed the output
+ * is finalized and any signatures etc written out. The BIO is a 'proper'
+ * BIO and can handle non blocking I/O correctly. The usage is simple. The
+ * implementation is *not*...
*/
/* BIO support data stored in the ASN1 BIO ex_arg */
-typedef struct ndef_aux_st
- {
- /* ASN1 structure this BIO refers to */
- ASN1_VALUE *val;
- const ASN1_ITEM *it;
- /* Top of the BIO chain */
- BIO *ndef_bio;
- /* Output BIO */
- BIO *out;
- /* Boundary where content is inserted */
- unsigned char **boundary;
- /* DER buffer start */
- unsigned char *derbuf;
- } NDEF_SUPPORT;
+typedef struct ndef_aux_st {
+ /* ASN1 structure this BIO refers to */
+ ASN1_VALUE *val;
+ const ASN1_ITEM *it;
+ /* Top of the BIO chain */
+ BIO *ndef_bio;
+ /* Output BIO */
+ BIO *out;
+ /* Boundary where content is inserted */
+ unsigned char **boundary;
+ /* DER buffer start */
+ unsigned char *derbuf;
+} NDEF_SUPPORT;
static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
-static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg);
+static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen,
+ void *parg);
static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
-static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg);
+static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen,
+ void *parg);
BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it)
- {
- NDEF_SUPPORT *ndef_aux = NULL;
- BIO *asn_bio = NULL;
- const ASN1_AUX *aux = it->funcs;
- ASN1_STREAM_ARG sarg;
+{
+ NDEF_SUPPORT *ndef_aux = NULL;
+ BIO *asn_bio = NULL;
+ const ASN1_AUX *aux = it->funcs;
+ ASN1_STREAM_ARG sarg;
- if (!aux || !aux->asn1_cb)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_STREAMING_NOT_SUPPORTED);
- return NULL;
- }
- ndef_aux = OPENSSL_malloc(sizeof(NDEF_SUPPORT));
- asn_bio = BIO_new(BIO_f_asn1());
+ if (!aux || !aux->asn1_cb) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_STREAMING_NOT_SUPPORTED);
+ return NULL;
+ }
+ ndef_aux = OPENSSL_malloc(sizeof(NDEF_SUPPORT));
+ asn_bio = BIO_new(BIO_f_asn1());
- /* ASN1 bio needs to be next to output BIO */
+ /* ASN1 bio needs to be next to output BIO */
- out = BIO_push(asn_bio, out);
+ out = BIO_push(asn_bio, out);
- if (!ndef_aux || !asn_bio || !out)
- goto err;
+ if (!ndef_aux || !asn_bio || !out)
+ goto err;
- BIO_asn1_set_prefix(asn_bio, ndef_prefix, ndef_prefix_free);
- BIO_asn1_set_suffix(asn_bio, ndef_suffix, ndef_suffix_free);
+ BIO_asn1_set_prefix(asn_bio, ndef_prefix, ndef_prefix_free);
+ BIO_asn1_set_suffix(asn_bio, ndef_suffix, ndef_suffix_free);
- /* Now let callback prepend any digest, cipher etc BIOs
- * ASN1 structure needs.
- */
+ /*
+ * Now let callback prepend any digest, cipher etc BIOs ASN1 structure
+ * needs.
+ */
- sarg.out = out;
- sarg.ndef_bio = NULL;
- sarg.boundary = NULL;
+ sarg.out = out;
+ sarg.ndef_bio = NULL;
+ sarg.boundary = NULL;
- if (aux->asn1_cb(ASN1_OP_STREAM_PRE, &val, it, &sarg) <= 0)
- goto err;
+ if (aux->asn1_cb(ASN1_OP_STREAM_PRE, &val, it, &sarg) <= 0)
+ goto err;
- ndef_aux->val = val;
- ndef_aux->it = it;
- ndef_aux->ndef_bio = sarg.ndef_bio;
- ndef_aux->boundary = sarg.boundary;
- ndef_aux->out = out;
+ ndef_aux->val = val;
+ ndef_aux->it = it;
+ ndef_aux->ndef_bio = sarg.ndef_bio;
+ ndef_aux->boundary = sarg.boundary;
+ ndef_aux->out = out;
- BIO_ctrl(asn_bio, BIO_C_SET_EX_ARG, 0, ndef_aux);
+ BIO_ctrl(asn_bio, BIO_C_SET_EX_ARG, 0, ndef_aux);
- return sarg.ndef_bio;
+ return sarg.ndef_bio;
- err:
- if (asn_bio)
- BIO_free(asn_bio);
- if (ndef_aux)
- OPENSSL_free(ndef_aux);
- return NULL;
- }
+ err:
+ if (asn_bio)
+ BIO_free(asn_bio);
+ if (ndef_aux)
+ OPENSSL_free(ndef_aux);
+ return NULL;
+}
static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
- {
- NDEF_SUPPORT *ndef_aux;
- unsigned char *p;
- int derlen;
+{
+ NDEF_SUPPORT *ndef_aux;
+ unsigned char *p;
+ int derlen;
- if (!parg)
- return 0;
+ if (!parg)
+ return 0;
- ndef_aux = *(NDEF_SUPPORT **)parg;
+ ndef_aux = *(NDEF_SUPPORT **)parg;
- derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
- p = OPENSSL_malloc(derlen);
- if (p == NULL)
- return 0;
+ derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
+ p = OPENSSL_malloc(derlen);
+ if (p == NULL)
+ return 0;
- ndef_aux->derbuf = p;
- *pbuf = p;
- derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
+ ndef_aux->derbuf = p;
+ *pbuf = p;
+ derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
- if (!*ndef_aux->boundary)
- return 0;
+ if (!*ndef_aux->boundary)
+ return 0;
- *plen = *ndef_aux->boundary - *pbuf;
+ *plen = *ndef_aux->boundary - *pbuf;
- return 1;
- }
+ return 1;
+}
-static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg)
- {
- NDEF_SUPPORT *ndef_aux;
+static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen,
+ void *parg)
+{
+ NDEF_SUPPORT *ndef_aux;
- if (!parg)
- return 0;
+ if (!parg)
+ return 0;
- ndef_aux = *(NDEF_SUPPORT **)parg;
+ ndef_aux = *(NDEF_SUPPORT **)parg;
- if (ndef_aux->derbuf)
- OPENSSL_free(ndef_aux->derbuf);
+ if (ndef_aux->derbuf)
+ OPENSSL_free(ndef_aux->derbuf);
- ndef_aux->derbuf = NULL;
- *pbuf = NULL;
- *plen = 0;
- return 1;
- }
+ ndef_aux->derbuf = NULL;
+ *pbuf = NULL;
+ *plen = 0;
+ return 1;
+}
-static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg)
- {
- NDEF_SUPPORT **pndef_aux = (NDEF_SUPPORT **)parg;
- if (!ndef_prefix_free(b, pbuf, plen, parg))
- return 0;
- OPENSSL_free(*pndef_aux);
- *pndef_aux = NULL;
- return 1;
- }
+static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen,
+ void *parg)
+{
+ NDEF_SUPPORT **pndef_aux = (NDEF_SUPPORT **)parg;
+ if (!ndef_prefix_free(b, pbuf, plen, parg))
+ return 0;
+ OPENSSL_free(*pndef_aux);
+ *pndef_aux = NULL;
+ return 1;
+}
static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
- {
- NDEF_SUPPORT *ndef_aux;
- unsigned char *p;
- int derlen;
- const ASN1_AUX *aux;
- ASN1_STREAM_ARG sarg;
-
- if (!parg)
- return 0;
-
- ndef_aux = *(NDEF_SUPPORT **)parg;
-
- aux = ndef_aux->it->funcs;
-
- /* Finalize structures */
- sarg.ndef_bio = ndef_aux->ndef_bio;
- sarg.out = ndef_aux->out;
- sarg.boundary = ndef_aux->boundary;
- if (aux->asn1_cb(ASN1_OP_STREAM_POST,
- &ndef_aux->val, ndef_aux->it, &sarg) <= 0)
- return 0;
-
- derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
- p = OPENSSL_malloc(derlen);
- if (p == NULL)
- return 0;
-
- ndef_aux->derbuf = p;
- *pbuf = p;
- derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
-
- if (!*ndef_aux->boundary)
- return 0;
- *pbuf = *ndef_aux->boundary;
- *plen = derlen - (*ndef_aux->boundary - ndef_aux->derbuf);
-
- return 1;
- }
+{
+ NDEF_SUPPORT *ndef_aux;
+ unsigned char *p;
+ int derlen;
+ const ASN1_AUX *aux;
+ ASN1_STREAM_ARG sarg;
+
+ if (!parg)
+ return 0;
+
+ ndef_aux = *(NDEF_SUPPORT **)parg;
+
+ aux = ndef_aux->it->funcs;
+
+ /* Finalize structures */
+ sarg.ndef_bio = ndef_aux->ndef_bio;
+ sarg.out = ndef_aux->out;
+ sarg.boundary = ndef_aux->boundary;
+ if (aux->asn1_cb(ASN1_OP_STREAM_POST,
+ &ndef_aux->val, ndef_aux->it, &sarg) <= 0)
+ return 0;
+
+ derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
+ p = OPENSSL_malloc(derlen);
+ if (p == NULL)
+ return 0;
+
+ ndef_aux->derbuf = p;
+ *pbuf = p;
+ derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
+
+ if (!*ndef_aux->boundary)
+ return 0;
+ *pbuf = *ndef_aux->boundary;
+ *plen = derlen - (*ndef_aux->boundary - ndef_aux->derbuf);
+
+ return 1;
+}
diff --git a/src/crypto/asn1/f_enum.c b/src/crypto/asn1/f_enum.c
index bcdb7735..3af16f8a 100644
--- a/src/crypto/asn1/f_enum.c
+++ b/src/crypto/asn1/f_enum.c
@@ -62,145 +62,139 @@
/* Based on a_int.c: equivalent ENUMERATED functions */
int i2a_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *a)
- {
- int i,n=0;
- static const char *h="0123456789ABCDEF";
- char buf[2];
+{
+ int i, n = 0;
+ static const char *h = "0123456789ABCDEF";
+ char buf[2];
- if (a == NULL) return(0);
+ if (a == NULL)
+ return (0);
- if (a->length == 0)
- {
- if (BIO_write(bp,"00",2) != 2) goto err;
- n=2;
- }
- else
- {
- for (i=0; i<a->length; i++)
- {
- if ((i != 0) && (i%35 == 0))
- {
- if (BIO_write(bp,"\\\n",2) != 2) goto err;
- n+=2;
- }
- buf[0]=h[((unsigned char)a->data[i]>>4)&0x0f];
- buf[1]=h[((unsigned char)a->data[i] )&0x0f];
- if (BIO_write(bp,buf,2) != 2) goto err;
- n+=2;
- }
- }
- return(n);
-err:
- return(-1);
- }
+ if (a->length == 0) {
+ if (BIO_write(bp, "00", 2) != 2)
+ goto err;
+ n = 2;
+ } else {
+ for (i = 0; i < a->length; i++) {
+ if ((i != 0) && (i % 35 == 0)) {
+ if (BIO_write(bp, "\\\n", 2) != 2)
+ goto err;
+ n += 2;
+ }
+ buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f];
+ buf[1] = h[((unsigned char)a->data[i]) & 0x0f];
+ if (BIO_write(bp, buf, 2) != 2)
+ goto err;
+ n += 2;
+ }
+ }
+ return (n);
+ err:
+ return (-1);
+}
int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size)
- {
- int ret=0;
- int i,j,k,m,n,again,bufsize;
- unsigned char *s=NULL,*sp;
- unsigned char *bufp;
- int num=0,slen=0,first=1;
+{
+ int ret = 0;
+ int i, j, k, m, n, again, bufsize;
+ unsigned char *s = NULL, *sp;
+ unsigned char *bufp;
+ int num = 0, slen = 0, first = 1;
- bs->type=V_ASN1_ENUMERATED;
+ bs->type = V_ASN1_ENUMERATED;
- bufsize=BIO_gets(bp,buf,size);
- for (;;)
- {
- if (bufsize < 1) goto err_sl;
- i=bufsize;
- if (buf[i-1] == '\n') buf[--i]='\0';
- if (i == 0) goto err_sl;
- if (buf[i-1] == '\r') buf[--i]='\0';
- if (i == 0) goto err_sl;
- again=(buf[i-1] == '\\');
+ bufsize = BIO_gets(bp, buf, size);
+ for (;;) {
+ if (bufsize < 1)
+ goto err_sl;
+ i = bufsize;
+ if (buf[i - 1] == '\n')
+ buf[--i] = '\0';
+ if (i == 0)
+ goto err_sl;
+ if (buf[i - 1] == '\r')
+ buf[--i] = '\0';
+ if (i == 0)
+ goto err_sl;
+ again = (buf[i - 1] == '\\');
- for (j=0; j<i; j++)
- {
- if (!( ((buf[j] >= '0') && (buf[j] <= '9')) ||
- ((buf[j] >= 'a') && (buf[j] <= 'f')) ||
- ((buf[j] >= 'A') && (buf[j] <= 'F'))))
- {
- i=j;
- break;
- }
- }
- buf[i]='\0';
- /* We have now cleared all the crap off the end of the
- * line */
- if (i < 2) goto err_sl;
-
- bufp=(unsigned char *)buf;
- if (first)
- {
- first=0;
- if ((bufp[0] == '0') && (buf[1] == '0'))
- {
- bufp+=2;
- i-=2;
- }
- }
- k=0;
- i-=again;
- if (i%2 != 0)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_ODD_NUMBER_OF_CHARS);
- goto err;
- }
- i/=2;
- if (num+i > slen)
- {
- if (s == NULL)
- sp=(unsigned char *)OPENSSL_malloc(
- (unsigned int)num+i*2);
- else
- sp=(unsigned char *)OPENSSL_realloc(s,
- (unsigned int)num+i*2);
- if (sp == NULL)
- {
- OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- s=sp;
- slen=num+i*2;
- }
- for (j=0; j<i; j++,k+=2)
- {
- for (n=0; n<2; n++)
- {
- m=bufp[k+n];
- if ((m >= '0') && (m <= '9'))
- m-='0';
- else if ((m >= 'a') && (m <= 'f'))
- m=m-'a'+10;
- else if ((m >= 'A') && (m <= 'F'))
- m=m-'A'+10;
- else
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_NON_HEX_CHARACTERS);
- goto err;
- }
- s[num+j]<<=4;
- s[num+j]|=m;
- }
- }
- num+=i;
- if (again)
- bufsize=BIO_gets(bp,buf,size);
- else
- break;
- }
- bs->length=num;
- bs->data=s;
- ret=1;
-err:
- if (0)
- {
-err_sl:
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_SHORT_LINE);
- }
- if (s != NULL)
- OPENSSL_free(s);
- return(ret);
- }
+ for (j = 0; j < i; j++) {
+ if (!(((buf[j] >= '0') && (buf[j] <= '9')) ||
+ ((buf[j] >= 'a') && (buf[j] <= 'f')) ||
+ ((buf[j] >= 'A') && (buf[j] <= 'F')))) {
+ i = j;
+ break;
+ }
+ }
+ buf[i] = '\0';
+ /*
+ * We have now cleared all the crap off the end of the line
+ */
+ if (i < 2)
+ goto err_sl;
+ bufp = (unsigned char *)buf;
+ if (first) {
+ first = 0;
+ if ((bufp[0] == '0') && (buf[1] == '0')) {
+ bufp += 2;
+ i -= 2;
+ }
+ }
+ k = 0;
+ i -= again;
+ if (i % 2 != 0) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ODD_NUMBER_OF_CHARS);
+ goto err;
+ }
+ i /= 2;
+ if (num + i > slen) {
+ if (s == NULL)
+ sp = (unsigned char *)OPENSSL_malloc((unsigned int)num +
+ i * 2);
+ else
+ sp = (unsigned char *)OPENSSL_realloc(s,
+ (unsigned int)num +
+ i * 2);
+ if (sp == NULL) {
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ s = sp;
+ slen = num + i * 2;
+ }
+ for (j = 0; j < i; j++, k += 2) {
+ for (n = 0; n < 2; n++) {
+ m = bufp[k + n];
+ if ((m >= '0') && (m <= '9'))
+ m -= '0';
+ else if ((m >= 'a') && (m <= 'f'))
+ m = m - 'a' + 10;
+ else if ((m >= 'A') && (m <= 'F'))
+ m = m - 'A' + 10;
+ else {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NON_HEX_CHARACTERS);
+ goto err;
+ }
+ s[num + j] <<= 4;
+ s[num + j] |= m;
+ }
+ }
+ num += i;
+ if (again)
+ bufsize = BIO_gets(bp, buf, size);
+ else
+ break;
+ }
+ bs->length = num;
+ bs->data = s;
+ ret = 1;
+ err:
+ if (0) {
+ err_sl:
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_SHORT_LINE);
+ }
+ if (s != NULL)
+ OPENSSL_free(s);
+ return (ret);
+}
diff --git a/src/crypto/asn1/f_int.c b/src/crypto/asn1/f_int.c
index 5186304b..60c0f2f2 100644
--- a/src/crypto/asn1/f_int.c
+++ b/src/crypto/asn1/f_int.c
@@ -59,152 +59,144 @@
#include <openssl/err.h>
#include <openssl/mem.h>
-
int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a)
- {
- int i,n=0;
- static const char *h="0123456789ABCDEF";
- char buf[2];
+{
+ int i, n = 0;
+ static const char *h = "0123456789ABCDEF";
+ char buf[2];
- if (a == NULL) return(0);
+ if (a == NULL)
+ return (0);
- if (a->type & V_ASN1_NEG)
- {
- if (BIO_write(bp, "-", 1) != 1) goto err;
- n = 1;
- }
+ if (a->type & V_ASN1_NEG) {
+ if (BIO_write(bp, "-", 1) != 1)
+ goto err;
+ n = 1;
+ }
- if (a->length == 0)
- {
- if (BIO_write(bp,"00",2) != 2) goto err;
- n += 2;
- }
- else
- {
- for (i=0; i<a->length; i++)
- {
- if ((i != 0) && (i%35 == 0))
- {
- if (BIO_write(bp,"\\\n",2) != 2) goto err;
- n+=2;
- }
- buf[0]=h[((unsigned char)a->data[i]>>4)&0x0f];
- buf[1]=h[((unsigned char)a->data[i] )&0x0f];
- if (BIO_write(bp,buf,2) != 2) goto err;
- n+=2;
- }
- }
- return(n);
-err:
- return(-1);
- }
+ if (a->length == 0) {
+ if (BIO_write(bp, "00", 2) != 2)
+ goto err;
+ n += 2;
+ } else {
+ for (i = 0; i < a->length; i++) {
+ if ((i != 0) && (i % 35 == 0)) {
+ if (BIO_write(bp, "\\\n", 2) != 2)
+ goto err;
+ n += 2;
+ }
+ buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f];
+ buf[1] = h[((unsigned char)a->data[i]) & 0x0f];
+ if (BIO_write(bp, buf, 2) != 2)
+ goto err;
+ n += 2;
+ }
+ }
+ return (n);
+ err:
+ return (-1);
+}
int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size)
- {
- int ret=0;
- int i,j,k,m,n,again,bufsize;
- unsigned char *s=NULL,*sp;
- unsigned char *bufp;
- int num=0,slen=0,first=1;
-
- bs->type=V_ASN1_INTEGER;
+{
+ int ret = 0;
+ int i, j, k, m, n, again, bufsize;
+ unsigned char *s = NULL, *sp;
+ unsigned char *bufp;
+ int num = 0, slen = 0, first = 1;
- bufsize=BIO_gets(bp,buf,size);
- for (;;)
- {
- if (bufsize < 1) goto err_sl;
- i=bufsize;
- if (buf[i-1] == '\n') buf[--i]='\0';
- if (i == 0) goto err_sl;
- if (buf[i-1] == '\r') buf[--i]='\0';
- if (i == 0) goto err_sl;
- again=(buf[i-1] == '\\');
+ bs->type = V_ASN1_INTEGER;
- for (j=0; j<i; j++)
- {
- if (!( ((buf[j] >= '0') && (buf[j] <= '9')) ||
- ((buf[j] >= 'a') && (buf[j] <= 'f')) ||
- ((buf[j] >= 'A') && (buf[j] <= 'F'))))
- {
- i=j;
- break;
- }
- }
- buf[i]='\0';
- /* We have now cleared all the crap off the end of the
- * line */
- if (i < 2) goto err_sl;
+ bufsize = BIO_gets(bp, buf, size);
+ for (;;) {
+ if (bufsize < 1)
+ goto err_sl;
+ i = bufsize;
+ if (buf[i - 1] == '\n')
+ buf[--i] = '\0';
+ if (i == 0)
+ goto err_sl;
+ if (buf[i - 1] == '\r')
+ buf[--i] = '\0';
+ if (i == 0)
+ goto err_sl;
+ again = (buf[i - 1] == '\\');
- bufp=(unsigned char *)buf;
- if (first)
- {
- first=0;
- if ((bufp[0] == '0') && (buf[1] == '0'))
- {
- bufp+=2;
- i-=2;
- }
- }
- k=0;
- i-=again;
- if (i%2 != 0)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_ODD_NUMBER_OF_CHARS);
- goto err;
- }
- i/=2;
- if (num+i > slen)
- {
- if (s == NULL)
- sp=(unsigned char *)OPENSSL_malloc(
- (unsigned int)num+i*2);
- else
- sp=OPENSSL_realloc_clean(s,slen,num+i*2);
- if (sp == NULL)
- {
- OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- s=sp;
- slen=num+i*2;
- }
- for (j=0; j<i; j++,k+=2)
- {
- for (n=0; n<2; n++)
- {
- m=bufp[k+n];
- if ((m >= '0') && (m <= '9'))
- m-='0';
- else if ((m >= 'a') && (m <= 'f'))
- m=m-'a'+10;
- else if ((m >= 'A') && (m <= 'F'))
- m=m-'A'+10;
- else
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_NON_HEX_CHARACTERS);
- goto err;
- }
- s[num+j]<<=4;
- s[num+j]|=m;
- }
- }
- num+=i;
- if (again)
- bufsize=BIO_gets(bp,buf,size);
- else
- break;
- }
- bs->length=num;
- bs->data=s;
- ret=1;
-err:
- if (0)
- {
-err_sl:
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_SHORT_LINE);
- }
- if (s != NULL)
- OPENSSL_free(s);
- return(ret);
- }
+ for (j = 0; j < i; j++) {
+ if (!(((buf[j] >= '0') && (buf[j] <= '9')) ||
+ ((buf[j] >= 'a') && (buf[j] <= 'f')) ||
+ ((buf[j] >= 'A') && (buf[j] <= 'F')))) {
+ i = j;
+ break;
+ }
+ }
+ buf[i] = '\0';
+ /*
+ * We have now cleared all the crap off the end of the line
+ */
+ if (i < 2)
+ goto err_sl;
+ bufp = (unsigned char *)buf;
+ if (first) {
+ first = 0;
+ if ((bufp[0] == '0') && (buf[1] == '0')) {
+ bufp += 2;
+ i -= 2;
+ }
+ }
+ k = 0;
+ i -= again;
+ if (i % 2 != 0) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ODD_NUMBER_OF_CHARS);
+ goto err;
+ }
+ i /= 2;
+ if (num + i > slen) {
+ if (s == NULL)
+ sp = (unsigned char *)OPENSSL_malloc((unsigned int)num +
+ i * 2);
+ else
+ sp = OPENSSL_realloc_clean(s, slen, num + i * 2);
+ if (sp == NULL) {
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ s = sp;
+ slen = num + i * 2;
+ }
+ for (j = 0; j < i; j++, k += 2) {
+ for (n = 0; n < 2; n++) {
+ m = bufp[k + n];
+ if ((m >= '0') && (m <= '9'))
+ m -= '0';
+ else if ((m >= 'a') && (m <= 'f'))
+ m = m - 'a' + 10;
+ else if ((m >= 'A') && (m <= 'F'))
+ m = m - 'A' + 10;
+ else {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NON_HEX_CHARACTERS);
+ goto err;
+ }
+ s[num + j] <<= 4;
+ s[num + j] |= m;
+ }
+ }
+ num += i;
+ if (again)
+ bufsize = BIO_gets(bp, buf, size);
+ else
+ break;
+ }
+ bs->length = num;
+ bs->data = s;
+ ret = 1;
+ err:
+ if (0) {
+ err_sl:
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_SHORT_LINE);
+ }
+ if (s != NULL)
+ OPENSSL_free(s);
+ return (ret);
+}
diff --git a/src/crypto/asn1/f_string.c b/src/crypto/asn1/f_string.c
index 5a7fe36a..ec9cb83d 100644
--- a/src/crypto/asn1/f_string.c
+++ b/src/crypto/asn1/f_string.c
@@ -59,146 +59,138 @@
#include <openssl/err.h>
#include <openssl/mem.h>
-
-
int i2a_ASN1_STRING(BIO *bp, ASN1_STRING *a, int type)
- {
- int i,n=0;
- static const char *h="0123456789ABCDEF";
- char buf[2];
+{
+ int i, n = 0;
+ static const char *h = "0123456789ABCDEF";
+ char buf[2];
- if (a == NULL) return(0);
+ if (a == NULL)
+ return (0);
- if (a->length == 0)
- {
- if (BIO_write(bp,"0",1) != 1) goto err;
- n=1;
- }
- else
- {
- for (i=0; i<a->length; i++)
- {
- if ((i != 0) && (i%35 == 0))
- {
- if (BIO_write(bp,"\\\n",2) != 2) goto err;
- n+=2;
- }
- buf[0]=h[((unsigned char)a->data[i]>>4)&0x0f];
- buf[1]=h[((unsigned char)a->data[i] )&0x0f];
- if (BIO_write(bp,buf,2) != 2) goto err;
- n+=2;
- }
- }
- return(n);
-err:
- return(-1);
- }
+ if (a->length == 0) {
+ if (BIO_write(bp, "0", 1) != 1)
+ goto err;
+ n = 1;
+ } else {
+ for (i = 0; i < a->length; i++) {
+ if ((i != 0) && (i % 35 == 0)) {
+ if (BIO_write(bp, "\\\n", 2) != 2)
+ goto err;
+ n += 2;
+ }
+ buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f];
+ buf[1] = h[((unsigned char)a->data[i]) & 0x0f];
+ if (BIO_write(bp, buf, 2) != 2)
+ goto err;
+ n += 2;
+ }
+ }
+ return (n);
+ err:
+ return (-1);
+}
int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size)
- {
- int ret=0;
- int i,j,k,m,n,again,bufsize;
- unsigned char *s=NULL,*sp;
- unsigned char *bufp;
- int num=0,slen=0,first=1;
-
- bufsize=BIO_gets(bp,buf,size);
- for (;;)
- {
- if (bufsize < 1)
- {
- if (first)
- break;
- else
- goto err_sl;
- }
- first=0;
+{
+ int ret = 0;
+ int i, j, k, m, n, again, bufsize;
+ unsigned char *s = NULL, *sp;
+ unsigned char *bufp;
+ int num = 0, slen = 0, first = 1;
- i=bufsize;
- if (buf[i-1] == '\n') buf[--i]='\0';
- if (i == 0) goto err_sl;
- if (buf[i-1] == '\r') buf[--i]='\0';
- if (i == 0) goto err_sl;
- again=(buf[i-1] == '\\');
+ bufsize = BIO_gets(bp, buf, size);
+ for (;;) {
+ if (bufsize < 1) {
+ if (first)
+ break;
+ else
+ goto err_sl;
+ }
+ first = 0;
- for (j=i-1; j>0; j--)
- {
- if (!( ((buf[j] >= '0') && (buf[j] <= '9')) ||
- ((buf[j] >= 'a') && (buf[j] <= 'f')) ||
- ((buf[j] >= 'A') && (buf[j] <= 'F'))))
- {
- i=j;
- break;
- }
- }
- buf[i]='\0';
- /* We have now cleared all the crap off the end of the
- * line */
- if (i < 2) goto err_sl;
+ i = bufsize;
+ if (buf[i - 1] == '\n')
+ buf[--i] = '\0';
+ if (i == 0)
+ goto err_sl;
+ if (buf[i - 1] == '\r')
+ buf[--i] = '\0';
+ if (i == 0)
+ goto err_sl;
+ again = (buf[i - 1] == '\\');
- bufp=(unsigned char *)buf;
+ for (j = i - 1; j > 0; j--) {
+ if (!(((buf[j] >= '0') && (buf[j] <= '9')) ||
+ ((buf[j] >= 'a') && (buf[j] <= 'f')) ||
+ ((buf[j] >= 'A') && (buf[j] <= 'F')))) {
+ i = j;
+ break;
+ }
+ }
+ buf[i] = '\0';
+ /*
+ * We have now cleared all the crap off the end of the line
+ */
+ if (i < 2)
+ goto err_sl;
- k=0;
- i-=again;
- if (i%2 != 0)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_ODD_NUMBER_OF_CHARS);
- goto err;
- }
- i/=2;
- if (num+i > slen)
- {
- if (s == NULL)
- sp=(unsigned char *)OPENSSL_malloc(
- (unsigned int)num+i*2);
- else
- sp=(unsigned char *)OPENSSL_realloc(s,
- (unsigned int)num+i*2);
- if (sp == NULL)
- {
- OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- s=sp;
- slen=num+i*2;
- }
- for (j=0; j<i; j++,k+=2)
- {
- for (n=0; n<2; n++)
- {
- m=bufp[k+n];
- if ((m >= '0') && (m <= '9'))
- m-='0';
- else if ((m >= 'a') && (m <= 'f'))
- m=m-'a'+10;
- else if ((m >= 'A') && (m <= 'F'))
- m=m-'A'+10;
- else
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_NON_HEX_CHARACTERS);
- goto err;
- }
- s[num+j]<<=4;
- s[num+j]|=m;
- }
- }
- num+=i;
- if (again)
- bufsize=BIO_gets(bp,buf,size);
- else
- break;
- }
- bs->length=num;
- bs->data=s;
- ret=1;
-err:
- if (0)
- {
-err_sl:
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_SHORT_LINE);
- }
- if (s != NULL)
- OPENSSL_free(s);
- return(ret);
- }
+ bufp = (unsigned char *)buf;
+ k = 0;
+ i -= again;
+ if (i % 2 != 0) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ODD_NUMBER_OF_CHARS);
+ goto err;
+ }
+ i /= 2;
+ if (num + i > slen) {
+ if (s == NULL)
+ sp = (unsigned char *)OPENSSL_malloc((unsigned int)num +
+ i * 2);
+ else
+ sp = (unsigned char *)OPENSSL_realloc(s,
+ (unsigned int)num +
+ i * 2);
+ if (sp == NULL) {
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ s = sp;
+ slen = num + i * 2;
+ }
+ for (j = 0; j < i; j++, k += 2) {
+ for (n = 0; n < 2; n++) {
+ m = bufp[k + n];
+ if ((m >= '0') && (m <= '9'))
+ m -= '0';
+ else if ((m >= 'a') && (m <= 'f'))
+ m = m - 'a' + 10;
+ else if ((m >= 'A') && (m <= 'F'))
+ m = m - 'A' + 10;
+ else {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NON_HEX_CHARACTERS);
+ goto err;
+ }
+ s[num + j] <<= 4;
+ s[num + j] |= m;
+ }
+ }
+ num += i;
+ if (again)
+ bufsize = BIO_gets(bp, buf, size);
+ else
+ break;
+ }
+ bs->length = num;
+ bs->data = s;
+ ret = 1;
+ err:
+ if (0) {
+ err_sl:
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_SHORT_LINE);
+ }
+ if (s != NULL)
+ OPENSSL_free(s);
+ return (ret);
+}
diff --git a/src/crypto/asn1/t_bitst.c b/src/crypto/asn1/t_bitst.c
index 1ca6e089..e754ca73 100644
--- a/src/crypto/asn1/t_bitst.c
+++ b/src/crypto/asn1/t_bitst.c
@@ -60,43 +60,44 @@
#include <openssl/mem.h>
-
int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs,
- BIT_STRING_BITNAME *tbl, int indent)
+ BIT_STRING_BITNAME *tbl, int indent)
{
- BIT_STRING_BITNAME *bnam;
- char first = 1;
- BIO_printf(out, "%*s", indent, "");
- for(bnam = tbl; bnam->lname; bnam++) {
- if(ASN1_BIT_STRING_get_bit(bs, bnam->bitnum)) {
- if(!first) BIO_puts(out, ", ");
- BIO_puts(out, bnam->lname);
- first = 0;
- }
- }
- BIO_puts(out, "\n");
- return 1;
+ BIT_STRING_BITNAME *bnam;
+ char first = 1;
+ BIO_printf(out, "%*s", indent, "");
+ for (bnam = tbl; bnam->lname; bnam++) {
+ if (ASN1_BIT_STRING_get_bit(bs, bnam->bitnum)) {
+ if (!first)
+ BIO_puts(out, ", ");
+ BIO_puts(out, bnam->lname);
+ first = 0;
+ }
+ }
+ BIO_puts(out, "\n");
+ return 1;
}
int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, char *name, int value,
- BIT_STRING_BITNAME *tbl)
+ BIT_STRING_BITNAME *tbl)
{
- int bitnum;
- bitnum = ASN1_BIT_STRING_num_asc(name, tbl);
- if(bitnum < 0) return 0;
- if(bs) {
- if(!ASN1_BIT_STRING_set_bit(bs, bitnum, value))
- return 0;
- }
- return 1;
+ int bitnum;
+ bitnum = ASN1_BIT_STRING_num_asc(name, tbl);
+ if (bitnum < 0)
+ return 0;
+ if (bs) {
+ if (!ASN1_BIT_STRING_set_bit(bs, bitnum, value))
+ return 0;
+ }
+ return 1;
}
int ASN1_BIT_STRING_num_asc(char *name, BIT_STRING_BITNAME *tbl)
{
- BIT_STRING_BITNAME *bnam;
- for(bnam = tbl; bnam->lname; bnam++) {
- if(!strcmp(bnam->sname, name) ||
- !strcmp(bnam->lname, name) ) return bnam->bitnum;
- }
- return -1;
+ BIT_STRING_BITNAME *bnam;
+ for (bnam = tbl; bnam->lname; bnam++) {
+ if (!strcmp(bnam->sname, name) || !strcmp(bnam->lname, name))
+ return bnam->bitnum;
+ }
+ return -1;
}
diff --git a/src/crypto/asn1/tasn_dec.c b/src/crypto/asn1/tasn_dec.c
index 7c81753f..40d575d2 100644
--- a/src/crypto/asn1/tasn_dec.c
+++ b/src/crypto/asn1/tasn_dec.c
@@ -65,1278 +65,1157 @@
#include "../internal.h"
-
static int asn1_check_eoc(const unsigned char **in, long len);
static int asn1_find_end(const unsigned char **in, long len, char inf);
static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len,
- char inf, int tag, int aclass, int depth);
+ char inf, int tag, int aclass, int depth);
static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen);
static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
- char *inf, char *cst,
- const unsigned char **in, long len,
- int exptag, int expclass, char opt,
- ASN1_TLC *ctx);
+ char *inf, char *cst,
+ const unsigned char **in, long len,
+ int exptag, int expclass, char opt, ASN1_TLC *ctx);
static int asn1_template_ex_d2i(ASN1_VALUE **pval,
- const unsigned char **in, long len,
- const ASN1_TEMPLATE *tt, char opt,
- ASN1_TLC *ctx);
+ const unsigned char **in, long len,
+ const ASN1_TEMPLATE *tt, char opt,
+ ASN1_TLC *ctx);
static int asn1_template_noexp_d2i(ASN1_VALUE **val,
- const unsigned char **in, long len,
- const ASN1_TEMPLATE *tt, char opt,
- ASN1_TLC *ctx);
+ const unsigned char **in, long len,
+ const ASN1_TEMPLATE *tt, char opt,
+ ASN1_TLC *ctx);
static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
- const unsigned char **in, long len,
- const ASN1_ITEM *it,
- int tag, int aclass, char opt, ASN1_TLC *ctx);
+ const unsigned char **in, long len,
+ const ASN1_ITEM *it,
+ int tag, int aclass, char opt,
+ ASN1_TLC *ctx);
/* Table to convert tags to bit values, used for MSTRING type */
static const unsigned long tag2bit[32] = {
-0, 0, 0, B_ASN1_BIT_STRING, /* tags 0 - 3 */
-B_ASN1_OCTET_STRING, 0, 0, B_ASN1_UNKNOWN,/* tags 4- 7 */
-B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN,/* tags 8-11 */
-B_ASN1_UTF8STRING,B_ASN1_UNKNOWN,B_ASN1_UNKNOWN,B_ASN1_UNKNOWN,/* tags 12-15 */
-B_ASN1_SEQUENCE,0,B_ASN1_NUMERICSTRING,B_ASN1_PRINTABLESTRING, /* tags 16-19 */
-B_ASN1_T61STRING,B_ASN1_VIDEOTEXSTRING,B_ASN1_IA5STRING, /* tags 20-22 */
-B_ASN1_UTCTIME, B_ASN1_GENERALIZEDTIME, /* tags 23-24 */
-B_ASN1_GRAPHICSTRING,B_ASN1_ISO64STRING,B_ASN1_GENERALSTRING, /* tags 25-27 */
-B_ASN1_UNIVERSALSTRING,B_ASN1_UNKNOWN,B_ASN1_BMPSTRING,B_ASN1_UNKNOWN, /* tags 28-31 */
- };
+ 0, 0, 0, B_ASN1_BIT_STRING, /* tags 0 - 3 */
+ B_ASN1_OCTET_STRING, 0, 0, B_ASN1_UNKNOWN, /* tags 4- 7 */
+ B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, /* tags
+ * 8-11 */
+ B_ASN1_UTF8STRING, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, /* tags
+ * 12-15
+ */
+ B_ASN1_SEQUENCE, 0, B_ASN1_NUMERICSTRING, B_ASN1_PRINTABLESTRING, /* tags
+ * 16-19
+ */
+ B_ASN1_T61STRING, B_ASN1_VIDEOTEXSTRING, B_ASN1_IA5STRING, /* tags 20-22 */
+ B_ASN1_UTCTIME, B_ASN1_GENERALIZEDTIME, /* tags 23-24 */
+ B_ASN1_GRAPHICSTRING, B_ASN1_ISO64STRING, B_ASN1_GENERALSTRING, /* tags
+ * 25-27 */
+ B_ASN1_UNIVERSALSTRING, B_ASN1_UNKNOWN, B_ASN1_BMPSTRING, B_ASN1_UNKNOWN, /* tags
+ * 28-31
+ */
+};
unsigned long ASN1_tag2bit(int tag)
- {
- if ((tag < 0) || (tag > 30)) return 0;
- return tag2bit[tag];
- }
+{
+ if ((tag < 0) || (tag > 30))
+ return 0;
+ return tag2bit[tag];
+}
/* Macro to initialize and invalidate the cache */
-#define asn1_tlc_clear(c) if (c) (c)->valid = 0
+#define asn1_tlc_clear(c) if (c) (c)->valid = 0
/* Version to avoid compiler warning about 'c' always non-NULL */
-#define asn1_tlc_clear_nc(c) (c)->valid = 0
-
-/* Decode an ASN1 item, this currently behaves just
- * like a standard 'd2i' function. 'in' points to
- * a buffer to read the data from, in future we will
- * have more advanced versions that can input data
- * a piece at a time and this will simply be a special
- * case.
+#define asn1_tlc_clear_nc(c) (c)->valid = 0
+
+/*
+ * Decode an ASN1 item, this currently behaves just like a standard 'd2i'
+ * function. 'in' points to a buffer to read the data from, in future we
+ * will have more advanced versions that can input data a piece at a time and
+ * this will simply be a special case.
*/
ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval,
- const unsigned char **in, long len, const ASN1_ITEM *it)
- {
- ASN1_TLC c;
- ASN1_VALUE *ptmpval = NULL;
- if (!pval)
- pval = &ptmpval;
- asn1_tlc_clear_nc(&c);
- if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0)
- return *pval;
- return NULL;
- }
+ const unsigned char **in, long len,
+ const ASN1_ITEM *it)
+{
+ ASN1_TLC c;
+ ASN1_VALUE *ptmpval = NULL;
+ if (!pval)
+ pval = &ptmpval;
+ asn1_tlc_clear_nc(&c);
+ if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0)
+ return *pval;
+ return NULL;
+}
int ASN1_template_d2i(ASN1_VALUE **pval,
- const unsigned char **in, long len, const ASN1_TEMPLATE *tt)
- {
- ASN1_TLC c;
- asn1_tlc_clear_nc(&c);
- return asn1_template_ex_d2i(pval, in, len, tt, 0, &c);
- }
-
-
-/* Decode an item, taking care of IMPLICIT tagging, if any.
- * If 'opt' set and tag mismatch return -1 to handle OPTIONAL
+ const unsigned char **in, long len,
+ const ASN1_TEMPLATE *tt)
+{
+ ASN1_TLC c;
+ asn1_tlc_clear_nc(&c);
+ return asn1_template_ex_d2i(pval, in, len, tt, 0, &c);
+}
+
+/*
+ * Decode an item, taking care of IMPLICIT tagging, if any. If 'opt' set and
+ * tag mismatch return -1 to handle OPTIONAL
*/
int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
- const ASN1_ITEM *it,
- int tag, int aclass, char opt, ASN1_TLC *ctx)
- {
- const ASN1_TEMPLATE *tt, *errtt = NULL;
- const ASN1_COMPAT_FUNCS *cf;
- const ASN1_EXTERN_FUNCS *ef;
- const ASN1_AUX *aux = it->funcs;
- ASN1_aux_cb *asn1_cb;
- const unsigned char *p = NULL, *q;
- unsigned char *wp=NULL; /* BIG FAT WARNING! BREAKS CONST WHERE USED */
- unsigned char imphack = 0, oclass;
- char seq_eoc, seq_nolen, cst, isopt;
- long tmplen;
- int i;
- int otag;
- int ret = 0;
- ASN1_VALUE **pchptr, *ptmpval;
- int combine = aclass & ASN1_TFLG_COMBINE;
- if (!pval)
- return 0;
- if (aux && aux->asn1_cb)
- asn1_cb = aux->asn1_cb;
- else asn1_cb = 0;
-
- switch(it->itype)
- {
- case ASN1_ITYPE_PRIMITIVE:
- if (it->templates)
- {
- /* tagging or OPTIONAL is currently illegal on an item
- * template because the flags can't get passed down.
- * In practice this isn't a problem: we include the
- * relevant flags from the item template in the
- * template itself.
- */
- if ((tag != -1) || opt)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE);
- goto err;
- }
- return asn1_template_ex_d2i(pval, in, len,
- it->templates, opt, ctx);
- }
- return asn1_d2i_ex_primitive(pval, in, len, it,
- tag, aclass, opt, ctx);
- break;
-
- case ASN1_ITYPE_MSTRING:
- p = *in;
- /* Just read in tag and class */
- ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL,
- &p, len, -1, 0, 1, ctx);
- if (!ret)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
- goto err;
- }
-
- /* Must be UNIVERSAL class */
- if (oclass != V_ASN1_UNIVERSAL)
- {
- /* If OPTIONAL, assume this is OK */
- if (opt) return -1;
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_MSTRING_NOT_UNIVERSAL);
- goto err;
- }
- /* Check tag matches bit map */
- if (!(ASN1_tag2bit(otag) & it->utype))
- {
- /* If OPTIONAL, assume this is OK */
- if (opt)
- return -1;
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_MSTRING_WRONG_TAG);
- goto err;
- }
- return asn1_d2i_ex_primitive(pval, in, len,
- it, otag, 0, 0, ctx);
-
- case ASN1_ITYPE_EXTERN:
- /* Use new style d2i */
- ef = it->funcs;
- return ef->asn1_ex_d2i(pval, in, len,
- it, tag, aclass, opt, ctx);
-
- case ASN1_ITYPE_COMPAT:
- /* we must resort to old style evil hackery */
- cf = it->funcs;
-
- /* If OPTIONAL see if it is there */
- if (opt)
- {
- int exptag;
- p = *in;
- if (tag == -1)
- exptag = it->utype;
- else exptag = tag;
- /* Don't care about anything other than presence
- * of expected tag */
-
- ret = asn1_check_tlen(NULL, NULL, NULL, NULL, NULL,
- &p, len, exptag, aclass, 1, ctx);
- if (!ret)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
- goto err;
- }
- if (ret == -1)
- return -1;
- }
-
- /* This is the old style evil hack IMPLICIT handling:
- * since the underlying code is expecting a tag and
- * class other than the one present we change the
- * buffer temporarily then change it back afterwards.
- * This doesn't and never did work for tags > 30.
- *
- * Yes this is *horrible* but it is only needed for
- * old style d2i which will hopefully not be around
- * for much longer.
- * FIXME: should copy the buffer then modify it so
- * the input buffer can be const: we should *always*
- * copy because the old style d2i might modify the
- * buffer.
- */
-
- if (tag != -1)
- {
- wp = *(unsigned char **)in;
- imphack = *wp;
- if (p == NULL)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
- goto err;
- }
- *wp = (unsigned char)((*p & V_ASN1_CONSTRUCTED)
- | it->utype);
- }
-
- ptmpval = cf->asn1_d2i(pval, in, len);
-
- if (tag != -1)
- *wp = imphack;
-
- if (ptmpval)
- return 1;
-
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
- goto err;
-
-
- case ASN1_ITYPE_CHOICE:
- if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
- goto auxerr;
-
- if (*pval)
- {
- /* Free up and zero CHOICE value if initialised */
- i = asn1_get_choice_selector(pval, it);
- if ((i >= 0) && (i < it->tcount))
- {
- tt = it->templates + i;
- pchptr = asn1_get_field_ptr(pval, tt);
- ASN1_template_free(pchptr, tt);
- asn1_set_choice_selector(pval, -1, it);
- }
- }
- else if (!ASN1_item_ex_new(pval, it))
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
- goto err;
- }
- /* CHOICE type, try each possibility in turn */
- p = *in;
- for (i = 0, tt=it->templates; i < it->tcount; i++, tt++)
- {
- pchptr = asn1_get_field_ptr(pval, tt);
- /* We mark field as OPTIONAL so its absence
- * can be recognised.
- */
- ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx);
- /* If field not present, try the next one */
- if (ret == -1)
- continue;
- /* If positive return, read OK, break loop */
- if (ret > 0)
- break;
- /* Otherwise must be an ASN1 parsing error */
- errtt = tt;
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
- goto err;
- }
-
- /* Did we fall off the end without reading anything? */
- if (i == it->tcount)
- {
- /* If OPTIONAL, this is OK */
- if (opt)
- {
- /* Free and zero it */
- ASN1_item_ex_free(pval, it);
- return -1;
- }
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_NO_MATCHING_CHOICE_TYPE);
- goto err;
- }
-
- asn1_set_choice_selector(pval, i, it);
- if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
- goto auxerr;
- *in = p;
- return 1;
-
- case ASN1_ITYPE_NDEF_SEQUENCE:
- case ASN1_ITYPE_SEQUENCE:
- p = *in;
- tmplen = len;
-
- /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
- if (tag == -1)
- {
- tag = V_ASN1_SEQUENCE;
- aclass = V_ASN1_UNIVERSAL;
- }
- /* Get SEQUENCE length and update len, p */
- ret = asn1_check_tlen(&len, NULL, NULL, &seq_eoc, &cst,
- &p, len, tag, aclass, opt, ctx);
- if (!ret)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
- goto err;
- }
- else if (ret == -1)
- return -1;
- if (aux && (aux->flags & ASN1_AFLG_BROKEN))
- {
- len = tmplen - (p - *in);
- seq_nolen = 1;
- }
- /* If indefinite we don't do a length check */
- else seq_nolen = seq_eoc;
- if (!cst)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_NOT_CONSTRUCTED);
- goto err;
- }
-
- if (!*pval && !ASN1_item_ex_new(pval, it))
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
- goto err;
- }
-
- if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
- goto auxerr;
-
- /* Free up and zero any ADB found */
- for (i = 0, tt = it->templates; i < it->tcount; i++, tt++)
- {
- if (tt->flags & ASN1_TFLG_ADB_MASK)
- {
- const ASN1_TEMPLATE *seqtt;
- ASN1_VALUE **pseqval;
- seqtt = asn1_do_adb(pval, tt, 1);
- pseqval = asn1_get_field_ptr(pval, seqtt);
- ASN1_template_free(pseqval, seqtt);
- }
- }
-
- /* Get each field entry */
- for (i = 0, tt = it->templates; i < it->tcount; i++, tt++)
- {
- const ASN1_TEMPLATE *seqtt;
- ASN1_VALUE **pseqval;
- seqtt = asn1_do_adb(pval, tt, 1);
- if (!seqtt)
- goto err;
- pseqval = asn1_get_field_ptr(pval, seqtt);
- /* Have we ran out of data? */
- if (!len)
- break;
- q = p;
- if (asn1_check_eoc(&p, len))
- {
- if (!seq_eoc)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNEXPECTED_EOC);
- goto err;
- }
- len -= p - q;
- seq_eoc = 0;
- q = p;
- break;
- }
- /* This determines the OPTIONAL flag value. The field
- * cannot be omitted if it is the last of a SEQUENCE
- * and there is still data to be read. This isn't
- * strictly necessary but it increases efficiency in
- * some cases.
- */
- if (i == (it->tcount - 1))
- isopt = 0;
- else isopt = (char)(seqtt->flags & ASN1_TFLG_OPTIONAL);
- /* attempt to read in field, allowing each to be
- * OPTIONAL */
-
- ret = asn1_template_ex_d2i(pseqval, &p, len,
- seqtt, isopt, ctx);
- if (!ret)
- {
- errtt = seqtt;
- goto err;
- }
- else if (ret == -1)
- {
- /* OPTIONAL component absent.
- * Free and zero the field.
- */
- ASN1_template_free(pseqval, seqtt);
- continue;
- }
- /* Update length */
- len -= p - q;
- }
-
- /* Check for EOC if expecting one */
- if (seq_eoc && !asn1_check_eoc(&p, len))
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC);
- goto err;
- }
- /* Check all data read */
- if (!seq_nolen && len)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_LENGTH_MISMATCH);
- goto err;
- }
-
- /* If we get here we've got no more data in the SEQUENCE,
- * however we may not have read all fields so check all
- * remaining are OPTIONAL and clear any that are.
- */
- for (; i < it->tcount; tt++, i++)
- {
- const ASN1_TEMPLATE *seqtt;
- seqtt = asn1_do_adb(pval, tt, 1);
- if (!seqtt)
- goto err;
- if (seqtt->flags & ASN1_TFLG_OPTIONAL)
- {
- ASN1_VALUE **pseqval;
- pseqval = asn1_get_field_ptr(pval, seqtt);
- ASN1_template_free(pseqval, seqtt);
- }
- else
- {
- errtt = seqtt;
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_FIELD_MISSING);
- goto err;
- }
- }
- /* Save encoding */
- if (!asn1_enc_save(pval, *in, p - *in, it))
- goto auxerr;
- 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_R_AUX_ERROR);
- err:
- if (combine == 0)
- ASN1_item_ex_free(pval, it);
- if (errtt)
- ERR_add_error_data(4, "Field=", errtt->field_name,
- ", Type=", it->sname);
- else
- ERR_add_error_data(2, "Type=", it->sname);
- return 0;
- }
-
-/* Templates are handled with two separate functions.
- * One handles any EXPLICIT tag and the other handles the rest.
+ const ASN1_ITEM *it,
+ int tag, int aclass, char opt, ASN1_TLC *ctx)
+{
+ const ASN1_TEMPLATE *tt, *errtt = NULL;
+ const ASN1_COMPAT_FUNCS *cf;
+ const ASN1_EXTERN_FUNCS *ef;
+ const ASN1_AUX *aux = it->funcs;
+ ASN1_aux_cb *asn1_cb;
+ const unsigned char *p = NULL, *q;
+ unsigned char *wp = NULL; /* BIG FAT WARNING! BREAKS CONST WHERE USED */
+ unsigned char imphack = 0, oclass;
+ char seq_eoc, seq_nolen, cst, isopt;
+ long tmplen;
+ int i;
+ int otag;
+ int ret = 0;
+ ASN1_VALUE **pchptr, *ptmpval;
+ int combine = aclass & ASN1_TFLG_COMBINE;
+ if (!pval)
+ return 0;
+ if (aux && aux->asn1_cb)
+ asn1_cb = aux->asn1_cb;
+ else
+ asn1_cb = 0;
+
+ switch (it->itype) {
+ case ASN1_ITYPE_PRIMITIVE:
+ if (it->templates) {
+ /*
+ * tagging or OPTIONAL is currently illegal on an item template
+ * because the flags can't get passed down. In practice this
+ * isn't a problem: we include the relevant flags from the item
+ * template in the template itself.
+ */
+ if ((tag != -1) || opt) {
+ OPENSSL_PUT_ERROR(ASN1,
+ ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE);
+ goto err;
+ }
+ return asn1_template_ex_d2i(pval, in, len,
+ it->templates, opt, ctx);
+ }
+ return asn1_d2i_ex_primitive(pval, in, len, it,
+ tag, aclass, opt, ctx);
+ break;
+
+ case ASN1_ITYPE_MSTRING:
+ p = *in;
+ /* Just read in tag and class */
+ ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL,
+ &p, len, -1, 0, 1, ctx);
+ if (!ret) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
+ goto err;
+ }
+
+ /* Must be UNIVERSAL class */
+ if (oclass != V_ASN1_UNIVERSAL) {
+ /* If OPTIONAL, assume this is OK */
+ if (opt)
+ return -1;
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_MSTRING_NOT_UNIVERSAL);
+ goto err;
+ }
+ /* Check tag matches bit map */
+ if (!(ASN1_tag2bit(otag) & it->utype)) {
+ /* If OPTIONAL, assume this is OK */
+ if (opt)
+ return -1;
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_MSTRING_WRONG_TAG);
+ goto err;
+ }
+ return asn1_d2i_ex_primitive(pval, in, len, it, otag, 0, 0, ctx);
+
+ case ASN1_ITYPE_EXTERN:
+ /* Use new style d2i */
+ ef = it->funcs;
+ return ef->asn1_ex_d2i(pval, in, len, it, tag, aclass, opt, ctx);
+
+ case ASN1_ITYPE_COMPAT:
+ /* we must resort to old style evil hackery */
+ cf = it->funcs;
+
+ /* If OPTIONAL see if it is there */
+ if (opt) {
+ int exptag;
+ p = *in;
+ if (tag == -1)
+ exptag = it->utype;
+ else
+ exptag = tag;
+ /*
+ * Don't care about anything other than presence of expected tag
+ */
+
+ ret = asn1_check_tlen(NULL, NULL, NULL, NULL, NULL,
+ &p, len, exptag, aclass, 1, ctx);
+ if (!ret) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
+ goto err;
+ }
+ if (ret == -1)
+ return -1;
+ }
+
+ /*
+ * This is the old style evil hack IMPLICIT handling: since the
+ * underlying code is expecting a tag and class other than the one
+ * present we change the buffer temporarily then change it back
+ * afterwards. This doesn't and never did work for tags > 30. Yes
+ * this is *horrible* but it is only needed for old style d2i which
+ * will hopefully not be around for much longer. FIXME: should copy
+ * the buffer then modify it so the input buffer can be const: we
+ * should *always* copy because the old style d2i might modify the
+ * buffer.
+ */
+
+ if (tag != -1) {
+ wp = *(unsigned char **)in;
+ imphack = *wp;
+ if (p == NULL) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
+ goto err;
+ }
+ *wp = (unsigned char)((*p & V_ASN1_CONSTRUCTED)
+ | it->utype);
+ }
+
+ ptmpval = cf->asn1_d2i(pval, in, len);
+
+ if (tag != -1)
+ *wp = imphack;
+
+ if (ptmpval)
+ return 1;
+
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
+ goto err;
+
+ case ASN1_ITYPE_CHOICE:
+ if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
+ goto auxerr;
+
+ if (*pval) {
+ /* Free up and zero CHOICE value if initialised */
+ i = asn1_get_choice_selector(pval, it);
+ if ((i >= 0) && (i < it->tcount)) {
+ tt = it->templates + i;
+ pchptr = asn1_get_field_ptr(pval, tt);
+ ASN1_template_free(pchptr, tt);
+ asn1_set_choice_selector(pval, -1, it);
+ }
+ } else if (!ASN1_item_ex_new(pval, it)) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
+ goto err;
+ }
+ /* CHOICE type, try each possibility in turn */
+ p = *in;
+ for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
+ pchptr = asn1_get_field_ptr(pval, tt);
+ /*
+ * We mark field as OPTIONAL so its absence can be recognised.
+ */
+ ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx);
+ /* If field not present, try the next one */
+ if (ret == -1)
+ continue;
+ /* If positive return, read OK, break loop */
+ if (ret > 0)
+ break;
+ /* Otherwise must be an ASN1 parsing error */
+ errtt = tt;
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
+ goto err;
+ }
+
+ /* Did we fall off the end without reading anything? */
+ if (i == it->tcount) {
+ /* If OPTIONAL, this is OK */
+ if (opt) {
+ /* Free and zero it */
+ ASN1_item_ex_free(pval, it);
+ return -1;
+ }
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NO_MATCHING_CHOICE_TYPE);
+ goto err;
+ }
+
+ asn1_set_choice_selector(pval, i, it);
+ if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
+ goto auxerr;
+ *in = p;
+ return 1;
+
+ case ASN1_ITYPE_NDEF_SEQUENCE:
+ case ASN1_ITYPE_SEQUENCE:
+ p = *in;
+ tmplen = len;
+
+ /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
+ if (tag == -1) {
+ tag = V_ASN1_SEQUENCE;
+ aclass = V_ASN1_UNIVERSAL;
+ }
+ /* Get SEQUENCE length and update len, p */
+ ret = asn1_check_tlen(&len, NULL, NULL, &seq_eoc, &cst,
+ &p, len, tag, aclass, opt, ctx);
+ if (!ret) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
+ goto err;
+ } else if (ret == -1)
+ return -1;
+ if (aux && (aux->flags & ASN1_AFLG_BROKEN)) {
+ len = tmplen - (p - *in);
+ seq_nolen = 1;
+ }
+ /* If indefinite we don't do a length check */
+ else
+ seq_nolen = seq_eoc;
+ if (!cst) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_NOT_CONSTRUCTED);
+ goto err;
+ }
+
+ if (!*pval && !ASN1_item_ex_new(pval, it)) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
+ goto err;
+ }
+
+ if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
+ goto auxerr;
+
+ /* Free up and zero any ADB found */
+ for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
+ if (tt->flags & ASN1_TFLG_ADB_MASK) {
+ const ASN1_TEMPLATE *seqtt;
+ ASN1_VALUE **pseqval;
+ seqtt = asn1_do_adb(pval, tt, 1);
+ pseqval = asn1_get_field_ptr(pval, seqtt);
+ ASN1_template_free(pseqval, seqtt);
+ }
+ }
+
+ /* Get each field entry */
+ for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
+ const ASN1_TEMPLATE *seqtt;
+ ASN1_VALUE **pseqval;
+ seqtt = asn1_do_adb(pval, tt, 1);
+ if (!seqtt)
+ goto err;
+ pseqval = asn1_get_field_ptr(pval, seqtt);
+ /* Have we ran out of data? */
+ if (!len)
+ break;
+ q = p;
+ if (asn1_check_eoc(&p, len)) {
+ if (!seq_eoc) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNEXPECTED_EOC);
+ goto err;
+ }
+ len -= p - q;
+ seq_eoc = 0;
+ q = p;
+ break;
+ }
+ /*
+ * This determines the OPTIONAL flag value. The field cannot be
+ * omitted if it is the last of a SEQUENCE and there is still
+ * data to be read. This isn't strictly necessary but it
+ * increases efficiency in some cases.
+ */
+ if (i == (it->tcount - 1))
+ isopt = 0;
+ else
+ isopt = (char)(seqtt->flags & ASN1_TFLG_OPTIONAL);
+ /*
+ * attempt to read in field, allowing each to be OPTIONAL
+ */
+
+ ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, ctx);
+ if (!ret) {
+ errtt = seqtt;
+ goto err;
+ } else if (ret == -1) {
+ /*
+ * OPTIONAL component absent. Free and zero the field.
+ */
+ ASN1_template_free(pseqval, seqtt);
+ continue;
+ }
+ /* Update length */
+ len -= p - q;
+ }
+
+ /* Check for EOC if expecting one */
+ if (seq_eoc && !asn1_check_eoc(&p, len)) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC);
+ goto err;
+ }
+ /* Check all data read */
+ if (!seq_nolen && len) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_LENGTH_MISMATCH);
+ goto err;
+ }
+
+ /*
+ * If we get here we've got no more data in the SEQUENCE, however we
+ * may not have read all fields so check all remaining are OPTIONAL
+ * and clear any that are.
+ */
+ for (; i < it->tcount; tt++, i++) {
+ const ASN1_TEMPLATE *seqtt;
+ seqtt = asn1_do_adb(pval, tt, 1);
+ if (!seqtt)
+ goto err;
+ if (seqtt->flags & ASN1_TFLG_OPTIONAL) {
+ ASN1_VALUE **pseqval;
+ pseqval = asn1_get_field_ptr(pval, seqtt);
+ ASN1_template_free(pseqval, seqtt);
+ } else {
+ errtt = seqtt;
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_FIELD_MISSING);
+ goto err;
+ }
+ }
+ /* Save encoding */
+ if (!asn1_enc_save(pval, *in, p - *in, it))
+ goto auxerr;
+ 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_R_AUX_ERROR);
+ err:
+ if (combine == 0)
+ ASN1_item_ex_free(pval, it);
+ if (errtt)
+ ERR_add_error_data(4, "Field=", errtt->field_name,
+ ", Type=", it->sname);
+ else
+ ERR_add_error_data(2, "Type=", it->sname);
+ return 0;
+}
+
+/*
+ * Templates are handled with two separate functions. One handles any
+ * EXPLICIT tag and the other handles the rest.
*/
static int asn1_template_ex_d2i(ASN1_VALUE **val,
- const unsigned char **in, long inlen,
- const ASN1_TEMPLATE *tt, char opt,
- ASN1_TLC *ctx)
- {
- int flags, aclass;
- int ret;
- long len;
- const unsigned char *p, *q;
- char exp_eoc;
- if (!val)
- return 0;
- flags = tt->flags;
- aclass = flags & ASN1_TFLG_TAG_CLASS;
-
- p = *in;
-
- /* Check if EXPLICIT tag expected */
- if (flags & ASN1_TFLG_EXPTAG)
- {
- char cst;
- /* Need to work out amount of data available to the inner
- * content and where it starts: so read in EXPLICIT header to
- * get the info.
- */
- ret = asn1_check_tlen(&len, NULL, NULL, &exp_eoc, &cst,
- &p, inlen, tt->tag, aclass, opt, ctx);
- q = p;
- if (!ret)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
- return 0;
- }
- else if (ret == -1)
- return -1;
- if (!cst)
- {
- 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_R_NESTED_ASN1_ERROR);
- return 0;
- }
- /* We read the field in OK so update length */
- len -= p - q;
- if (exp_eoc)
- {
- /* If NDEF we must have an EOC here */
- if (!asn1_check_eoc(&p, len))
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC);
- goto err;
- }
- }
- else
- {
- /* Otherwise we must hit the EXPLICIT tag end or its
- * an error */
- if (len)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_EXPLICIT_LENGTH_MISMATCH);
- goto err;
- }
- }
- }
- else
- return asn1_template_noexp_d2i(val, in, inlen,
- tt, opt, ctx);
-
- *in = p;
- return 1;
-
- err:
- ASN1_template_free(val, tt);
- return 0;
- }
+ const unsigned char **in, long inlen,
+ const ASN1_TEMPLATE *tt, char opt,
+ ASN1_TLC *ctx)
+{
+ int flags, aclass;
+ int ret;
+ long len;
+ const unsigned char *p, *q;
+ char exp_eoc;
+ if (!val)
+ return 0;
+ flags = tt->flags;
+ aclass = flags & ASN1_TFLG_TAG_CLASS;
+
+ p = *in;
+
+ /* Check if EXPLICIT tag expected */
+ if (flags & ASN1_TFLG_EXPTAG) {
+ char cst;
+ /*
+ * Need to work out amount of data available to the inner content and
+ * where it starts: so read in EXPLICIT header to get the info.
+ */
+ ret = asn1_check_tlen(&len, NULL, NULL, &exp_eoc, &cst,
+ &p, inlen, tt->tag, aclass, opt, ctx);
+ q = p;
+ if (!ret) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
+ return 0;
+ } else if (ret == -1)
+ return -1;
+ if (!cst) {
+ 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_R_NESTED_ASN1_ERROR);
+ return 0;
+ }
+ /* We read the field in OK so update length */
+ len -= p - q;
+ if (exp_eoc) {
+ /* If NDEF we must have an EOC here */
+ if (!asn1_check_eoc(&p, len)) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC);
+ goto err;
+ }
+ } else {
+ /*
+ * Otherwise we must hit the EXPLICIT tag end or its an error
+ */
+ if (len) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_EXPLICIT_LENGTH_MISMATCH);
+ goto err;
+ }
+ }
+ } else
+ return asn1_template_noexp_d2i(val, in, inlen, tt, opt, ctx);
+
+ *in = p;
+ return 1;
+
+ err:
+ ASN1_template_free(val, tt);
+ return 0;
+}
static int asn1_template_noexp_d2i(ASN1_VALUE **val,
- const unsigned char **in, long len,
- const ASN1_TEMPLATE *tt, char opt,
- ASN1_TLC *ctx)
- {
- int flags, aclass;
- int ret;
- const unsigned char *p;
- if (!val)
- return 0;
- flags = tt->flags;
- aclass = flags & ASN1_TFLG_TAG_CLASS;
-
- p = *in;
-
- if (flags & ASN1_TFLG_SK_MASK)
- {
- /* SET OF, SEQUENCE OF */
- int sktag, skaclass;
- char sk_eoc;
- /* First work out expected inner tag value */
- if (flags & ASN1_TFLG_IMPTAG)
- {
- sktag = tt->tag;
- skaclass = aclass;
- }
- else
- {
- skaclass = V_ASN1_UNIVERSAL;
- if (flags & ASN1_TFLG_SET_OF)
- sktag = V_ASN1_SET;
- else
- sktag = V_ASN1_SEQUENCE;
- }
- /* Get the tag */
- ret = asn1_check_tlen(&len, NULL, NULL, &sk_eoc, NULL,
- &p, len, sktag, skaclass, opt, ctx);
- if (!ret)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
- return 0;
- }
- else if (ret == -1)
- return -1;
- if (!*val)
- *val = (ASN1_VALUE *)sk_new_null();
- else
- {
- /* We've got a valid STACK: free up any items present */
- STACK_OF(ASN1_VALUE) *sktmp
- = (STACK_OF(ASN1_VALUE) *)*val;
- ASN1_VALUE *vtmp;
- while(sk_ASN1_VALUE_num(sktmp) > 0)
- {
- vtmp = sk_ASN1_VALUE_pop(sktmp);
- ASN1_item_ex_free(&vtmp,
- ASN1_ITEM_ptr(tt->item));
- }
- }
-
- if (!*val)
- {
- OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
- goto err;
- }
-
- /* Read as many items as we can */
- while(len > 0)
- {
- ASN1_VALUE *skfield;
- const unsigned char *q = p;
- /* See if EOC found */
- if (asn1_check_eoc(&p, len))
- {
- if (!sk_eoc)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNEXPECTED_EOC);
- goto err;
- }
- len -= p - q;
- sk_eoc = 0;
- break;
- }
- skfield = NULL;
- if (!ASN1_item_ex_d2i(&skfield, &p, len,
- ASN1_ITEM_ptr(tt->item),
- -1, 0, 0, ctx))
- {
- 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, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- }
- if (sk_eoc)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC);
- goto err;
- }
- }
- else if (flags & ASN1_TFLG_IMPTAG)
- {
- /* IMPLICIT tagging */
- ret = ASN1_item_ex_d2i(val, &p, len,
- ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt, ctx);
- if (!ret)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
- goto err;
- }
- else if (ret == -1)
- return -1;
- }
- else
- {
- /* Nothing special */
- ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item),
- -1, tt->flags & ASN1_TFLG_COMBINE, opt, ctx);
- if (!ret)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
- goto err;
- }
- else if (ret == -1)
- return -1;
- }
-
- *in = p;
- return 1;
-
- err:
- ASN1_template_free(val, tt);
- return 0;
- }
+ const unsigned char **in, long len,
+ const ASN1_TEMPLATE *tt, char opt,
+ ASN1_TLC *ctx)
+{
+ int flags, aclass;
+ int ret;
+ const unsigned char *p;
+ if (!val)
+ return 0;
+ flags = tt->flags;
+ aclass = flags & ASN1_TFLG_TAG_CLASS;
+
+ p = *in;
+
+ if (flags & ASN1_TFLG_SK_MASK) {
+ /* SET OF, SEQUENCE OF */
+ int sktag, skaclass;
+ char sk_eoc;
+ /* First work out expected inner tag value */
+ if (flags & ASN1_TFLG_IMPTAG) {
+ sktag = tt->tag;
+ skaclass = aclass;
+ } else {
+ skaclass = V_ASN1_UNIVERSAL;
+ if (flags & ASN1_TFLG_SET_OF)
+ sktag = V_ASN1_SET;
+ else
+ sktag = V_ASN1_SEQUENCE;
+ }
+ /* Get the tag */
+ ret = asn1_check_tlen(&len, NULL, NULL, &sk_eoc, NULL,
+ &p, len, sktag, skaclass, opt, ctx);
+ if (!ret) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
+ return 0;
+ } else if (ret == -1)
+ return -1;
+ if (!*val)
+ *val = (ASN1_VALUE *)sk_new_null();
+ else {
+ /*
+ * We've got a valid STACK: free up any items present
+ */
+ STACK_OF(ASN1_VALUE) *sktmp = (STACK_OF(ASN1_VALUE) *)*val;
+ ASN1_VALUE *vtmp;
+ while (sk_ASN1_VALUE_num(sktmp) > 0) {
+ vtmp = sk_ASN1_VALUE_pop(sktmp);
+ ASN1_item_ex_free(&vtmp, ASN1_ITEM_ptr(tt->item));
+ }
+ }
+
+ if (!*val) {
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ /* Read as many items as we can */
+ while (len > 0) {
+ ASN1_VALUE *skfield;
+ const unsigned char *q = p;
+ /* See if EOC found */
+ if (asn1_check_eoc(&p, len)) {
+ if (!sk_eoc) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNEXPECTED_EOC);
+ goto err;
+ }
+ len -= p - q;
+ sk_eoc = 0;
+ break;
+ }
+ skfield = NULL;
+ if (!ASN1_item_ex_d2i(&skfield, &p, len,
+ ASN1_ITEM_ptr(tt->item), -1, 0, 0, ctx)) {
+ 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, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+ if (sk_eoc) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC);
+ goto err;
+ }
+ } else if (flags & ASN1_TFLG_IMPTAG) {
+ /* IMPLICIT tagging */
+ ret = ASN1_item_ex_d2i(val, &p, len,
+ ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt,
+ ctx);
+ if (!ret) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
+ goto err;
+ } else if (ret == -1)
+ return -1;
+ } else {
+ /* Nothing special */
+ ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item),
+ -1, tt->flags & ASN1_TFLG_COMBINE, opt, ctx);
+ if (!ret) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
+ goto err;
+ } else if (ret == -1)
+ return -1;
+ }
+
+ *in = p;
+ return 1;
+
+ err:
+ ASN1_template_free(val, tt);
+ return 0;
+}
static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
- const unsigned char **in, long inlen,
- const ASN1_ITEM *it,
- int tag, int aclass, char opt, ASN1_TLC *ctx)
- OPENSSL_SUPPRESS_POTENTIALLY_UNINITIALIZED_WARNINGS
- {
- int ret = 0, utype;
- long plen;
- char cst, inf, free_cont = 0;
- const unsigned char *p;
- BUF_MEM buf;
- const unsigned char *cont = NULL;
- long len;
- if (!pval)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NULL);
- return 0; /* Should never happen */
- }
-
- if (it->itype == ASN1_ITYPE_MSTRING)
- {
- utype = tag;
- tag = -1;
- }
- else
- utype = it->utype;
-
- if (utype == V_ASN1_ANY)
- {
- /* If type is ANY need to figure out type from tag */
- unsigned char oclass;
- if (tag >= 0)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_TAGGED_ANY);
- return 0;
- }
- if (opt)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OPTIONAL_ANY);
- return 0;
- }
- p = *in;
- ret = asn1_check_tlen(NULL, &utype, &oclass, NULL, NULL,
- &p, inlen, -1, 0, 0, ctx);
- if (!ret)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
- return 0;
- }
- if (oclass != V_ASN1_UNIVERSAL)
- utype = V_ASN1_OTHER;
- }
- if (tag == -1)
- {
- tag = utype;
- aclass = V_ASN1_UNIVERSAL;
- }
- p = *in;
- /* Check header */
- ret = asn1_check_tlen(&plen, NULL, NULL, &inf, &cst,
- &p, inlen, tag, aclass, opt, ctx);
- if (!ret)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
- return 0;
- }
- else if (ret == -1)
- return -1;
- ret = 0;
- /* SEQUENCE, SET and "OTHER" are left in encoded form */
- if ((utype == V_ASN1_SEQUENCE)
- || (utype == V_ASN1_SET) || (utype == V_ASN1_OTHER))
- {
- /* Clear context cache for type OTHER because the auto clear
- * when we have a exact match wont work
- */
- if (utype == V_ASN1_OTHER)
- {
- asn1_tlc_clear(ctx);
- }
- /* SEQUENCE and SET must be constructed */
- else if (!cst)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_TYPE_NOT_CONSTRUCTED);
- return 0;
- }
-
- cont = *in;
- /* If indefinite length constructed find the real end */
- if (inf)
- {
- if (!asn1_find_end(&p, plen, inf))
- goto err;
- len = p - cont;
- }
- else
- {
- len = p - cont + plen;
- p += plen;
- buf.data = NULL;
- }
- }
- else if (cst)
- {
- if (utype == V_ASN1_NULL || utype == V_ASN1_BOOLEAN
- || utype == V_ASN1_OBJECT || utype == V_ASN1_INTEGER
- || utype == V_ASN1_ENUMERATED)
- {
- /* These types only have primitive encodings. */
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_TYPE_NOT_PRIMITIVE);
- return 0;
- }
-
- buf.length = 0;
- buf.max = 0;
- buf.data = NULL;
- /* Should really check the internal tags are correct but
- * some things may get this wrong. The relevant specs
- * say that constructed string types should be OCTET STRINGs
- * internally irrespective of the type. So instead just check
- * for UNIVERSAL class and ignore the tag.
- */
- if (!asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL, 0))
- {
- free_cont = 1;
- goto err;
- }
- len = buf.length;
- /* Append a final null to string */
- if (!BUF_MEM_grow_clean(&buf, len + 1))
- {
- OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
- return 0;
- }
- buf.data[len] = 0;
- cont = (const unsigned char *)buf.data;
- free_cont = 1;
- }
- else
- {
- cont = p;
- len = plen;
- p += plen;
- }
-
- /* We now have content length and type: translate into a structure */
- if (!asn1_ex_c2i(pval, cont, len, utype, &free_cont, it))
- goto err;
-
- *in = p;
- ret = 1;
- err:
- if (free_cont && buf.data) OPENSSL_free(buf.data);
- return ret;
- }
+ const unsigned char **in, long inlen,
+ const ASN1_ITEM *it,
+ int tag, int aclass, char opt, ASN1_TLC *ctx)
+{
+ int ret = 0, utype;
+ long plen;
+ char cst, inf, free_cont = 0;
+ const unsigned char *p;
+ BUF_MEM buf = {0, NULL, 0 };
+ const unsigned char *cont = NULL;
+ long len;
+ if (!pval) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NULL);
+ return 0; /* Should never happen */
+ }
+
+ if (it->itype == ASN1_ITYPE_MSTRING) {
+ utype = tag;
+ tag = -1;
+ } else
+ utype = it->utype;
+
+ if (utype == V_ASN1_ANY) {
+ /* If type is ANY need to figure out type from tag */
+ unsigned char oclass;
+ if (tag >= 0) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_TAGGED_ANY);
+ return 0;
+ }
+ if (opt) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OPTIONAL_ANY);
+ return 0;
+ }
+ p = *in;
+ ret = asn1_check_tlen(NULL, &utype, &oclass, NULL, NULL,
+ &p, inlen, -1, 0, 0, ctx);
+ if (!ret) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
+ return 0;
+ }
+ if (oclass != V_ASN1_UNIVERSAL)
+ utype = V_ASN1_OTHER;
+ }
+ if (tag == -1) {
+ tag = utype;
+ aclass = V_ASN1_UNIVERSAL;
+ }
+ p = *in;
+ /* Check header */
+ ret = asn1_check_tlen(&plen, NULL, NULL, &inf, &cst,
+ &p, inlen, tag, aclass, opt, ctx);
+ if (!ret) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
+ return 0;
+ } else if (ret == -1)
+ return -1;
+ ret = 0;
+ /* SEQUENCE, SET and "OTHER" are left in encoded form */
+ if ((utype == V_ASN1_SEQUENCE)
+ || (utype == V_ASN1_SET) || (utype == V_ASN1_OTHER)) {
+ /*
+ * Clear context cache for type OTHER because the auto clear when we
+ * have a exact match wont work
+ */
+ if (utype == V_ASN1_OTHER) {
+ asn1_tlc_clear(ctx);
+ }
+ /* SEQUENCE and SET must be constructed */
+ else if (!cst) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_TYPE_NOT_CONSTRUCTED);
+ return 0;
+ }
+
+ cont = *in;
+ /* If indefinite length constructed find the real end */
+ if (inf) {
+ if (!asn1_find_end(&p, plen, inf))
+ goto err;
+ len = p - cont;
+ } else {
+ len = p - cont + plen;
+ p += plen;
+ }
+ } else if (cst) {
+ if (utype == V_ASN1_NULL || utype == V_ASN1_BOOLEAN
+ || utype == V_ASN1_OBJECT || utype == V_ASN1_INTEGER
+ || utype == V_ASN1_ENUMERATED) {
+ /* These types only have primitive encodings. */
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_TYPE_NOT_PRIMITIVE);
+ return 0;
+ }
+
+ /* Free any returned 'buf' content */
+ free_cont = 1;
+ /*
+ * Should really check the internal tags are correct but some things
+ * may get this wrong. The relevant specs say that constructed string
+ * types should be OCTET STRINGs internally irrespective of the type.
+ * So instead just check for UNIVERSAL class and ignore the tag.
+ */
+ if (!asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL, 0)) {
+ goto err;
+ }
+ len = buf.length;
+ /* Append a final null to string */
+ if (!BUF_MEM_grow_clean(&buf, len + 1)) {
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ buf.data[len] = 0;
+ cont = (const unsigned char *)buf.data;
+ } else {
+ cont = p;
+ len = plen;
+ p += plen;
+ }
+
+ /* We now have content length and type: translate into a structure */
+ /* asn1_ex_c2i may reuse allocated buffer, and so sets free_cont to 0 */
+ if (!asn1_ex_c2i(pval, cont, len, utype, &free_cont, it))
+ goto err;
+
+ *in = p;
+ ret = 1;
+ err:
+ if (free_cont && buf.data)
+ OPENSSL_free(buf.data);
+ return ret;
+}
/* Translate ASN1 content octets into a structure */
int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
- int utype, char *free_cont, const ASN1_ITEM *it)
- {
- ASN1_VALUE **opval = NULL;
- ASN1_STRING *stmp;
- ASN1_TYPE *typ = NULL;
- int ret = 0;
- const ASN1_PRIMITIVE_FUNCS *pf;
- ASN1_INTEGER **tint;
- pf = it->funcs;
-
- if (pf && pf->prim_c2i)
- return pf->prim_c2i(pval, cont, len, utype, free_cont, it);
- /* If ANY type clear type and set pointer to internal value */
- if (it->utype == V_ASN1_ANY)
- {
- if (!*pval)
- {
- typ = ASN1_TYPE_new();
- if (typ == NULL)
- goto err;
- *pval = (ASN1_VALUE *)typ;
- }
- else
- typ = (ASN1_TYPE *)*pval;
-
- if (utype != typ->type)
- ASN1_TYPE_set(typ, utype, NULL);
- opval = pval;
- pval = &typ->value.asn1_value;
- }
- switch(utype)
- {
- case V_ASN1_OBJECT:
- if (!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len))
- goto err;
- break;
-
- case V_ASN1_NULL:
- if (len)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_NULL_IS_WRONG_LENGTH);
- goto err;
- }
- *pval = (ASN1_VALUE *)1;
- break;
-
- case V_ASN1_BOOLEAN:
- if (len != 1)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_BOOLEAN_IS_WRONG_LENGTH);
- goto err;
- }
- else
- {
- ASN1_BOOLEAN *tbool;
- tbool = (ASN1_BOOLEAN *)pval;
- *tbool = *cont;
- }
- break;
-
- case V_ASN1_BIT_STRING:
- if (!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len))
- goto err;
- break;
-
- case V_ASN1_INTEGER:
- case V_ASN1_NEG_INTEGER:
- case V_ASN1_ENUMERATED:
- case V_ASN1_NEG_ENUMERATED:
- tint = (ASN1_INTEGER **)pval;
- if (!c2i_ASN1_INTEGER(tint, &cont, len))
- goto err;
- /* Fixup type to match the expected form */
- (*tint)->type = utype | ((*tint)->type & V_ASN1_NEG);
- break;
-
- case V_ASN1_OCTET_STRING:
- case V_ASN1_NUMERICSTRING:
- case V_ASN1_PRINTABLESTRING:
- case V_ASN1_T61STRING:
- case V_ASN1_VIDEOTEXSTRING:
- case V_ASN1_IA5STRING:
- case V_ASN1_UTCTIME:
- case V_ASN1_GENERALIZEDTIME:
- case V_ASN1_GRAPHICSTRING:
- case V_ASN1_VISIBLESTRING:
- case V_ASN1_GENERALSTRING:
- case V_ASN1_UNIVERSALSTRING:
- case V_ASN1_BMPSTRING:
- case V_ASN1_UTF8STRING:
- case V_ASN1_OTHER:
- case V_ASN1_SET:
- case V_ASN1_SEQUENCE:
- default:
- if (utype == V_ASN1_BMPSTRING && (len & 1))
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_BMPSTRING_IS_WRONG_LENGTH);
- goto err;
- }
- if (utype == V_ASN1_UNIVERSALSTRING && (len & 3))
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH);
- goto err;
- }
- /* All based on ASN1_STRING and handled the same */
- if (!*pval)
- {
- stmp = ASN1_STRING_type_new(utype);
- if (!stmp)
- {
- OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- *pval = (ASN1_VALUE *)stmp;
- }
- else
- {
- stmp = (ASN1_STRING *)*pval;
- stmp->type = utype;
- }
- /* If we've already allocated a buffer use it */
- if (*free_cont)
- {
- if (stmp->data)
- OPENSSL_free(stmp->data);
- stmp->data = (unsigned char *)cont; /* UGLY CAST! RL */
- stmp->length = len;
- *free_cont = 0;
- }
- else
- {
- if (!ASN1_STRING_set(stmp, cont, len))
- {
- OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
- ASN1_STRING_free(stmp);
- *pval = NULL;
- goto err;
- }
- }
- break;
- }
- /* If ASN1_ANY and NULL type fix up value */
- if (typ && (utype == V_ASN1_NULL))
- typ->value.ptr = NULL;
-
- ret = 1;
- err:
- if (!ret)
- {
- ASN1_TYPE_free(typ);
- if (opval)
- *opval = NULL;
- }
- return ret;
- }
-
-
-/* This function finds the end of an ASN1 structure when passed its maximum
- * length, whether it is indefinite length and a pointer to the content.
- * This is more efficient than calling asn1_collect because it does not
- * recurse on each indefinite length header.
+ int utype, char *free_cont, const ASN1_ITEM *it)
+{
+ ASN1_VALUE **opval = NULL;
+ ASN1_STRING *stmp;
+ ASN1_TYPE *typ = NULL;
+ int ret = 0;
+ const ASN1_PRIMITIVE_FUNCS *pf;
+ ASN1_INTEGER **tint;
+ pf = it->funcs;
+
+ if (pf && pf->prim_c2i)
+ return pf->prim_c2i(pval, cont, len, utype, free_cont, it);
+ /* If ANY type clear type and set pointer to internal value */
+ if (it->utype == V_ASN1_ANY) {
+ if (!*pval) {
+ typ = ASN1_TYPE_new();
+ if (typ == NULL)
+ goto err;
+ *pval = (ASN1_VALUE *)typ;
+ } else
+ typ = (ASN1_TYPE *)*pval;
+
+ if (utype != typ->type)
+ ASN1_TYPE_set(typ, utype, NULL);
+ opval = pval;
+ pval = &typ->value.asn1_value;
+ }
+ switch (utype) {
+ case V_ASN1_OBJECT:
+ if (!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len))
+ goto err;
+ break;
+
+ case V_ASN1_NULL:
+ if (len) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NULL_IS_WRONG_LENGTH);
+ goto err;
+ }
+ *pval = (ASN1_VALUE *)1;
+ break;
+
+ case V_ASN1_BOOLEAN:
+ if (len != 1) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_BOOLEAN_IS_WRONG_LENGTH);
+ goto err;
+ } else {
+ ASN1_BOOLEAN *tbool;
+ tbool = (ASN1_BOOLEAN *)pval;
+ *tbool = *cont;
+ }
+ break;
+
+ case V_ASN1_BIT_STRING:
+ if (!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len))
+ goto err;
+ break;
+
+ case V_ASN1_INTEGER:
+ case V_ASN1_NEG_INTEGER:
+ case V_ASN1_ENUMERATED:
+ case V_ASN1_NEG_ENUMERATED:
+ tint = (ASN1_INTEGER **)pval;
+ if (!c2i_ASN1_INTEGER(tint, &cont, len))
+ goto err;
+ /* Fixup type to match the expected form */
+ (*tint)->type = utype | ((*tint)->type & V_ASN1_NEG);
+ break;
+
+ case V_ASN1_OCTET_STRING:
+ case V_ASN1_NUMERICSTRING:
+ case V_ASN1_PRINTABLESTRING:
+ case V_ASN1_T61STRING:
+ case V_ASN1_VIDEOTEXSTRING:
+ case V_ASN1_IA5STRING:
+ case V_ASN1_UTCTIME:
+ case V_ASN1_GENERALIZEDTIME:
+ case V_ASN1_GRAPHICSTRING:
+ case V_ASN1_VISIBLESTRING:
+ case V_ASN1_GENERALSTRING:
+ case V_ASN1_UNIVERSALSTRING:
+ case V_ASN1_BMPSTRING:
+ case V_ASN1_UTF8STRING:
+ case V_ASN1_OTHER:
+ case V_ASN1_SET:
+ case V_ASN1_SEQUENCE:
+ default:
+ if (utype == V_ASN1_BMPSTRING && (len & 1)) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_BMPSTRING_IS_WRONG_LENGTH);
+ goto err;
+ }
+ if (utype == V_ASN1_UNIVERSALSTRING && (len & 3)) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH);
+ goto err;
+ }
+ /* All based on ASN1_STRING and handled the same */
+ if (!*pval) {
+ stmp = ASN1_STRING_type_new(utype);
+ if (!stmp) {
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ *pval = (ASN1_VALUE *)stmp;
+ } else {
+ stmp = (ASN1_STRING *)*pval;
+ stmp->type = utype;
+ }
+ /* If we've already allocated a buffer use it */
+ if (*free_cont) {
+ if (stmp->data)
+ OPENSSL_free(stmp->data);
+ stmp->data = (unsigned char *)cont; /* UGLY CAST! RL */
+ stmp->length = len;
+ *free_cont = 0;
+ } else {
+ if (!ASN1_STRING_set(stmp, cont, len)) {
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+ ASN1_STRING_free(stmp);
+ *pval = NULL;
+ goto err;
+ }
+ }
+ break;
+ }
+ /* If ASN1_ANY and NULL type fix up value */
+ if (typ && (utype == V_ASN1_NULL))
+ typ->value.ptr = NULL;
+
+ ret = 1;
+ err:
+ if (!ret) {
+ ASN1_TYPE_free(typ);
+ if (opval)
+ *opval = NULL;
+ }
+ return ret;
+}
+
+/*
+ * This function finds the end of an ASN1 structure when passed its maximum
+ * length, whether it is indefinite length and a pointer to the content. This
+ * is more efficient than calling asn1_collect because it does not recurse on
+ * each indefinite length header.
*/
static int asn1_find_end(const unsigned char **in, long len, char inf)
- {
- int expected_eoc;
- long plen;
- const unsigned char *p = *in, *q;
- /* If not indefinite length constructed just add length */
- if (inf == 0)
- {
- *in += len;
- return 1;
- }
- expected_eoc = 1;
- /* Indefinite length constructed form. Find the end when enough EOCs
- * are found. If more indefinite length constructed headers
- * are encountered increment the expected eoc count otherwise just
- * skip to the end of the data.
- */
- while (len > 0)
- {
- if(asn1_check_eoc(&p, len))
- {
- expected_eoc--;
- if (expected_eoc == 0)
- break;
- len -= 2;
- continue;
- }
- q = p;
- /* Just read in a header: only care about the length */
- if(!asn1_check_tlen(&plen, NULL, NULL, &inf, NULL, &p, len,
- -1, 0, 0, NULL))
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
- return 0;
- }
- if (inf)
- expected_eoc++;
- else
- p += plen;
- len -= p - q;
- }
- if (expected_eoc)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC);
- return 0;
- }
- *in = p;
- return 1;
- }
-/* This function collects the asn1 data from a constructred string
- * type into a buffer. The values of 'in' and 'len' should refer
- * to the contents of the constructed type and 'inf' should be set
- * if it is indefinite length.
+{
+ int expected_eoc;
+ long plen;
+ const unsigned char *p = *in, *q;
+ /* If not indefinite length constructed just add length */
+ if (inf == 0) {
+ *in += len;
+ return 1;
+ }
+ expected_eoc = 1;
+ /*
+ * Indefinite length constructed form. Find the end when enough EOCs are
+ * found. If more indefinite length constructed headers are encountered
+ * increment the expected eoc count otherwise just skip to the end of the
+ * data.
+ */
+ while (len > 0) {
+ if (asn1_check_eoc(&p, len)) {
+ expected_eoc--;
+ if (expected_eoc == 0)
+ break;
+ len -= 2;
+ continue;
+ }
+ q = p;
+ /* Just read in a header: only care about the length */
+ if (!asn1_check_tlen(&plen, NULL, NULL, &inf, NULL, &p, len,
+ -1, 0, 0, NULL)) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
+ return 0;
+ }
+ if (inf)
+ expected_eoc++;
+ else
+ p += plen;
+ len -= p - q;
+ }
+ if (expected_eoc) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC);
+ return 0;
+ }
+ *in = p;
+ return 1;
+}
+
+/*
+ * This function collects the asn1 data from a constructred string type into
+ * a buffer. The values of 'in' and 'len' should refer to the contents of the
+ * constructed type and 'inf' should be set if it is indefinite length.
*/
#ifndef ASN1_MAX_STRING_NEST
-/* This determines how many levels of recursion are permitted in ASN1
- * string types. If it is not limited stack overflows can occur. If set
- * to zero no recursion is allowed at all. Although zero should be adequate
- * examples exist that require a value of 1. So 5 should be more than enough.
+/*
+ * This determines how many levels of recursion are permitted in ASN1 string
+ * types. If it is not limited stack overflows can occur. If set to zero no
+ * recursion is allowed at all. Although zero should be adequate examples
+ * exist that require a value of 1. So 5 should be more than enough.
*/
-#define ASN1_MAX_STRING_NEST 5
+# define ASN1_MAX_STRING_NEST 5
#endif
-
static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len,
- char inf, int tag, int aclass, int depth)
- {
- const unsigned char *p, *q;
- long plen;
- char cst, ininf;
- p = *in;
- inf &= 1;
- /* If no buffer and not indefinite length constructed just pass over
- * the encoded data */
- if (!buf && !inf)
- {
- *in += len;
- return 1;
- }
- while(len > 0)
- {
- q = p;
- /* Check for EOC */
- if (asn1_check_eoc(&p, len))
- {
- /* EOC is illegal outside indefinite length
- * constructed form */
- if (!inf)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNEXPECTED_EOC);
- return 0;
- }
- inf = 0;
- break;
- }
-
- if (!asn1_check_tlen(&plen, NULL, NULL, &ininf, &cst, &p,
- len, tag, aclass, 0, NULL))
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
- return 0;
- }
-
- /* If indefinite length constructed update max length */
- if (cst)
- {
- if (depth >= ASN1_MAX_STRING_NEST)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_STRING);
- return 0;
- }
- if (!asn1_collect(buf, &p, plen, ininf, tag, aclass,
- depth + 1))
- return 0;
- }
- else if (plen && !collect_data(buf, &p, plen))
- return 0;
- len -= p - q;
- }
- if (inf)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC);
- return 0;
- }
- *in = p;
- return 1;
- }
+ char inf, int tag, int aclass, int depth)
+{
+ const unsigned char *p, *q;
+ long plen;
+ char cst, ininf;
+ p = *in;
+ inf &= 1;
+ /*
+ * If no buffer and not indefinite length constructed just pass over the
+ * encoded data
+ */
+ if (!buf && !inf) {
+ *in += len;
+ return 1;
+ }
+ while (len > 0) {
+ q = p;
+ /* Check for EOC */
+ if (asn1_check_eoc(&p, len)) {
+ /*
+ * EOC is illegal outside indefinite length constructed form
+ */
+ if (!inf) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNEXPECTED_EOC);
+ return 0;
+ }
+ inf = 0;
+ break;
+ }
+
+ if (!asn1_check_tlen(&plen, NULL, NULL, &ininf, &cst, &p,
+ len, tag, aclass, 0, NULL)) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
+ return 0;
+ }
+
+ /* If indefinite length constructed update max length */
+ if (cst) {
+ if (depth >= ASN1_MAX_STRING_NEST) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_STRING);
+ return 0;
+ }
+ if (!asn1_collect(buf, &p, plen, ininf, tag, aclass, depth + 1))
+ return 0;
+ } else if (plen && !collect_data(buf, &p, plen))
+ return 0;
+ len -= p - q;
+ }
+ if (inf) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC);
+ return 0;
+ }
+ *in = p;
+ return 1;
+}
static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen)
- {
- int len;
- if (buf)
- {
- len = buf->length;
- if (!BUF_MEM_grow_clean(buf, len + plen))
- {
- OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
- return 0;
- }
- memcpy(buf->data + len, *p, plen);
- }
- *p += plen;
- return 1;
- }
+{
+ int len;
+ if (buf) {
+ len = buf->length;
+ if (!BUF_MEM_grow_clean(buf, len + plen)) {
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ memcpy(buf->data + len, *p, plen);
+ }
+ *p += plen;
+ return 1;
+}
/* Check for ASN1 EOC and swallow it if found */
static int asn1_check_eoc(const unsigned char **in, long len)
- {
- const unsigned char *p;
- if (len < 2) return 0;
- p = *in;
- if (!p[0] && !p[1])
- {
- *in += 2;
- return 1;
- }
- return 0;
- }
-
-/* Check an ASN1 tag and length: a bit like ASN1_get_object
- * but it sets the length for indefinite length constructed
- * form, we don't know the exact length but we can set an
- * upper bound to the amount of data available minus the
- * header length just read.
+{
+ const unsigned char *p;
+ if (len < 2)
+ return 0;
+ p = *in;
+ if (!p[0] && !p[1]) {
+ *in += 2;
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Check an ASN1 tag and length: a bit like ASN1_get_object but it sets the
+ * length for indefinite length constructed form, we don't know the exact
+ * length but we can set an upper bound to the amount of data available minus
+ * the header length just read.
*/
static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
- char *inf, char *cst,
- const unsigned char **in, long len,
- int exptag, int expclass, char opt,
- ASN1_TLC *ctx)
- {
- int i;
- int ptag, pclass;
- long plen;
- const unsigned char *p, *q;
- p = *in;
- q = p;
-
- if (ctx && ctx->valid)
- {
- i = ctx->ret;
- plen = ctx->plen;
- pclass = ctx->pclass;
- ptag = ctx->ptag;
- p += ctx->hdrlen;
- }
- else
- {
- i = ASN1_get_object(&p, &plen, &ptag, &pclass, len);
- if (ctx)
- {
- ctx->ret = i;
- ctx->plen = plen;
- ctx->pclass = pclass;
- ctx->ptag = ptag;
- ctx->hdrlen = p - q;
- ctx->valid = 1;
- /* If definite length, and no error, length +
- * header can't exceed total amount of data available.
- */
- if (!(i & 0x81) && ((plen + ctx->hdrlen) > len))
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
- asn1_tlc_clear(ctx);
- return 0;
- }
- }
- }
-
- if (i & 0x80)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_OBJECT_HEADER);
- asn1_tlc_clear(ctx);
- return 0;
- }
- if (exptag >= 0)
- {
- if ((exptag != ptag) || (expclass != pclass))
- {
- /* If type is OPTIONAL, not an error:
- * indicate missing type.
- */
- if (opt) return -1;
- asn1_tlc_clear(ctx);
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_TAG);
- return 0;
- }
- /* We have a tag and class match:
- * assume we are going to do something with it */
- asn1_tlc_clear(ctx);
- }
-
- if (i & 1)
- plen = len - (p - q);
-
- if (inf)
- *inf = i & 1;
-
- if (cst)
- *cst = i & V_ASN1_CONSTRUCTED;
-
- if (olen)
- *olen = plen;
-
- if (oclass)
- *oclass = pclass;
-
- if (otag)
- *otag = ptag;
-
- *in = p;
- return 1;
- }
+ char *inf, char *cst,
+ const unsigned char **in, long len,
+ int exptag, int expclass, char opt, ASN1_TLC *ctx)
+{
+ int i;
+ int ptag, pclass;
+ long plen;
+ const unsigned char *p, *q;
+ p = *in;
+ q = p;
+
+ if (ctx && ctx->valid) {
+ i = ctx->ret;
+ plen = ctx->plen;
+ pclass = ctx->pclass;
+ ptag = ctx->ptag;
+ p += ctx->hdrlen;
+ } else {
+ i = ASN1_get_object(&p, &plen, &ptag, &pclass, len);
+ if (ctx) {
+ ctx->ret = i;
+ ctx->plen = plen;
+ ctx->pclass = pclass;
+ ctx->ptag = ptag;
+ ctx->hdrlen = p - q;
+ ctx->valid = 1;
+ /*
+ * If definite length, and no error, length + header can't exceed
+ * total amount of data available.
+ */
+ if (!(i & 0x81) && ((plen + ctx->hdrlen) > len)) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
+ asn1_tlc_clear(ctx);
+ return 0;
+ }
+ }
+ }
+
+ if (i & 0x80) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_OBJECT_HEADER);
+ asn1_tlc_clear(ctx);
+ return 0;
+ }
+ if (exptag >= 0) {
+ if ((exptag != ptag) || (expclass != pclass)) {
+ /*
+ * If type is OPTIONAL, not an error: indicate missing type.
+ */
+ if (opt)
+ return -1;
+ asn1_tlc_clear(ctx);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_TAG);
+ return 0;
+ }
+ /*
+ * We have a tag and class match: assume we are going to do something
+ * with it
+ */
+ asn1_tlc_clear(ctx);
+ }
+
+ if (i & 1)
+ plen = len - (p - q);
+
+ if (inf)
+ *inf = i & 1;
+
+ if (cst)
+ *cst = i & V_ASN1_CONSTRUCTED;
+
+ if (olen)
+ *olen = plen;
+
+ if (oclass)
+ *oclass = pclass;
+
+ if (otag)
+ *otag = ptag;
+
+ *in = p;
+ return 1;
+}
diff --git a/src/crypto/asn1/tasn_enc.c b/src/crypto/asn1/tasn_enc.c
index 38e14d2a..a56d08ed 100644
--- a/src/crypto/asn1/tasn_enc.c
+++ b/src/crypto/asn1/tasn_enc.c
@@ -61,635 +61,599 @@
#include <openssl/asn1t.h>
#include <openssl/mem.h>
-
static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
- const ASN1_ITEM *it,
- int tag, int aclass);
+ const ASN1_ITEM *it, int tag, int aclass);
static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
- int skcontlen, const ASN1_ITEM *item,
- int do_sort, int iclass);
+ int skcontlen, const ASN1_ITEM *item,
+ int do_sort, int iclass);
static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
- const ASN1_TEMPLATE *tt,
- int tag, int aclass);
+ const ASN1_TEMPLATE *tt, int tag, int aclass);
static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out,
- const ASN1_ITEM *it, int flags);
+ const ASN1_ITEM *it, int flags);
-/* Top level i2d equivalents: the 'ndef' variant instructs the encoder
- * to use indefinite length constructed encoding, where appropriate
+/*
+ * Top level i2d equivalents: the 'ndef' variant instructs the encoder to use
+ * indefinite length constructed encoding, where appropriate
*/
int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out,
- const ASN1_ITEM *it)
- {
- return asn1_item_flags_i2d(val, out, it, ASN1_TFLG_NDEF);
- }
+ const ASN1_ITEM *it)
+{
+ return asn1_item_flags_i2d(val, out, it, ASN1_TFLG_NDEF);
+}
int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it)
- {
- return asn1_item_flags_i2d(val, out, it, 0);
- }
+{
+ return asn1_item_flags_i2d(val, out, it, 0);
+}
-/* Encode an ASN1 item, this is use by the
- * standard 'i2d' function. 'out' points to
- * a buffer to output the data to.
- *
- * The new i2d has one additional feature. If the output
- * buffer is NULL (i.e. *out == NULL) then a buffer is
+/*
+ * Encode an ASN1 item, this is use by the standard 'i2d' function. 'out'
+ * points to a buffer to output the data to. The new i2d has one additional
+ * feature. If the output buffer is NULL (i.e. *out == NULL) then a buffer is
* allocated and populated with the encoding.
*/
static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out,
- const ASN1_ITEM *it, int flags)
- {
- if (out && !*out)
- {
- unsigned char *p, *buf;
- int len;
- len = ASN1_item_ex_i2d(&val, NULL, it, -1, flags);
- if (len <= 0)
- return len;
- buf = OPENSSL_malloc(len);
- if (!buf)
- return -1;
- p = buf;
- ASN1_item_ex_i2d(&val, &p, it, -1, flags);
- *out = buf;
- return len;
- }
-
- return ASN1_item_ex_i2d(&val, out, it, -1, flags);
- }
-
-/* Encode an item, taking care of IMPLICIT tagging (if any).
- * This function performs the normal item handling: it can be
- * used in external types.
+ const ASN1_ITEM *it, int flags)
+{
+ if (out && !*out) {
+ unsigned char *p, *buf;
+ int len;
+ len = ASN1_item_ex_i2d(&val, NULL, it, -1, flags);
+ if (len <= 0)
+ return len;
+ buf = OPENSSL_malloc(len);
+ if (!buf)
+ return -1;
+ p = buf;
+ ASN1_item_ex_i2d(&val, &p, it, -1, flags);
+ *out = buf;
+ return len;
+ }
+
+ return ASN1_item_ex_i2d(&val, out, it, -1, flags);
+}
+
+/*
+ * Encode an item, taking care of IMPLICIT tagging (if any). This function
+ * performs the normal item handling: it can be used in external types.
*/
int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
- const ASN1_ITEM *it, int tag, int aclass)
- {
- const ASN1_TEMPLATE *tt = NULL;
- unsigned char *p = NULL;
- int i, seqcontlen, seqlen, ndef = 1;
- const ASN1_COMPAT_FUNCS *cf;
- const ASN1_EXTERN_FUNCS *ef;
- const ASN1_AUX *aux = it->funcs;
- ASN1_aux_cb *asn1_cb = 0;
-
- if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval)
- return 0;
-
- if (aux && aux->asn1_cb)
- asn1_cb = aux->asn1_cb;
-
- switch(it->itype)
- {
-
- case ASN1_ITYPE_PRIMITIVE:
- if (it->templates)
- return asn1_template_ex_i2d(pval, out, it->templates,
- tag, aclass);
- return asn1_i2d_ex_primitive(pval, out, it, tag, aclass);
- break;
-
- case ASN1_ITYPE_MSTRING:
- return asn1_i2d_ex_primitive(pval, out, it, -1, aclass);
-
- case ASN1_ITYPE_CHOICE:
- if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
- return 0;
- i = asn1_get_choice_selector(pval, it);
- if ((i >= 0) && (i < it->tcount))
- {
- ASN1_VALUE **pchval;
- const ASN1_TEMPLATE *chtt;
- chtt = it->templates + i;
- pchval = asn1_get_field_ptr(pval, chtt);
- return asn1_template_ex_i2d(pchval, out, chtt,
- -1, aclass);
- }
- /* Fixme: error condition if selector out of range */
- if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
- return 0;
- break;
-
- case ASN1_ITYPE_EXTERN:
- /* If new style i2d it does all the work */
- ef = it->funcs;
- return ef->asn1_ex_i2d(pval, out, it, tag, aclass);
-
- case ASN1_ITYPE_COMPAT:
- /* old style hackery... */
- cf = it->funcs;
- if (out)
- p = *out;
- i = cf->asn1_i2d(*pval, out);
- /* Fixup for IMPLICIT tag: note this messes up for tags > 30,
- * but so did the old code. Tags > 30 are very rare anyway.
- */
- if (out && (tag != -1))
- *p = aclass | tag | (*p & V_ASN1_CONSTRUCTED);
- return i;
-
- case ASN1_ITYPE_NDEF_SEQUENCE:
- /* Use indefinite length constructed if requested */
- if (aclass & ASN1_TFLG_NDEF) ndef = 2;
- /* fall through */
-
- case ASN1_ITYPE_SEQUENCE:
- i = asn1_enc_restore(&seqcontlen, out, pval, it);
- /* An error occurred */
- if (i < 0)
- return 0;
- /* We have a valid cached encoding... */
- if (i > 0)
- return seqcontlen;
- /* Otherwise carry on */
- seqcontlen = 0;
- /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
- if (tag == -1)
- {
- tag = V_ASN1_SEQUENCE;
- /* Retain any other flags in aclass */
- aclass = (aclass & ~ASN1_TFLG_TAG_CLASS)
- | V_ASN1_UNIVERSAL;
- }
- if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
- return 0;
- /* First work out sequence content length */
- for (i = 0, tt = it->templates; i < it->tcount; tt++, i++)
- {
- const ASN1_TEMPLATE *seqtt;
- ASN1_VALUE **pseqval;
- seqtt = asn1_do_adb(pval, tt, 1);
- if (!seqtt)
- return 0;
- pseqval = asn1_get_field_ptr(pval, seqtt);
- /* FIXME: check for errors in enhanced version */
- seqcontlen += asn1_template_ex_i2d(pseqval, NULL, seqtt,
- -1, aclass);
- }
-
- seqlen = ASN1_object_size(ndef, seqcontlen, tag);
- if (!out)
- return seqlen;
- /* Output SEQUENCE header */
- ASN1_put_object(out, ndef, seqcontlen, tag, aclass);
- for (i = 0, tt = it->templates; i < it->tcount; tt++, i++)
- {
- const ASN1_TEMPLATE *seqtt;
- ASN1_VALUE **pseqval;
- seqtt = asn1_do_adb(pval, tt, 1);
- if (!seqtt)
- return 0;
- pseqval = asn1_get_field_ptr(pval, seqtt);
- /* FIXME: check for errors in enhanced version */
- asn1_template_ex_i2d(pseqval, out, seqtt, -1, aclass);
- }
- if (ndef == 2)
- ASN1_put_eoc(out);
- if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
- return 0;
- return seqlen;
-
- default:
- return 0;
-
- }
- return 0;
- }
+ const ASN1_ITEM *it, int tag, int aclass)
+{
+ const ASN1_TEMPLATE *tt = NULL;
+ unsigned char *p = NULL;
+ int i, seqcontlen, seqlen, ndef = 1;
+ const ASN1_COMPAT_FUNCS *cf;
+ const ASN1_EXTERN_FUNCS *ef;
+ const ASN1_AUX *aux = it->funcs;
+ ASN1_aux_cb *asn1_cb = 0;
+
+ if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval)
+ return 0;
+
+ if (aux && aux->asn1_cb)
+ asn1_cb = aux->asn1_cb;
+
+ switch (it->itype) {
+
+ case ASN1_ITYPE_PRIMITIVE:
+ if (it->templates)
+ return asn1_template_ex_i2d(pval, out, it->templates,
+ tag, aclass);
+ return asn1_i2d_ex_primitive(pval, out, it, tag, aclass);
+ break;
+
+ case ASN1_ITYPE_MSTRING:
+ return asn1_i2d_ex_primitive(pval, out, it, -1, aclass);
+
+ case ASN1_ITYPE_CHOICE:
+ if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
+ return 0;
+ i = asn1_get_choice_selector(pval, it);
+ if ((i >= 0) && (i < it->tcount)) {
+ ASN1_VALUE **pchval;
+ const ASN1_TEMPLATE *chtt;
+ chtt = it->templates + i;
+ pchval = asn1_get_field_ptr(pval, chtt);
+ return asn1_template_ex_i2d(pchval, out, chtt, -1, aclass);
+ }
+ /* Fixme: error condition if selector out of range */
+ if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
+ return 0;
+ break;
+
+ case ASN1_ITYPE_EXTERN:
+ /* If new style i2d it does all the work */
+ ef = it->funcs;
+ return ef->asn1_ex_i2d(pval, out, it, tag, aclass);
+
+ case ASN1_ITYPE_COMPAT:
+ /* old style hackery... */
+ cf = it->funcs;
+ if (out)
+ p = *out;
+ i = cf->asn1_i2d(*pval, out);
+ /*
+ * Fixup for IMPLICIT tag: note this messes up for tags > 30, but so
+ * did the old code. Tags > 30 are very rare anyway.
+ */
+ if (out && (tag != -1))
+ *p = aclass | tag | (*p & V_ASN1_CONSTRUCTED);
+ return i;
+
+ case ASN1_ITYPE_NDEF_SEQUENCE:
+ /* Use indefinite length constructed if requested */
+ if (aclass & ASN1_TFLG_NDEF)
+ ndef = 2;
+ /* fall through */
+
+ case ASN1_ITYPE_SEQUENCE:
+ i = asn1_enc_restore(&seqcontlen, out, pval, it);
+ /* An error occurred */
+ if (i < 0)
+ return 0;
+ /* We have a valid cached encoding... */
+ if (i > 0)
+ return seqcontlen;
+ /* Otherwise carry on */
+ seqcontlen = 0;
+ /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
+ if (tag == -1) {
+ tag = V_ASN1_SEQUENCE;
+ /* Retain any other flags in aclass */
+ aclass = (aclass & ~ASN1_TFLG_TAG_CLASS)
+ | V_ASN1_UNIVERSAL;
+ }
+ if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
+ return 0;
+ /* First work out sequence content length */
+ for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
+ const ASN1_TEMPLATE *seqtt;
+ ASN1_VALUE **pseqval;
+ seqtt = asn1_do_adb(pval, tt, 1);
+ if (!seqtt)
+ return 0;
+ pseqval = asn1_get_field_ptr(pval, seqtt);
+ /* FIXME: check for errors in enhanced version */
+ seqcontlen += asn1_template_ex_i2d(pseqval, NULL, seqtt,
+ -1, aclass);
+ }
+
+ seqlen = ASN1_object_size(ndef, seqcontlen, tag);
+ if (!out)
+ return seqlen;
+ /* Output SEQUENCE header */
+ ASN1_put_object(out, ndef, seqcontlen, tag, aclass);
+ for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
+ const ASN1_TEMPLATE *seqtt;
+ ASN1_VALUE **pseqval;
+ seqtt = asn1_do_adb(pval, tt, 1);
+ if (!seqtt)
+ return 0;
+ pseqval = asn1_get_field_ptr(pval, seqtt);
+ /* FIXME: check for errors in enhanced version */
+ asn1_template_ex_i2d(pseqval, out, seqtt, -1, aclass);
+ }
+ if (ndef == 2)
+ ASN1_put_eoc(out);
+ if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
+ return 0;
+ return seqlen;
+
+ default:
+ return 0;
+
+ }
+ return 0;
+}
int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out,
- const ASN1_TEMPLATE *tt)
- {
- return asn1_template_ex_i2d(pval, out, tt, -1, 0);
- }
+ const ASN1_TEMPLATE *tt)
+{
+ return asn1_template_ex_i2d(pval, out, tt, -1, 0);
+}
static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
- const ASN1_TEMPLATE *tt, int tag, int iclass)
- {
- int i, ret, flags, ttag, tclass, ndef;
- size_t j;
- flags = tt->flags;
- /* Work out tag and class to use: tagging may come
- * either from the template or the arguments, not both
- * because this would create ambiguity. Additionally
- * the iclass argument may contain some additional flags
- * which should be noted and passed down to other levels.
- */
- if (flags & ASN1_TFLG_TAG_MASK)
- {
- /* Error if argument and template tagging */
- if (tag != -1)
- /* FIXME: error code here */
- return -1;
- /* Get tagging from template */
- ttag = tt->tag;
- tclass = flags & ASN1_TFLG_TAG_CLASS;
- }
- else if (tag != -1)
- {
- /* No template tagging, get from arguments */
- ttag = tag;
- tclass = iclass & ASN1_TFLG_TAG_CLASS;
- }
- else
- {
- ttag = -1;
- tclass = 0;
- }
- /*
- * Remove any class mask from iflag.
- */
- iclass &= ~ASN1_TFLG_TAG_CLASS;
-
- /* At this point 'ttag' contains the outer tag to use,
- * 'tclass' is the class and iclass is any flags passed
- * to this function.
- */
-
- /* if template and arguments require ndef, use it */
- if ((flags & ASN1_TFLG_NDEF) && (iclass & ASN1_TFLG_NDEF))
- ndef = 2;
- else ndef = 1;
-
- if (flags & ASN1_TFLG_SK_MASK)
- {
- /* SET OF, SEQUENCE OF */
- STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
- int isset, sktag, skaclass;
- int skcontlen, sklen;
- ASN1_VALUE *skitem;
-
- if (!*pval)
- return 0;
-
- if (flags & ASN1_TFLG_SET_OF)
- {
- isset = 1;
- /* 2 means we reorder */
- if (flags & ASN1_TFLG_SEQUENCE_OF)
- isset = 2;
- }
- else isset = 0;
-
- /* Work out inner tag value: if EXPLICIT
- * or no tagging use underlying type.
- */
- if ((ttag != -1) && !(flags & ASN1_TFLG_EXPTAG))
- {
- sktag = ttag;
- skaclass = tclass;
- }
- else
- {
- skaclass = V_ASN1_UNIVERSAL;
- if (isset)
- sktag = V_ASN1_SET;
- else sktag = V_ASN1_SEQUENCE;
- }
-
- /* Determine total length of items */
- skcontlen = 0;
- for (j = 0; j < sk_ASN1_VALUE_num(sk); j++)
- {
- skitem = sk_ASN1_VALUE_value(sk, j);
- skcontlen += ASN1_item_ex_i2d(&skitem, NULL,
- ASN1_ITEM_ptr(tt->item),
- -1, iclass);
- }
- sklen = ASN1_object_size(ndef, skcontlen, sktag);
- /* If EXPLICIT need length of surrounding tag */
- if (flags & ASN1_TFLG_EXPTAG)
- ret = ASN1_object_size(ndef, sklen, ttag);
- else ret = sklen;
-
- if (!out)
- return ret;
-
- /* Now encode this lot... */
- /* EXPLICIT tag */
- if (flags & ASN1_TFLG_EXPTAG)
- ASN1_put_object(out, ndef, sklen, ttag, tclass);
- /* SET or SEQUENCE and IMPLICIT tag */
- ASN1_put_object(out, ndef, skcontlen, sktag, skaclass);
- /* And the stuff itself */
- asn1_set_seq_out(sk, out, skcontlen, ASN1_ITEM_ptr(tt->item),
- isset, iclass);
- if (ndef == 2)
- {
- ASN1_put_eoc(out);
- if (flags & ASN1_TFLG_EXPTAG)
- ASN1_put_eoc(out);
- }
-
- return ret;
- }
-
- if (flags & ASN1_TFLG_EXPTAG)
- {
- /* EXPLICIT tagging */
- /* Find length of tagged item */
- i = ASN1_item_ex_i2d(pval, NULL, ASN1_ITEM_ptr(tt->item),
- -1, iclass);
- if (!i)
- return 0;
- /* Find length of EXPLICIT tag */
- ret = ASN1_object_size(ndef, i, ttag);
- if (out)
- {
- /* Output tag and item */
- ASN1_put_object(out, ndef, i, ttag, tclass);
- ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item),
- -1, iclass);
- if (ndef == 2)
- ASN1_put_eoc(out);
- }
- return ret;
- }
-
- /* Either normal or IMPLICIT tagging: combine class and flags */
- return ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item),
- ttag, tclass | iclass);
+ const ASN1_TEMPLATE *tt, int tag, int iclass)
+{
+ int i, ret, flags, ttag, tclass, ndef;
+ size_t j;
+ flags = tt->flags;
+ /*
+ * Work out tag and class to use: tagging may come either from the
+ * template or the arguments, not both because this would create
+ * ambiguity. Additionally the iclass argument may contain some
+ * additional flags which should be noted and passed down to other
+ * levels.
+ */
+ if (flags & ASN1_TFLG_TAG_MASK) {
+ /* Error if argument and template tagging */
+ if (tag != -1)
+ /* FIXME: error code here */
+ return -1;
+ /* Get tagging from template */
+ ttag = tt->tag;
+ tclass = flags & ASN1_TFLG_TAG_CLASS;
+ } else if (tag != -1) {
+ /* No template tagging, get from arguments */
+ ttag = tag;
+ tclass = iclass & ASN1_TFLG_TAG_CLASS;
+ } else {
+ ttag = -1;
+ tclass = 0;
+ }
+ /*
+ * Remove any class mask from iflag.
+ */
+ iclass &= ~ASN1_TFLG_TAG_CLASS;
+
+ /*
+ * At this point 'ttag' contains the outer tag to use, 'tclass' is the
+ * class and iclass is any flags passed to this function.
+ */
+
+ /* if template and arguments require ndef, use it */
+ if ((flags & ASN1_TFLG_NDEF) && (iclass & ASN1_TFLG_NDEF))
+ ndef = 2;
+ else
+ ndef = 1;
+
+ if (flags & ASN1_TFLG_SK_MASK) {
+ /* SET OF, SEQUENCE OF */
+ STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
+ int isset, sktag, skaclass;
+ int skcontlen, sklen;
+ ASN1_VALUE *skitem;
+
+ if (!*pval)
+ return 0;
+
+ if (flags & ASN1_TFLG_SET_OF) {
+ isset = 1;
+ /* 2 means we reorder */
+ if (flags & ASN1_TFLG_SEQUENCE_OF)
+ isset = 2;
+ } else
+ isset = 0;
+
+ /*
+ * Work out inner tag value: if EXPLICIT or no tagging use underlying
+ * type.
+ */
+ if ((ttag != -1) && !(flags & ASN1_TFLG_EXPTAG)) {
+ sktag = ttag;
+ skaclass = tclass;
+ } else {
+ skaclass = V_ASN1_UNIVERSAL;
+ if (isset)
+ sktag = V_ASN1_SET;
+ else
+ sktag = V_ASN1_SEQUENCE;
+ }
+
+ /* Determine total length of items */
+ skcontlen = 0;
+ for (j = 0; j < sk_ASN1_VALUE_num(sk); j++) {
+ skitem = sk_ASN1_VALUE_value(sk, j);
+ skcontlen += ASN1_item_ex_i2d(&skitem, NULL,
+ ASN1_ITEM_ptr(tt->item),
+ -1, iclass);
+ }
+ sklen = ASN1_object_size(ndef, skcontlen, sktag);
+ /* If EXPLICIT need length of surrounding tag */
+ if (flags & ASN1_TFLG_EXPTAG)
+ ret = ASN1_object_size(ndef, sklen, ttag);
+ else
+ ret = sklen;
+
+ if (!out)
+ return ret;
+
+ /* Now encode this lot... */
+ /* EXPLICIT tag */
+ if (flags & ASN1_TFLG_EXPTAG)
+ ASN1_put_object(out, ndef, sklen, ttag, tclass);
+ /* SET or SEQUENCE and IMPLICIT tag */
+ ASN1_put_object(out, ndef, skcontlen, sktag, skaclass);
+ /* And the stuff itself */
+ asn1_set_seq_out(sk, out, skcontlen, ASN1_ITEM_ptr(tt->item),
+ isset, iclass);
+ if (ndef == 2) {
+ ASN1_put_eoc(out);
+ if (flags & ASN1_TFLG_EXPTAG)
+ ASN1_put_eoc(out);
+ }
+
+ return ret;
+ }
+
+ if (flags & ASN1_TFLG_EXPTAG) {
+ /* EXPLICIT tagging */
+ /* Find length of tagged item */
+ i = ASN1_item_ex_i2d(pval, NULL, ASN1_ITEM_ptr(tt->item), -1, iclass);
+ if (!i)
+ return 0;
+ /* Find length of EXPLICIT tag */
+ ret = ASN1_object_size(ndef, i, ttag);
+ if (out) {
+ /* Output tag and item */
+ ASN1_put_object(out, ndef, i, ttag, tclass);
+ ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), -1, iclass);
+ if (ndef == 2)
+ ASN1_put_eoc(out);
+ }
+ return ret;
+ }
+
+ /* Either normal or IMPLICIT tagging: combine class and flags */
+ return ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item),
+ ttag, tclass | iclass);
}
/* Temporary structure used to hold DER encoding of items for SET OF */
-typedef struct {
- unsigned char *data;
- int length;
- ASN1_VALUE *field;
+typedef struct {
+ unsigned char *data;
+ int length;
+ ASN1_VALUE *field;
} DER_ENC;
static int der_cmp(const void *a, const void *b)
- {
- const DER_ENC *d1 = a, *d2 = b;
- int cmplen, i;
- cmplen = (d1->length < d2->length) ? d1->length : d2->length;
- i = memcmp(d1->data, d2->data, cmplen);
- if (i)
- return i;
- return d1->length - d2->length;
- }
+{
+ const DER_ENC *d1 = a, *d2 = b;
+ int cmplen, i;
+ cmplen = (d1->length < d2->length) ? d1->length : d2->length;
+ i = memcmp(d1->data, d2->data, cmplen);
+ if (i)
+ return i;
+ return d1->length - d2->length;
+}
/* Output the content octets of SET OF or SEQUENCE OF */
static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
- int skcontlen, const ASN1_ITEM *item,
- int do_sort, int iclass)
- {
- size_t i;
- ASN1_VALUE *skitem;
- unsigned char *tmpdat = NULL, *p = NULL;
- DER_ENC *derlst = NULL, *tder;
- if (do_sort)
- {
- /* Don't need to sort less than 2 items */
- if (sk_ASN1_VALUE_num(sk) < 2)
- do_sort = 0;
- else
- {
- derlst = OPENSSL_malloc(sk_ASN1_VALUE_num(sk)
- * sizeof(*derlst));
- if (!derlst)
- return 0;
- tmpdat = OPENSSL_malloc(skcontlen);
- if (!tmpdat)
- {
- OPENSSL_free(derlst);
- return 0;
- }
- }
- }
- /* If not sorting just output each item */
- if (!do_sort)
- {
- for (i = 0; i < sk_ASN1_VALUE_num(sk); i++)
- {
- skitem = sk_ASN1_VALUE_value(sk, i);
- ASN1_item_ex_i2d(&skitem, out, item, -1, iclass);
- }
- return 1;
- }
- p = tmpdat;
-
- /* Doing sort: build up a list of each member's DER encoding */
- for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++)
- {
- skitem = sk_ASN1_VALUE_value(sk, i);
- tder->data = p;
- tder->length = ASN1_item_ex_i2d(&skitem, &p, item, -1, iclass);
- tder->field = skitem;
- }
-
- /* Now sort them */
- qsort(derlst, sk_ASN1_VALUE_num(sk), sizeof(*derlst), der_cmp);
- /* Output sorted DER encoding */
- p = *out;
- for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++)
- {
- memcpy(p, tder->data, tder->length);
- p += tder->length;
- }
- *out = p;
- /* If do_sort is 2 then reorder the STACK */
- if (do_sort == 2)
- {
- for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk);
- i++, tder++)
- (void)sk_ASN1_VALUE_set(sk, i, tder->field);
- }
- OPENSSL_free(derlst);
- OPENSSL_free(tmpdat);
- return 1;
- }
+ int skcontlen, const ASN1_ITEM *item,
+ int do_sort, int iclass)
+{
+ size_t i;
+ ASN1_VALUE *skitem;
+ unsigned char *tmpdat = NULL, *p = NULL;
+ DER_ENC *derlst = NULL, *tder;
+ if (do_sort) {
+ /* Don't need to sort less than 2 items */
+ if (sk_ASN1_VALUE_num(sk) < 2)
+ do_sort = 0;
+ else {
+ derlst = OPENSSL_malloc(sk_ASN1_VALUE_num(sk)
+ * sizeof(*derlst));
+ if (!derlst)
+ return 0;
+ tmpdat = OPENSSL_malloc(skcontlen);
+ if (!tmpdat) {
+ OPENSSL_free(derlst);
+ return 0;
+ }
+ }
+ }
+ /* If not sorting just output each item */
+ if (!do_sort) {
+ for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
+ skitem = sk_ASN1_VALUE_value(sk, i);
+ ASN1_item_ex_i2d(&skitem, out, item, -1, iclass);
+ }
+ return 1;
+ }
+ p = tmpdat;
+
+ /* Doing sort: build up a list of each member's DER encoding */
+ for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) {
+ skitem = sk_ASN1_VALUE_value(sk, i);
+ tder->data = p;
+ tder->length = ASN1_item_ex_i2d(&skitem, &p, item, -1, iclass);
+ tder->field = skitem;
+ }
+
+ /* Now sort them */
+ qsort(derlst, sk_ASN1_VALUE_num(sk), sizeof(*derlst), der_cmp);
+ /* Output sorted DER encoding */
+ p = *out;
+ for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) {
+ memcpy(p, tder->data, tder->length);
+ p += tder->length;
+ }
+ *out = p;
+ /* If do_sort is 2 then reorder the STACK */
+ if (do_sort == 2) {
+ for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++)
+ (void)sk_ASN1_VALUE_set(sk, i, tder->field);
+ }
+ OPENSSL_free(derlst);
+ OPENSSL_free(tmpdat);
+ return 1;
+}
static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
- const ASN1_ITEM *it, int tag, int aclass)
- {
- int len;
- int utype;
- int usetag;
- int ndef = 0;
-
- utype = it->utype;
-
- /* Get length of content octets and maybe find
- * out the underlying type.
- */
-
- len = asn1_ex_i2c(pval, NULL, &utype, it);
-
- /* If SEQUENCE, SET or OTHER then header is
- * included in pseudo content octets so don't
- * include tag+length. We need to check here
- * because the call to asn1_ex_i2c() could change
- * utype.
- */
- if ((utype == V_ASN1_SEQUENCE) || (utype == V_ASN1_SET) ||
- (utype == V_ASN1_OTHER))
- usetag = 0;
- else usetag = 1;
-
- /* -1 means omit type */
-
- if (len == -1)
- return 0;
-
- /* -2 return is special meaning use ndef */
- if (len == -2)
- {
- ndef = 2;
- len = 0;
- }
-
- /* If not implicitly tagged get tag from underlying type */
- if (tag == -1) tag = utype;
-
- /* Output tag+length followed by content octets */
- if (out)
- {
- if (usetag)
- ASN1_put_object(out, ndef, len, tag, aclass);
- asn1_ex_i2c(pval, *out, &utype, it);
- if (ndef)
- ASN1_put_eoc(out);
- else
- *out += len;
- }
-
- if (usetag)
- return ASN1_object_size(ndef, len, tag);
- return len;
- }
+ const ASN1_ITEM *it, int tag, int aclass)
+{
+ int len;
+ int utype;
+ int usetag;
+ int ndef = 0;
+
+ utype = it->utype;
+
+ /*
+ * Get length of content octets and maybe find out the underlying type.
+ */
+
+ len = asn1_ex_i2c(pval, NULL, &utype, it);
+
+ /*
+ * If SEQUENCE, SET or OTHER then header is included in pseudo content
+ * octets so don't include tag+length. We need to check here because the
+ * call to asn1_ex_i2c() could change utype.
+ */
+ if ((utype == V_ASN1_SEQUENCE) || (utype == V_ASN1_SET) ||
+ (utype == V_ASN1_OTHER))
+ usetag = 0;
+ else
+ usetag = 1;
+
+ /* -1 means omit type */
+
+ if (len == -1)
+ return 0;
+
+ /* -2 return is special meaning use ndef */
+ if (len == -2) {
+ ndef = 2;
+ len = 0;
+ }
+
+ /* If not implicitly tagged get tag from underlying type */
+ if (tag == -1)
+ tag = utype;
+
+ /* Output tag+length followed by content octets */
+ if (out) {
+ if (usetag)
+ ASN1_put_object(out, ndef, len, tag, aclass);
+ asn1_ex_i2c(pval, *out, &utype, it);
+ if (ndef)
+ ASN1_put_eoc(out);
+ else
+ *out += len;
+ }
+
+ if (usetag)
+ return ASN1_object_size(ndef, len, tag);
+ return len;
+}
/* Produce content octets from a structure */
int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype,
- const ASN1_ITEM *it)
- {
- ASN1_BOOLEAN *tbool = NULL;
- ASN1_STRING *strtmp;
- ASN1_OBJECT *otmp;
- int utype;
- const unsigned char *cont;
- unsigned char c;
- int len;
- const ASN1_PRIMITIVE_FUNCS *pf;
- pf = it->funcs;
- if (pf && pf->prim_i2c)
- return pf->prim_i2c(pval, cout, putype, it);
-
- /* Should type be omitted? */
- if ((it->itype != ASN1_ITYPE_PRIMITIVE)
- || (it->utype != V_ASN1_BOOLEAN))
- {
- if (!*pval) return -1;
- }
-
- if (it->itype == ASN1_ITYPE_MSTRING)
- {
- /* If MSTRING type set the underlying type */
- strtmp = (ASN1_STRING *)*pval;
- utype = strtmp->type;
- *putype = utype;
- }
- else if (it->utype == V_ASN1_ANY)
- {
- /* If ANY set type and pointer to value */
- ASN1_TYPE *typ;
- typ = (ASN1_TYPE *)*pval;
- utype = typ->type;
- *putype = utype;
- pval = &typ->value.asn1_value;
- }
- else utype = *putype;
-
- switch(utype)
- {
- case V_ASN1_OBJECT:
- otmp = (ASN1_OBJECT *)*pval;
- cont = otmp->data;
- len = otmp->length;
- break;
-
- case V_ASN1_NULL:
- cont = NULL;
- len = 0;
- break;
-
- case V_ASN1_BOOLEAN:
- tbool = (ASN1_BOOLEAN *)pval;
- if (*tbool == -1)
- return -1;
- if (it->utype != V_ASN1_ANY)
- {
- /* Default handling if value == size field then omit */
- if (*tbool && (it->size > 0))
- return -1;
- if (!*tbool && !it->size)
- return -1;
- }
- c = (unsigned char)*tbool;
- cont = &c;
- len = 1;
- break;
-
- case V_ASN1_BIT_STRING:
- return i2c_ASN1_BIT_STRING((ASN1_BIT_STRING *)*pval,
- cout ? &cout : NULL);
- break;
-
- case V_ASN1_INTEGER:
- case V_ASN1_NEG_INTEGER:
- case V_ASN1_ENUMERATED:
- case V_ASN1_NEG_ENUMERATED:
- /* These are all have the same content format
- * as ASN1_INTEGER
- */
- return i2c_ASN1_INTEGER((ASN1_INTEGER *)*pval,
- cout ? &cout : NULL);
- break;
-
- case V_ASN1_OCTET_STRING:
- case V_ASN1_NUMERICSTRING:
- case V_ASN1_PRINTABLESTRING:
- case V_ASN1_T61STRING:
- case V_ASN1_VIDEOTEXSTRING:
- case V_ASN1_IA5STRING:
- case V_ASN1_UTCTIME:
- case V_ASN1_GENERALIZEDTIME:
- case V_ASN1_GRAPHICSTRING:
- case V_ASN1_VISIBLESTRING:
- case V_ASN1_GENERALSTRING:
- case V_ASN1_UNIVERSALSTRING:
- case V_ASN1_BMPSTRING:
- case V_ASN1_UTF8STRING:
- case V_ASN1_SEQUENCE:
- case V_ASN1_SET:
- default:
- /* All based on ASN1_STRING and handled the same */
- strtmp = (ASN1_STRING *)*pval;
- /* Special handling for NDEF */
- if ((it->size == ASN1_TFLG_NDEF)
- && (strtmp->flags & ASN1_STRING_FLAG_NDEF))
- {
- if (cout)
- {
- strtmp->data = cout;
- strtmp->length = 0;
- }
- /* Special return code */
- return -2;
- }
- cont = strtmp->data;
- len = strtmp->length;
-
- break;
-
- }
- if (cout && len)
- memcpy(cout, cont, len);
- return len;
- }
+ const ASN1_ITEM *it)
+{
+ ASN1_BOOLEAN *tbool = NULL;
+ ASN1_STRING *strtmp;
+ ASN1_OBJECT *otmp;
+ int utype;
+ const unsigned char *cont;
+ unsigned char c;
+ int len;
+ const ASN1_PRIMITIVE_FUNCS *pf;
+ pf = it->funcs;
+ if (pf && pf->prim_i2c)
+ return pf->prim_i2c(pval, cout, putype, it);
+
+ /* Should type be omitted? */
+ if ((it->itype != ASN1_ITYPE_PRIMITIVE)
+ || (it->utype != V_ASN1_BOOLEAN)) {
+ if (!*pval)
+ return -1;
+ }
+
+ if (it->itype == ASN1_ITYPE_MSTRING) {
+ /* If MSTRING type set the underlying type */
+ strtmp = (ASN1_STRING *)*pval;
+ utype = strtmp->type;
+ *putype = utype;
+ } else if (it->utype == V_ASN1_ANY) {
+ /* If ANY set type and pointer to value */
+ ASN1_TYPE *typ;
+ typ = (ASN1_TYPE *)*pval;
+ utype = typ->type;
+ *putype = utype;
+ pval = &typ->value.asn1_value;
+ } else
+ utype = *putype;
+
+ switch (utype) {
+ case V_ASN1_OBJECT:
+ otmp = (ASN1_OBJECT *)*pval;
+ cont = otmp->data;
+ len = otmp->length;
+ break;
+
+ case V_ASN1_NULL:
+ cont = NULL;
+ len = 0;
+ break;
+
+ case V_ASN1_BOOLEAN:
+ tbool = (ASN1_BOOLEAN *)pval;
+ if (*tbool == -1)
+ return -1;
+ if (it->utype != V_ASN1_ANY) {
+ /*
+ * Default handling if value == size field then omit
+ */
+ if (*tbool && (it->size > 0))
+ return -1;
+ if (!*tbool && !it->size)
+ return -1;
+ }
+ c = (unsigned char)*tbool;
+ cont = &c;
+ len = 1;
+ break;
+
+ case V_ASN1_BIT_STRING:
+ return i2c_ASN1_BIT_STRING((ASN1_BIT_STRING *)*pval,
+ cout ? &cout : NULL);
+ break;
+
+ case V_ASN1_INTEGER:
+ case V_ASN1_NEG_INTEGER:
+ case V_ASN1_ENUMERATED:
+ case V_ASN1_NEG_ENUMERATED:
+ /*
+ * These are all have the same content format as ASN1_INTEGER
+ */
+ return i2c_ASN1_INTEGER((ASN1_INTEGER *)*pval, cout ? &cout : NULL);
+ break;
+
+ case V_ASN1_OCTET_STRING:
+ case V_ASN1_NUMERICSTRING:
+ case V_ASN1_PRINTABLESTRING:
+ case V_ASN1_T61STRING:
+ case V_ASN1_VIDEOTEXSTRING:
+ case V_ASN1_IA5STRING:
+ case V_ASN1_UTCTIME:
+ case V_ASN1_GENERALIZEDTIME:
+ case V_ASN1_GRAPHICSTRING:
+ case V_ASN1_VISIBLESTRING:
+ case V_ASN1_GENERALSTRING:
+ case V_ASN1_UNIVERSALSTRING:
+ case V_ASN1_BMPSTRING:
+ case V_ASN1_UTF8STRING:
+ case V_ASN1_SEQUENCE:
+ case V_ASN1_SET:
+ default:
+ /* All based on ASN1_STRING and handled the same */
+ strtmp = (ASN1_STRING *)*pval;
+ /* Special handling for NDEF */
+ if ((it->size == ASN1_TFLG_NDEF)
+ && (strtmp->flags & ASN1_STRING_FLAG_NDEF)) {
+ if (cout) {
+ strtmp->data = cout;
+ strtmp->length = 0;
+ }
+ /* Special return code */
+ return -2;
+ }
+ cont = strtmp->data;
+ len = strtmp->length;
+
+ break;
+
+ }
+ if (cout && len)
+ memcpy(cout, cont, len);
+ return len;
+}
diff --git a/src/crypto/asn1/tasn_fre.c b/src/crypto/asn1/tasn_fre.c
index d1317ae4..609cb9f9 100644
--- a/src/crypto/asn1/tasn_fre.c
+++ b/src/crypto/asn1/tasn_fre.c
@@ -59,206 +59,188 @@
#include <openssl/asn1t.h>
#include <openssl/mem.h>
-
-static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine);
+static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it,
+ int combine);
/* Free up an ASN1 structure */
void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it)
- {
- asn1_item_combine_free(&val, it, 0);
- }
+{
+ asn1_item_combine_free(&val, it, 0);
+}
void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
- {
- asn1_item_combine_free(pval, it, 0);
- }
-
-static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine)
- {
- const ASN1_TEMPLATE *tt = NULL, *seqtt;
- const ASN1_EXTERN_FUNCS *ef;
- const ASN1_COMPAT_FUNCS *cf;
- const ASN1_AUX *aux = it->funcs;
- ASN1_aux_cb *asn1_cb;
- int i;
- if (!pval)
- return;
- if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval)
- return;
- if (aux && aux->asn1_cb)
- asn1_cb = aux->asn1_cb;
- else
- asn1_cb = 0;
-
- switch(it->itype)
- {
-
- case ASN1_ITYPE_PRIMITIVE:
- if (it->templates)
- ASN1_template_free(pval, it->templates);
- else
- ASN1_primitive_free(pval, it);
- break;
-
- case ASN1_ITYPE_MSTRING:
- ASN1_primitive_free(pval, it);
- break;
-
- case ASN1_ITYPE_CHOICE:
- if (asn1_cb)
- {
- i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
- if (i == 2)
- return;
- }
- i = asn1_get_choice_selector(pval, it);
- if ((i >= 0) && (i < it->tcount))
- {
- ASN1_VALUE **pchval;
- tt = it->templates + i;
- pchval = asn1_get_field_ptr(pval, tt);
- ASN1_template_free(pchval, tt);
- }
- if (asn1_cb)
- asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
- if (!combine)
- {
- OPENSSL_free(*pval);
- *pval = NULL;
- }
- break;
-
- case ASN1_ITYPE_COMPAT:
- cf = it->funcs;
- if (cf && cf->asn1_free)
- cf->asn1_free(*pval);
- break;
-
- case ASN1_ITYPE_EXTERN:
- ef = it->funcs;
- if (ef && ef->asn1_ex_free)
- ef->asn1_ex_free(pval, it);
- break;
-
- case ASN1_ITYPE_NDEF_SEQUENCE:
- case ASN1_ITYPE_SEQUENCE:
- if (!asn1_refcount_dec_and_test_zero(pval, it))
- return;
- if (asn1_cb)
- {
- i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
- if (i == 2)
- return;
- }
- asn1_enc_free(pval, it);
- /* If we free up as normal we will invalidate any
- * ANY DEFINED BY field and we wont be able to
- * determine the type of the field it defines. So
- * free up in reverse order.
- */
- tt = it->templates + it->tcount - 1;
- for (i = 0; i < it->tcount; tt--, i++)
- {
- ASN1_VALUE **pseqval;
- seqtt = asn1_do_adb(pval, tt, 0);
- if (!seqtt)
- continue;
- pseqval = asn1_get_field_ptr(pval, seqtt);
- ASN1_template_free(pseqval, seqtt);
- }
- if (asn1_cb)
- asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
- if (!combine)
- {
- OPENSSL_free(*pval);
- *pval = NULL;
- }
- break;
- }
- }
+{
+ asn1_item_combine_free(pval, it, 0);
+}
+
+static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it,
+ int combine)
+{
+ const ASN1_TEMPLATE *tt = NULL, *seqtt;
+ const ASN1_EXTERN_FUNCS *ef;
+ const ASN1_COMPAT_FUNCS *cf;
+ const ASN1_AUX *aux = it->funcs;
+ ASN1_aux_cb *asn1_cb;
+ int i;
+ if (!pval)
+ return;
+ if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval)
+ return;
+ if (aux && aux->asn1_cb)
+ asn1_cb = aux->asn1_cb;
+ else
+ asn1_cb = 0;
+
+ switch (it->itype) {
+
+ case ASN1_ITYPE_PRIMITIVE:
+ if (it->templates)
+ ASN1_template_free(pval, it->templates);
+ else
+ ASN1_primitive_free(pval, it);
+ break;
+
+ case ASN1_ITYPE_MSTRING:
+ ASN1_primitive_free(pval, it);
+ break;
+
+ case ASN1_ITYPE_CHOICE:
+ if (asn1_cb) {
+ i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
+ if (i == 2)
+ return;
+ }
+ i = asn1_get_choice_selector(pval, it);
+ if ((i >= 0) && (i < it->tcount)) {
+ ASN1_VALUE **pchval;
+ tt = it->templates + i;
+ pchval = asn1_get_field_ptr(pval, tt);
+ ASN1_template_free(pchval, tt);
+ }
+ if (asn1_cb)
+ asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
+ if (!combine) {
+ OPENSSL_free(*pval);
+ *pval = NULL;
+ }
+ break;
+
+ case ASN1_ITYPE_COMPAT:
+ cf = it->funcs;
+ if (cf && cf->asn1_free)
+ cf->asn1_free(*pval);
+ break;
+
+ case ASN1_ITYPE_EXTERN:
+ ef = it->funcs;
+ if (ef && ef->asn1_ex_free)
+ ef->asn1_ex_free(pval, it);
+ break;
+
+ case ASN1_ITYPE_NDEF_SEQUENCE:
+ case ASN1_ITYPE_SEQUENCE:
+ if (!asn1_refcount_dec_and_test_zero(pval, it))
+ return;
+ if (asn1_cb) {
+ i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
+ if (i == 2)
+ return;
+ }
+ asn1_enc_free(pval, it);
+ /*
+ * If we free up as normal we will invalidate any ANY DEFINED BY
+ * field and we wont be able to determine the type of the field it
+ * defines. So free up in reverse order.
+ */
+ tt = it->templates + it->tcount - 1;
+ for (i = 0; i < it->tcount; tt--, i++) {
+ ASN1_VALUE **pseqval;
+ seqtt = asn1_do_adb(pval, tt, 0);
+ if (!seqtt)
+ continue;
+ pseqval = asn1_get_field_ptr(pval, seqtt);
+ ASN1_template_free(pseqval, seqtt);
+ }
+ if (asn1_cb)
+ asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
+ if (!combine) {
+ OPENSSL_free(*pval);
+ *pval = NULL;
+ }
+ break;
+ }
+}
void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
- {
- size_t i;
- if (tt->flags & ASN1_TFLG_SK_MASK)
- {
- STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
- for (i = 0; i < sk_ASN1_VALUE_num(sk); i++)
- {
- ASN1_VALUE *vtmp;
- vtmp = sk_ASN1_VALUE_value(sk, i);
- asn1_item_combine_free(&vtmp, ASN1_ITEM_ptr(tt->item),
- 0);
- }
- sk_ASN1_VALUE_free(sk);
- *pval = NULL;
- }
- else
- asn1_item_combine_free(pval, ASN1_ITEM_ptr(tt->item),
- tt->flags & ASN1_TFLG_COMBINE);
- }
+{
+ size_t i;
+ if (tt->flags & ASN1_TFLG_SK_MASK) {
+ STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
+ for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
+ ASN1_VALUE *vtmp;
+ vtmp = sk_ASN1_VALUE_value(sk, i);
+ asn1_item_combine_free(&vtmp, ASN1_ITEM_ptr(tt->item), 0);
+ }
+ sk_ASN1_VALUE_free(sk);
+ *pval = NULL;
+ } else
+ asn1_item_combine_free(pval, ASN1_ITEM_ptr(tt->item),
+ tt->flags & ASN1_TFLG_COMBINE);
+}
void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
- {
- int utype;
- if (it)
- {
- const ASN1_PRIMITIVE_FUNCS *pf;
- pf = it->funcs;
- if (pf && pf->prim_free)
- {
- pf->prim_free(pval, it);
- return;
- }
- }
- /* Special case: if 'it' is NULL free contents of ASN1_TYPE */
- if (!it)
- {
- ASN1_TYPE *typ = (ASN1_TYPE *)*pval;
- utype = typ->type;
- pval = &typ->value.asn1_value;
- if (!*pval)
- return;
- }
- else if (it->itype == ASN1_ITYPE_MSTRING)
- {
- utype = -1;
- if (!*pval)
- return;
- }
- else
- {
- utype = it->utype;
- if ((utype != V_ASN1_BOOLEAN) && !*pval)
- return;
- }
-
- switch(utype)
- {
- case V_ASN1_OBJECT:
- ASN1_OBJECT_free((ASN1_OBJECT *)*pval);
- break;
-
- case V_ASN1_BOOLEAN:
- if (it)
- *(ASN1_BOOLEAN *)pval = it->size;
- else
- *(ASN1_BOOLEAN *)pval = -1;
- return;
-
- case V_ASN1_NULL:
- break;
-
- case V_ASN1_ANY:
- ASN1_primitive_free(pval, NULL);
- OPENSSL_free(*pval);
- break;
-
- default:
- ASN1_STRING_free((ASN1_STRING *)*pval);
- *pval = NULL;
- break;
- }
- *pval = NULL;
- }
+{
+ int utype;
+ if (it) {
+ const ASN1_PRIMITIVE_FUNCS *pf;
+ pf = it->funcs;
+ if (pf && pf->prim_free) {
+ pf->prim_free(pval, it);
+ return;
+ }
+ }
+ /* Special case: if 'it' is NULL free contents of ASN1_TYPE */
+ if (!it) {
+ ASN1_TYPE *typ = (ASN1_TYPE *)*pval;
+ utype = typ->type;
+ pval = &typ->value.asn1_value;
+ if (!*pval)
+ return;
+ } else if (it->itype == ASN1_ITYPE_MSTRING) {
+ utype = -1;
+ if (!*pval)
+ return;
+ } else {
+ utype = it->utype;
+ if ((utype != V_ASN1_BOOLEAN) && !*pval)
+ return;
+ }
+
+ switch (utype) {
+ case V_ASN1_OBJECT:
+ ASN1_OBJECT_free((ASN1_OBJECT *)*pval);
+ break;
+
+ case V_ASN1_BOOLEAN:
+ if (it)
+ *(ASN1_BOOLEAN *)pval = it->size;
+ else
+ *(ASN1_BOOLEAN *)pval = -1;
+ return;
+
+ case V_ASN1_NULL:
+ break;
+
+ case V_ASN1_ANY:
+ ASN1_primitive_free(pval, NULL);
+ OPENSSL_free(*pval);
+ break;
+
+ default:
+ ASN1_STRING_free((ASN1_STRING *)*pval);
+ *pval = NULL;
+ break;
+ }
+ *pval = NULL;
+}
diff --git a/src/crypto/asn1/tasn_new.c b/src/crypto/asn1/tasn_new.c
index c68fe066..232fe46a 100644
--- a/src/crypto/asn1/tasn_new.c
+++ b/src/crypto/asn1/tasn_new.c
@@ -63,336 +63,319 @@
#include <openssl/mem.h>
#include <openssl/obj.h>
-
static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
- int combine);
+ int combine);
static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it)
- {
- ASN1_VALUE *ret = NULL;
- if (ASN1_item_ex_new(&ret, it) > 0)
- return ret;
- return NULL;
- }
+{
+ ASN1_VALUE *ret = NULL;
+ if (ASN1_item_ex_new(&ret, it) > 0)
+ return ret;
+ return NULL;
+}
/* Allocate an ASN1 structure */
int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
- {
- return asn1_item_ex_combine_new(pval, it, 0);
- }
+{
+ return asn1_item_ex_combine_new(pval, it, 0);
+}
static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
- int combine)
- {
- const ASN1_TEMPLATE *tt = NULL;
- const ASN1_COMPAT_FUNCS *cf;
- const ASN1_EXTERN_FUNCS *ef;
- const ASN1_AUX *aux = it->funcs;
- ASN1_aux_cb *asn1_cb;
- ASN1_VALUE **pseqval;
- int i;
- if (aux && aux->asn1_cb)
- asn1_cb = aux->asn1_cb;
- else
- asn1_cb = 0;
+ int combine)
+{
+ const ASN1_TEMPLATE *tt = NULL;
+ const ASN1_COMPAT_FUNCS *cf;
+ const ASN1_EXTERN_FUNCS *ef;
+ const ASN1_AUX *aux = it->funcs;
+ ASN1_aux_cb *asn1_cb;
+ ASN1_VALUE **pseqval;
+ int i;
+ if (aux && aux->asn1_cb)
+ asn1_cb = aux->asn1_cb;
+ else
+ asn1_cb = 0;
#ifdef CRYPTO_MDEBUG
- if (it->sname)
- CRYPTO_push_info(it->sname);
+ if (it->sname)
+ CRYPTO_push_info(it->sname);
#endif
- switch(it->itype)
- {
-
- case ASN1_ITYPE_EXTERN:
- ef = it->funcs;
- if (ef && ef->asn1_ex_new)
- {
- if (!ef->asn1_ex_new(pval, it))
- goto memerr;
- }
- break;
-
- case ASN1_ITYPE_COMPAT:
- cf = it->funcs;
- if (cf && cf->asn1_new) {
- *pval = cf->asn1_new();
- if (!*pval)
- goto memerr;
- }
- break;
-
- case ASN1_ITYPE_PRIMITIVE:
- if (it->templates)
- {
- if (!ASN1_template_new(pval, it->templates))
- goto memerr;
- }
- else if (!ASN1_primitive_new(pval, it))
- goto memerr;
- break;
-
- case ASN1_ITYPE_MSTRING:
- if (!ASN1_primitive_new(pval, it))
- goto memerr;
- break;
-
- case ASN1_ITYPE_CHOICE:
- if (asn1_cb)
- {
- i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
- if (!i)
- goto auxerr;
- if (i==2)
- {
+ switch (it->itype) {
+
+ case ASN1_ITYPE_EXTERN:
+ ef = it->funcs;
+ if (ef && ef->asn1_ex_new) {
+ if (!ef->asn1_ex_new(pval, it))
+ goto memerr;
+ }
+ break;
+
+ case ASN1_ITYPE_COMPAT:
+ cf = it->funcs;
+ if (cf && cf->asn1_new) {
+ *pval = cf->asn1_new();
+ if (!*pval)
+ goto memerr;
+ }
+ break;
+
+ case ASN1_ITYPE_PRIMITIVE:
+ if (it->templates) {
+ if (!ASN1_template_new(pval, it->templates))
+ goto memerr;
+ } else if (!ASN1_primitive_new(pval, it))
+ goto memerr;
+ break;
+
+ case ASN1_ITYPE_MSTRING:
+ if (!ASN1_primitive_new(pval, it))
+ goto memerr;
+ break;
+
+ case ASN1_ITYPE_CHOICE:
+ if (asn1_cb) {
+ i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
+ if (!i)
+ goto auxerr;
+ if (i == 2) {
#ifdef CRYPTO_MDEBUG
- if (it->sname)
- CRYPTO_pop_info();
+ if (it->sname)
+ CRYPTO_pop_info();
#endif
- return 1;
- }
- }
- if (!combine)
- {
- *pval = OPENSSL_malloc(it->size);
- if (!*pval)
- goto memerr;
- memset(*pval, 0, it->size);
- }
- asn1_set_choice_selector(pval, -1, it);
- if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
- goto auxerr;
- break;
-
- case ASN1_ITYPE_NDEF_SEQUENCE:
- case ASN1_ITYPE_SEQUENCE:
- if (asn1_cb)
- {
- i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
- if (!i)
- goto auxerr;
- if (i==2)
- {
+ return 1;
+ }
+ }
+ if (!combine) {
+ *pval = OPENSSL_malloc(it->size);
+ if (!*pval)
+ goto memerr;
+ memset(*pval, 0, it->size);
+ }
+ asn1_set_choice_selector(pval, -1, it);
+ if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
+ goto auxerr;
+ break;
+
+ case ASN1_ITYPE_NDEF_SEQUENCE:
+ case ASN1_ITYPE_SEQUENCE:
+ if (asn1_cb) {
+ i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
+ if (!i)
+ goto auxerr;
+ if (i == 2) {
#ifdef CRYPTO_MDEBUG
- if (it->sname)
- CRYPTO_pop_info();
+ if (it->sname)
+ CRYPTO_pop_info();
#endif
- return 1;
- }
- }
- if (!combine)
- {
- *pval = OPENSSL_malloc(it->size);
- if (!*pval)
- goto memerr;
- memset(*pval, 0, it->size);
- asn1_refcount_set_one(pval, it);
- asn1_enc_init(pval, it);
- }
- for (i = 0, tt = it->templates; i < it->tcount; tt++, i++)
- {
- pseqval = asn1_get_field_ptr(pval, tt);
- if (!ASN1_template_new(pseqval, tt))
- goto memerr;
- }
- if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
- goto auxerr;
- break;
- }
+ return 1;
+ }
+ }
+ if (!combine) {
+ *pval = OPENSSL_malloc(it->size);
+ if (!*pval)
+ goto memerr;
+ memset(*pval, 0, it->size);
+ asn1_refcount_set_one(pval, it);
+ asn1_enc_init(pval, it);
+ }
+ for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
+ pseqval = asn1_get_field_ptr(pval, tt);
+ if (!ASN1_template_new(pseqval, tt))
+ goto memerr;
+ }
+ if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
+ goto auxerr;
+ break;
+ }
#ifdef CRYPTO_MDEBUG
- if (it->sname) CRYPTO_pop_info();
+ if (it->sname)
+ CRYPTO_pop_info();
#endif
- return 1;
+ return 1;
- memerr:
- OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
- ASN1_item_ex_free(pval, it);
+ memerr:
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+ ASN1_item_ex_free(pval, it);
#ifdef CRYPTO_MDEBUG
- if (it->sname) CRYPTO_pop_info();
+ if (it->sname)
+ CRYPTO_pop_info();
#endif
- return 0;
+ return 0;
- auxerr:
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_AUX_ERROR);
- ASN1_item_ex_free(pval, it);
+ auxerr:
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_AUX_ERROR);
+ ASN1_item_ex_free(pval, it);
#ifdef CRYPTO_MDEBUG
- if (it->sname) CRYPTO_pop_info();
+ if (it->sname)
+ CRYPTO_pop_info();
#endif
- return 0;
+ return 0;
- }
+}
static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
- {
- const ASN1_EXTERN_FUNCS *ef;
-
- switch(it->itype)
- {
-
- case ASN1_ITYPE_EXTERN:
- ef = it->funcs;
- if (ef && ef->asn1_ex_clear)
- ef->asn1_ex_clear(pval, it);
- else *pval = NULL;
- break;
-
-
- case ASN1_ITYPE_PRIMITIVE:
- if (it->templates)
- asn1_template_clear(pval, it->templates);
- else
- asn1_primitive_clear(pval, it);
- break;
-
- case ASN1_ITYPE_MSTRING:
- asn1_primitive_clear(pval, it);
- break;
-
- case ASN1_ITYPE_COMPAT:
- case ASN1_ITYPE_CHOICE:
- case ASN1_ITYPE_SEQUENCE:
- case ASN1_ITYPE_NDEF_SEQUENCE:
- *pval = NULL;
- break;
- }
- }
-
+{
+ const ASN1_EXTERN_FUNCS *ef;
+
+ switch (it->itype) {
+
+ case ASN1_ITYPE_EXTERN:
+ ef = it->funcs;
+ if (ef && ef->asn1_ex_clear)
+ ef->asn1_ex_clear(pval, it);
+ else
+ *pval = NULL;
+ break;
+
+ case ASN1_ITYPE_PRIMITIVE:
+ if (it->templates)
+ asn1_template_clear(pval, it->templates);
+ else
+ asn1_primitive_clear(pval, it);
+ break;
+
+ case ASN1_ITYPE_MSTRING:
+ asn1_primitive_clear(pval, it);
+ break;
+
+ case ASN1_ITYPE_COMPAT:
+ case ASN1_ITYPE_CHOICE:
+ case ASN1_ITYPE_SEQUENCE:
+ case ASN1_ITYPE_NDEF_SEQUENCE:
+ *pval = NULL;
+ break;
+ }
+}
int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
- {
- const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item);
- int ret;
- if (tt->flags & ASN1_TFLG_OPTIONAL)
- {
- asn1_template_clear(pval, tt);
- return 1;
- }
- /* If ANY DEFINED BY nothing to do */
-
- if (tt->flags & ASN1_TFLG_ADB_MASK)
- {
- *pval = NULL;
- return 1;
- }
+{
+ const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item);
+ int ret;
+ if (tt->flags & ASN1_TFLG_OPTIONAL) {
+ asn1_template_clear(pval, tt);
+ return 1;
+ }
+ /* If ANY DEFINED BY nothing to do */
+
+ if (tt->flags & ASN1_TFLG_ADB_MASK) {
+ *pval = NULL;
+ return 1;
+ }
#ifdef CRYPTO_MDEBUG
- if (tt->field_name)
- CRYPTO_push_info(tt->field_name);
+ if (tt->field_name)
+ CRYPTO_push_info(tt->field_name);
#endif
- /* If SET OF or SEQUENCE OF, its a STACK */
- if (tt->flags & ASN1_TFLG_SK_MASK)
- {
- STACK_OF(ASN1_VALUE) *skval;
- skval = sk_ASN1_VALUE_new_null();
- if (!skval)
- {
- OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
- ret = 0;
- goto done;
- }
- *pval = (ASN1_VALUE *)skval;
- ret = 1;
- goto done;
- }
- /* Otherwise pass it back to the item routine */
- ret = asn1_item_ex_combine_new(pval, it, tt->flags & ASN1_TFLG_COMBINE);
- done:
+ /* If SET OF or SEQUENCE OF, its a STACK */
+ if (tt->flags & ASN1_TFLG_SK_MASK) {
+ STACK_OF(ASN1_VALUE) *skval;
+ skval = sk_ASN1_VALUE_new_null();
+ if (!skval) {
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+ ret = 0;
+ goto done;
+ }
+ *pval = (ASN1_VALUE *)skval;
+ ret = 1;
+ goto done;
+ }
+ /* Otherwise pass it back to the item routine */
+ ret = asn1_item_ex_combine_new(pval, it, tt->flags & ASN1_TFLG_COMBINE);
+ done:
#ifdef CRYPTO_MDEBUG
- if (it->sname)
- CRYPTO_pop_info();
+ if (it->sname)
+ CRYPTO_pop_info();
#endif
- return ret;
- }
+ return ret;
+}
static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
- {
- /* If ADB or STACK just NULL the field */
- if (tt->flags & (ASN1_TFLG_ADB_MASK|ASN1_TFLG_SK_MASK))
- *pval = NULL;
- else
- asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item));
- }
-
-
-/* NB: could probably combine most of the real XXX_new() behaviour and junk
+{
+ /* If ADB or STACK just NULL the field */
+ if (tt->flags & (ASN1_TFLG_ADB_MASK | ASN1_TFLG_SK_MASK))
+ *pval = NULL;
+ else
+ asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item));
+}
+
+/*
+ * NB: could probably combine most of the real XXX_new() behaviour and junk
* all the old functions.
*/
int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
- {
- ASN1_TYPE *typ;
- ASN1_STRING *str;
- int utype;
-
- if (!it)
- return 0;
-
- if (it->funcs)
- {
- const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
- if (pf->prim_new)
- return pf->prim_new(pval, it);
- }
-
- if (it->itype == ASN1_ITYPE_MSTRING)
- utype = -1;
- else
- utype = it->utype;
- switch(utype)
- {
- case V_ASN1_OBJECT:
- *pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef);
- return 1;
-
- case V_ASN1_BOOLEAN:
- *(ASN1_BOOLEAN *)pval = it->size;
- return 1;
-
- case V_ASN1_NULL:
- *pval = (ASN1_VALUE *)1;
- return 1;
-
- case V_ASN1_ANY:
- typ = OPENSSL_malloc(sizeof(ASN1_TYPE));
- if (!typ)
- return 0;
- typ->value.ptr = NULL;
- typ->type = -1;
- *pval = (ASN1_VALUE *)typ;
- break;
-
- default:
- str = ASN1_STRING_type_new(utype);
- if (it->itype == ASN1_ITYPE_MSTRING && str)
- str->flags |= ASN1_STRING_FLAG_MSTRING;
- *pval = (ASN1_VALUE *)str;
- break;
- }
- if (*pval)
- return 1;
- return 0;
- }
+{
+ ASN1_TYPE *typ;
+ ASN1_STRING *str;
+ int utype;
+
+ if (!it)
+ return 0;
+
+ if (it->funcs) {
+ const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
+ if (pf->prim_new)
+ return pf->prim_new(pval, it);
+ }
+
+ if (it->itype == ASN1_ITYPE_MSTRING)
+ utype = -1;
+ else
+ utype = it->utype;
+ switch (utype) {
+ case V_ASN1_OBJECT:
+ *pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef);
+ return 1;
+
+ case V_ASN1_BOOLEAN:
+ *(ASN1_BOOLEAN *)pval = it->size;
+ return 1;
+
+ case V_ASN1_NULL:
+ *pval = (ASN1_VALUE *)1;
+ return 1;
+
+ case V_ASN1_ANY:
+ typ = OPENSSL_malloc(sizeof(ASN1_TYPE));
+ if (!typ)
+ return 0;
+ typ->value.ptr = NULL;
+ typ->type = -1;
+ *pval = (ASN1_VALUE *)typ;
+ break;
+
+ default:
+ str = ASN1_STRING_type_new(utype);
+ if (it->itype == ASN1_ITYPE_MSTRING && str)
+ str->flags |= ASN1_STRING_FLAG_MSTRING;
+ *pval = (ASN1_VALUE *)str;
+ break;
+ }
+ if (*pval)
+ return 1;
+ return 0;
+}
static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
- {
- int utype;
- if (it && it->funcs)
- {
- const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
- if (pf->prim_clear)
- pf->prim_clear(pval, it);
- else
- *pval = NULL;
- return;
- }
- if (!it || (it->itype == ASN1_ITYPE_MSTRING))
- utype = -1;
- else
- utype = it->utype;
- if (utype == V_ASN1_BOOLEAN)
- *(ASN1_BOOLEAN *)pval = it->size;
- else *pval = NULL;
- }
+{
+ int utype;
+ if (it && it->funcs) {
+ const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
+ if (pf->prim_clear)
+ pf->prim_clear(pval, it);
+ else
+ *pval = NULL;
+ return;
+ }
+ if (!it || (it->itype == ASN1_ITYPE_MSTRING))
+ utype = -1;
+ else
+ utype = it->utype;
+ if (utype == V_ASN1_BOOLEAN)
+ *(ASN1_BOOLEAN *)pval = it->size;
+ else
+ *pval = NULL;
+}
diff --git a/src/crypto/asn1/tasn_prn.c b/src/crypto/asn1/tasn_prn.c
index a5740554..dd20cb4d 100644
--- a/src/crypto/asn1/tasn_prn.c
+++ b/src/crypto/asn1/tasn_prn.c
@@ -65,578 +65,532 @@
#include "asn1_locl.h"
-
-
-/* Print routines.
+/*
+ * Print routines.
*/
/* ASN1_PCTX routines */
-static ASN1_PCTX default_pctx =
- {
- ASN1_PCTX_FLAGS_SHOW_ABSENT, /* flags */
- 0, /* nm_flags */
- 0, /* cert_flags */
- 0, /* oid_flags */
- 0 /* str_flags */
- };
-
+static ASN1_PCTX default_pctx = {
+ ASN1_PCTX_FLAGS_SHOW_ABSENT, /* flags */
+ 0, /* nm_flags */
+ 0, /* cert_flags */
+ 0, /* oid_flags */
+ 0 /* str_flags */
+};
ASN1_PCTX *ASN1_PCTX_new(void)
- {
- ASN1_PCTX *ret;
- ret = OPENSSL_malloc(sizeof(ASN1_PCTX));
- if (ret == NULL)
- {
- OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
- ret->flags = 0;
- ret->nm_flags = 0;
- ret->cert_flags = 0;
- ret->oid_flags = 0;
- ret->str_flags = 0;
- return ret;
- }
+{
+ ASN1_PCTX *ret;
+ ret = OPENSSL_malloc(sizeof(ASN1_PCTX));
+ if (ret == NULL) {
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ ret->flags = 0;
+ ret->nm_flags = 0;
+ ret->cert_flags = 0;
+ ret->oid_flags = 0;
+ ret->str_flags = 0;
+ return ret;
+}
void ASN1_PCTX_free(ASN1_PCTX *p)
- {
- OPENSSL_free(p);
- }
+{
+ OPENSSL_free(p);
+}
unsigned long ASN1_PCTX_get_flags(ASN1_PCTX *p)
- {
- return p->flags;
- }
+{
+ return p->flags;
+}
void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags)
- {
- p->flags = flags;
- }
+{
+ p->flags = flags;
+}
unsigned long ASN1_PCTX_get_nm_flags(ASN1_PCTX *p)
- {
- return p->nm_flags;
- }
+{
+ return p->nm_flags;
+}
void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags)
- {
- p->nm_flags = flags;
- }
+{
+ p->nm_flags = flags;
+}
unsigned long ASN1_PCTX_get_cert_flags(ASN1_PCTX *p)
- {
- return p->cert_flags;
- }
+{
+ return p->cert_flags;
+}
void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags)
- {
- p->cert_flags = flags;
- }
+{
+ p->cert_flags = flags;
+}
unsigned long ASN1_PCTX_get_oid_flags(ASN1_PCTX *p)
- {
- return p->oid_flags;
- }
+{
+ return p->oid_flags;
+}
void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags)
- {
- p->oid_flags = flags;
- }
+{
+ p->oid_flags = flags;
+}
unsigned long ASN1_PCTX_get_str_flags(ASN1_PCTX *p)
- {
- return p->str_flags;
- }
+{
+ return p->str_flags;
+}
void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags)
- {
- p->str_flags = flags;
- }
+{
+ p->str_flags = flags;
+}
/* Main print routines */
static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
- const ASN1_ITEM *it,
- const char *fname, const char *sname,
- int nohdr, const ASN1_PCTX *pctx);
+ const ASN1_ITEM *it,
+ const char *fname, const char *sname,
+ int nohdr, const ASN1_PCTX *pctx);
int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
- const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx);
+ const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx);
static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
- const ASN1_ITEM *it, int indent,
- const char *fname, const char *sname,
- const ASN1_PCTX *pctx);
+ const ASN1_ITEM *it, int indent,
+ const char *fname, const char *sname,
+ const ASN1_PCTX *pctx);
static int asn1_print_fsname(BIO *out, int indent,
- const char *fname, const char *sname,
- const ASN1_PCTX *pctx);
+ const char *fname, const char *sname,
+ const ASN1_PCTX *pctx);
int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent,
- const ASN1_ITEM *it, const ASN1_PCTX *pctx)
- {
- const char *sname;
- if (pctx == NULL)
- pctx = &default_pctx;
- if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
- sname = NULL;
- else
- sname = it->sname;
- return asn1_item_print_ctx(out, &ifld, indent, it,
- NULL, sname, 0, pctx);
- }
+ const ASN1_ITEM *it, const ASN1_PCTX *pctx)
+{
+ const char *sname;
+ if (pctx == NULL)
+ pctx = &default_pctx;
+ if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
+ sname = NULL;
+ else
+ sname = it->sname;
+ return asn1_item_print_ctx(out, &ifld, indent, it, NULL, sname, 0, pctx);
+}
static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
- const ASN1_ITEM *it,
- const char *fname, const char *sname,
- int nohdr, const ASN1_PCTX *pctx)
- {
- const ASN1_TEMPLATE *tt;
- const ASN1_EXTERN_FUNCS *ef;
- ASN1_VALUE **tmpfld;
- const ASN1_AUX *aux = it->funcs;
- ASN1_aux_cb *asn1_cb;
- ASN1_PRINT_ARG parg;
- int i;
- if (aux && aux->asn1_cb)
- {
- parg.out = out;
- parg.indent = indent;
- parg.pctx = pctx;
- asn1_cb = aux->asn1_cb;
- }
- else asn1_cb = 0;
-
- if(*fld == NULL)
- {
- if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_ABSENT)
- {
- if (!nohdr && !asn1_print_fsname(out, indent,
- fname, sname, pctx))
- return 0;
- if (BIO_puts(out, "<ABSENT>\n") <= 0)
- return 0;
- }
- return 1;
- }
-
- switch(it->itype)
- {
- case ASN1_ITYPE_PRIMITIVE:
- if(it->templates)
- {
- if (!asn1_template_print_ctx(out, fld, indent,
- it->templates, pctx))
- return 0;
- break;
- }
- /* fall thru */
- case ASN1_ITYPE_MSTRING:
- if (!asn1_primitive_print(out, fld, it,
- indent, fname, sname,pctx))
- return 0;
- break;
-
- case ASN1_ITYPE_EXTERN:
- if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
- return 0;
- /* Use new style print routine if possible */
- ef = it->funcs;
- if (ef && ef->asn1_ex_print)
- {
- i = ef->asn1_ex_print(out, fld, indent, "", pctx);
- if (!i)
- return 0;
- if ((i == 2) && (BIO_puts(out, "\n") <= 0))
- return 0;
- return 1;
- }
- else if (sname &&
- BIO_printf(out, ":EXTERNAL TYPE %s\n", sname) <= 0)
- return 0;
- break;
-
- case ASN1_ITYPE_CHOICE:
+ const ASN1_ITEM *it,
+ const char *fname, const char *sname,
+ int nohdr, const ASN1_PCTX *pctx)
+{
+ const ASN1_TEMPLATE *tt;
+ const ASN1_EXTERN_FUNCS *ef;
+ ASN1_VALUE **tmpfld;
+ const ASN1_AUX *aux = it->funcs;
+ ASN1_aux_cb *asn1_cb;
+ ASN1_PRINT_ARG parg;
+ int i;
+ if (aux && aux->asn1_cb) {
+ parg.out = out;
+ parg.indent = indent;
+ parg.pctx = pctx;
+ asn1_cb = aux->asn1_cb;
+ } else
+ asn1_cb = 0;
+
+ if (*fld == NULL) {
+ if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_ABSENT) {
+ if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
+ return 0;
+ if (BIO_puts(out, "<ABSENT>\n") <= 0)
+ return 0;
+ }
+ return 1;
+ }
+
+ switch (it->itype) {
+ case ASN1_ITYPE_PRIMITIVE:
+ if (it->templates) {
+ if (!asn1_template_print_ctx(out, fld, indent,
+ it->templates, pctx))
+ return 0;
+ break;
+ }
+ /* fall thru */
+ case ASN1_ITYPE_MSTRING:
+ if (!asn1_primitive_print(out, fld, it, indent, fname, sname, pctx))
+ return 0;
+ break;
+
+ case ASN1_ITYPE_EXTERN:
+ if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
+ return 0;
+ /* Use new style print routine if possible */
+ ef = it->funcs;
+ if (ef && ef->asn1_ex_print) {
+ i = ef->asn1_ex_print(out, fld, indent, "", pctx);
+ if (!i)
+ return 0;
+ if ((i == 2) && (BIO_puts(out, "\n") <= 0))
+ return 0;
+ return 1;
+ } else if (sname &&
+ BIO_printf(out, ":EXTERNAL TYPE %s\n", sname) <= 0)
+ return 0;
+ break;
+
+ case ASN1_ITYPE_CHOICE:
#if 0
- if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
- return 0;
+ if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
+ return 0;
#endif
- /* CHOICE type, get selector */
- i = asn1_get_choice_selector(fld, it);
- /* This should never happen... */
- if((i < 0) || (i >= it->tcount))
- {
- if (BIO_printf(out,
- "ERROR: selector [%d] invalid\n", i) <= 0)
- return 0;
- return 1;
- }
- tt = it->templates + i;
- tmpfld = asn1_get_field_ptr(fld, tt);
- if (!asn1_template_print_ctx(out, tmpfld, indent, tt, pctx))
- return 0;
- break;
-
- case ASN1_ITYPE_SEQUENCE:
- case ASN1_ITYPE_NDEF_SEQUENCE:
- if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
- return 0;
- if (fname || sname)
- {
- if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE)
- {
- if (BIO_puts(out, " {\n") <= 0)
- return 0;
- }
- else
- {
- if (BIO_puts(out, "\n") <= 0)
- return 0;
- }
- }
-
- if (asn1_cb)
- {
- i = asn1_cb(ASN1_OP_PRINT_PRE, fld, it, &parg);
- if (i == 0)
- return 0;
- if (i == 2)
- return 1;
- }
-
- /* Print each field entry */
- for(i = 0, tt = it->templates; i < it->tcount; i++, tt++)
- {
- const ASN1_TEMPLATE *seqtt;
- seqtt = asn1_do_adb(fld, tt, 1);
- if (!seqtt)
- return 0;
- tmpfld = asn1_get_field_ptr(fld, seqtt);
- if (!asn1_template_print_ctx(out, tmpfld,
- indent + 2, seqtt, pctx))
- return 0;
- }
- if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE)
- {
- if (BIO_printf(out, "%*s}\n", indent, "") < 0)
- return 0;
- }
-
- if (asn1_cb)
- {
- i = asn1_cb(ASN1_OP_PRINT_POST, fld, it, &parg);
- if (i == 0)
- return 0;
- }
- break;
-
- default:
- BIO_printf(out, "Unprocessed type %d\n", it->itype);
- return 0;
- }
-
- return 1;
- }
+ /* CHOICE type, get selector */
+ i = asn1_get_choice_selector(fld, it);
+ /* This should never happen... */
+ if ((i < 0) || (i >= it->tcount)) {
+ if (BIO_printf(out, "ERROR: selector [%d] invalid\n", i) <= 0)
+ return 0;
+ return 1;
+ }
+ tt = it->templates + i;
+ tmpfld = asn1_get_field_ptr(fld, tt);
+ if (!asn1_template_print_ctx(out, tmpfld, indent, tt, pctx))
+ return 0;
+ break;
+
+ case ASN1_ITYPE_SEQUENCE:
+ case ASN1_ITYPE_NDEF_SEQUENCE:
+ if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
+ return 0;
+ if (fname || sname) {
+ if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) {
+ if (BIO_puts(out, " {\n") <= 0)
+ return 0;
+ } else {
+ if (BIO_puts(out, "\n") <= 0)
+ return 0;
+ }
+ }
+
+ if (asn1_cb) {
+ i = asn1_cb(ASN1_OP_PRINT_PRE, fld, it, &parg);
+ if (i == 0)
+ return 0;
+ if (i == 2)
+ return 1;
+ }
+
+ /* Print each field entry */
+ for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
+ const ASN1_TEMPLATE *seqtt;
+ seqtt = asn1_do_adb(fld, tt, 1);
+ if (!seqtt)
+ return 0;
+ tmpfld = asn1_get_field_ptr(fld, seqtt);
+ if (!asn1_template_print_ctx(out, tmpfld,
+ indent + 2, seqtt, pctx))
+ return 0;
+ }
+ if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) {
+ if (BIO_printf(out, "%*s}\n", indent, "") < 0)
+ return 0;
+ }
+
+ if (asn1_cb) {
+ i = asn1_cb(ASN1_OP_PRINT_POST, fld, it, &parg);
+ if (i == 0)
+ return 0;
+ }
+ break;
+
+ default:
+ BIO_printf(out, "Unprocessed type %d\n", it->itype);
+ return 0;
+ }
+
+ return 1;
+}
int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
- const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx)
- {
- int flags;
- size_t i;
- const char *sname, *fname;
- flags = tt->flags;
- if(pctx->flags & ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME)
- sname = ASN1_ITEM_ptr(tt->item)->sname;
- else
- sname = NULL;
- if(pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
- fname = NULL;
- else
- fname = tt->field_name;
- if(flags & ASN1_TFLG_SK_MASK)
- {
- const char *tname;
- ASN1_VALUE *skitem;
- STACK_OF(ASN1_VALUE) *stack;
-
- /* SET OF, SEQUENCE OF */
- if (fname)
- {
- if(pctx->flags & ASN1_PCTX_FLAGS_SHOW_SSOF)
- {
- if(flags & ASN1_TFLG_SET_OF)
- tname = "SET";
- else
- tname = "SEQUENCE";
- if (BIO_printf(out, "%*s%s OF %s {\n",
- indent, "", tname, tt->field_name) <= 0)
- return 0;
- }
- else if (BIO_printf(out, "%*s%s:\n", indent, "",
- fname) <= 0)
- return 0;
- }
- stack = (STACK_OF(ASN1_VALUE) *)*fld;
- for(i = 0; i < sk_ASN1_VALUE_num(stack); i++)
- {
- if ((i > 0) && (BIO_puts(out, "\n") <= 0))
- return 0;
-
- skitem = sk_ASN1_VALUE_value(stack, i);
- if (!asn1_item_print_ctx(out, &skitem, indent + 2,
- ASN1_ITEM_ptr(tt->item), NULL, NULL, 1, pctx))
- return 0;
- }
- if (!i && BIO_printf(out, "%*s<EMPTY>\n", indent + 2, "") <= 0)
- return 0;
- if(pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE)
- {
- if (BIO_printf(out, "%*s}\n", indent, "") <= 0)
- return 0;
- }
- return 1;
- }
- return asn1_item_print_ctx(out, fld, indent, ASN1_ITEM_ptr(tt->item),
- fname, sname, 0, pctx);
- }
+ const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx)
+{
+ int flags;
+ size_t i;
+ const char *sname, *fname;
+ flags = tt->flags;
+ if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME)
+ sname = ASN1_ITEM_ptr(tt->item)->sname;
+ else
+ sname = NULL;
+ if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
+ fname = NULL;
+ else
+ fname = tt->field_name;
+ if (flags & ASN1_TFLG_SK_MASK) {
+ const char *tname;
+ ASN1_VALUE *skitem;
+ STACK_OF(ASN1_VALUE) *stack;
+
+ /* SET OF, SEQUENCE OF */
+ if (fname) {
+ if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SSOF) {
+ if (flags & ASN1_TFLG_SET_OF)
+ tname = "SET";
+ else
+ tname = "SEQUENCE";
+ if (BIO_printf(out, "%*s%s OF %s {\n",
+ indent, "", tname, tt->field_name) <= 0)
+ return 0;
+ } else if (BIO_printf(out, "%*s%s:\n", indent, "", fname) <= 0)
+ return 0;
+ }
+ stack = (STACK_OF(ASN1_VALUE) *)*fld;
+ for (i = 0; i < sk_ASN1_VALUE_num(stack); i++) {
+ if ((i > 0) && (BIO_puts(out, "\n") <= 0))
+ return 0;
+
+ skitem = sk_ASN1_VALUE_value(stack, i);
+ if (!asn1_item_print_ctx(out, &skitem, indent + 2,
+ ASN1_ITEM_ptr(tt->item), NULL, NULL, 1,
+ pctx))
+ return 0;
+ }
+ if (!i && BIO_printf(out, "%*s<EMPTY>\n", indent + 2, "") <= 0)
+ return 0;
+ if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) {
+ if (BIO_printf(out, "%*s}\n", indent, "") <= 0)
+ return 0;
+ }
+ return 1;
+ }
+ return asn1_item_print_ctx(out, fld, indent, ASN1_ITEM_ptr(tt->item),
+ fname, sname, 0, pctx);
+}
static int asn1_print_fsname(BIO *out, int indent,
- const char *fname, const char *sname,
- const ASN1_PCTX *pctx)
- {
- static char spaces[] = " ";
- const int nspaces = sizeof(spaces) - 1;
+ const char *fname, const char *sname,
+ const ASN1_PCTX *pctx)
+{
+ static char spaces[] = " ";
+ const int nspaces = sizeof(spaces) - 1;
#if 0
- if (!sname && !fname)
- return 1;
+ if (!sname && !fname)
+ return 1;
#endif
- while (indent > nspaces)
- {
- if (BIO_write(out, spaces, nspaces) != nspaces)
- return 0;
- indent -= nspaces;
- }
- if (BIO_write(out, spaces, indent) != indent)
- return 0;
- if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
- sname = NULL;
- if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
- fname = NULL;
- if (!sname && !fname)
- return 1;
- if (fname)
- {
- if (BIO_puts(out, fname) <= 0)
- return 0;
- }
- if (sname)
- {
- if (fname)
- {
- if (BIO_printf(out, " (%s)", sname) <= 0)
- return 0;
- }
- else
- {
- if (BIO_puts(out, sname) <= 0)
- return 0;
- }
- }
- if (BIO_write(out, ": ", 2) != 2)
- return 0;
- return 1;
- }
+ while (indent > nspaces) {
+ if (BIO_write(out, spaces, nspaces) != nspaces)
+ return 0;
+ indent -= nspaces;
+ }
+ if (BIO_write(out, spaces, indent) != indent)
+ return 0;
+ if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
+ sname = NULL;
+ if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
+ fname = NULL;
+ if (!sname && !fname)
+ return 1;
+ if (fname) {
+ if (BIO_puts(out, fname) <= 0)
+ return 0;
+ }
+ if (sname) {
+ if (fname) {
+ if (BIO_printf(out, " (%s)", sname) <= 0)
+ return 0;
+ } else {
+ if (BIO_puts(out, sname) <= 0)
+ return 0;
+ }
+ }
+ if (BIO_write(out, ": ", 2) != 2)
+ return 0;
+ return 1;
+}
static int asn1_print_boolean_ctx(BIO *out, int boolval,
- const ASN1_PCTX *pctx)
- {
- const char *str;
- switch (boolval)
- {
- case -1:
- str = "BOOL ABSENT";
- break;
+ const ASN1_PCTX *pctx)
+{
+ const char *str;
+ switch (boolval) {
+ case -1:
+ str = "BOOL ABSENT";
+ break;
- case 0:
- str = "FALSE";
- break;
+ case 0:
+ str = "FALSE";
+ break;
- default:
- str = "TRUE";
- break;
+ default:
+ str = "TRUE";
+ break;
- }
+ }
- if (BIO_puts(out, str) <= 0)
- return 0;
- return 1;
+ if (BIO_puts(out, str) <= 0)
+ return 0;
+ return 1;
- }
+}
static int asn1_print_integer_ctx(BIO *out, ASN1_INTEGER *str,
- const ASN1_PCTX *pctx)
- {
- BIGNUM *bn = NULL;
- char *s = NULL;
- int ret = 1;
-
- bn = ASN1_INTEGER_to_BN(str, NULL);
- if (bn == NULL) {
- return 0;
- }
- s = BN_bn2dec(bn);
- BN_free(bn);
- if (s == NULL) {
- return 0;
- }
-
- if (BIO_puts(out, s) <= 0) {
- ret = 0;
- }
- OPENSSL_free(s);
- return ret;
- }
+ const ASN1_PCTX *pctx)
+{
+ BIGNUM *bn = NULL;
+ char *s = NULL;
+ int ret = 1;
+
+ bn = ASN1_INTEGER_to_BN(str, NULL);
+ if (bn == NULL) {
+ return 0;
+ }
+ s = BN_bn2dec(bn);
+ BN_free(bn);
+ if (s == NULL) {
+ return 0;
+ }
+
+ if (BIO_puts(out, s) <= 0) {
+ ret = 0;
+ }
+ OPENSSL_free(s);
+ return ret;
+}
static int asn1_print_oid_ctx(BIO *out, const ASN1_OBJECT *oid,
- const ASN1_PCTX *pctx)
- {
- char objbuf[80];
- const char *ln;
- ln = OBJ_nid2ln(OBJ_obj2nid(oid));
- if(!ln)
- ln = "";
- OBJ_obj2txt(objbuf, sizeof objbuf, oid, 1);
- if (BIO_printf(out, "%s (%s)", ln, objbuf) <= 0)
- return 0;
- return 1;
- }
+ const ASN1_PCTX *pctx)
+{
+ char objbuf[80];
+ const char *ln;
+ ln = OBJ_nid2ln(OBJ_obj2nid(oid));
+ if (!ln)
+ ln = "";
+ OBJ_obj2txt(objbuf, sizeof objbuf, oid, 1);
+ if (BIO_printf(out, "%s (%s)", ln, objbuf) <= 0)
+ return 0;
+ return 1;
+}
static int asn1_print_obstring_ctx(BIO *out, ASN1_STRING *str, int indent,
- const ASN1_PCTX *pctx)
- {
- if (str->type == V_ASN1_BIT_STRING)
- {
- if (BIO_printf(out, " (%ld unused bits)\n",
- str->flags & 0x7) <= 0)
- return 0;
- }
- else if (BIO_puts(out, "\n") <= 0)
- return 0;
- if (str->length > 0 && !BIO_hexdump(out, str->data, str->length, indent + 2)) {
- return 0;
- }
- return 1;
- }
+ const ASN1_PCTX *pctx)
+{
+ if (str->type == V_ASN1_BIT_STRING) {
+ if (BIO_printf(out, " (%ld unused bits)\n", str->flags & 0x7) <= 0)
+ return 0;
+ } else if (BIO_puts(out, "\n") <= 0)
+ return 0;
+ if (str->length > 0
+ && !BIO_hexdump(out, str->data, str->length, indent + 2)) {
+ return 0;
+ }
+ return 1;
+}
static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
- const ASN1_ITEM *it, int indent,
- const char *fname, const char *sname,
- const ASN1_PCTX *pctx)
- {
- long utype;
- ASN1_STRING *str;
- int ret = 1, needlf = 1;
- const char *pname;
- const ASN1_PRIMITIVE_FUNCS *pf;
- pf = it->funcs;
- if (!asn1_print_fsname(out, indent, fname, sname, pctx))
- return 0;
- if (pf && pf->prim_print)
- return pf->prim_print(out, fld, it, indent, pctx);
- str = (ASN1_STRING *)*fld;
- if (it->itype == ASN1_ITYPE_MSTRING)
- utype = str->type & ~V_ASN1_NEG;
- else
- utype = it->utype;
- if (utype == V_ASN1_ANY)
- {
- ASN1_TYPE *atype = (ASN1_TYPE *)*fld;
- utype = atype->type;
- fld = &atype->value.asn1_value;
- str = (ASN1_STRING *)*fld;
- if (pctx->flags & ASN1_PCTX_FLAGS_NO_ANY_TYPE)
- pname = NULL;
- else
- pname = ASN1_tag2str(utype);
- }
- else
- {
- if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_TYPE)
- pname = ASN1_tag2str(utype);
- else
- pname = NULL;
- }
-
- if (utype == V_ASN1_NULL)
- {
- if (BIO_puts(out, "NULL\n") <= 0)
- return 0;
- return 1;
- }
-
- if (pname)
- {
- if (BIO_puts(out, pname) <= 0)
- return 0;
- if (BIO_puts(out, ":") <= 0)
- return 0;
- }
-
- switch (utype)
- {
- case V_ASN1_BOOLEAN:
- {
- int boolval = *(int *)fld;
- if (boolval == -1)
- boolval = it->size;
- ret = asn1_print_boolean_ctx(out, boolval, pctx);
- }
- break;
-
- case V_ASN1_INTEGER:
- case V_ASN1_ENUMERATED:
- ret = asn1_print_integer_ctx(out, str, pctx);
- break;
-
- case V_ASN1_UTCTIME:
- ret = ASN1_UTCTIME_print(out, str);
- break;
-
- case V_ASN1_GENERALIZEDTIME:
- ret = ASN1_GENERALIZEDTIME_print(out, str);
- break;
-
- case V_ASN1_OBJECT:
- ret = asn1_print_oid_ctx(out, (const ASN1_OBJECT *)*fld, pctx);
- break;
-
- case V_ASN1_OCTET_STRING:
- case V_ASN1_BIT_STRING:
- ret = asn1_print_obstring_ctx(out, str, indent, pctx);
- needlf = 0;
- break;
-
- case V_ASN1_SEQUENCE:
- case V_ASN1_SET:
- case V_ASN1_OTHER:
- if (BIO_puts(out, "\n") <= 0)
- return 0;
- if (ASN1_parse_dump(out, str->data, str->length,
- indent, 0) <= 0)
- ret = 0;
- needlf = 0;
- break;
-
- default:
- ret = ASN1_STRING_print_ex(out, str, pctx->str_flags);
-
- }
- if (!ret)
- return 0;
- if (needlf && BIO_puts(out, "\n") <= 0)
- return 0;
- return 1;
- }
+ const ASN1_ITEM *it, int indent,
+ const char *fname, const char *sname,
+ const ASN1_PCTX *pctx)
+{
+ long utype;
+ ASN1_STRING *str;
+ int ret = 1, needlf = 1;
+ const char *pname;
+ const ASN1_PRIMITIVE_FUNCS *pf;
+ pf = it->funcs;
+ if (!asn1_print_fsname(out, indent, fname, sname, pctx))
+ return 0;
+ if (pf && pf->prim_print)
+ return pf->prim_print(out, fld, it, indent, pctx);
+ str = (ASN1_STRING *)*fld;
+ if (it->itype == ASN1_ITYPE_MSTRING)
+ utype = str->type & ~V_ASN1_NEG;
+ else
+ utype = it->utype;
+ if (utype == V_ASN1_ANY) {
+ ASN1_TYPE *atype = (ASN1_TYPE *)*fld;
+ utype = atype->type;
+ fld = &atype->value.asn1_value;
+ str = (ASN1_STRING *)*fld;
+ if (pctx->flags & ASN1_PCTX_FLAGS_NO_ANY_TYPE)
+ pname = NULL;
+ else
+ pname = ASN1_tag2str(utype);
+ } else {
+ if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_TYPE)
+ pname = ASN1_tag2str(utype);
+ else
+ pname = NULL;
+ }
+
+ if (utype == V_ASN1_NULL) {
+ if (BIO_puts(out, "NULL\n") <= 0)
+ return 0;
+ return 1;
+ }
+
+ if (pname) {
+ if (BIO_puts(out, pname) <= 0)
+ return 0;
+ if (BIO_puts(out, ":") <= 0)
+ return 0;
+ }
+
+ switch (utype) {
+ case V_ASN1_BOOLEAN:
+ {
+ int boolval = *(int *)fld;
+ if (boolval == -1)
+ boolval = it->size;
+ ret = asn1_print_boolean_ctx(out, boolval, pctx);
+ }
+ break;
+
+ case V_ASN1_INTEGER:
+ case V_ASN1_ENUMERATED:
+ ret = asn1_print_integer_ctx(out, str, pctx);
+ break;
+
+ case V_ASN1_UTCTIME:
+ ret = ASN1_UTCTIME_print(out, str);
+ break;
+
+ case V_ASN1_GENERALIZEDTIME:
+ ret = ASN1_GENERALIZEDTIME_print(out, str);
+ break;
+
+ case V_ASN1_OBJECT:
+ ret = asn1_print_oid_ctx(out, (const ASN1_OBJECT *)*fld, pctx);
+ break;
+
+ case V_ASN1_OCTET_STRING:
+ case V_ASN1_BIT_STRING:
+ ret = asn1_print_obstring_ctx(out, str, indent, pctx);
+ needlf = 0;
+ break;
+
+ case V_ASN1_SEQUENCE:
+ case V_ASN1_SET:
+ case V_ASN1_OTHER:
+ if (BIO_puts(out, "\n") <= 0)
+ return 0;
+ if (ASN1_parse_dump(out, str->data, str->length, indent, 0) <= 0)
+ ret = 0;
+ needlf = 0;
+ break;
+
+ default:
+ ret = ASN1_STRING_print_ex(out, str, pctx->str_flags);
+
+ }
+ if (!ret)
+ return 0;
+ if (needlf && BIO_puts(out, "\n") <= 0)
+ return 0;
+ return 1;
+}
diff --git a/src/crypto/asn1/tasn_typ.c b/src/crypto/asn1/tasn_typ.c
index f004b0dc..daf02eae 100644
--- a/src/crypto/asn1/tasn_typ.c
+++ b/src/crypto/asn1/tasn_typ.c
@@ -58,20 +58,19 @@
#include <openssl/asn1t.h>
-
/* Declarations for string types */
#define IMPLEMENT_ASN1_STRING_FUNCTIONS(sname) \
- IMPLEMENT_ASN1_TYPE(sname) \
- IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(sname, sname, sname) \
- sname *sname##_new(void) \
- { \
- return ASN1_STRING_type_new(V_##sname); \
- } \
- void sname##_free(sname *x) \
- { \
- ASN1_STRING_free(x); \
- }
+ IMPLEMENT_ASN1_TYPE(sname) \
+ IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(sname, sname, sname) \
+ sname *sname##_new(void) \
+ { \
+ return ASN1_STRING_type_new(V_##sname); \
+ } \
+ void sname##_free(sname *x) \
+ { \
+ ASN1_STRING_free(x); \
+ }
IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_OCTET_STRING)
IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_INTEGER)
@@ -95,12 +94,16 @@ IMPLEMENT_ASN1_TYPE(ASN1_OBJECT);
IMPLEMENT_ASN1_TYPE(ASN1_ANY);
-/* Just swallow an ASN1_SEQUENCE in an ASN1_STRING */;
+/*
+ * Just swallow an ASN1_SEQUENCE in an ASN1_STRING
+ */ ;
IMPLEMENT_ASN1_TYPE(ASN1_SEQUENCE);
IMPLEMENT_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE);
-/* Multistring types */;
+/*
+ * Multistring types
+ */ ;
IMPLEMENT_ASN1_MSTRING(ASN1_PRINTABLE, B_ASN1_PRINTABLE);
IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, ASN1_PRINTABLE);
@@ -111,18 +114,23 @@ IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, DISPLAYTEXT);
IMPLEMENT_ASN1_MSTRING(DIRECTORYSTRING, B_ASN1_DIRECTORYSTRING);
IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, DIRECTORYSTRING);
-/* Three separate BOOLEAN type: normal, DEFAULT TRUE and DEFAULT FALSE */;
+/*
+ * Three separate BOOLEAN type: normal, DEFAULT TRUE and DEFAULT FALSE
+ */ ;
IMPLEMENT_ASN1_TYPE_ex(ASN1_BOOLEAN, ASN1_BOOLEAN, -1);
IMPLEMENT_ASN1_TYPE_ex(ASN1_TBOOLEAN, ASN1_BOOLEAN, 1);
IMPLEMENT_ASN1_TYPE_ex(ASN1_FBOOLEAN, ASN1_BOOLEAN, 0);
-/* Special, OCTET STRING with indefinite length constructed support */;
+/*
+ * Special, OCTET STRING with indefinite length constructed support
+ */ ;
IMPLEMENT_ASN1_TYPE_ex(ASN1_OCTET_STRING_NDEF, ASN1_OCTET_STRING,
- ASN1_TFLG_NDEF);
+ASN1_TFLG_NDEF);
-ASN1_ITEM_TEMPLATE(ASN1_SEQUENCE_ANY) = ASN1_EX_TEMPLATE_TYPE(
- ASN1_TFLG_SEQUENCE_OF, 0, ASN1_SEQUENCE_ANY, ASN1_ANY);
+ASN1_ITEM_TEMPLATE(ASN1_SEQUENCE_ANY) =
+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, ASN1_SEQUENCE_ANY,
+ ASN1_ANY);
ASN1_ITEM_TEMPLATE_END(ASN1_SEQUENCE_ANY);
ASN1_ITEM_TEMPLATE(ASN1_SET_ANY) = ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0,
@@ -131,7 +139,6 @@ ASN1_ITEM_TEMPLATE(ASN1_SET_ANY) = ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0,
ASN1_ITEM_TEMPLATE_END(ASN1_SET_ANY);
IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY,
- ASN1_SEQUENCE_ANY,
- ASN1_SEQUENCE_ANY);
+ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY);
IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY, ASN1_SET_ANY,
- ASN1_SET_ANY);
+ASN1_SET_ANY);
diff --git a/src/crypto/asn1/x_bignum.c b/src/crypto/asn1/x_bignum.c
index 5867c4ff..585d9d4a 100644
--- a/src/crypto/asn1/x_bignum.c
+++ b/src/crypto/asn1/x_bignum.c
@@ -59,85 +59,95 @@
#include <openssl/asn1t.h>
#include <openssl/bn.h>
-
-/* Custom primitive type for BIGNUM handling. This reads in an ASN1_INTEGER as a
- * BIGNUM directly. Currently it ignores the sign which isn't a problem since all
- * BIGNUMs used are non negative and anything that looks negative is normally due
- * to an encoding error.
+/*
+ * Custom primitive type for BIGNUM handling. This reads in an ASN1_INTEGER
+ * as a BIGNUM directly. Currently it ignores the sign which isn't a problem
+ * since all BIGNUMs used are non negative and anything that looks negative
+ * is normally due to an encoding error.
*/
-#define BN_SENSITIVE 1
+#define BN_SENSITIVE 1
static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
-static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it);
-static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);
+static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
+ const ASN1_ITEM *it);
+static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
+ int utype, char *free_cont, const ASN1_ITEM *it);
static const ASN1_PRIMITIVE_FUNCS bignum_pf = {
- NULL, 0,
- bn_new,
- bn_free,
- 0,
- bn_c2i,
- bn_i2c,
- NULL /* prim_print */,
+ NULL, 0,
+ bn_new,
+ bn_free,
+ 0,
+ bn_c2i,
+ bn_i2c,
+ NULL /* prim_print */ ,
};
ASN1_ITEM_start(BIGNUM)
- ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &bignum_pf, 0, "BIGNUM"
+ ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &bignum_pf, 0, "BIGNUM"
ASN1_ITEM_end(BIGNUM)
ASN1_ITEM_start(CBIGNUM)
- ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &bignum_pf, BN_SENSITIVE, "BIGNUM"
+ ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &bignum_pf, BN_SENSITIVE, "BIGNUM"
ASN1_ITEM_end(CBIGNUM)
static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
- *pval = (ASN1_VALUE *)BN_new();
- if(*pval) return 1;
- else return 0;
+ *pval = (ASN1_VALUE *)BN_new();
+ if (*pval)
+ return 1;
+ else
+ return 0;
}
static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
- if(!*pval) return;
- if(it->size & BN_SENSITIVE) BN_clear_free((BIGNUM *)*pval);
- else BN_free((BIGNUM *)*pval);
- *pval = NULL;
+ if (!*pval)
+ return;
+ if (it->size & BN_SENSITIVE)
+ BN_clear_free((BIGNUM *)*pval);
+ else
+ BN_free((BIGNUM *)*pval);
+ *pval = NULL;
}
-static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it)
+static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
+ const ASN1_ITEM *it)
{
- BIGNUM *bn;
- int pad;
- if(!*pval) return -1;
- bn = (BIGNUM *)*pval;
- /* If MSB set in an octet we need a padding byte */
- if(BN_num_bits(bn) & 0x7) pad = 0;
- else pad = 1;
- if(cont) {
- if(pad) *cont++ = 0;
- BN_bn2bin(bn, cont);
- }
- return pad + BN_num_bytes(bn);
+ BIGNUM *bn;
+ int pad;
+ if (!*pval)
+ return -1;
+ bn = (BIGNUM *)*pval;
+ /* If MSB set in an octet we need a padding byte */
+ if (BN_num_bits(bn) & 0x7)
+ pad = 0;
+ else
+ pad = 1;
+ if (cont) {
+ if (pad)
+ *cont++ = 0;
+ BN_bn2bin(bn, cont);
+ }
+ return pad + BN_num_bytes(bn);
}
static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
- int utype, char *free_cont, const ASN1_ITEM *it)
+ int utype, char *free_cont, const ASN1_ITEM *it)
{
- BIGNUM *bn;
- if(!*pval)
- {
- if (!bn_new(pval, it))
- {
- return 0;
- }
- }
- bn = (BIGNUM *)*pval;
- if(!BN_bin2bn(cont, len, bn)) {
- bn_free(pval, it);
- return 0;
- }
- return 1;
+ BIGNUM *bn;
+ if (!*pval) {
+ if (!bn_new(pval, it)) {
+ return 0;
+ }
+ }
+ bn = (BIGNUM *)*pval;
+ if (!BN_bin2bn(cont, len, bn)) {
+ bn_free(pval, it);
+ return 0;
+ }
+ return 1;
}
diff --git a/src/crypto/asn1/x_long.c b/src/crypto/asn1/x_long.c
index 7b1a6fe8..bc4d2751 100644
--- a/src/crypto/asn1/x_long.c
+++ b/src/crypto/asn1/x_long.c
@@ -63,120 +63,135 @@
#include <openssl/err.h>
#include <openssl/mem.h>
-
-/* Custom primitive type for long handling. This converts between an ASN1_INTEGER
- * and a long directly.
+/*
+ * Custom primitive type for long handling. This converts between an
+ * ASN1_INTEGER and a long directly.
*/
-
static int long_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
-static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it);
-static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);
-static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, int indent, const ASN1_PCTX *pctx);
+static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
+ const ASN1_ITEM *it);
+static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
+ int utype, char *free_cont, const ASN1_ITEM *it);
+static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
+ int indent, const ASN1_PCTX *pctx);
static const ASN1_PRIMITIVE_FUNCS long_pf = {
- NULL, 0,
- long_new,
- long_free,
- long_free, /* Clear should set to initial value */
- long_c2i,
- long_i2c,
- long_print
+ NULL, 0,
+ long_new,
+ long_free,
+ long_free, /* Clear should set to initial value */
+ long_c2i,
+ long_i2c,
+ long_print
};
ASN1_ITEM_start(LONG)
- ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, ASN1_LONG_UNDEF, "LONG"
+ ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, ASN1_LONG_UNDEF, "LONG"
ASN1_ITEM_end(LONG)
ASN1_ITEM_start(ZLONG)
- ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, 0, "ZLONG"
+ ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, 0, "ZLONG"
ASN1_ITEM_end(ZLONG)
static int long_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
- *(long *)pval = it->size;
- return 1;
+ *(long *)pval = it->size;
+ return 1;
}
static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
- *(long *)pval = it->size;
+ *(long *)pval = it->size;
}
-static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it)
+static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
+ const ASN1_ITEM *it)
{
- long ltmp;
- unsigned long utmp;
- int clen, pad, i;
- /* this exists to bypass broken gcc optimization */
- char *cp = (char *)pval;
-
- /* use memcpy, because we may not be long aligned */
- memcpy(&ltmp, cp, sizeof(long));
-
- if(ltmp == it->size) return -1;
- /* Convert the long to positive: we subtract one if negative so
- * we can cleanly handle the padding if only the MSB of the leading
- * octet is set.
- */
- if(ltmp < 0) utmp = -ltmp - 1;
- else utmp = ltmp;
- clen = BN_num_bits_word(utmp);
- /* If MSB of leading octet set we need to pad */
- if(!(clen & 0x7)) pad = 1;
- else pad = 0;
-
- /* Convert number of bits to number of octets */
- clen = (clen + 7) >> 3;
-
- if(cont) {
- if(pad) *cont++ = (ltmp < 0) ? 0xff : 0;
- for(i = clen - 1; i >= 0; i--) {
- cont[i] = (unsigned char)(utmp & 0xff);
- if(ltmp < 0) cont[i] ^= 0xff;
- utmp >>= 8;
- }
- }
- return clen + pad;
+ long ltmp;
+ unsigned long utmp;
+ int clen, pad, i;
+ /* this exists to bypass broken gcc optimization */
+ char *cp = (char *)pval;
+
+ /* use memcpy, because we may not be long aligned */
+ memcpy(&ltmp, cp, sizeof(long));
+
+ if (ltmp == it->size)
+ return -1;
+ /*
+ * Convert the long to positive: we subtract one if negative so we can
+ * cleanly handle the padding if only the MSB of the leading octet is
+ * set.
+ */
+ if (ltmp < 0)
+ utmp = -ltmp - 1;
+ else
+ utmp = ltmp;
+ clen = BN_num_bits_word(utmp);
+ /* If MSB of leading octet set we need to pad */
+ if (!(clen & 0x7))
+ pad = 1;
+ else
+ pad = 0;
+
+ /* Convert number of bits to number of octets */
+ clen = (clen + 7) >> 3;
+
+ if (cont) {
+ if (pad)
+ *cont++ = (ltmp < 0) ? 0xff : 0;
+ for (i = clen - 1; i >= 0; i--) {
+ cont[i] = (unsigned char)(utmp & 0xff);
+ if (ltmp < 0)
+ cont[i] ^= 0xff;
+ utmp >>= 8;
+ }
+ }
+ return clen + pad;
}
static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
- int utype, char *free_cont, const ASN1_ITEM *it)
+ int utype, char *free_cont, const ASN1_ITEM *it)
{
- int neg, i;
- long ltmp;
- unsigned long utmp = 0;
- char *cp = (char *)pval;
- if(len > (int)sizeof(long)) {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
- return 0;
- }
- /* Is it negative? */
- if(len && (cont[0] & 0x80)) neg = 1;
- else neg = 0;
- utmp = 0;
- for(i = 0; i < len; i++) {
- utmp <<= 8;
- if(neg) utmp |= cont[i] ^ 0xff;
- else utmp |= cont[i];
- }
- ltmp = (long)utmp;
- if(neg) {
- ltmp++;
- ltmp = -ltmp;
- }
- if(ltmp == it->size) {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
- return 0;
- }
- memcpy(cp, &ltmp, sizeof(long));
- return 1;
+ int neg, i;
+ long ltmp;
+ unsigned long utmp = 0;
+ char *cp = (char *)pval;
+ if (len > (int)sizeof(long)) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
+ return 0;
+ }
+ /* Is it negative? */
+ if (len && (cont[0] & 0x80))
+ neg = 1;
+ else
+ neg = 0;
+ utmp = 0;
+ for (i = 0; i < len; i++) {
+ utmp <<= 8;
+ if (neg)
+ utmp |= cont[i] ^ 0xff;
+ else
+ utmp |= cont[i];
+ }
+ ltmp = (long)utmp;
+ if (neg) {
+ ltmp++;
+ ltmp = -ltmp;
+ }
+ if (ltmp == it->size) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
+ return 0;
+ }
+ memcpy(cp, &ltmp, sizeof(long));
+ return 1;
}
static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
- int indent, const ASN1_PCTX *pctx)
- {
- return BIO_printf(out, "%ld\n", *(long *)pval);
- }
+ int indent, const ASN1_PCTX *pctx)
+{
+ return BIO_printf(out, "%ld\n", *(long *)pval);
+}
diff --git a/src/crypto/base64/base64_test.cc b/src/crypto/base64/base64_test.cc
index fde0b469..da016e66 100644
--- a/src/crypto/base64/base64_test.cc
+++ b/src/crypto/base64/base64_test.cc
@@ -116,7 +116,6 @@ static bool TestDecode() {
int main(void) {
CRYPTO_library_init();
- ERR_load_crypto_strings();
if (!TestEncode() ||
!TestDecode()) {
diff --git a/src/crypto/bio/bio_mem.c b/src/crypto/bio/bio_mem.c
index 6864f6f1..844fba7e 100644
--- a/src/crypto/bio/bio_mem.c
+++ b/src/crypto/bio/bio_mem.c
@@ -64,7 +64,7 @@
#include <openssl/mem.h>
-BIO *BIO_new_mem_buf(void *buf, int len) {
+BIO *BIO_new_mem_buf(const void *buf, int len) {
BIO *ret;
BUF_MEM *b;
const size_t size = len < 0 ? strlen((char *)buf) : (size_t)len;
@@ -80,7 +80,8 @@ BIO *BIO_new_mem_buf(void *buf, int len) {
}
b = (BUF_MEM *)ret->ptr;
- b->data = buf;
+ /* BIO_FLAGS_MEM_RDONLY ensures |b->data| is not written to. */
+ b->data = (void *)buf;
b->length = size;
b->max = size;
diff --git a/src/crypto/bio/bio_test.cc b/src/crypto/bio/bio_test.cc
index 4d7dfe28..3615ab46 100644
--- a/src/crypto/bio/bio_test.cc
+++ b/src/crypto/bio/bio_test.cc
@@ -331,7 +331,7 @@ static bool TestPrintf() {
static bool ReadASN1(bool should_succeed, const uint8_t *data, size_t data_len,
size_t expected_len, size_t max_len) {
- ScopedBIO bio(BIO_new_mem_buf(const_cast<uint8_t*>(data), data_len));
+ ScopedBIO bio(BIO_new_mem_buf(data, data_len));
uint8_t *out;
size_t out_len;
@@ -412,7 +412,6 @@ static bool TestASN1() {
int main(void) {
CRYPTO_library_init();
- ERR_load_crypto_strings();
#if defined(OPENSSL_WINDOWS)
// Initialize Winsock.
diff --git a/src/crypto/bio/buffer.c b/src/crypto/bio/buffer.c
index 9d0cb3c0..15574510 100644
--- a/src/crypto/bio/buffer.c
+++ b/src/crypto/bio/buffer.c
@@ -100,7 +100,7 @@ static int buffer_new(BIO *bio) {
if (ctx->ibuf == NULL) {
goto err1;
}
- ctx->obuf = (char *)OPENSSL_malloc(DEFAULT_BUFFER_SIZE);
+ ctx->obuf = OPENSSL_malloc(DEFAULT_BUFFER_SIZE);
if (ctx->obuf == NULL) {
goto err2;
}
@@ -340,13 +340,13 @@ static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr) {
p1 = ctx->ibuf;
p2 = ctx->obuf;
if (ibs > DEFAULT_BUFFER_SIZE && ibs != ctx->ibuf_size) {
- p1 = (char *)OPENSSL_malloc(ibs);
+ p1 = OPENSSL_malloc(ibs);
if (p1 == NULL) {
goto malloc_error;
}
}
if (obs > DEFAULT_BUFFER_SIZE && obs != ctx->obuf_size) {
- p2 = (char *)OPENSSL_malloc(obs);
+ p2 = OPENSSL_malloc(obs);
if (p2 == NULL) {
if (p1 != ctx->ibuf) {
OPENSSL_free(p1);
diff --git a/src/crypto/bio/connect.c b/src/crypto/bio/connect.c
index 0b0bf131..01d49b1b 100644
--- a/src/crypto/bio/connect.c
+++ b/src/crypto/bio/connect.c
@@ -58,7 +58,6 @@
#include <assert.h>
#include <errno.h>
-#include <stdio.h>
#include <string.h>
#if !defined(OPENSSL_WINDOWS)
@@ -542,3 +541,7 @@ int BIO_set_conn_port(BIO *bio, const char *port_str) {
int BIO_set_nbio(BIO *bio, int on) {
return BIO_ctrl(bio, BIO_C_SET_NBIO, on, NULL);
}
+
+int BIO_do_connect(BIO *bio) {
+ return BIO_ctrl(bio, BIO_C_DO_STATE_MACHINE, 0, NULL);
+}
diff --git a/src/crypto/bio/fd.c b/src/crypto/bio/fd.c
index 0b3484c9..12e6a72b 100644
--- a/src/crypto/bio/fd.c
+++ b/src/crypto/bio/fd.c
@@ -72,6 +72,8 @@
#include <openssl/err.h>
#include <openssl/mem.h>
+#include "internal.h"
+
static int bio_fd_non_fatal_error(int err) {
if (
diff --git a/src/crypto/bio/file.c b/src/crypto/bio/file.c
index 9e29b43c..b903bc28 100644
--- a/src/crypto/bio/file.c
+++ b/src/crypto/bio/file.c
@@ -87,47 +87,11 @@
#define BIO_FP_WRITE 0x04
#define BIO_FP_APPEND 0x08
-static FILE *open_file(const char *filename, const char *mode) {
-#if defined(OPENSSL_WINDOWS) && defined(CP_UTF8)
- int sz, len_0 = (int)strlen(filename) + 1;
- DWORD flags;
-
- /* Basically there are three cases to cover: a) filename is pure ASCII
- * string; b) actual UTF-8 encoded string and c) locale-ized string, i.e. one
- * containing 8-bit characters that are meaningful in current system locale.
- * If filename is pure ASCII or real UTF-8 encoded string,
- * MultiByteToWideChar succeeds and _wfopen works. If filename is locale-ized
- * string, chances are that MultiByteToWideChar fails reporting
- * ERROR_NO_UNICODE_TRANSLATION, in which case we fall back to fopen... */
- if ((sz = MultiByteToWideChar(CP_UTF8, (flags = MB_ERR_INVALID_CHARS),
- filename, len_0, NULL, 0)) > 0 ||
- (GetLastError() == ERROR_INVALID_FLAGS &&
- (sz = MultiByteToWideChar(CP_UTF8, (flags = 0), filename, len_0, NULL,
- 0)) > 0)) {
- WCHAR wmode[8];
- WCHAR *wfilename = _alloca(sz * sizeof(WCHAR));
-
- if (MultiByteToWideChar(CP_UTF8, flags, filename, len_0, wfilename, sz) &&
- MultiByteToWideChar(CP_UTF8, 0, mode, strlen(mode) + 1, wmode,
- sizeof(wmode) / sizeof(wmode[0])) &&
- (file = _wfopen(wfilename, wmode)) == NULL &&
- (errno == ENOENT ||
- errno == EBADF)) /* UTF-8 decode succeeded, but no file, filename
- * could still have been locale-ized... */
- return fopen(filename, mode);
- } else if (GetLastError() == ERROR_NO_UNICODE_TRANSLATION) {
- return fopen(filename, mode);
- }
-#else
- return fopen(filename, mode);
-#endif
-}
-
BIO *BIO_new_file(const char *filename, const char *mode) {
BIO *ret;
FILE *file;
- file = open_file(filename, mode);
+ file = fopen(filename, mode);
if (file == NULL) {
OPENSSL_PUT_SYSTEM_ERROR();
@@ -256,7 +220,7 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr) {
ret = 0;
break;
}
- fp = open_file(ptr, p);
+ fp = fopen(ptr, p);
if (fp == NULL) {
OPENSSL_PUT_SYSTEM_ERROR();
ERR_add_error_data(5, "fopen('", ptr, "','", p, "')");
diff --git a/src/crypto/bio/internal.h b/src/crypto/bio/internal.h
index d9a34f18..eb6b26f6 100644
--- a/src/crypto/bio/internal.h
+++ b/src/crypto/bio/internal.h
@@ -67,6 +67,9 @@ typedef unsigned short u_short;
#include <sys/types.h>
#include <sys/socket.h>
#else
+#pragma warning(push, 3)
+#include <winsock2.h>
+#pragma warning(pop)
typedef int socklen_t;
#endif
diff --git a/src/crypto/bio/pair.c b/src/crypto/bio/pair.c
index fba4be2c..2da2d203 100644
--- a/src/crypto/bio/pair.c
+++ b/src/crypto/bio/pair.c
@@ -742,7 +742,7 @@ static const BIO_METHOD methods_biop = {
bio_free, NULL /* no bio_callback_ctrl */
};
-const BIO_METHOD *bio_s_bio(void) { return &methods_biop; }
+static const BIO_METHOD *bio_s_bio(void) { return &methods_biop; }
int BIO_new_bio_pair(BIO** bio1_p, size_t writebuf1,
BIO** bio2_p, size_t writebuf2) {
diff --git a/src/crypto/bio/socket.c b/src/crypto/bio/socket.c
index 98f32a62..3ef69674 100644
--- a/src/crypto/bio/socket.c
+++ b/src/crypto/bio/socket.c
@@ -110,7 +110,11 @@ static int sock_read(BIO *b, char *out, int outl) {
}
bio_clear_socket_error();
+#if defined(OPENSSL_WINDOWS)
ret = recv(b->num, out, outl, 0);
+#else
+ ret = read(b->num, out, outl);
+#endif
BIO_clear_retry_flags(b);
if (ret <= 0) {
if (bio_fd_should_retry(ret)) {
@@ -124,7 +128,11 @@ static int sock_write(BIO *b, const char *in, int inl) {
int ret;
bio_clear_socket_error();
+#if defined(OPENSSL_WINDOWS)
ret = send(b->num, in, inl, 0);
+#else
+ ret = write(b->num, in, inl);
+#endif
BIO_clear_retry_flags(b);
if (ret <= 0) {
if (bio_fd_should_retry(ret)) {
diff --git a/src/crypto/bn/asm/armv4-mont.pl b/src/crypto/bn/asm/armv4-mont.pl
index 4206fd85..b7511128 100644
--- a/src/crypto/bn/asm/armv4-mont.pl
+++ b/src/crypto/bn/asm/armv4-mont.pl
@@ -91,7 +91,6 @@ $code=<<___;
#endif
.global bn_mul_mont
-.hidden bn_mul_mont
.type bn_mul_mont,%function
.align 5
@@ -108,7 +107,7 @@ bn_mul_mont:
#ifdef __APPLE__
ldr r0,[r0]
#endif
- tst r0,#1 @ NEON available?
+ tst r0,#ARMV7_NEON @ NEON available?
ldmia sp, {r0,r2}
beq .Lialu
add sp,sp,#8
diff --git a/src/crypto/bn/asm/rsaz-avx2.pl b/src/crypto/bn/asm/rsaz-avx2.pl
index bbceccb3..6b57bd0b 100644..100755
--- a/src/crypto/bn/asm/rsaz-avx2.pl
+++ b/src/crypto/bn/asm/rsaz-avx2.pl
@@ -427,7 +427,7 @@ $TEMP2 = $B2;
$TEMP3 = $Y1;
$TEMP4 = $Y2;
$code.=<<___;
- #we need to fix indexes 32-39 to avoid overflow
+ # we need to fix indices 32-39 to avoid overflow
vmovdqu 32*8(%rsp), $ACC8 # 32*8-192($tp0),
vmovdqu 32*9(%rsp), $ACC1 # 32*9-192($tp0)
vmovdqu 32*10(%rsp), $ACC2 # 32*10-192($tp0)
@@ -1576,68 +1576,128 @@ rsaz_1024_scatter5_avx2:
.type rsaz_1024_gather5_avx2,\@abi-omnipotent
.align 32
rsaz_1024_gather5_avx2:
+ vzeroupper
+ mov %rsp,%r11
___
$code.=<<___ if ($win64);
lea -0x88(%rsp),%rax
- vzeroupper
.LSEH_begin_rsaz_1024_gather5:
# I can't trust assembler to use specific encoding:-(
- .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,0(%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)
+ .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,0(%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.=<<___;
- lea .Lgather_table(%rip),%r11
- mov $power,%eax
- and \$3,$power
- shr \$2,%eax # cache line number
- shl \$4,$power # offset within cache line
-
- vmovdqu -32(%r11),%ymm7 # .Lgather_permd
- vpbroadcastb 8(%r11,%rax), %xmm8
- vpbroadcastb 7(%r11,%rax), %xmm9
- vpbroadcastb 6(%r11,%rax), %xmm10
- vpbroadcastb 5(%r11,%rax), %xmm11
- vpbroadcastb 4(%r11,%rax), %xmm12
- vpbroadcastb 3(%r11,%rax), %xmm13
- vpbroadcastb 2(%r11,%rax), %xmm14
- vpbroadcastb 1(%r11,%rax), %xmm15
-
- lea 64($inp,$power),$inp
- mov \$64,%r11 # size optimization
- mov \$9,%eax
- jmp .Loop_gather_1024
+ lea -0x100(%rsp),%rsp
+ and \$-32, %rsp
+ lea .Linc(%rip), %r10
+ lea -128(%rsp),%rax # control u-op density
+
+ vmovd $power, %xmm4
+ vmovdqa (%r10),%ymm0
+ vmovdqa 32(%r10),%ymm1
+ vmovdqa 64(%r10),%ymm5
+ vpbroadcastd %xmm4,%ymm4
+
+ vpaddd %ymm5, %ymm0, %ymm2
+ vpcmpeqd %ymm4, %ymm0, %ymm0
+ vpaddd %ymm5, %ymm1, %ymm3
+ vpcmpeqd %ymm4, %ymm1, %ymm1
+ vmovdqa %ymm0, 32*0+128(%rax)
+ vpaddd %ymm5, %ymm2, %ymm0
+ vpcmpeqd %ymm4, %ymm2, %ymm2
+ vmovdqa %ymm1, 32*1+128(%rax)
+ vpaddd %ymm5, %ymm3, %ymm1
+ vpcmpeqd %ymm4, %ymm3, %ymm3
+ vmovdqa %ymm2, 32*2+128(%rax)
+ vpaddd %ymm5, %ymm0, %ymm2
+ vpcmpeqd %ymm4, %ymm0, %ymm0
+ vmovdqa %ymm3, 32*3+128(%rax)
+ vpaddd %ymm5, %ymm1, %ymm3
+ vpcmpeqd %ymm4, %ymm1, %ymm1
+ vmovdqa %ymm0, 32*4+128(%rax)
+ vpaddd %ymm5, %ymm2, %ymm8
+ vpcmpeqd %ymm4, %ymm2, %ymm2
+ vmovdqa %ymm1, 32*5+128(%rax)
+ vpaddd %ymm5, %ymm3, %ymm9
+ vpcmpeqd %ymm4, %ymm3, %ymm3
+ vmovdqa %ymm2, 32*6+128(%rax)
+ vpaddd %ymm5, %ymm8, %ymm10
+ vpcmpeqd %ymm4, %ymm8, %ymm8
+ vmovdqa %ymm3, 32*7+128(%rax)
+ vpaddd %ymm5, %ymm9, %ymm11
+ vpcmpeqd %ymm4, %ymm9, %ymm9
+ vpaddd %ymm5, %ymm10, %ymm12
+ vpcmpeqd %ymm4, %ymm10, %ymm10
+ vpaddd %ymm5, %ymm11, %ymm13
+ vpcmpeqd %ymm4, %ymm11, %ymm11
+ vpaddd %ymm5, %ymm12, %ymm14
+ vpcmpeqd %ymm4, %ymm12, %ymm12
+ vpaddd %ymm5, %ymm13, %ymm15
+ vpcmpeqd %ymm4, %ymm13, %ymm13
+ vpcmpeqd %ymm4, %ymm14, %ymm14
+ vpcmpeqd %ymm4, %ymm15, %ymm15
+
+ vmovdqa -32(%r10),%ymm7 # .Lgather_permd
+ lea 128($inp), $inp
+ mov \$9,$power
-.align 32
.Loop_gather_1024:
- vpand -64($inp), %xmm8,%xmm0
- vpand ($inp), %xmm9,%xmm1
- vpand 64($inp), %xmm10,%xmm2
- vpand ($inp,%r11,2), %xmm11,%xmm3
- vpor %xmm0,%xmm1,%xmm1
- vpand 64($inp,%r11,2), %xmm12,%xmm4
- vpor %xmm2,%xmm3,%xmm3
- vpand ($inp,%r11,4), %xmm13,%xmm5
- vpor %xmm1,%xmm3,%xmm3
- vpand 64($inp,%r11,4), %xmm14,%xmm6
- vpor %xmm4,%xmm5,%xmm5
- vpand -128($inp,%r11,8), %xmm15,%xmm2
- lea ($inp,%r11,8),$inp
- vpor %xmm3,%xmm5,%xmm5
- vpor %xmm2,%xmm6,%xmm6
- vpor %xmm5,%xmm6,%xmm6
- vpermd %ymm6,%ymm7,%ymm6
- vmovdqu %ymm6,($out)
+ vmovdqa 32*0-128($inp), %ymm0
+ vmovdqa 32*1-128($inp), %ymm1
+ vmovdqa 32*2-128($inp), %ymm2
+ vmovdqa 32*3-128($inp), %ymm3
+ vpand 32*0+128(%rax), %ymm0, %ymm0
+ vpand 32*1+128(%rax), %ymm1, %ymm1
+ vpand 32*2+128(%rax), %ymm2, %ymm2
+ vpor %ymm0, %ymm1, %ymm4
+ vpand 32*3+128(%rax), %ymm3, %ymm3
+ vmovdqa 32*4-128($inp), %ymm0
+ vmovdqa 32*5-128($inp), %ymm1
+ vpor %ymm2, %ymm3, %ymm5
+ vmovdqa 32*6-128($inp), %ymm2
+ vmovdqa 32*7-128($inp), %ymm3
+ vpand 32*4+128(%rax), %ymm0, %ymm0
+ vpand 32*5+128(%rax), %ymm1, %ymm1
+ vpand 32*6+128(%rax), %ymm2, %ymm2
+ vpor %ymm0, %ymm4, %ymm4
+ vpand 32*7+128(%rax), %ymm3, %ymm3
+ vpand 32*8-128($inp), %ymm8, %ymm0
+ vpor %ymm1, %ymm5, %ymm5
+ vpand 32*9-128($inp), %ymm9, %ymm1
+ vpor %ymm2, %ymm4, %ymm4
+ vpand 32*10-128($inp),%ymm10, %ymm2
+ vpor %ymm3, %ymm5, %ymm5
+ vpand 32*11-128($inp),%ymm11, %ymm3
+ vpor %ymm0, %ymm4, %ymm4
+ vpand 32*12-128($inp),%ymm12, %ymm0
+ vpor %ymm1, %ymm5, %ymm5
+ vpand 32*13-128($inp),%ymm13, %ymm1
+ vpor %ymm2, %ymm4, %ymm4
+ vpand 32*14-128($inp),%ymm14, %ymm2
+ vpor %ymm3, %ymm5, %ymm5
+ vpand 32*15-128($inp),%ymm15, %ymm3
+ lea 32*16($inp), $inp
+ vpor %ymm0, %ymm4, %ymm4
+ vpor %ymm1, %ymm5, %ymm5
+ vpor %ymm2, %ymm4, %ymm4
+ vpor %ymm3, %ymm5, %ymm5
+
+ vpor %ymm5, %ymm4, %ymm4
+ vextracti128 \$1, %ymm4, %xmm5 # upper half is cleared
+ vpor %xmm4, %xmm5, %xmm5
+ vpermd %ymm5,%ymm7,%ymm5
+ vmovdqu %ymm5,($out)
lea 32($out),$out
- dec %eax
+ dec $power
jnz .Loop_gather_1024
vpxor %ymm0,%ymm0,%ymm0
@@ -1645,20 +1705,20 @@ $code.=<<___;
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
+ movaps -0xa8(%r11),%xmm6
+ movaps -0x98(%r11),%xmm7
+ movaps -0x88(%r11),%xmm8
+ movaps -0x78(%r11),%xmm9
+ movaps -0x68(%r11),%xmm10
+ movaps -0x58(%r11),%xmm11
+ movaps -0x48(%r11),%xmm12
+ movaps -0x38(%r11),%xmm13
+ movaps -0x28(%r11),%xmm14
+ movaps -0x18(%r11),%xmm15
.LSEH_end_rsaz_1024_gather5:
___
$code.=<<___;
+ lea (%r11),%rsp
ret
.size rsaz_1024_gather5_avx2,.-rsaz_1024_gather5_avx2
___
@@ -1692,8 +1752,10 @@ $code.=<<___;
.long 0,2,4,6,7,7,7,7
.Lgather_permd:
.long 0,7,1,7,2,7,3,7
-.Lgather_table:
- .byte 0,0,0,0,0,0,0,0, 0xff,0,0,0,0,0,0,0
+.Linc:
+ .long 0,0,0,0, 1,1,1,1
+ .long 2,2,2,2, 3,3,3,3
+ .long 4,4,4,4, 4,4,4,4
.align 64
___
@@ -1821,18 +1883,19 @@ rsaz_se_handler:
.rva rsaz_se_handler
.rva .Lmul_1024_body,.Lmul_1024_epilogue
.LSEH_info_rsaz_1024_gather5:
- .byte 0x01,0x33,0x16,0x00
- .byte 0x36,0xf8,0x09,0x00 #vmovaps 0x90(rsp),xmm15
- .byte 0x31,0xe8,0x08,0x00 #vmovaps 0x80(rsp),xmm14
- .byte 0x2c,0xd8,0x07,0x00 #vmovaps 0x70(rsp),xmm13
- .byte 0x27,0xc8,0x06,0x00 #vmovaps 0x60(rsp),xmm12
- .byte 0x22,0xb8,0x05,0x00 #vmovaps 0x50(rsp),xmm11
- .byte 0x1d,0xa8,0x04,0x00 #vmovaps 0x40(rsp),xmm10
- .byte 0x18,0x98,0x03,0x00 #vmovaps 0x30(rsp),xmm9
- .byte 0x13,0x88,0x02,0x00 #vmovaps 0x20(rsp),xmm8
- .byte 0x0e,0x78,0x01,0x00 #vmovaps 0x10(rsp),xmm7
- .byte 0x09,0x68,0x00,0x00 #vmovaps 0x00(rsp),xmm6
- .byte 0x04,0x01,0x15,0x00 #sub rsp,0xa8
+ .byte 0x01,0x36,0x17,0x0b
+ .byte 0x36,0xf8,0x09,0x00 # vmovaps 0x90(rsp),xmm15
+ .byte 0x31,0xe8,0x08,0x00 # vmovaps 0x80(rsp),xmm14
+ .byte 0x2c,0xd8,0x07,0x00 # vmovaps 0x70(rsp),xmm13
+ .byte 0x27,0xc8,0x06,0x00 # vmovaps 0x60(rsp),xmm12
+ .byte 0x22,0xb8,0x05,0x00 # vmovaps 0x50(rsp),xmm11
+ .byte 0x1d,0xa8,0x04,0x00 # vmovaps 0x40(rsp),xmm10
+ .byte 0x18,0x98,0x03,0x00 # vmovaps 0x30(rsp),xmm9
+ .byte 0x13,0x88,0x02,0x00 # vmovaps 0x20(rsp),xmm8
+ .byte 0x0e,0x78,0x01,0x00 # vmovaps 0x10(rsp),xmm7
+ .byte 0x09,0x68,0x00,0x00 # vmovaps 0x00(rsp),xmm6
+ .byte 0x04,0x01,0x15,0x00 # sub rsp,0xa8
+ .byte 0x00,0xb3,0x00,0x00 # set_frame r11
___
}
diff --git a/src/crypto/bn/asm/rsaz-x86_64.pl b/src/crypto/bn/asm/rsaz-x86_64.pl
index 4113d533..c38bde95 100644..100755
--- a/src/crypto/bn/asm/rsaz-x86_64.pl
+++ b/src/crypto/bn/asm/rsaz-x86_64.pl
@@ -902,9 +902,76 @@ rsaz_512_mul_gather4:
push %r14
push %r15
- mov $pwr, $pwr
- subq \$128+24, %rsp
+ subq \$`128+24+($win64?0xb0:0)`, %rsp
+___
+$code.=<<___ if ($win64);
+ movaps %xmm6,0xa0(%rsp)
+ movaps %xmm7,0xb0(%rsp)
+ movaps %xmm8,0xc0(%rsp)
+ movaps %xmm9,0xd0(%rsp)
+ movaps %xmm10,0xe0(%rsp)
+ movaps %xmm11,0xf0(%rsp)
+ movaps %xmm12,0x100(%rsp)
+ movaps %xmm13,0x110(%rsp)
+ movaps %xmm14,0x120(%rsp)
+ movaps %xmm15,0x130(%rsp)
+___
+$code.=<<___;
.Lmul_gather4_body:
+ movd $pwr,%xmm8
+ movdqa .Linc+16(%rip),%xmm1 # 00000002000000020000000200000002
+ movdqa .Linc(%rip),%xmm0 # 00000001000000010000000000000000
+
+ pshufd \$0,%xmm8,%xmm8 # broadcast $power
+ movdqa %xmm1,%xmm7
+ movdqa %xmm1,%xmm2
+___
+########################################################################
+# calculate mask by comparing 0..15 to $power
+#
+for($i=0;$i<4;$i++) {
+$code.=<<___;
+ paddd %xmm`$i`,%xmm`$i+1`
+ pcmpeqd %xmm8,%xmm`$i`
+ movdqa %xmm7,%xmm`$i+3`
+___
+}
+for(;$i<7;$i++) {
+$code.=<<___;
+ paddd %xmm`$i`,%xmm`$i+1`
+ pcmpeqd %xmm8,%xmm`$i`
+___
+}
+$code.=<<___;
+ pcmpeqd %xmm8,%xmm7
+
+ movdqa 16*0($bp),%xmm8
+ movdqa 16*1($bp),%xmm9
+ movdqa 16*2($bp),%xmm10
+ movdqa 16*3($bp),%xmm11
+ pand %xmm0,%xmm8
+ movdqa 16*4($bp),%xmm12
+ pand %xmm1,%xmm9
+ movdqa 16*5($bp),%xmm13
+ pand %xmm2,%xmm10
+ movdqa 16*6($bp),%xmm14
+ pand %xmm3,%xmm11
+ movdqa 16*7($bp),%xmm15
+ leaq 128($bp), %rbp
+ pand %xmm4,%xmm12
+ pand %xmm5,%xmm13
+ pand %xmm6,%xmm14
+ pand %xmm7,%xmm15
+ por %xmm10,%xmm8
+ por %xmm11,%xmm9
+ por %xmm12,%xmm8
+ por %xmm13,%xmm9
+ por %xmm14,%xmm8
+ por %xmm15,%xmm9
+
+ por %xmm9,%xmm8
+ pshufd \$0x4e,%xmm8,%xmm9
+ por %xmm9,%xmm8
___
$code.=<<___ if ($addx);
movl \$0x80100,%r11d
@@ -913,45 +980,38 @@ $code.=<<___ if ($addx);
je .Lmulx_gather
___
$code.=<<___;
- movl 64($bp,$pwr,4), %eax
- movq $out, %xmm0 # off-load arguments
- movl ($bp,$pwr,4), %ebx
- movq $mod, %xmm1
- movq $n0, 128(%rsp)
+ movq %xmm8,%rbx
+
+ movq $n0, 128(%rsp) # off-load arguments
+ movq $out, 128+8(%rsp)
+ movq $mod, 128+16(%rsp)
- shlq \$32, %rax
- or %rax, %rbx
movq ($ap), %rax
movq 8($ap), %rcx
- leaq 128($bp,$pwr,4), %rbp
mulq %rbx # 0 iteration
movq %rax, (%rsp)
movq %rcx, %rax
movq %rdx, %r8
mulq %rbx
- movd (%rbp), %xmm4
addq %rax, %r8
movq 16($ap), %rax
movq %rdx, %r9
adcq \$0, %r9
mulq %rbx
- movd 64(%rbp), %xmm5
addq %rax, %r9
movq 24($ap), %rax
movq %rdx, %r10
adcq \$0, %r10
mulq %rbx
- pslldq \$4, %xmm5
addq %rax, %r10
movq 32($ap), %rax
movq %rdx, %r11
adcq \$0, %r11
mulq %rbx
- por %xmm5, %xmm4
addq %rax, %r11
movq 40($ap), %rax
movq %rdx, %r12
@@ -964,14 +1024,12 @@ $code.=<<___;
adcq \$0, %r13
mulq %rbx
- leaq 128(%rbp), %rbp
addq %rax, %r13
movq 56($ap), %rax
movq %rdx, %r14
adcq \$0, %r14
mulq %rbx
- movq %xmm4, %rbx
addq %rax, %r14
movq ($ap), %rax
movq %rdx, %r15
@@ -983,6 +1041,35 @@ $code.=<<___;
.align 32
.Loop_mul_gather:
+ movdqa 16*0(%rbp),%xmm8
+ movdqa 16*1(%rbp),%xmm9
+ movdqa 16*2(%rbp),%xmm10
+ movdqa 16*3(%rbp),%xmm11
+ pand %xmm0,%xmm8
+ movdqa 16*4(%rbp),%xmm12
+ pand %xmm1,%xmm9
+ movdqa 16*5(%rbp),%xmm13
+ pand %xmm2,%xmm10
+ movdqa 16*6(%rbp),%xmm14
+ pand %xmm3,%xmm11
+ movdqa 16*7(%rbp),%xmm15
+ leaq 128(%rbp), %rbp
+ pand %xmm4,%xmm12
+ pand %xmm5,%xmm13
+ pand %xmm6,%xmm14
+ pand %xmm7,%xmm15
+ por %xmm10,%xmm8
+ por %xmm11,%xmm9
+ por %xmm12,%xmm8
+ por %xmm13,%xmm9
+ por %xmm14,%xmm8
+ por %xmm15,%xmm9
+
+ por %xmm9,%xmm8
+ pshufd \$0x4e,%xmm8,%xmm9
+ por %xmm9,%xmm8
+ movq %xmm8,%rbx
+
mulq %rbx
addq %rax, %r8
movq 8($ap), %rax
@@ -991,7 +1078,6 @@ $code.=<<___;
adcq \$0, %r8
mulq %rbx
- movd (%rbp), %xmm4
addq %rax, %r9
movq 16($ap), %rax
adcq \$0, %rdx
@@ -1000,7 +1086,6 @@ $code.=<<___;
adcq \$0, %r9
mulq %rbx
- movd 64(%rbp), %xmm5
addq %rax, %r10
movq 24($ap), %rax
adcq \$0, %rdx
@@ -1009,7 +1094,6 @@ $code.=<<___;
adcq \$0, %r10
mulq %rbx
- pslldq \$4, %xmm5
addq %rax, %r11
movq 32($ap), %rax
adcq \$0, %rdx
@@ -1018,7 +1102,6 @@ $code.=<<___;
adcq \$0, %r11
mulq %rbx
- por %xmm5, %xmm4
addq %rax, %r12
movq 40($ap), %rax
adcq \$0, %rdx
@@ -1043,7 +1126,6 @@ $code.=<<___;
adcq \$0, %r14
mulq %rbx
- movq %xmm4, %rbx
addq %rax, %r15
movq ($ap), %rax
adcq \$0, %rdx
@@ -1051,7 +1133,6 @@ $code.=<<___;
movq %rdx, %r15
adcq \$0, %r15
- leaq 128(%rbp), %rbp
leaq 8(%rdi), %rdi
decl %ecx
@@ -1066,8 +1147,8 @@ $code.=<<___;
movq %r14, 48(%rdi)
movq %r15, 56(%rdi)
- movq %xmm0, $out
- movq %xmm1, %rbp
+ movq 128+8(%rsp), $out
+ movq 128+16(%rsp), %rbp
movq (%rsp), %r8
movq 8(%rsp), %r9
@@ -1085,45 +1166,37 @@ $code.=<<___ if ($addx);
.align 32
.Lmulx_gather:
- mov 64($bp,$pwr,4), %eax
- movq $out, %xmm0 # off-load arguments
- lea 128($bp,$pwr,4), %rbp
- mov ($bp,$pwr,4), %edx
- movq $mod, %xmm1
- mov $n0, 128(%rsp)
+ movq %xmm8,%rdx
+
+ mov $n0, 128(%rsp) # off-load arguments
+ mov $out, 128+8(%rsp)
+ mov $mod, 128+16(%rsp)
- shl \$32, %rax
- or %rax, %rdx
mulx ($ap), %rbx, %r8 # 0 iteration
mov %rbx, (%rsp)
xor %edi, %edi # cf=0, of=0
mulx 8($ap), %rax, %r9
- movd (%rbp), %xmm4
mulx 16($ap), %rbx, %r10
- movd 64(%rbp), %xmm5
adcx %rax, %r8
mulx 24($ap), %rax, %r11
- pslldq \$4, %xmm5
adcx %rbx, %r9
mulx 32($ap), %rbx, %r12
- por %xmm5, %xmm4
adcx %rax, %r10
mulx 40($ap), %rax, %r13
adcx %rbx, %r11
mulx 48($ap), %rbx, %r14
- lea 128(%rbp), %rbp
adcx %rax, %r12
mulx 56($ap), %rax, %r15
- movq %xmm4, %rdx
adcx %rbx, %r13
adcx %rax, %r14
+ .byte 0x67
mov %r8, %rbx
adcx %rdi, %r15 # %rdi is 0
@@ -1132,24 +1205,48 @@ $code.=<<___ if ($addx);
.align 32
.Loop_mulx_gather:
- mulx ($ap), %rax, %r8
+ movdqa 16*0(%rbp),%xmm8
+ movdqa 16*1(%rbp),%xmm9
+ movdqa 16*2(%rbp),%xmm10
+ movdqa 16*3(%rbp),%xmm11
+ pand %xmm0,%xmm8
+ movdqa 16*4(%rbp),%xmm12
+ pand %xmm1,%xmm9
+ movdqa 16*5(%rbp),%xmm13
+ pand %xmm2,%xmm10
+ movdqa 16*6(%rbp),%xmm14
+ pand %xmm3,%xmm11
+ movdqa 16*7(%rbp),%xmm15
+ leaq 128(%rbp), %rbp
+ pand %xmm4,%xmm12
+ pand %xmm5,%xmm13
+ pand %xmm6,%xmm14
+ pand %xmm7,%xmm15
+ por %xmm10,%xmm8
+ por %xmm11,%xmm9
+ por %xmm12,%xmm8
+ por %xmm13,%xmm9
+ por %xmm14,%xmm8
+ por %xmm15,%xmm9
+
+ por %xmm9,%xmm8
+ pshufd \$0x4e,%xmm8,%xmm9
+ por %xmm9,%xmm8
+ movq %xmm8,%rdx
+
+ .byte 0xc4,0x62,0xfb,0xf6,0x86,0x00,0x00,0x00,0x00 # mulx ($ap), %rax, %r8
adcx %rax, %rbx
adox %r9, %r8
mulx 8($ap), %rax, %r9
- .byte 0x66,0x0f,0x6e,0xa5,0x00,0x00,0x00,0x00 # movd (%rbp), %xmm4
adcx %rax, %r8
adox %r10, %r9
mulx 16($ap), %rax, %r10
- movd 64(%rbp), %xmm5
- lea 128(%rbp), %rbp
adcx %rax, %r9
adox %r11, %r10
.byte 0xc4,0x62,0xfb,0xf6,0x9e,0x18,0x00,0x00,0x00 # mulx 24($ap), %rax, %r11
- pslldq \$4, %xmm5
- por %xmm5, %xmm4
adcx %rax, %r10
adox %r12, %r11
@@ -1163,10 +1260,10 @@ $code.=<<___ if ($addx);
.byte 0xc4,0x62,0xfb,0xf6,0xb6,0x30,0x00,0x00,0x00 # mulx 48($ap), %rax, %r14
adcx %rax, %r13
+ .byte 0x67
adox %r15, %r14
mulx 56($ap), %rax, %r15
- movq %xmm4, %rdx
mov %rbx, 64(%rsp,%rcx,8)
adcx %rax, %r14
adox %rdi, %r15
@@ -1185,10 +1282,10 @@ $code.=<<___ if ($addx);
mov %r14, 64+48(%rsp)
mov %r15, 64+56(%rsp)
- movq %xmm0, $out
- movq %xmm1, %rbp
+ mov 128(%rsp), %rdx # pull arguments
+ mov 128+8(%rsp), $out
+ mov 128+16(%rsp), %rbp
- mov 128(%rsp), %rdx # pull $n0
mov (%rsp), %r8
mov 8(%rsp), %r9
mov 16(%rsp), %r10
@@ -1216,6 +1313,21 @@ $code.=<<___;
call __rsaz_512_subtract
leaq 128+24+48(%rsp), %rax
+___
+$code.=<<___ if ($win64);
+ movaps 0xa0-0xc8(%rax),%xmm6
+ movaps 0xb0-0xc8(%rax),%xmm7
+ movaps 0xc0-0xc8(%rax),%xmm8
+ movaps 0xd0-0xc8(%rax),%xmm9
+ movaps 0xe0-0xc8(%rax),%xmm10
+ movaps 0xf0-0xc8(%rax),%xmm11
+ movaps 0x100-0xc8(%rax),%xmm12
+ movaps 0x110-0xc8(%rax),%xmm13
+ movaps 0x120-0xc8(%rax),%xmm14
+ movaps 0x130-0xc8(%rax),%xmm15
+ lea 0xb0(%rax),%rax
+___
+$code.=<<___;
movq -48(%rax), %r15
movq -40(%rax), %r14
movq -32(%rax), %r13
@@ -1245,7 +1357,7 @@ rsaz_512_mul_scatter4:
mov $pwr, $pwr
subq \$128+24, %rsp
.Lmul_scatter4_body:
- leaq ($tbl,$pwr,4), $tbl
+ leaq ($tbl,$pwr,8), $tbl
movq $out, %xmm0 # off-load arguments
movq $mod, %xmm1
movq $tbl, %xmm2
@@ -1316,30 +1428,14 @@ $code.=<<___;
call __rsaz_512_subtract
- movl %r8d, 64*0($inp) # scatter
- shrq \$32, %r8
- movl %r9d, 64*2($inp)
- shrq \$32, %r9
- movl %r10d, 64*4($inp)
- shrq \$32, %r10
- movl %r11d, 64*6($inp)
- shrq \$32, %r11
- movl %r12d, 64*8($inp)
- shrq \$32, %r12
- movl %r13d, 64*10($inp)
- shrq \$32, %r13
- movl %r14d, 64*12($inp)
- shrq \$32, %r14
- movl %r15d, 64*14($inp)
- shrq \$32, %r15
- movl %r8d, 64*1($inp)
- movl %r9d, 64*3($inp)
- movl %r10d, 64*5($inp)
- movl %r11d, 64*7($inp)
- movl %r12d, 64*9($inp)
- movl %r13d, 64*11($inp)
- movl %r14d, 64*13($inp)
- movl %r15d, 64*15($inp)
+ movq %r8, 128*0($inp) # scatter
+ movq %r9, 128*1($inp)
+ movq %r10, 128*2($inp)
+ movq %r11, 128*3($inp)
+ movq %r12, 128*4($inp)
+ movq %r13, 128*5($inp)
+ movq %r14, 128*6($inp)
+ movq %r15, 128*7($inp)
leaq 128+24+48(%rsp), %rax
movq -48(%rax), %r15
@@ -1943,16 +2039,14 @@ $code.=<<___;
.type rsaz_512_scatter4,\@abi-omnipotent
.align 16
rsaz_512_scatter4:
- leaq ($out,$power,4), $out
+ leaq ($out,$power,8), $out
movl \$8, %r9d
jmp .Loop_scatter
.align 16
.Loop_scatter:
movq ($inp), %rax
leaq 8($inp), $inp
- movl %eax, ($out)
- shrq \$32, %rax
- movl %eax, 64($out)
+ movq %rax, ($out)
leaq 128($out), $out
decl %r9d
jnz .Loop_scatter
@@ -1963,22 +2057,106 @@ rsaz_512_scatter4:
.type rsaz_512_gather4,\@abi-omnipotent
.align 16
rsaz_512_gather4:
- leaq ($inp,$power,4), $inp
+___
+$code.=<<___ if ($win64);
+.LSEH_begin_rsaz_512_gather4:
+ .byte 0x48,0x81,0xec,0xa8,0x00,0x00,0x00 # sub $0xa8,%rsp
+ .byte 0x0f,0x29,0x34,0x24 # movaps %xmm6,(%rsp)
+ .byte 0x0f,0x29,0x7c,0x24,0x10 # movaps %xmm7,0x10(%rsp)
+ .byte 0x44,0x0f,0x29,0x44,0x24,0x20 # movaps %xmm8,0x20(%rsp)
+ .byte 0x44,0x0f,0x29,0x4c,0x24,0x30 # movaps %xmm9,0x30(%rsp)
+ .byte 0x44,0x0f,0x29,0x54,0x24,0x40 # movaps %xmm10,0x40(%rsp)
+ .byte 0x44,0x0f,0x29,0x5c,0x24,0x50 # movaps %xmm11,0x50(%rsp)
+ .byte 0x44,0x0f,0x29,0x64,0x24,0x60 # movaps %xmm12,0x60(%rsp)
+ .byte 0x44,0x0f,0x29,0x6c,0x24,0x70 # movaps %xmm13,0x70(%rsp)
+ .byte 0x44,0x0f,0x29,0xb4,0x24,0x80,0,0,0 # movaps %xmm14,0x80(%rsp)
+ .byte 0x44,0x0f,0x29,0xbc,0x24,0x90,0,0,0 # movaps %xmm15,0x90(%rsp)
+___
+$code.=<<___;
+ movd $power,%xmm8
+ movdqa .Linc+16(%rip),%xmm1 # 00000002000000020000000200000002
+ movdqa .Linc(%rip),%xmm0 # 00000001000000010000000000000000
+
+ pshufd \$0,%xmm8,%xmm8 # broadcast $power
+ movdqa %xmm1,%xmm7
+ movdqa %xmm1,%xmm2
+___
+########################################################################
+# calculate mask by comparing 0..15 to $power
+#
+for($i=0;$i<4;$i++) {
+$code.=<<___;
+ paddd %xmm`$i`,%xmm`$i+1`
+ pcmpeqd %xmm8,%xmm`$i`
+ movdqa %xmm7,%xmm`$i+3`
+___
+}
+for(;$i<7;$i++) {
+$code.=<<___;
+ paddd %xmm`$i`,%xmm`$i+1`
+ pcmpeqd %xmm8,%xmm`$i`
+___
+}
+$code.=<<___;
+ pcmpeqd %xmm8,%xmm7
movl \$8, %r9d
jmp .Loop_gather
.align 16
.Loop_gather:
- movl ($inp), %eax
- movl 64($inp), %r8d
+ movdqa 16*0($inp),%xmm8
+ movdqa 16*1($inp),%xmm9
+ movdqa 16*2($inp),%xmm10
+ movdqa 16*3($inp),%xmm11
+ pand %xmm0,%xmm8
+ movdqa 16*4($inp),%xmm12
+ pand %xmm1,%xmm9
+ movdqa 16*5($inp),%xmm13
+ pand %xmm2,%xmm10
+ movdqa 16*6($inp),%xmm14
+ pand %xmm3,%xmm11
+ movdqa 16*7($inp),%xmm15
leaq 128($inp), $inp
- shlq \$32, %r8
- or %r8, %rax
- movq %rax, ($out)
+ pand %xmm4,%xmm12
+ pand %xmm5,%xmm13
+ pand %xmm6,%xmm14
+ pand %xmm7,%xmm15
+ por %xmm10,%xmm8
+ por %xmm11,%xmm9
+ por %xmm12,%xmm8
+ por %xmm13,%xmm9
+ por %xmm14,%xmm8
+ por %xmm15,%xmm9
+
+ por %xmm9,%xmm8
+ pshufd \$0x4e,%xmm8,%xmm9
+ por %xmm9,%xmm8
+ movq %xmm8,($out)
leaq 8($out), $out
decl %r9d
jnz .Loop_gather
+___
+$code.=<<___ if ($win64);
+ movaps 0x00(%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
+ add \$0xa8,%rsp
+___
+$code.=<<___;
ret
+.LSEH_end_rsaz_512_gather4:
.size rsaz_512_gather4,.-rsaz_512_gather4
+
+.align 64
+.Linc:
+ .long 0,0, 1,1
+ .long 2,2, 2,2
___
}
@@ -2026,6 +2204,18 @@ se_handler:
lea 128+24+48(%rax),%rax
+ lea .Lmul_gather4_epilogue(%rip),%rbx
+ cmp %r10,%rbx
+ jne .Lse_not_in_mul_gather4
+
+ lea 0xb0(%rax),%rax
+
+ lea -48-0xa8(%rax),%rsi
+ lea 512($context),%rdi
+ mov \$20,%ecx
+ .long 0xa548f3fc # cld; rep movsq
+
+.Lse_not_in_mul_gather4:
mov -8(%rax),%rbx
mov -16(%rax),%rbp
mov -24(%rax),%r12
@@ -2077,7 +2267,7 @@ se_handler:
pop %rdi
pop %rsi
ret
-.size sqr_handler,.-sqr_handler
+.size se_handler,.-se_handler
.section .pdata
.align 4
@@ -2101,6 +2291,10 @@ se_handler:
.rva .LSEH_end_rsaz_512_mul_by_one
.rva .LSEH_info_rsaz_512_mul_by_one
+ .rva .LSEH_begin_rsaz_512_gather4
+ .rva .LSEH_end_rsaz_512_gather4
+ .rva .LSEH_info_rsaz_512_gather4
+
.section .xdata
.align 8
.LSEH_info_rsaz_512_sqr:
@@ -2123,6 +2317,19 @@ se_handler:
.byte 9,0,0,0
.rva se_handler
.rva .Lmul_by_one_body,.Lmul_by_one_epilogue # HandlerData[]
+.LSEH_info_rsaz_512_gather4:
+ .byte 0x01,0x46,0x16,0x00
+ .byte 0x46,0xf8,0x09,0x00 # vmovaps 0x90(rsp),xmm15
+ .byte 0x3d,0xe8,0x08,0x00 # vmovaps 0x80(rsp),xmm14
+ .byte 0x34,0xd8,0x07,0x00 # vmovaps 0x70(rsp),xmm13
+ .byte 0x2e,0xc8,0x06,0x00 # vmovaps 0x60(rsp),xmm12
+ .byte 0x28,0xb8,0x05,0x00 # vmovaps 0x50(rsp),xmm11
+ .byte 0x22,0xa8,0x04,0x00 # vmovaps 0x40(rsp),xmm10
+ .byte 0x1c,0x98,0x03,0x00 # vmovaps 0x30(rsp),xmm9
+ .byte 0x16,0x88,0x02,0x00 # vmovaps 0x20(rsp),xmm8
+ .byte 0x10,0x78,0x01,0x00 # vmovaps 0x10(rsp),xmm7
+ .byte 0x0b,0x68,0x00,0x00 # vmovaps 0x00(rsp),xmm6
+ .byte 0x07,0x01,0x15,0x00 # sub rsp,0xa8
___
}
diff --git a/src/crypto/bn/asm/x86_64-gcc.c b/src/crypto/bn/asm/x86_64-gcc.c
index 0496b959..214c12af 100644
--- a/src/crypto/bn/asm/x86_64-gcc.c
+++ b/src/crypto/bn/asm/x86_64-gcc.c
@@ -1,9 +1,3 @@
-#include <openssl/bn.h>
-
-#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && !defined(OPENSSL_WINDOWS)
-
-#include "../internal.h"
-
/* x86_64 BIGNUM accelerator version 0.1, December 2002.
*
* Implemented by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
@@ -56,7 +50,13 @@
* machine.
*/
- /* TODO(davidben): Get this file working on Windows x64. */
+#include <openssl/bn.h>
+
+/* TODO(davidben): Get this file working on Windows x64. */
+#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && defined(__GNUC__)
+
+#include "../internal.h"
+
#undef mul
#undef mul_add
@@ -186,14 +186,6 @@ void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n) {
}
}
-BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) {
- BN_ULONG ret, waste;
-
- asm("divq %4" : "=a"(ret), "=d"(waste) : "a"(l), "d"(h), "g"(d) : "cc");
-
- return ret;
-}
-
BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
int n) {
BN_ULONG ret;
@@ -220,7 +212,6 @@ BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
return ret & 1;
}
-#ifndef SIMICS
BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
int n) {
BN_ULONG ret;
@@ -246,65 +237,6 @@ BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
return ret & 1;
}
-#else
-/* Simics 1.4<7 has buggy sbbq:-( */
-#define BN_MASK2 0xffffffffffffffffL
-BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n) {
- BN_ULONG t1, t2;
- int c = 0;
-
- if (n <= 0) {
- return (BN_ULONG)0;
- }
-
- for (;;) {
- t1 = a[0];
- t2 = b[0];
- r[0] = (t1 - t2 - c) & BN_MASK2;
- if (t1 != t2) {
- c = (t1 < t2);
- }
- if (--n <= 0) {
- break;
- }
-
- t1 = a[1];
- t2 = b[1];
- r[1] = (t1 - t2 - c) & BN_MASK2;
- if (t1 != t2) {
- c = (t1 < t2);
- }
- if (--n <= 0) {
- break;
- }
-
- t1 = a[2];
- t2 = b[2];
- r[2] = (t1 - t2 - c) & BN_MASK2;
- if (t1 != t2) {
- c = (t1 < t2);
- }
- if (--n <= 0) {
- break;
- }
-
- t1 = a[3];
- t2 = b[3];
- r[3] = (t1 - t2 - c) & BN_MASK2;
- if (t1 != t2) {
- c = (t1 < t2);
- }
- if (--n <= 0) {
- break;
- }
-
- a += 4;
- b += 4;
- r += 4;
- }
- return c;
-}
-#endif
/* mul_add_c(a,b,c0,c1,c2) -- c+=a*b for three word number c=(c2,c1,c0) */
/* mul_add_c2(a,b,c0,c1,c2) -- c+=2*a*b for three word number c=(c2,c1,c0) */
@@ -596,4 +528,4 @@ void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a) {
r[7] = c2;
}
-#endif /* !NO_ASM && X86_64 && !WINDOWS */
+#endif /* !NO_ASM && X86_64 && __GNUC__ */
diff --git a/src/crypto/bn/asm/x86_64-mont.pl b/src/crypto/bn/asm/x86_64-mont.pl
index 04c4beaf..1ca2b1ef 100644..100755
--- a/src/crypto/bn/asm/x86_64-mont.pl
+++ b/src/crypto/bn/asm/x86_64-mont.pl
@@ -761,100 +761,126 @@ bn_sqr8x_mont:
# 4096. this is done to allow memory disambiguation logic
# do its job.
#
- lea -64(%rsp,$num,4),%r11
+ lea -64(%rsp,$num,2),%r11
mov ($n0),$n0 # *n0
sub $aptr,%r11
and \$4095,%r11
cmp %r11,%r10
jb .Lsqr8x_sp_alt
sub %r11,%rsp # align with $aptr
- lea -64(%rsp,$num,4),%rsp # alloca(frame+4*$num)
+ lea -64(%rsp,$num,2),%rsp # alloca(frame+2*$num)
jmp .Lsqr8x_sp_done
.align 32
.Lsqr8x_sp_alt:
- lea 4096-64(,$num,4),%r10 # 4096-frame-4*$num
- lea -64(%rsp,$num,4),%rsp # alloca(frame+4*$num)
+ lea 4096-64(,$num,2),%r10 # 4096-frame-2*$num
+ lea -64(%rsp,$num,2),%rsp # alloca(frame+2*$num)
sub %r10,%r11
mov \$0,%r10
cmovc %r10,%r11
sub %r11,%rsp
.Lsqr8x_sp_done:
and \$-64,%rsp
- mov $num,%r10
+ mov $num,%r10
neg $num
- lea 64(%rsp,$num,2),%r11 # copy of modulus
mov $n0, 32(%rsp)
mov %rax, 40(%rsp) # save original %rsp
.Lsqr8x_body:
- mov $num,$i
- movq %r11, %xmm2 # save pointer to modulus copy
- shr \$3+2,$i
- mov OPENSSL_ia32cap_P+8(%rip),%eax
- jmp .Lsqr8x_copy_n
-
-.align 32
-.Lsqr8x_copy_n:
- movq 8*0($nptr),%xmm0
- movq 8*1($nptr),%xmm1
- movq 8*2($nptr),%xmm3
- movq 8*3($nptr),%xmm4
- lea 8*4($nptr),$nptr
- movdqa %xmm0,16*0(%r11)
- movdqa %xmm1,16*1(%r11)
- movdqa %xmm3,16*2(%r11)
- movdqa %xmm4,16*3(%r11)
- lea 16*4(%r11),%r11
- dec $i
- jnz .Lsqr8x_copy_n
-
+ movq $nptr, %xmm2 # save pointer to modulus
pxor %xmm0,%xmm0
movq $rptr,%xmm1 # save $rptr
movq %r10, %xmm3 # -$num
___
$code.=<<___ if ($addx);
+ mov OPENSSL_ia32cap_P+8(%rip),%eax
and \$0x80100,%eax
cmp \$0x80100,%eax
jne .Lsqr8x_nox
call bn_sqrx8x_internal # see x86_64-mont5 module
-
- pxor %xmm0,%xmm0
- lea 48(%rsp),%rax
- lea 64(%rsp,$num,2),%rdx
- shr \$3+2,$num
- mov 40(%rsp),%rsi # restore %rsp
- jmp .Lsqr8x_zero
+ # %rax top-most carry
+ # %rbp nptr
+ # %rcx -8*num
+ # %r8 end of tp[2*num]
+ lea (%r8,%rcx),%rbx
+ mov %rcx,$num
+ mov %rcx,%rdx
+ movq %xmm1,$rptr
+ sar \$3+2,%rcx # %cf=0
+ jmp .Lsqr8x_sub
.align 32
.Lsqr8x_nox:
___
$code.=<<___;
call bn_sqr8x_internal # see x86_64-mont5 module
+ # %rax top-most carry
+ # %rbp nptr
+ # %r8 -8*num
+ # %rdi end of tp[2*num]
+ lea (%rdi,$num),%rbx
+ mov $num,%rcx
+ mov $num,%rdx
+ movq %xmm1,$rptr
+ sar \$3+2,%rcx # %cf=0
+ jmp .Lsqr8x_sub
+.align 32
+.Lsqr8x_sub:
+ mov 8*0(%rbx),%r12
+ mov 8*1(%rbx),%r13
+ mov 8*2(%rbx),%r14
+ mov 8*3(%rbx),%r15
+ lea 8*4(%rbx),%rbx
+ sbb 8*0(%rbp),%r12
+ sbb 8*1(%rbp),%r13
+ sbb 8*2(%rbp),%r14
+ sbb 8*3(%rbp),%r15
+ lea 8*4(%rbp),%rbp
+ mov %r12,8*0($rptr)
+ mov %r13,8*1($rptr)
+ mov %r14,8*2($rptr)
+ mov %r15,8*3($rptr)
+ lea 8*4($rptr),$rptr
+ inc %rcx # preserves %cf
+ jnz .Lsqr8x_sub
+
+ sbb \$0,%rax # top-most carry
+ lea (%rbx,$num),%rbx # rewind
+ lea ($rptr,$num),$rptr # rewind
+
+ movq %rax,%xmm1
pxor %xmm0,%xmm0
- lea 48(%rsp),%rax
- lea 64(%rsp,$num,2),%rdx
- shr \$3+2,$num
+ pshufd \$0,%xmm1,%xmm1
mov 40(%rsp),%rsi # restore %rsp
- jmp .Lsqr8x_zero
+ jmp .Lsqr8x_cond_copy
.align 32
-.Lsqr8x_zero:
- movdqa %xmm0,16*0(%rax) # wipe t
- movdqa %xmm0,16*1(%rax)
- movdqa %xmm0,16*2(%rax)
- movdqa %xmm0,16*3(%rax)
- lea 16*4(%rax),%rax
- movdqa %xmm0,16*0(%rdx) # wipe n
- movdqa %xmm0,16*1(%rdx)
- movdqa %xmm0,16*2(%rdx)
- movdqa %xmm0,16*3(%rdx)
- lea 16*4(%rdx),%rdx
- dec $num
- jnz .Lsqr8x_zero
+.Lsqr8x_cond_copy:
+ movdqa 16*0(%rbx),%xmm2
+ movdqa 16*1(%rbx),%xmm3
+ lea 16*2(%rbx),%rbx
+ movdqu 16*0($rptr),%xmm4
+ movdqu 16*1($rptr),%xmm5
+ lea 16*2($rptr),$rptr
+ movdqa %xmm0,-16*2(%rbx) # zero tp
+ movdqa %xmm0,-16*1(%rbx)
+ movdqa %xmm0,-16*2(%rbx,%rdx)
+ movdqa %xmm0,-16*1(%rbx,%rdx)
+ pcmpeqd %xmm1,%xmm0
+ pand %xmm1,%xmm2
+ pand %xmm1,%xmm3
+ pand %xmm0,%xmm4
+ pand %xmm0,%xmm5
+ pxor %xmm0,%xmm0
+ por %xmm2,%xmm4
+ por %xmm3,%xmm5
+ movdqu %xmm4,-16*2($rptr)
+ movdqu %xmm5,-16*1($rptr)
+ add \$32,$num
+ jnz .Lsqr8x_cond_copy
mov \$1,%rax
mov -48(%rsi),%r15
@@ -1121,64 +1147,75 @@ $code.=<<___;
adc $zero,%r15 # modulo-scheduled
sub 0*8($tptr),$zero # pull top-most carry
adc %r15,%r14
- mov -8($nptr),$mi
sbb %r15,%r15 # top-most carry
mov %r14,-1*8($tptr)
cmp 16(%rsp),$bptr
jne .Lmulx4x_outer
- sub %r14,$mi # compare top-most words
- sbb $mi,$mi
- or $mi,%r15
-
- neg $num
- xor %rdx,%rdx
+ lea 64(%rsp),$tptr
+ sub $num,$nptr # rewind $nptr
+ neg %r15
+ mov $num,%rdx
+ shr \$3+2,$num # %cf=0
mov 32(%rsp),$rptr # restore rp
+ jmp .Lmulx4x_sub
+
+.align 32
+.Lmulx4x_sub:
+ mov 8*0($tptr),%r11
+ mov 8*1($tptr),%r12
+ mov 8*2($tptr),%r13
+ mov 8*3($tptr),%r14
+ lea 8*4($tptr),$tptr
+ sbb 8*0($nptr),%r11
+ sbb 8*1($nptr),%r12
+ sbb 8*2($nptr),%r13
+ sbb 8*3($nptr),%r14
+ lea 8*4($nptr),$nptr
+ mov %r11,8*0($rptr)
+ mov %r12,8*1($rptr)
+ mov %r13,8*2($rptr)
+ mov %r14,8*3($rptr)
+ lea 8*4($rptr),$rptr
+ dec $num # preserves %cf
+ jnz .Lmulx4x_sub
+
+ sbb \$0,%r15 # top-most carry
lea 64(%rsp),$tptr
+ sub %rdx,$rptr # rewind
+ movq %r15,%xmm1
pxor %xmm0,%xmm0
- mov 0*8($nptr,$num),%r8
- mov 1*8($nptr,$num),%r9
- neg %r8
- jmp .Lmulx4x_sub_entry
+ pshufd \$0,%xmm1,%xmm1
+ mov 40(%rsp),%rsi # restore %rsp
+ jmp .Lmulx4x_cond_copy
.align 32
-.Lmulx4x_sub:
- mov 0*8($nptr,$num),%r8
- mov 1*8($nptr,$num),%r9
- not %r8
-.Lmulx4x_sub_entry:
- mov 2*8($nptr,$num),%r10
- not %r9
- and %r15,%r8
- mov 3*8($nptr,$num),%r11
- not %r10
- and %r15,%r9
- not %r11
- and %r15,%r10
- and %r15,%r11
-
- neg %rdx # mov %rdx,%cf
- adc 0*8($tptr),%r8
- adc 1*8($tptr),%r9
- movdqa %xmm0,($tptr)
- adc 2*8($tptr),%r10
- adc 3*8($tptr),%r11
- movdqa %xmm0,16($tptr)
- lea 4*8($tptr),$tptr
- sbb %rdx,%rdx # mov %cf,%rdx
-
- mov %r8,0*8($rptr)
- mov %r9,1*8($rptr)
- mov %r10,2*8($rptr)
- mov %r11,3*8($rptr)
- lea 4*8($rptr),$rptr
+.Lmulx4x_cond_copy:
+ movdqa 16*0($tptr),%xmm2
+ movdqa 16*1($tptr),%xmm3
+ lea 16*2($tptr),$tptr
+ movdqu 16*0($rptr),%xmm4
+ movdqu 16*1($rptr),%xmm5
+ lea 16*2($rptr),$rptr
+ movdqa %xmm0,-16*2($tptr) # zero tp
+ movdqa %xmm0,-16*1($tptr)
+ pcmpeqd %xmm1,%xmm0
+ pand %xmm1,%xmm2
+ pand %xmm1,%xmm3
+ pand %xmm0,%xmm4
+ pand %xmm0,%xmm5
+ pxor %xmm0,%xmm0
+ por %xmm2,%xmm4
+ por %xmm3,%xmm5
+ movdqu %xmm4,-16*2($rptr)
+ movdqu %xmm5,-16*1($rptr)
+ sub \$32,%rdx
+ jnz .Lmulx4x_cond_copy
- add \$32,$num
- jnz .Lmulx4x_sub
+ mov %rdx,($tptr)
- mov 40(%rsp),%rsi # restore %rsp
mov \$1,%rax
mov -48(%rsi),%r15
mov -40(%rsi),%r14
diff --git a/src/crypto/bn/asm/x86_64-mont5.pl b/src/crypto/bn/asm/x86_64-mont5.pl
index 3c5a8fc9..ced3acba 100644..100755
--- a/src/crypto/bn/asm/x86_64-mont5.pl
+++ b/src/crypto/bn/asm/x86_64-mont5.pl
@@ -86,58 +86,111 @@ $code.=<<___;
.Lmul_enter:
mov ${num}d,${num}d
mov %rsp,%rax
- mov `($win64?56:8)`(%rsp),%r10d # load 7th argument
+ movd `($win64?56:8)`(%rsp),%xmm5 # load 7th argument
+ lea .Linc(%rip),%r10
push %rbx
push %rbp
push %r12
push %r13
push %r14
push %r15
-___
-$code.=<<___ if ($win64);
- lea -0x28(%rsp),%rsp
- movaps %xmm6,(%rsp)
- movaps %xmm7,0x10(%rsp)
-___
-$code.=<<___;
+
lea 2($num),%r11
neg %r11
- lea (%rsp,%r11,8),%rsp # tp=alloca(8*(num+2))
+ lea -264(%rsp,%r11,8),%rsp # tp=alloca(8*(num+2)+256+8)
and \$-1024,%rsp # minimize TLB usage
mov %rax,8(%rsp,$num,8) # tp[num+1]=%rsp
.Lmul_body:
- mov $bp,%r12 # reassign $bp
+ lea 128($bp),%r12 # reassign $bp (+size optimization)
___
$bp="%r12";
$STRIDE=2**5*8; # 5 is "window size"
$N=$STRIDE/4; # should match cache line size
$code.=<<___;
- mov %r10,%r11
- shr \$`log($N/8)/log(2)`,%r10
- and \$`$N/8-1`,%r11
- not %r10
- lea .Lmagic_masks(%rip),%rax
- and \$`2**5/($N/8)-1`,%r10 # 5 is "window size"
- lea 96($bp,%r11,8),$bp # pointer within 1st cache line
- movq 0(%rax,%r10,8),%xmm4 # set of masks denoting which
- movq 8(%rax,%r10,8),%xmm5 # cache line contains element
- movq 16(%rax,%r10,8),%xmm6 # denoted by 7th argument
- movq 24(%rax,%r10,8),%xmm7
-
- movq `0*$STRIDE/4-96`($bp),%xmm0
- movq `1*$STRIDE/4-96`($bp),%xmm1
- pand %xmm4,%xmm0
- movq `2*$STRIDE/4-96`($bp),%xmm2
- pand %xmm5,%xmm1
- movq `3*$STRIDE/4-96`($bp),%xmm3
- pand %xmm6,%xmm2
- por %xmm1,%xmm0
- pand %xmm7,%xmm3
+ movdqa 0(%r10),%xmm0 # 00000001000000010000000000000000
+ movdqa 16(%r10),%xmm1 # 00000002000000020000000200000002
+ lea 24-112(%rsp,$num,8),%r10# place the mask after tp[num+3] (+ICache optimization)
+ and \$-16,%r10
+
+ pshufd \$0,%xmm5,%xmm5 # broadcast index
+ movdqa %xmm1,%xmm4
+ movdqa %xmm1,%xmm2
+___
+########################################################################
+# calculate mask by comparing 0..31 to index and save result to stack
+#
+$code.=<<___;
+ paddd %xmm0,%xmm1
+ pcmpeqd %xmm5,%xmm0 # compare to 1,0
+ .byte 0x67
+ movdqa %xmm4,%xmm3
+___
+for($k=0;$k<$STRIDE/16-4;$k+=4) {
+$code.=<<___;
+ paddd %xmm1,%xmm2
+ pcmpeqd %xmm5,%xmm1 # compare to 3,2
+ movdqa %xmm0,`16*($k+0)+112`(%r10)
+ movdqa %xmm4,%xmm0
+
+ paddd %xmm2,%xmm3
+ pcmpeqd %xmm5,%xmm2 # compare to 5,4
+ movdqa %xmm1,`16*($k+1)+112`(%r10)
+ movdqa %xmm4,%xmm1
+
+ paddd %xmm3,%xmm0
+ pcmpeqd %xmm5,%xmm3 # compare to 7,6
+ movdqa %xmm2,`16*($k+2)+112`(%r10)
+ movdqa %xmm4,%xmm2
+
+ paddd %xmm0,%xmm1
+ pcmpeqd %xmm5,%xmm0
+ movdqa %xmm3,`16*($k+3)+112`(%r10)
+ movdqa %xmm4,%xmm3
+___
+}
+$code.=<<___; # last iteration can be optimized
+ paddd %xmm1,%xmm2
+ pcmpeqd %xmm5,%xmm1
+ movdqa %xmm0,`16*($k+0)+112`(%r10)
+
+ paddd %xmm2,%xmm3
+ .byte 0x67
+ pcmpeqd %xmm5,%xmm2
+ movdqa %xmm1,`16*($k+1)+112`(%r10)
+
+ pcmpeqd %xmm5,%xmm3
+ movdqa %xmm2,`16*($k+2)+112`(%r10)
+ pand `16*($k+0)-128`($bp),%xmm0 # while it's still in register
+
+ pand `16*($k+1)-128`($bp),%xmm1
+ pand `16*($k+2)-128`($bp),%xmm2
+ movdqa %xmm3,`16*($k+3)+112`(%r10)
+ pand `16*($k+3)-128`($bp),%xmm3
por %xmm2,%xmm0
+ por %xmm3,%xmm1
+___
+for($k=0;$k<$STRIDE/16-4;$k+=4) {
+$code.=<<___;
+ movdqa `16*($k+0)-128`($bp),%xmm4
+ movdqa `16*($k+1)-128`($bp),%xmm5
+ movdqa `16*($k+2)-128`($bp),%xmm2
+ pand `16*($k+0)+112`(%r10),%xmm4
+ movdqa `16*($k+3)-128`($bp),%xmm3
+ pand `16*($k+1)+112`(%r10),%xmm5
+ por %xmm4,%xmm0
+ pand `16*($k+2)+112`(%r10),%xmm2
+ por %xmm5,%xmm1
+ pand `16*($k+3)+112`(%r10),%xmm3
+ por %xmm2,%xmm0
+ por %xmm3,%xmm1
+___
+}
+$code.=<<___;
+ por %xmm1,%xmm0
+ pshufd \$0x4e,%xmm0,%xmm1
+ por %xmm1,%xmm0
lea $STRIDE($bp),$bp
- por %xmm3,%xmm0
-
movq %xmm0,$m0 # m0=bp[0]
mov ($n0),$n0 # pull n0[0] value
@@ -146,29 +199,14 @@ $code.=<<___;
xor $i,$i # i=0
xor $j,$j # j=0
- movq `0*$STRIDE/4-96`($bp),%xmm0
- movq `1*$STRIDE/4-96`($bp),%xmm1
- pand %xmm4,%xmm0
- movq `2*$STRIDE/4-96`($bp),%xmm2
- pand %xmm5,%xmm1
-
mov $n0,$m1
mulq $m0 # ap[0]*bp[0]
mov %rax,$lo0
mov ($np),%rax
- movq `3*$STRIDE/4-96`($bp),%xmm3
- pand %xmm6,%xmm2
- por %xmm1,%xmm0
- pand %xmm7,%xmm3
-
imulq $lo0,$m1 # "tp[0]"*n0
mov %rdx,$hi0
- por %xmm2,%xmm0
- lea $STRIDE($bp),$bp
- por %xmm3,%xmm0
-
mulq $m1 # np[0]*m1
add %rax,$lo0 # discarded
mov 8($ap),%rax
@@ -199,16 +237,14 @@ $code.=<<___;
mulq $m1 # np[j]*m1
cmp $num,$j
- jne .L1st
-
- movq %xmm0,$m0 # bp[1]
+ jne .L1st # note that upon exit $j==$num, so
+ # they can be used interchangeably
add %rax,$hi1
- mov ($ap),%rax # ap[0]
adc \$0,%rdx
add $hi0,$hi1 # np[j]*m1+ap[j]*bp[0]
adc \$0,%rdx
- mov $hi1,-16(%rsp,$j,8) # tp[j-1]
+ mov $hi1,-16(%rsp,$num,8) # tp[num-1]
mov %rdx,$hi1
mov $lo0,$hi0
@@ -222,33 +258,48 @@ $code.=<<___;
jmp .Louter
.align 16
.Louter:
+ lea 24+128(%rsp,$num,8),%rdx # where 256-byte mask is (+size optimization)
+ and \$-16,%rdx
+ pxor %xmm4,%xmm4
+ pxor %xmm5,%xmm5
+___
+for($k=0;$k<$STRIDE/16;$k+=4) {
+$code.=<<___;
+ movdqa `16*($k+0)-128`($bp),%xmm0
+ movdqa `16*($k+1)-128`($bp),%xmm1
+ movdqa `16*($k+2)-128`($bp),%xmm2
+ movdqa `16*($k+3)-128`($bp),%xmm3
+ pand `16*($k+0)-128`(%rdx),%xmm0
+ pand `16*($k+1)-128`(%rdx),%xmm1
+ por %xmm0,%xmm4
+ pand `16*($k+2)-128`(%rdx),%xmm2
+ por %xmm1,%xmm5
+ pand `16*($k+3)-128`(%rdx),%xmm3
+ por %xmm2,%xmm4
+ por %xmm3,%xmm5
+___
+}
+$code.=<<___;
+ por %xmm5,%xmm4
+ pshufd \$0x4e,%xmm4,%xmm0
+ por %xmm4,%xmm0
+ lea $STRIDE($bp),$bp
+
+ mov ($ap),%rax # ap[0]
+ movq %xmm0,$m0 # m0=bp[i]
+
xor $j,$j # j=0
mov $n0,$m1
mov (%rsp),$lo0
- movq `0*$STRIDE/4-96`($bp),%xmm0
- movq `1*$STRIDE/4-96`($bp),%xmm1
- pand %xmm4,%xmm0
- movq `2*$STRIDE/4-96`($bp),%xmm2
- pand %xmm5,%xmm1
-
mulq $m0 # ap[0]*bp[i]
add %rax,$lo0 # ap[0]*bp[i]+tp[0]
mov ($np),%rax
adc \$0,%rdx
- movq `3*$STRIDE/4-96`($bp),%xmm3
- pand %xmm6,%xmm2
- por %xmm1,%xmm0
- pand %xmm7,%xmm3
-
imulq $lo0,$m1 # tp[0]*n0
mov %rdx,$hi0
- por %xmm2,%xmm0
- lea $STRIDE($bp),$bp
- por %xmm3,%xmm0
-
mulq $m1 # np[0]*m1
add %rax,$lo0 # discarded
mov 8($ap),%rax
@@ -282,17 +333,14 @@ $code.=<<___;
mulq $m1 # np[j]*m1
cmp $num,$j
- jne .Linner
-
- movq %xmm0,$m0 # bp[i+1]
-
+ jne .Linner # note that upon exit $j==$num, so
+ # they can be used interchangeably
add %rax,$hi1
- mov ($ap),%rax # ap[0]
adc \$0,%rdx
add $lo0,$hi1 # np[j]*m1+ap[j]*bp[i]+tp[j]
- mov (%rsp,$j,8),$lo0
+ mov (%rsp,$num,8),$lo0
adc \$0,%rdx
- mov $hi1,-16(%rsp,$j,8) # tp[j-1]
+ mov $hi1,-16(%rsp,$num,8) # tp[num-1]
mov %rdx,$hi1
xor %rdx,%rdx
@@ -338,12 +386,7 @@ $code.=<<___;
mov 8(%rsp,$num,8),%rsi # restore %rsp
mov \$1,%rax
-___
-$code.=<<___ if ($win64);
- movaps -88(%rsi),%xmm6
- movaps -72(%rsi),%xmm7
-___
-$code.=<<___;
+
mov -48(%rsi),%r15
mov -40(%rsi),%r14
mov -32(%rsi),%r13
@@ -365,8 +408,8 @@ bn_mul4x_mont_gather5:
.Lmul4x_enter:
___
$code.=<<___ if ($addx);
- and \$0x80100,%r11d
- cmp \$0x80100,%r11d
+ and \$0x80108,%r11d
+ cmp \$0x80108,%r11d # check for AD*X+BMI2+BMI1
je .Lmulx4x_enter
___
$code.=<<___;
@@ -378,39 +421,34 @@ $code.=<<___;
push %r13
push %r14
push %r15
-___
-$code.=<<___ if ($win64);
- lea -0x28(%rsp),%rsp
- movaps %xmm6,(%rsp)
- movaps %xmm7,0x10(%rsp)
-___
-$code.=<<___;
+
.byte 0x67
- mov ${num}d,%r10d
- shl \$3,${num}d
- shl \$3+2,%r10d # 4*$num
+ shl \$3,${num}d # convert $num to bytes
+ lea ($num,$num,2),%r10 # 3*$num in bytes
neg $num # -$num
##############################################################
- # ensure that stack frame doesn't alias with $aptr+4*$num
- # modulo 4096, which covers ret[num], am[num] and n[2*num]
- # (see bn_exp.c). this is done to allow memory disambiguation
- # logic do its magic. [excessive frame is allocated in order
- # to allow bn_from_mont8x to clear it.]
+ # Ensure that stack frame doesn't alias with $rptr+3*$num
+ # modulo 4096, which covers ret[num], am[num] and n[num]
+ # (see bn_exp.c). This is done to allow memory disambiguation
+ # logic do its magic. [Extra [num] is allocated in order
+ # to align with bn_power5's frame, which is cleansed after
+ # completing exponentiation. Extra 256 bytes is for power mask
+ # calculated from 7th argument, the index.]
#
- lea -64(%rsp,$num,2),%r11
- sub $ap,%r11
+ lea -320(%rsp,$num,2),%r11
+ sub $rp,%r11
and \$4095,%r11
cmp %r11,%r10
jb .Lmul4xsp_alt
- sub %r11,%rsp # align with $ap
- lea -64(%rsp,$num,2),%rsp # alloca(128+num*8)
+ sub %r11,%rsp # align with $rp
+ lea -320(%rsp,$num,2),%rsp # alloca(frame+2*num*8+256)
jmp .Lmul4xsp_done
.align 32
.Lmul4xsp_alt:
- lea 4096-64(,$num,2),%r10
- lea -64(%rsp,$num,2),%rsp # alloca(128+num*8)
+ lea 4096-320(,$num,2),%r10
+ lea -320(%rsp,$num,2),%rsp # alloca(frame+2*num*8+256)
sub %r10,%r11
mov \$0,%r10
cmovc %r10,%r11
@@ -426,12 +464,7 @@ $code.=<<___;
mov 40(%rsp),%rsi # restore %rsp
mov \$1,%rax
-___
-$code.=<<___ if ($win64);
- movaps -88(%rsi),%xmm6
- movaps -72(%rsi),%xmm7
-___
-$code.=<<___;
+
mov -48(%rsi),%r15
mov -40(%rsi),%r14
mov -32(%rsi),%r13
@@ -446,9 +479,10 @@ $code.=<<___;
.type mul4x_internal,\@abi-omnipotent
.align 32
mul4x_internal:
- shl \$5,$num
- mov `($win64?56:8)`(%rax),%r10d # load 7th argument
- lea 256(%rdx,$num),%r13
+ shl \$5,$num # $num was in bytes
+ movd `($win64?56:8)`(%rax),%xmm5 # load 7th argument, index
+ lea .Linc(%rip),%rax
+ lea 128(%rdx,$num),%r13 # end of powers table (+size optimization)
shr \$5,$num # restore $num
___
$bp="%r12";
@@ -456,44 +490,92 @@ ___
$N=$STRIDE/4; # should match cache line size
$tp=$i;
$code.=<<___;
- mov %r10,%r11
- shr \$`log($N/8)/log(2)`,%r10
- and \$`$N/8-1`,%r11
- not %r10
- lea .Lmagic_masks(%rip),%rax
- and \$`2**5/($N/8)-1`,%r10 # 5 is "window size"
- lea 96(%rdx,%r11,8),$bp # pointer within 1st cache line
- movq 0(%rax,%r10,8),%xmm4 # set of masks denoting which
- movq 8(%rax,%r10,8),%xmm5 # cache line contains element
- add \$7,%r11
- movq 16(%rax,%r10,8),%xmm6 # denoted by 7th argument
- movq 24(%rax,%r10,8),%xmm7
- and \$7,%r11
-
- movq `0*$STRIDE/4-96`($bp),%xmm0
- lea $STRIDE($bp),$tp # borrow $tp
- movq `1*$STRIDE/4-96`($bp),%xmm1
- pand %xmm4,%xmm0
- movq `2*$STRIDE/4-96`($bp),%xmm2
- pand %xmm5,%xmm1
- movq `3*$STRIDE/4-96`($bp),%xmm3
- pand %xmm6,%xmm2
- .byte 0x67
- por %xmm1,%xmm0
- movq `0*$STRIDE/4-96`($tp),%xmm1
- .byte 0x67
- pand %xmm7,%xmm3
- .byte 0x67
- por %xmm2,%xmm0
- movq `1*$STRIDE/4-96`($tp),%xmm2
+ movdqa 0(%rax),%xmm0 # 00000001000000010000000000000000
+ movdqa 16(%rax),%xmm1 # 00000002000000020000000200000002
+ lea 88-112(%rsp,$num),%r10 # place the mask after tp[num+1] (+ICache optimization)
+ lea 128(%rdx),$bp # size optimization
+
+ pshufd \$0,%xmm5,%xmm5 # broadcast index
+ movdqa %xmm1,%xmm4
+ .byte 0x67,0x67
+ movdqa %xmm1,%xmm2
+___
+########################################################################
+# calculate mask by comparing 0..31 to index and save result to stack
+#
+$code.=<<___;
+ paddd %xmm0,%xmm1
+ pcmpeqd %xmm5,%xmm0 # compare to 1,0
.byte 0x67
- pand %xmm4,%xmm1
+ movdqa %xmm4,%xmm3
+___
+for($i=0;$i<$STRIDE/16-4;$i+=4) {
+$code.=<<___;
+ paddd %xmm1,%xmm2
+ pcmpeqd %xmm5,%xmm1 # compare to 3,2
+ movdqa %xmm0,`16*($i+0)+112`(%r10)
+ movdqa %xmm4,%xmm0
+
+ paddd %xmm2,%xmm3
+ pcmpeqd %xmm5,%xmm2 # compare to 5,4
+ movdqa %xmm1,`16*($i+1)+112`(%r10)
+ movdqa %xmm4,%xmm1
+
+ paddd %xmm3,%xmm0
+ pcmpeqd %xmm5,%xmm3 # compare to 7,6
+ movdqa %xmm2,`16*($i+2)+112`(%r10)
+ movdqa %xmm4,%xmm2
+
+ paddd %xmm0,%xmm1
+ pcmpeqd %xmm5,%xmm0
+ movdqa %xmm3,`16*($i+3)+112`(%r10)
+ movdqa %xmm4,%xmm3
+___
+}
+$code.=<<___; # last iteration can be optimized
+ paddd %xmm1,%xmm2
+ pcmpeqd %xmm5,%xmm1
+ movdqa %xmm0,`16*($i+0)+112`(%r10)
+
+ paddd %xmm2,%xmm3
.byte 0x67
- por %xmm3,%xmm0
- movq `2*$STRIDE/4-96`($tp),%xmm3
+ pcmpeqd %xmm5,%xmm2
+ movdqa %xmm1,`16*($i+1)+112`(%r10)
+ pcmpeqd %xmm5,%xmm3
+ movdqa %xmm2,`16*($i+2)+112`(%r10)
+ pand `16*($i+0)-128`($bp),%xmm0 # while it's still in register
+
+ pand `16*($i+1)-128`($bp),%xmm1
+ pand `16*($i+2)-128`($bp),%xmm2
+ movdqa %xmm3,`16*($i+3)+112`(%r10)
+ pand `16*($i+3)-128`($bp),%xmm3
+ por %xmm2,%xmm0
+ por %xmm3,%xmm1
+___
+for($i=0;$i<$STRIDE/16-4;$i+=4) {
+$code.=<<___;
+ movdqa `16*($i+0)-128`($bp),%xmm4
+ movdqa `16*($i+1)-128`($bp),%xmm5
+ movdqa `16*($i+2)-128`($bp),%xmm2
+ pand `16*($i+0)+112`(%r10),%xmm4
+ movdqa `16*($i+3)-128`($bp),%xmm3
+ pand `16*($i+1)+112`(%r10),%xmm5
+ por %xmm4,%xmm0
+ pand `16*($i+2)+112`(%r10),%xmm2
+ por %xmm5,%xmm1
+ pand `16*($i+3)+112`(%r10),%xmm3
+ por %xmm2,%xmm0
+ por %xmm3,%xmm1
+___
+}
+$code.=<<___;
+ por %xmm1,%xmm0
+ pshufd \$0x4e,%xmm0,%xmm1
+ por %xmm1,%xmm0
+ lea $STRIDE($bp),$bp
movq %xmm0,$m0 # m0=bp[0]
- movq `3*$STRIDE/4-96`($tp),%xmm0
+
mov %r13,16+8(%rsp) # save end of b[num]
mov $rp, 56+8(%rsp) # save $rp
@@ -507,26 +589,10 @@ $code.=<<___;
mov %rax,$A[0]
mov ($np),%rax
- pand %xmm5,%xmm2
- pand %xmm6,%xmm3
- por %xmm2,%xmm1
-
imulq $A[0],$m1 # "tp[0]"*n0
- ##############################################################
- # $tp is chosen so that writing to top-most element of the
- # vector occurs just "above" references to powers table,
- # "above" modulo cache-line size, which effectively precludes
- # possibility of memory disambiguation logic failure when
- # accessing the table.
- #
- lea 64+8(%rsp,%r11,8),$tp
+ lea 64+8(%rsp),$tp
mov %rdx,$A[1]
- pand %xmm7,%xmm0
- por %xmm3,%xmm1
- lea 2*$STRIDE($bp),$bp
- por %xmm1,%xmm0
-
mulq $m1 # np[0]*m1
add %rax,$A[0] # discarded
mov 8($ap,$num),%rax
@@ -535,7 +601,7 @@ $code.=<<___;
mulq $m0
add %rax,$A[1]
- mov 16*1($np),%rax # interleaved with 0, therefore 16*n
+ mov 8*1($np),%rax
adc \$0,%rdx
mov %rdx,$A[0]
@@ -545,7 +611,7 @@ $code.=<<___;
adc \$0,%rdx
add $A[1],$N[1]
lea 4*8($num),$j # j=4
- lea 16*4($np),$np
+ lea 8*4($np),$np
adc \$0,%rdx
mov $N[1],($tp)
mov %rdx,$N[0]
@@ -555,7 +621,7 @@ $code.=<<___;
.L1st4x:
mulq $m0 # ap[j]*bp[0]
add %rax,$A[0]
- mov -16*2($np),%rax
+ mov -8*2($np),%rax
lea 32($tp),$tp
adc \$0,%rdx
mov %rdx,$A[1]
@@ -571,7 +637,7 @@ $code.=<<___;
mulq $m0 # ap[j]*bp[0]
add %rax,$A[1]
- mov -16*1($np),%rax
+ mov -8*1($np),%rax
adc \$0,%rdx
mov %rdx,$A[0]
@@ -586,7 +652,7 @@ $code.=<<___;
mulq $m0 # ap[j]*bp[0]
add %rax,$A[0]
- mov 16*0($np),%rax
+ mov 8*0($np),%rax
adc \$0,%rdx
mov %rdx,$A[1]
@@ -601,7 +667,7 @@ $code.=<<___;
mulq $m0 # ap[j]*bp[0]
add %rax,$A[1]
- mov 16*1($np),%rax
+ mov 8*1($np),%rax
adc \$0,%rdx
mov %rdx,$A[0]
@@ -610,7 +676,7 @@ $code.=<<___;
mov 16($ap,$j),%rax
adc \$0,%rdx
add $A[1],$N[1] # np[j]*m1+ap[j]*bp[0]
- lea 16*4($np),$np
+ lea 8*4($np),$np
adc \$0,%rdx
mov $N[1],($tp) # tp[j-1]
mov %rdx,$N[0]
@@ -620,7 +686,7 @@ $code.=<<___;
mulq $m0 # ap[j]*bp[0]
add %rax,$A[0]
- mov -16*2($np),%rax
+ mov -8*2($np),%rax
lea 32($tp),$tp
adc \$0,%rdx
mov %rdx,$A[1]
@@ -636,7 +702,7 @@ $code.=<<___;
mulq $m0 # ap[j]*bp[0]
add %rax,$A[1]
- mov -16*1($np),%rax
+ mov -8*1($np),%rax
adc \$0,%rdx
mov %rdx,$A[0]
@@ -649,8 +715,7 @@ $code.=<<___;
mov $N[1],-16($tp) # tp[j-1]
mov %rdx,$N[0]
- movq %xmm0,$m0 # bp[1]
- lea ($np,$num,2),$np # rewind $np
+ lea ($np,$num),$np # rewind $np
xor $N[1],$N[1]
add $A[0],$N[0]
@@ -661,6 +726,33 @@ $code.=<<___;
.align 32
.Louter4x:
+ lea 16+128($tp),%rdx # where 256-byte mask is (+size optimization)
+ pxor %xmm4,%xmm4
+ pxor %xmm5,%xmm5
+___
+for($i=0;$i<$STRIDE/16;$i+=4) {
+$code.=<<___;
+ movdqa `16*($i+0)-128`($bp),%xmm0
+ movdqa `16*($i+1)-128`($bp),%xmm1
+ movdqa `16*($i+2)-128`($bp),%xmm2
+ movdqa `16*($i+3)-128`($bp),%xmm3
+ pand `16*($i+0)-128`(%rdx),%xmm0
+ pand `16*($i+1)-128`(%rdx),%xmm1
+ por %xmm0,%xmm4
+ pand `16*($i+2)-128`(%rdx),%xmm2
+ por %xmm1,%xmm5
+ pand `16*($i+3)-128`(%rdx),%xmm3
+ por %xmm2,%xmm4
+ por %xmm3,%xmm5
+___
+}
+$code.=<<___;
+ por %xmm5,%xmm4
+ pshufd \$0x4e,%xmm4,%xmm0
+ por %xmm4,%xmm0
+ lea $STRIDE($bp),$bp
+ movq %xmm0,$m0 # m0=bp[i]
+
mov ($tp,$num),$A[0]
mov $n0,$m1
mulq $m0 # ap[0]*bp[i]
@@ -668,25 +760,11 @@ $code.=<<___;
mov ($np),%rax
adc \$0,%rdx
- movq `0*$STRIDE/4-96`($bp),%xmm0
- movq `1*$STRIDE/4-96`($bp),%xmm1
- pand %xmm4,%xmm0
- movq `2*$STRIDE/4-96`($bp),%xmm2
- pand %xmm5,%xmm1
- movq `3*$STRIDE/4-96`($bp),%xmm3
-
imulq $A[0],$m1 # tp[0]*n0
- .byte 0x67
mov %rdx,$A[1]
mov $N[1],($tp) # store upmost overflow bit
- pand %xmm6,%xmm2
- por %xmm1,%xmm0
- pand %xmm7,%xmm3
- por %xmm2,%xmm0
lea ($tp,$num),$tp # rewind $tp
- lea $STRIDE($bp),$bp
- por %xmm3,%xmm0
mulq $m1 # np[0]*m1
add %rax,$A[0] # "$N[0]", discarded
@@ -696,7 +774,7 @@ $code.=<<___;
mulq $m0 # ap[j]*bp[i]
add %rax,$A[1]
- mov 16*1($np),%rax # interleaved with 0, therefore 16*n
+ mov 8*1($np),%rax
adc \$0,%rdx
add 8($tp),$A[1] # +tp[1]
adc \$0,%rdx
@@ -708,7 +786,7 @@ $code.=<<___;
adc \$0,%rdx
add $A[1],$N[1] # np[j]*m1+ap[j]*bp[i]+tp[j]
lea 4*8($num),$j # j=4
- lea 16*4($np),$np
+ lea 8*4($np),$np
adc \$0,%rdx
mov %rdx,$N[0]
jmp .Linner4x
@@ -717,7 +795,7 @@ $code.=<<___;
.Linner4x:
mulq $m0 # ap[j]*bp[i]
add %rax,$A[0]
- mov -16*2($np),%rax
+ mov -8*2($np),%rax
adc \$0,%rdx
add 16($tp),$A[0] # ap[j]*bp[i]+tp[j]
lea 32($tp),$tp
@@ -735,7 +813,7 @@ $code.=<<___;
mulq $m0 # ap[j]*bp[i]
add %rax,$A[1]
- mov -16*1($np),%rax
+ mov -8*1($np),%rax
adc \$0,%rdx
add -8($tp),$A[1]
adc \$0,%rdx
@@ -752,7 +830,7 @@ $code.=<<___;
mulq $m0 # ap[j]*bp[i]
add %rax,$A[0]
- mov 16*0($np),%rax
+ mov 8*0($np),%rax
adc \$0,%rdx
add ($tp),$A[0] # ap[j]*bp[i]+tp[j]
adc \$0,%rdx
@@ -769,7 +847,7 @@ $code.=<<___;
mulq $m0 # ap[j]*bp[i]
add %rax,$A[1]
- mov 16*1($np),%rax
+ mov 8*1($np),%rax
adc \$0,%rdx
add 8($tp),$A[1]
adc \$0,%rdx
@@ -780,7 +858,7 @@ $code.=<<___;
mov 16($ap,$j),%rax
adc \$0,%rdx
add $A[1],$N[1]
- lea 16*4($np),$np
+ lea 8*4($np),$np
adc \$0,%rdx
mov $N[0],-8($tp) # tp[j-1]
mov %rdx,$N[0]
@@ -790,7 +868,7 @@ $code.=<<___;
mulq $m0 # ap[j]*bp[i]
add %rax,$A[0]
- mov -16*2($np),%rax
+ mov -8*2($np),%rax
adc \$0,%rdx
add 16($tp),$A[0] # ap[j]*bp[i]+tp[j]
lea 32($tp),$tp
@@ -809,7 +887,7 @@ $code.=<<___;
mulq $m0 # ap[j]*bp[i]
add %rax,$A[1]
mov $m1,%rax
- mov -16*1($np),$m1
+ mov -8*1($np),$m1
adc \$0,%rdx
add -8($tp),$A[1]
adc \$0,%rdx
@@ -824,9 +902,8 @@ $code.=<<___;
mov $N[0],-24($tp) # tp[j-1]
mov %rdx,$N[0]
- movq %xmm0,$m0 # bp[i+1]
mov $N[1],-16($tp) # tp[j-1]
- lea ($np,$num,2),$np # rewind $np
+ lea ($np,$num),$np # rewind $np
xor $N[1],$N[1]
add $A[0],$N[0]
@@ -840,16 +917,23 @@ $code.=<<___;
___
if (1) {
$code.=<<___;
+ xor %rax,%rax
sub $N[0],$m1 # compare top-most words
adc $j,$j # $j is zero
or $j,$N[1]
- xor \$1,$N[1]
+ sub $N[1],%rax # %rax=-$N[1]
lea ($tp,$num),%rbx # tptr in .sqr4x_sub
- lea ($np,$N[1],8),%rbp # nptr in .sqr4x_sub
+ mov ($np),%r12
+ lea ($np),%rbp # nptr in .sqr4x_sub
mov %r9,%rcx
- sar \$3+2,%rcx # cf=0
+ sar \$3+2,%rcx
mov 56+8(%rsp),%rdi # rptr in .sqr4x_sub
- jmp .Lsqr4x_sub
+ dec %r12 # so that after 'not' we get -n[0]
+ xor %r10,%r10
+ mov 8*1(%rbp),%r13
+ mov 8*2(%rbp),%r14
+ mov 8*3(%rbp),%r15
+ jmp .Lsqr4x_sub_entry
___
} else {
my @ri=("%rax",$bp,$m0,$m1);
@@ -916,8 +1000,8 @@ bn_power5:
___
$code.=<<___ if ($addx);
mov OPENSSL_ia32cap_P+8(%rip),%r11d
- and \$0x80100,%r11d
- cmp \$0x80100,%r11d
+ and \$0x80108,%r11d
+ cmp \$0x80108,%r11d # check for AD*X+BMI2+BMI1
je .Lpowerx5_enter
___
$code.=<<___;
@@ -928,38 +1012,32 @@ $code.=<<___;
push %r13
push %r14
push %r15
-___
-$code.=<<___ if ($win64);
- lea -0x28(%rsp),%rsp
- movaps %xmm6,(%rsp)
- movaps %xmm7,0x10(%rsp)
-___
-$code.=<<___;
- mov ${num}d,%r10d
+
shl \$3,${num}d # convert $num to bytes
- shl \$3+2,%r10d # 4*$num
+ lea ($num,$num,2),%r10d # 3*$num
neg $num
mov ($n0),$n0 # *n0
##############################################################
- # ensure that stack frame doesn't alias with $aptr+4*$num
- # modulo 4096, which covers ret[num], am[num] and n[2*num]
- # (see bn_exp.c). this is done to allow memory disambiguation
- # logic do its magic.
+ # Ensure that stack frame doesn't alias with $rptr+3*$num
+ # modulo 4096, which covers ret[num], am[num] and n[num]
+ # (see bn_exp.c). This is done to allow memory disambiguation
+ # logic do its magic. [Extra 256 bytes is for power mask
+ # calculated from 7th argument, the index.]
#
- lea -64(%rsp,$num,2),%r11
- sub $aptr,%r11
+ lea -320(%rsp,$num,2),%r11
+ sub $rptr,%r11
and \$4095,%r11
cmp %r11,%r10
jb .Lpwr_sp_alt
sub %r11,%rsp # align with $aptr
- lea -64(%rsp,$num,2),%rsp # alloca(frame+2*$num)
+ lea -320(%rsp,$num,2),%rsp # alloca(frame+2*num*8+256)
jmp .Lpwr_sp_done
.align 32
.Lpwr_sp_alt:
- lea 4096-64(,$num,2),%r10 # 4096-frame-2*$num
- lea -64(%rsp,$num,2),%rsp # alloca(frame+2*$num)
+ lea 4096-320(,$num,2),%r10
+ lea -320(%rsp,$num,2),%rsp # alloca(frame+2*num*8+256)
sub %r10,%r11
mov \$0,%r10
cmovc %r10,%r11
@@ -981,16 +1059,21 @@ $code.=<<___;
mov $n0, 32(%rsp)
mov %rax, 40(%rsp) # save original %rsp
.Lpower5_body:
- movq $rptr,%xmm1 # save $rptr
+ movq $rptr,%xmm1 # save $rptr, used in sqr8x
movq $nptr,%xmm2 # save $nptr
- movq %r10, %xmm3 # -$num
+ movq %r10, %xmm3 # -$num, used in sqr8x
movq $bptr,%xmm4
call __bn_sqr8x_internal
+ call __bn_post4x_internal
call __bn_sqr8x_internal
+ call __bn_post4x_internal
call __bn_sqr8x_internal
+ call __bn_post4x_internal
call __bn_sqr8x_internal
+ call __bn_post4x_internal
call __bn_sqr8x_internal
+ call __bn_post4x_internal
movq %xmm2,$nptr
movq %xmm4,$bptr
@@ -1551,9 +1634,9 @@ my ($nptr,$tptr,$carry,$m0)=("%rbp","%rdi","%rsi","%rbx");
$code.=<<___;
movq %xmm2,$nptr
-sqr8x_reduction:
+__bn_sqr8x_reduction:
xor %rax,%rax
- lea ($nptr,$num,2),%rcx # end of n[]
+ lea ($nptr,$num),%rcx # end of n[]
lea 48+8(%rsp,$num,2),%rdx # end of t[] buffer
mov %rcx,0+8(%rsp)
lea 48+8(%rsp,$num),$tptr # end of initial t[] window
@@ -1579,21 +1662,21 @@ sqr8x_reduction:
.byte 0x67
mov $m0,%r8
imulq 32+8(%rsp),$m0 # n0*a[0]
- mov 16*0($nptr),%rax # n[0]
+ mov 8*0($nptr),%rax # n[0]
mov \$8,%ecx
jmp .L8x_reduce
.align 32
.L8x_reduce:
mulq $m0
- mov 16*1($nptr),%rax # n[1]
+ mov 8*1($nptr),%rax # n[1]
neg %r8
mov %rdx,%r8
adc \$0,%r8
mulq $m0
add %rax,%r9
- mov 16*2($nptr),%rax
+ mov 8*2($nptr),%rax
adc \$0,%rdx
add %r9,%r8
mov $m0,48-8+8(%rsp,%rcx,8) # put aside n0*a[i]
@@ -1602,7 +1685,7 @@ sqr8x_reduction:
mulq $m0
add %rax,%r10
- mov 16*3($nptr),%rax
+ mov 8*3($nptr),%rax
adc \$0,%rdx
add %r10,%r9
mov 32+8(%rsp),$carry # pull n0, borrow $carry
@@ -1611,7 +1694,7 @@ sqr8x_reduction:
mulq $m0
add %rax,%r11
- mov 16*4($nptr),%rax
+ mov 8*4($nptr),%rax
adc \$0,%rdx
imulq %r8,$carry # modulo-scheduled
add %r11,%r10
@@ -1620,7 +1703,7 @@ sqr8x_reduction:
mulq $m0
add %rax,%r12
- mov 16*5($nptr),%rax
+ mov 8*5($nptr),%rax
adc \$0,%rdx
add %r12,%r11
mov %rdx,%r12
@@ -1628,7 +1711,7 @@ sqr8x_reduction:
mulq $m0
add %rax,%r13
- mov 16*6($nptr),%rax
+ mov 8*6($nptr),%rax
adc \$0,%rdx
add %r13,%r12
mov %rdx,%r13
@@ -1636,7 +1719,7 @@ sqr8x_reduction:
mulq $m0
add %rax,%r14
- mov 16*7($nptr),%rax
+ mov 8*7($nptr),%rax
adc \$0,%rdx
add %r14,%r13
mov %rdx,%r14
@@ -1645,7 +1728,7 @@ sqr8x_reduction:
mulq $m0
mov $carry,$m0 # n0*a[i]
add %rax,%r15
- mov 16*0($nptr),%rax # n[0]
+ mov 8*0($nptr),%rax # n[0]
adc \$0,%rdx
add %r15,%r14
mov %rdx,%r15
@@ -1654,7 +1737,7 @@ sqr8x_reduction:
dec %ecx
jnz .L8x_reduce
- lea 16*8($nptr),$nptr
+ lea 8*8($nptr),$nptr
xor %rax,%rax
mov 8+8(%rsp),%rdx # pull end of t[]
cmp 0+8(%rsp),$nptr # end of n[]?
@@ -1673,21 +1756,21 @@ sqr8x_reduction:
mov 48+56+8(%rsp),$m0 # pull n0*a[0]
mov \$8,%ecx
- mov 16*0($nptr),%rax
+ mov 8*0($nptr),%rax
jmp .L8x_tail
.align 32
.L8x_tail:
mulq $m0
add %rax,%r8
- mov 16*1($nptr),%rax
+ mov 8*1($nptr),%rax
mov %r8,($tptr) # save result
mov %rdx,%r8
adc \$0,%r8
mulq $m0
add %rax,%r9
- mov 16*2($nptr),%rax
+ mov 8*2($nptr),%rax
adc \$0,%rdx
add %r9,%r8
lea 8($tptr),$tptr # $tptr++
@@ -1696,7 +1779,7 @@ sqr8x_reduction:
mulq $m0
add %rax,%r10
- mov 16*3($nptr),%rax
+ mov 8*3($nptr),%rax
adc \$0,%rdx
add %r10,%r9
mov %rdx,%r10
@@ -1704,7 +1787,7 @@ sqr8x_reduction:
mulq $m0
add %rax,%r11
- mov 16*4($nptr),%rax
+ mov 8*4($nptr),%rax
adc \$0,%rdx
add %r11,%r10
mov %rdx,%r11
@@ -1712,7 +1795,7 @@ sqr8x_reduction:
mulq $m0
add %rax,%r12
- mov 16*5($nptr),%rax
+ mov 8*5($nptr),%rax
adc \$0,%rdx
add %r12,%r11
mov %rdx,%r12
@@ -1720,7 +1803,7 @@ sqr8x_reduction:
mulq $m0
add %rax,%r13
- mov 16*6($nptr),%rax
+ mov 8*6($nptr),%rax
adc \$0,%rdx
add %r13,%r12
mov %rdx,%r13
@@ -1728,7 +1811,7 @@ sqr8x_reduction:
mulq $m0
add %rax,%r14
- mov 16*7($nptr),%rax
+ mov 8*7($nptr),%rax
adc \$0,%rdx
add %r14,%r13
mov %rdx,%r14
@@ -1739,14 +1822,14 @@ sqr8x_reduction:
add %rax,%r15
adc \$0,%rdx
add %r15,%r14
- mov 16*0($nptr),%rax # pull n[0]
+ mov 8*0($nptr),%rax # pull n[0]
mov %rdx,%r15
adc \$0,%r15
dec %ecx
jnz .L8x_tail
- lea 16*8($nptr),$nptr
+ lea 8*8($nptr),$nptr
mov 8+8(%rsp),%rdx # pull end of t[]
cmp 0+8(%rsp),$nptr # end of n[]?
jae .L8x_tail_done # break out of loop
@@ -1792,7 +1875,7 @@ sqr8x_reduction:
adc 8*6($tptr),%r14
adc 8*7($tptr),%r15
adc \$0,%rax # top-most carry
- mov -16($nptr),%rcx # np[num-1]
+ mov -8($nptr),%rcx # np[num-1]
xor $carry,$carry
movq %xmm2,$nptr # restore $nptr
@@ -1810,6 +1893,8 @@ sqr8x_reduction:
cmp %rdx,$tptr # end of t[]?
jb .L8x_reduction_loop
+ ret
+.size bn_sqr8x_internal,.-bn_sqr8x_internal
___
}
##############################################################
@@ -1818,48 +1903,62 @@ ___
{
my ($tptr,$nptr)=("%rbx","%rbp");
$code.=<<___;
- #xor %rsi,%rsi # %rsi was $carry above
- sub %r15,%rcx # compare top-most words
+.type __bn_post4x_internal,\@abi-omnipotent
+.align 32
+__bn_post4x_internal:
+ mov 8*0($nptr),%r12
lea (%rdi,$num),$tptr # %rdi was $tptr above
- adc %rsi,%rsi
mov $num,%rcx
- or %rsi,%rax
movq %xmm1,$rptr # restore $rptr
- xor \$1,%rax
+ neg %rax
movq %xmm1,$aptr # prepare for back-to-back call
- lea ($nptr,%rax,8),$nptr
- sar \$3+2,%rcx # cf=0
- jmp .Lsqr4x_sub
+ sar \$3+2,%rcx
+ dec %r12 # so that after 'not' we get -n[0]
+ xor %r10,%r10
+ mov 8*1($nptr),%r13
+ mov 8*2($nptr),%r14
+ mov 8*3($nptr),%r15
+ jmp .Lsqr4x_sub_entry
-.align 32
+.align 16
.Lsqr4x_sub:
- .byte 0x66
- mov 8*0($tptr),%r12
- mov 8*1($tptr),%r13
- sbb 16*0($nptr),%r12
- mov 8*2($tptr),%r14
- sbb 16*1($nptr),%r13
- mov 8*3($tptr),%r15
- lea 8*4($tptr),$tptr
- sbb 16*2($nptr),%r14
+ mov 8*0($nptr),%r12
+ mov 8*1($nptr),%r13
+ mov 8*2($nptr),%r14
+ mov 8*3($nptr),%r15
+.Lsqr4x_sub_entry:
+ lea 8*4($nptr),$nptr
+ not %r12
+ not %r13
+ not %r14
+ not %r15
+ and %rax,%r12
+ and %rax,%r13
+ and %rax,%r14
+ and %rax,%r15
+
+ neg %r10 # mov %r10,%cf
+ adc 8*0($tptr),%r12
+ adc 8*1($tptr),%r13
+ adc 8*2($tptr),%r14
+ adc 8*3($tptr),%r15
mov %r12,8*0($rptr)
- sbb 16*3($nptr),%r15
- lea 16*4($nptr),$nptr
+ lea 8*4($tptr),$tptr
mov %r13,8*1($rptr)
+ sbb %r10,%r10 # mov %cf,%r10
mov %r14,8*2($rptr)
mov %r15,8*3($rptr)
lea 8*4($rptr),$rptr
inc %rcx # pass %cf
jnz .Lsqr4x_sub
-___
-}
-$code.=<<___;
+
mov $num,%r10 # prepare for back-to-back call
neg $num # restore $num
ret
-.size bn_sqr8x_internal,.-bn_sqr8x_internal
+.size __bn_post4x_internal,.-__bn_post4x_internal
___
+}
{
$code.=<<___;
.globl bn_from_montgomery
@@ -1883,39 +1982,32 @@ bn_from_mont8x:
push %r13
push %r14
push %r15
-___
-$code.=<<___ if ($win64);
- lea -0x28(%rsp),%rsp
- movaps %xmm6,(%rsp)
- movaps %xmm7,0x10(%rsp)
-___
-$code.=<<___;
- .byte 0x67
- mov ${num}d,%r10d
+
shl \$3,${num}d # convert $num to bytes
- shl \$3+2,%r10d # 4*$num
+ lea ($num,$num,2),%r10 # 3*$num in bytes
neg $num
mov ($n0),$n0 # *n0
##############################################################
- # ensure that stack frame doesn't alias with $aptr+4*$num
- # modulo 4096, which covers ret[num], am[num] and n[2*num]
- # (see bn_exp.c). this is done to allow memory disambiguation
- # logic do its magic.
+ # Ensure that stack frame doesn't alias with $rptr+3*$num
+ # modulo 4096, which covers ret[num], am[num] and n[num]
+ # (see bn_exp.c). The stack is allocated to aligned with
+ # bn_power5's frame, and as bn_from_montgomery happens to be
+ # last operation, we use the opportunity to cleanse it.
#
- lea -64(%rsp,$num,2),%r11
- sub $aptr,%r11
+ lea -320(%rsp,$num,2),%r11
+ sub $rptr,%r11
and \$4095,%r11
cmp %r11,%r10
jb .Lfrom_sp_alt
sub %r11,%rsp # align with $aptr
- lea -64(%rsp,$num,2),%rsp # alloca(frame+2*$num)
+ lea -320(%rsp,$num,2),%rsp # alloca(frame+2*$num*8+256)
jmp .Lfrom_sp_done
.align 32
.Lfrom_sp_alt:
- lea 4096-64(,$num,2),%r10 # 4096-frame-2*$num
- lea -64(%rsp,$num,2),%rsp # alloca(frame+2*$num)
+ lea 4096-320(,$num,2),%r10
+ lea -320(%rsp,$num,2),%rsp # alloca(frame+2*$num*8+256)
sub %r10,%r11
mov \$0,%r10
cmovc %r10,%r11
@@ -1969,12 +2061,13 @@ $code.=<<___;
___
$code.=<<___ if ($addx);
mov OPENSSL_ia32cap_P+8(%rip),%r11d
- and \$0x80100,%r11d
- cmp \$0x80100,%r11d
+ and \$0x80108,%r11d
+ cmp \$0x80108,%r11d # check for AD*X+BMI2+BMI1
jne .Lfrom_mont_nox
lea (%rax,$num),$rptr
- call sqrx8x_reduction
+ call __bn_sqrx8x_reduction
+ call __bn_postx4x_internal
pxor %xmm0,%xmm0
lea 48(%rsp),%rax
@@ -1985,7 +2078,8 @@ $code.=<<___ if ($addx);
.Lfrom_mont_nox:
___
$code.=<<___;
- call sqr8x_reduction
+ call __bn_sqr8x_reduction
+ call __bn_post4x_internal
pxor %xmm0,%xmm0
lea 48(%rsp),%rax
@@ -2025,7 +2119,6 @@ $code.=<<___;
.align 32
bn_mulx4x_mont_gather5:
.Lmulx4x_enter:
- .byte 0x67
mov %rsp,%rax
push %rbx
push %rbp
@@ -2033,40 +2126,33 @@ bn_mulx4x_mont_gather5:
push %r13
push %r14
push %r15
-___
-$code.=<<___ if ($win64);
- lea -0x28(%rsp),%rsp
- movaps %xmm6,(%rsp)
- movaps %xmm7,0x10(%rsp)
-___
-$code.=<<___;
- .byte 0x67
- mov ${num}d,%r10d
+
shl \$3,${num}d # convert $num to bytes
- shl \$3+2,%r10d # 4*$num
+ lea ($num,$num,2),%r10 # 3*$num in bytes
neg $num # -$num
mov ($n0),$n0 # *n0
##############################################################
- # ensure that stack frame doesn't alias with $aptr+4*$num
- # modulo 4096, which covers a[num], ret[num] and n[2*num]
- # (see bn_exp.c). this is done to allow memory disambiguation
- # logic do its magic. [excessive frame is allocated in order
- # to allow bn_from_mont8x to clear it.]
+ # Ensure that stack frame doesn't alias with $rptr+3*$num
+ # modulo 4096, which covers ret[num], am[num] and n[num]
+ # (see bn_exp.c). This is done to allow memory disambiguation
+ # logic do its magic. [Extra [num] is allocated in order
+ # to align with bn_power5's frame, which is cleansed after
+ # completing exponentiation. Extra 256 bytes is for power mask
+ # calculated from 7th argument, the index.]
#
- lea -64(%rsp,$num,2),%r11
- sub $ap,%r11
+ lea -320(%rsp,$num,2),%r11
+ sub $rp,%r11
and \$4095,%r11
cmp %r11,%r10
jb .Lmulx4xsp_alt
sub %r11,%rsp # align with $aptr
- lea -64(%rsp,$num,2),%rsp # alloca(frame+$num)
+ lea -320(%rsp,$num,2),%rsp # alloca(frame+2*$num*8+256)
jmp .Lmulx4xsp_done
-.align 32
.Lmulx4xsp_alt:
- lea 4096-64(,$num,2),%r10 # 4096-frame-$num
- lea -64(%rsp,$num,2),%rsp # alloca(frame+$num)
+ lea 4096-320(,$num,2),%r10
+ lea -320(%rsp,$num,2),%rsp # alloca(frame+2*$num*8+256)
sub %r10,%r11
mov \$0,%r10
cmovc %r10,%r11
@@ -2092,12 +2178,7 @@ $code.=<<___;
mov 40(%rsp),%rsi # restore %rsp
mov \$1,%rax
-___
-$code.=<<___ if ($win64);
- movaps -88(%rsi),%xmm6
- movaps -72(%rsi),%xmm7
-___
-$code.=<<___;
+
mov -48(%rsi),%r15
mov -40(%rsi),%r14
mov -32(%rsi),%r13
@@ -2112,14 +2193,16 @@ $code.=<<___;
.type mulx4x_internal,\@abi-omnipotent
.align 32
mulx4x_internal:
- .byte 0x4c,0x89,0x8c,0x24,0x08,0x00,0x00,0x00 # mov $num,8(%rsp) # save -$num
- .byte 0x67
+ mov $num,8(%rsp) # save -$num (it was in bytes)
+ mov $num,%r10
neg $num # restore $num
shl \$5,$num
- lea 256($bp,$num),%r13
+ neg %r10 # restore $num
+ lea 128($bp,$num),%r13 # end of powers table (+size optimization)
shr \$5+5,$num
- mov `($win64?56:8)`(%rax),%r10d # load 7th argument
+ movd `($win64?56:8)`(%rax),%xmm5 # load 7th argument
sub \$1,$num
+ lea .Linc(%rip),%rax
mov %r13,16+8(%rsp) # end of b[num]
mov $num,24+8(%rsp) # inner counter
mov $rp, 56+8(%rsp) # save $rp
@@ -2130,52 +2213,92 @@ my $rptr=$bptr;
my $STRIDE=2**5*8; # 5 is "window size"
my $N=$STRIDE/4; # should match cache line size
$code.=<<___;
- mov %r10,%r11
- shr \$`log($N/8)/log(2)`,%r10
- and \$`$N/8-1`,%r11
- not %r10
- lea .Lmagic_masks(%rip),%rax
- and \$`2**5/($N/8)-1`,%r10 # 5 is "window size"
- lea 96($bp,%r11,8),$bptr # pointer within 1st cache line
- movq 0(%rax,%r10,8),%xmm4 # set of masks denoting which
- movq 8(%rax,%r10,8),%xmm5 # cache line contains element
- add \$7,%r11
- movq 16(%rax,%r10,8),%xmm6 # denoted by 7th argument
- movq 24(%rax,%r10,8),%xmm7
- and \$7,%r11
-
- movq `0*$STRIDE/4-96`($bptr),%xmm0
- lea $STRIDE($bptr),$tptr # borrow $tptr
- movq `1*$STRIDE/4-96`($bptr),%xmm1
- pand %xmm4,%xmm0
- movq `2*$STRIDE/4-96`($bptr),%xmm2
- pand %xmm5,%xmm1
- movq `3*$STRIDE/4-96`($bptr),%xmm3
- pand %xmm6,%xmm2
- por %xmm1,%xmm0
- movq `0*$STRIDE/4-96`($tptr),%xmm1
- pand %xmm7,%xmm3
- por %xmm2,%xmm0
- movq `1*$STRIDE/4-96`($tptr),%xmm2
- por %xmm3,%xmm0
- .byte 0x67,0x67
- pand %xmm4,%xmm1
- movq `2*$STRIDE/4-96`($tptr),%xmm3
+ movdqa 0(%rax),%xmm0 # 00000001000000010000000000000000
+ movdqa 16(%rax),%xmm1 # 00000002000000020000000200000002
+ lea 88-112(%rsp,%r10),%r10 # place the mask after tp[num+1] (+ICache optimizaton)
+ lea 128($bp),$bptr # size optimization
+ pshufd \$0,%xmm5,%xmm5 # broadcast index
+ movdqa %xmm1,%xmm4
+ .byte 0x67
+ movdqa %xmm1,%xmm2
+___
+########################################################################
+# calculate mask by comparing 0..31 to index and save result to stack
+#
+$code.=<<___;
+ .byte 0x67
+ paddd %xmm0,%xmm1
+ pcmpeqd %xmm5,%xmm0 # compare to 1,0
+ movdqa %xmm4,%xmm3
+___
+for($i=0;$i<$STRIDE/16-4;$i+=4) {
+$code.=<<___;
+ paddd %xmm1,%xmm2
+ pcmpeqd %xmm5,%xmm1 # compare to 3,2
+ movdqa %xmm0,`16*($i+0)+112`(%r10)
+ movdqa %xmm4,%xmm0
+
+ paddd %xmm2,%xmm3
+ pcmpeqd %xmm5,%xmm2 # compare to 5,4
+ movdqa %xmm1,`16*($i+1)+112`(%r10)
+ movdqa %xmm4,%xmm1
+
+ paddd %xmm3,%xmm0
+ pcmpeqd %xmm5,%xmm3 # compare to 7,6
+ movdqa %xmm2,`16*($i+2)+112`(%r10)
+ movdqa %xmm4,%xmm2
+
+ paddd %xmm0,%xmm1
+ pcmpeqd %xmm5,%xmm0
+ movdqa %xmm3,`16*($i+3)+112`(%r10)
+ movdqa %xmm4,%xmm3
+___
+}
+$code.=<<___; # last iteration can be optimized
+ .byte 0x67
+ paddd %xmm1,%xmm2
+ pcmpeqd %xmm5,%xmm1
+ movdqa %xmm0,`16*($i+0)+112`(%r10)
+
+ paddd %xmm2,%xmm3
+ pcmpeqd %xmm5,%xmm2
+ movdqa %xmm1,`16*($i+1)+112`(%r10)
+
+ pcmpeqd %xmm5,%xmm3
+ movdqa %xmm2,`16*($i+2)+112`(%r10)
+
+ pand `16*($i+0)-128`($bptr),%xmm0 # while it's still in register
+ pand `16*($i+1)-128`($bptr),%xmm1
+ pand `16*($i+2)-128`($bptr),%xmm2
+ movdqa %xmm3,`16*($i+3)+112`(%r10)
+ pand `16*($i+3)-128`($bptr),%xmm3
+ por %xmm2,%xmm0
+ por %xmm3,%xmm1
+___
+for($i=0;$i<$STRIDE/16-4;$i+=4) {
+$code.=<<___;
+ movdqa `16*($i+0)-128`($bptr),%xmm4
+ movdqa `16*($i+1)-128`($bptr),%xmm5
+ movdqa `16*($i+2)-128`($bptr),%xmm2
+ pand `16*($i+0)+112`(%r10),%xmm4
+ movdqa `16*($i+3)-128`($bptr),%xmm3
+ pand `16*($i+1)+112`(%r10),%xmm5
+ por %xmm4,%xmm0
+ pand `16*($i+2)+112`(%r10),%xmm2
+ por %xmm5,%xmm1
+ pand `16*($i+3)+112`(%r10),%xmm3
+ por %xmm2,%xmm0
+ por %xmm3,%xmm1
+___
+}
+$code.=<<___;
+ pxor %xmm1,%xmm0
+ pshufd \$0x4e,%xmm0,%xmm1
+ por %xmm1,%xmm0
+ lea $STRIDE($bptr),$bptr
movq %xmm0,%rdx # bp[0]
- movq `3*$STRIDE/4-96`($tptr),%xmm0
- lea 2*$STRIDE($bptr),$bptr # next &b[i]
- pand %xmm5,%xmm2
- .byte 0x67,0x67
- pand %xmm6,%xmm3
- ##############################################################
- # $tptr is chosen so that writing to top-most element of the
- # vector occurs just "above" references to powers table,
- # "above" modulo cache-line size, which effectively precludes
- # possibility of memory disambiguation logic failure when
- # accessing the table.
- #
- lea 64+8*4+8(%rsp,%r11,8),$tptr
+ lea 64+8*4+8(%rsp),$tptr
mov %rdx,$bi
mulx 0*8($aptr),$mi,%rax # a[0]*b[0]
@@ -2191,37 +2314,31 @@ $code.=<<___;
xor $zero,$zero # cf=0, of=0
mov $mi,%rdx
- por %xmm2,%xmm1
- pand %xmm7,%xmm0
- por %xmm3,%xmm1
mov $bptr,8+8(%rsp) # off-load &b[i]
- por %xmm1,%xmm0
- .byte 0x48,0x8d,0xb6,0x20,0x00,0x00,0x00 # lea 4*8($aptr),$aptr
+ lea 4*8($aptr),$aptr
adcx %rax,%r13
adcx $zero,%r14 # cf=0
- mulx 0*16($nptr),%rax,%r10
+ mulx 0*8($nptr),%rax,%r10
adcx %rax,%r15 # discarded
adox %r11,%r10
- mulx 1*16($nptr),%rax,%r11
+ mulx 1*8($nptr),%rax,%r11
adcx %rax,%r10
adox %r12,%r11
- mulx 2*16($nptr),%rax,%r12
+ mulx 2*8($nptr),%rax,%r12
mov 24+8(%rsp),$bptr # counter value
- .byte 0x66
mov %r10,-8*4($tptr)
adcx %rax,%r11
adox %r13,%r12
- mulx 3*16($nptr),%rax,%r15
- .byte 0x67,0x67
+ mulx 3*8($nptr),%rax,%r15
mov $bi,%rdx
mov %r11,-8*3($tptr)
adcx %rax,%r12
adox $zero,%r15 # of=0
- .byte 0x48,0x8d,0x89,0x40,0x00,0x00,0x00 # lea 4*16($nptr),$nptr
+ lea 4*8($nptr),$nptr
mov %r12,-8*2($tptr)
- #jmp .Lmulx4x_1st
+ jmp .Lmulx4x_1st
.align 32
.Lmulx4x_1st:
@@ -2241,30 +2358,29 @@ $code.=<<___;
lea 4*8($tptr),$tptr
adox %r15,%r10
- mulx 0*16($nptr),%rax,%r15
+ mulx 0*8($nptr),%rax,%r15
adcx %rax,%r10
adox %r15,%r11
- mulx 1*16($nptr),%rax,%r15
+ mulx 1*8($nptr),%rax,%r15
adcx %rax,%r11
adox %r15,%r12
- mulx 2*16($nptr),%rax,%r15
+ mulx 2*8($nptr),%rax,%r15
mov %r10,-5*8($tptr)
adcx %rax,%r12
mov %r11,-4*8($tptr)
adox %r15,%r13
- mulx 3*16($nptr),%rax,%r15
+ mulx 3*8($nptr),%rax,%r15
mov $bi,%rdx
mov %r12,-3*8($tptr)
adcx %rax,%r13
adox $zero,%r15
- lea 4*16($nptr),$nptr
+ lea 4*8($nptr),$nptr
mov %r13,-2*8($tptr)
dec $bptr # of=0, pass cf
jnz .Lmulx4x_1st
mov 8(%rsp),$num # load -num
- movq %xmm0,%rdx # bp[1]
adc $zero,%r15 # modulo-scheduled
lea ($aptr,$num),$aptr # rewind $aptr
add %r15,%r14
@@ -2275,6 +2391,34 @@ $code.=<<___;
.align 32
.Lmulx4x_outer:
+ lea 16-256($tptr),%r10 # where 256-byte mask is (+density control)
+ pxor %xmm4,%xmm4
+ .byte 0x67,0x67
+ pxor %xmm5,%xmm5
+___
+for($i=0;$i<$STRIDE/16;$i+=4) {
+$code.=<<___;
+ movdqa `16*($i+0)-128`($bptr),%xmm0
+ movdqa `16*($i+1)-128`($bptr),%xmm1
+ movdqa `16*($i+2)-128`($bptr),%xmm2
+ pand `16*($i+0)+256`(%r10),%xmm0
+ movdqa `16*($i+3)-128`($bptr),%xmm3
+ pand `16*($i+1)+256`(%r10),%xmm1
+ por %xmm0,%xmm4
+ pand `16*($i+2)+256`(%r10),%xmm2
+ por %xmm1,%xmm5
+ pand `16*($i+3)+256`(%r10),%xmm3
+ por %xmm2,%xmm4
+ por %xmm3,%xmm5
+___
+}
+$code.=<<___;
+ por %xmm5,%xmm4
+ pshufd \$0x4e,%xmm4,%xmm0
+ por %xmm4,%xmm0
+ lea $STRIDE($bptr),$bptr
+ movq %xmm0,%rdx # m0=bp[i]
+
mov $zero,($tptr) # save top-most carry
lea 4*8($tptr,$num),$tptr # rewind $tptr
mulx 0*8($aptr),$mi,%r11 # a[0]*b[i]
@@ -2289,54 +2433,37 @@ $code.=<<___;
mulx 3*8($aptr),%rdx,%r14
adox -2*8($tptr),%r12
adcx %rdx,%r13
- lea ($nptr,$num,2),$nptr # rewind $nptr
+ lea ($nptr,$num),$nptr # rewind $nptr
lea 4*8($aptr),$aptr
adox -1*8($tptr),%r13
adcx $zero,%r14
adox $zero,%r14
- .byte 0x67
mov $mi,%r15
imulq 32+8(%rsp),$mi # "t[0]"*n0
- movq `0*$STRIDE/4-96`($bptr),%xmm0
- .byte 0x67,0x67
mov $mi,%rdx
- movq `1*$STRIDE/4-96`($bptr),%xmm1
- .byte 0x67
- pand %xmm4,%xmm0
- movq `2*$STRIDE/4-96`($bptr),%xmm2
- .byte 0x67
- pand %xmm5,%xmm1
- movq `3*$STRIDE/4-96`($bptr),%xmm3
- add \$$STRIDE,$bptr # next &b[i]
- .byte 0x67
- pand %xmm6,%xmm2
- por %xmm1,%xmm0
- pand %xmm7,%xmm3
xor $zero,$zero # cf=0, of=0
mov $bptr,8+8(%rsp) # off-load &b[i]
- mulx 0*16($nptr),%rax,%r10
+ mulx 0*8($nptr),%rax,%r10
adcx %rax,%r15 # discarded
adox %r11,%r10
- mulx 1*16($nptr),%rax,%r11
+ mulx 1*8($nptr),%rax,%r11
adcx %rax,%r10
adox %r12,%r11
- mulx 2*16($nptr),%rax,%r12
+ mulx 2*8($nptr),%rax,%r12
adcx %rax,%r11
adox %r13,%r12
- mulx 3*16($nptr),%rax,%r15
+ mulx 3*8($nptr),%rax,%r15
mov $bi,%rdx
- por %xmm2,%xmm0
mov 24+8(%rsp),$bptr # counter value
mov %r10,-8*4($tptr)
- por %xmm3,%xmm0
adcx %rax,%r12
mov %r11,-8*3($tptr)
adox $zero,%r15 # of=0
mov %r12,-8*2($tptr)
- lea 4*16($nptr),$nptr
+ lea 4*8($nptr),$nptr
jmp .Lmulx4x_inner
.align 32
@@ -2361,20 +2488,20 @@ $code.=<<___;
adcx $zero,%r14 # cf=0
adox %r15,%r10
- mulx 0*16($nptr),%rax,%r15
+ mulx 0*8($nptr),%rax,%r15
adcx %rax,%r10
adox %r15,%r11
- mulx 1*16($nptr),%rax,%r15
+ mulx 1*8($nptr),%rax,%r15
adcx %rax,%r11
adox %r15,%r12
- mulx 2*16($nptr),%rax,%r15
+ mulx 2*8($nptr),%rax,%r15
mov %r10,-5*8($tptr)
adcx %rax,%r12
adox %r15,%r13
mov %r11,-4*8($tptr)
- mulx 3*16($nptr),%rax,%r15
+ mulx 3*8($nptr),%rax,%r15
mov $bi,%rdx
- lea 4*16($nptr),$nptr
+ lea 4*8($nptr),$nptr
mov %r12,-3*8($tptr)
adcx %rax,%r13
adox $zero,%r15
@@ -2384,7 +2511,6 @@ $code.=<<___;
jnz .Lmulx4x_inner
mov 0+8(%rsp),$num # load -num
- movq %xmm0,%rdx # bp[i+1]
adc $zero,%r15 # modulo-scheduled
sub 0*8($tptr),$bptr # pull top-most carry to %cf
mov 8+8(%rsp),$bptr # re-load &b[i]
@@ -2397,20 +2523,26 @@ $code.=<<___;
cmp %r10,$bptr
jb .Lmulx4x_outer
- mov -16($nptr),%r10
+ mov -8($nptr),%r10
+ mov $zero,%r8
+ mov ($nptr,$num),%r12
+ lea ($nptr,$num),%rbp # rewind $nptr
+ mov $num,%rcx
+ lea ($tptr,$num),%rdi # rewind $tptr
+ xor %eax,%eax
xor %r15,%r15
sub %r14,%r10 # compare top-most words
adc %r15,%r15
- or %r15,$zero
- xor \$1,$zero
- lea ($tptr,$num),%rdi # rewind $tptr
- lea ($nptr,$num,2),$nptr # rewind $nptr
- .byte 0x67,0x67
- sar \$3+2,$num # cf=0
- lea ($nptr,$zero,8),%rbp
+ or %r15,%r8
+ sar \$3+2,%rcx
+ sub %r8,%rax # %rax=-%r8
mov 56+8(%rsp),%rdx # restore rp
- mov $num,%rcx
- jmp .Lsqrx4x_sub # common post-condition
+ dec %r12 # so that after 'not' we get -n[0]
+ mov 8*1(%rbp),%r13
+ xor %r8,%r8
+ mov 8*2(%rbp),%r14
+ mov 8*3(%rbp),%r15
+ jmp .Lsqrx4x_sub_entry # common post-condition
.size mulx4x_internal,.-mulx4x_internal
___
} {
@@ -2434,7 +2566,6 @@ $code.=<<___;
.align 32
bn_powerx5:
.Lpowerx5_enter:
- .byte 0x67
mov %rsp,%rax
push %rbx
push %rbp
@@ -2442,39 +2573,32 @@ bn_powerx5:
push %r13
push %r14
push %r15
-___
-$code.=<<___ if ($win64);
- lea -0x28(%rsp),%rsp
- movaps %xmm6,(%rsp)
- movaps %xmm7,0x10(%rsp)
-___
-$code.=<<___;
- .byte 0x67
- mov ${num}d,%r10d
+
shl \$3,${num}d # convert $num to bytes
- shl \$3+2,%r10d # 4*$num
+ lea ($num,$num,2),%r10 # 3*$num in bytes
neg $num
mov ($n0),$n0 # *n0
##############################################################
- # ensure that stack frame doesn't alias with $aptr+4*$num
- # modulo 4096, which covers ret[num], am[num] and n[2*num]
- # (see bn_exp.c). this is done to allow memory disambiguation
- # logic do its magic.
+ # Ensure that stack frame doesn't alias with $rptr+3*$num
+ # modulo 4096, which covers ret[num], am[num] and n[num]
+ # (see bn_exp.c). This is done to allow memory disambiguation
+ # logic do its magic. [Extra 256 bytes is for power mask
+ # calculated from 7th argument, the index.]
#
- lea -64(%rsp,$num,2),%r11
- sub $aptr,%r11
+ lea -320(%rsp,$num,2),%r11
+ sub $rptr,%r11
and \$4095,%r11
cmp %r11,%r10
jb .Lpwrx_sp_alt
sub %r11,%rsp # align with $aptr
- lea -64(%rsp,$num,2),%rsp # alloca(frame+2*$num)
+ lea -320(%rsp,$num,2),%rsp # alloca(frame+2*$num*8+256)
jmp .Lpwrx_sp_done
.align 32
.Lpwrx_sp_alt:
- lea 4096-64(,$num,2),%r10 # 4096-frame-2*$num
- lea -64(%rsp,$num,2),%rsp # alloca(frame+2*$num)
+ lea 4096-320(,$num,2),%r10
+ lea -320(%rsp,$num,2),%rsp # alloca(frame+2*$num*8+256)
sub %r10,%r11
mov \$0,%r10
cmovc %r10,%r11
@@ -2505,10 +2629,15 @@ $code.=<<___;
.Lpowerx5_body:
call __bn_sqrx8x_internal
+ call __bn_postx4x_internal
call __bn_sqrx8x_internal
+ call __bn_postx4x_internal
call __bn_sqrx8x_internal
+ call __bn_postx4x_internal
call __bn_sqrx8x_internal
+ call __bn_postx4x_internal
call __bn_sqrx8x_internal
+ call __bn_postx4x_internal
mov %r10,$num # -num
mov $aptr,$rptr
@@ -2520,12 +2649,7 @@ $code.=<<___;
mov 40(%rsp),%rsi # restore %rsp
mov \$1,%rax
-___
-$code.=<<___ if ($win64);
- movaps -88(%rsi),%xmm6
- movaps -72(%rsi),%xmm7
-___
-$code.=<<___;
+
mov -48(%rsi),%r15
mov -40(%rsi),%r14
mov -32(%rsi),%r13
@@ -2959,11 +3083,11 @@ my ($nptr,$carry,$m0)=("%rbp","%rsi","%rdx");
$code.=<<___;
movq %xmm2,$nptr
-sqrx8x_reduction:
+__bn_sqrx8x_reduction:
xor %eax,%eax # initial top-most carry bit
mov 32+8(%rsp),%rbx # n0
mov 48+8(%rsp),%rdx # "%r8", 8*0($tptr)
- lea -128($nptr,$num,2),%rcx # end of n[]
+ lea -8*8($nptr,$num),%rcx # end of n[]
#lea 48+8(%rsp,$num,2),$tptr # end of t[] buffer
mov %rcx, 0+8(%rsp) # save end of n[]
mov $tptr,8+8(%rsp) # save end of t[]
@@ -2992,23 +3116,23 @@ sqrx8x_reduction:
.align 32
.Lsqrx8x_reduce:
mov %r8, %rbx
- mulx 16*0($nptr),%rax,%r8 # n[0]
+ mulx 8*0($nptr),%rax,%r8 # n[0]
adcx %rbx,%rax # discarded
adox %r9,%r8
- mulx 16*1($nptr),%rbx,%r9 # n[1]
+ mulx 8*1($nptr),%rbx,%r9 # n[1]
adcx %rbx,%r8
adox %r10,%r9
- mulx 16*2($nptr),%rbx,%r10
+ mulx 8*2($nptr),%rbx,%r10
adcx %rbx,%r9
adox %r11,%r10
- mulx 16*3($nptr),%rbx,%r11
+ mulx 8*3($nptr),%rbx,%r11
adcx %rbx,%r10
adox %r12,%r11
- .byte 0xc4,0x62,0xe3,0xf6,0xa5,0x40,0x00,0x00,0x00 # mulx 16*4($nptr),%rbx,%r12
+ .byte 0xc4,0x62,0xe3,0xf6,0xa5,0x20,0x00,0x00,0x00 # mulx 8*4($nptr),%rbx,%r12
mov %rdx,%rax
mov %r8,%rdx
adcx %rbx,%r11
@@ -3018,15 +3142,15 @@ sqrx8x_reduction:
mov %rax,%rdx
mov %rax,64+48+8(%rsp,%rcx,8) # put aside n0*a[i]
- mulx 16*5($nptr),%rax,%r13
+ mulx 8*5($nptr),%rax,%r13
adcx %rax,%r12
adox %r14,%r13
- mulx 16*6($nptr),%rax,%r14
+ mulx 8*6($nptr),%rax,%r14
adcx %rax,%r13
adox %r15,%r14
- mulx 16*7($nptr),%rax,%r15
+ mulx 8*7($nptr),%rax,%r15
mov %rbx,%rdx
adcx %rax,%r14
adox $carry,%r15 # $carry is 0
@@ -3042,7 +3166,7 @@ sqrx8x_reduction:
mov 48+8(%rsp),%rdx # pull n0*a[0]
add 8*0($tptr),%r8
- lea 16*8($nptr),$nptr
+ lea 8*8($nptr),$nptr
mov \$-8,%rcx
adcx 8*1($tptr),%r9
adcx 8*2($tptr),%r10
@@ -3061,35 +3185,35 @@ sqrx8x_reduction:
.align 32
.Lsqrx8x_tail:
mov %r8,%rbx
- mulx 16*0($nptr),%rax,%r8
+ mulx 8*0($nptr),%rax,%r8
adcx %rax,%rbx
adox %r9,%r8
- mulx 16*1($nptr),%rax,%r9
+ mulx 8*1($nptr),%rax,%r9
adcx %rax,%r8
adox %r10,%r9
- mulx 16*2($nptr),%rax,%r10
+ mulx 8*2($nptr),%rax,%r10
adcx %rax,%r9
adox %r11,%r10
- mulx 16*3($nptr),%rax,%r11
+ mulx 8*3($nptr),%rax,%r11
adcx %rax,%r10
adox %r12,%r11
- .byte 0xc4,0x62,0xfb,0xf6,0xa5,0x40,0x00,0x00,0x00 # mulx 16*4($nptr),%rax,%r12
+ .byte 0xc4,0x62,0xfb,0xf6,0xa5,0x20,0x00,0x00,0x00 # mulx 8*4($nptr),%rax,%r12
adcx %rax,%r11
adox %r13,%r12
- mulx 16*5($nptr),%rax,%r13
+ mulx 8*5($nptr),%rax,%r13
adcx %rax,%r12
adox %r14,%r13
- mulx 16*6($nptr),%rax,%r14
+ mulx 8*6($nptr),%rax,%r14
adcx %rax,%r13
adox %r15,%r14
- mulx 16*7($nptr),%rax,%r15
+ mulx 8*7($nptr),%rax,%r15
mov 72+48+8(%rsp,%rcx,8),%rdx # pull n0*a[i]
adcx %rax,%r14
adox $carry,%r15
@@ -3105,7 +3229,7 @@ sqrx8x_reduction:
sub 16+8(%rsp),$carry # mov 16(%rsp),%cf
mov 48+8(%rsp),%rdx # pull n0*a[0]
- lea 16*8($nptr),$nptr
+ lea 8*8($nptr),$nptr
adc 8*0($tptr),%r8
adc 8*1($tptr),%r9
adc 8*2($tptr),%r10
@@ -3141,7 +3265,7 @@ sqrx8x_reduction:
adc 8*0($tptr),%r8
movq %xmm3,%rcx
adc 8*1($tptr),%r9
- mov 16*7($nptr),$carry
+ mov 8*7($nptr),$carry
movq %xmm2,$nptr # restore $nptr
adc 8*2($tptr),%r10
adc 8*3($tptr),%r11
@@ -3167,6 +3291,8 @@ sqrx8x_reduction:
lea 8*8($tptr,%rcx),$tptr # start of current t[] window
cmp 8+8(%rsp),%r8 # end of t[]?
jb .Lsqrx8x_reduction_loop
+ ret
+.size bn_sqrx8x_internal,.-bn_sqrx8x_internal
___
}
##############################################################
@@ -3174,52 +3300,59 @@ ___
#
{
my ($rptr,$nptr)=("%rdx","%rbp");
-my @ri=map("%r$_",(10..13));
-my @ni=map("%r$_",(14..15));
$code.=<<___;
- xor %ebx,%ebx
- sub %r15,%rsi # compare top-most words
- adc %rbx,%rbx
+.align 32
+__bn_postx4x_internal:
+ mov 8*0($nptr),%r12
mov %rcx,%r10 # -$num
- or %rbx,%rax
mov %rcx,%r9 # -$num
- xor \$1,%rax
- sar \$3+2,%rcx # cf=0
+ neg %rax
+ sar \$3+2,%rcx
#lea 48+8(%rsp,%r9),$tptr
- lea ($nptr,%rax,8),$nptr
movq %xmm1,$rptr # restore $rptr
movq %xmm1,$aptr # prepare for back-to-back call
- jmp .Lsqrx4x_sub
+ dec %r12 # so that after 'not' we get -n[0]
+ mov 8*1($nptr),%r13
+ xor %r8,%r8
+ mov 8*2($nptr),%r14
+ mov 8*3($nptr),%r15
+ jmp .Lsqrx4x_sub_entry
-.align 32
+.align 16
.Lsqrx4x_sub:
- .byte 0x66
- mov 8*0($tptr),%r12
- mov 8*1($tptr),%r13
- sbb 16*0($nptr),%r12
- mov 8*2($tptr),%r14
- sbb 16*1($nptr),%r13
- mov 8*3($tptr),%r15
- lea 8*4($tptr),$tptr
- sbb 16*2($nptr),%r14
+ mov 8*0($nptr),%r12
+ mov 8*1($nptr),%r13
+ mov 8*2($nptr),%r14
+ mov 8*3($nptr),%r15
+.Lsqrx4x_sub_entry:
+ andn %rax,%r12,%r12
+ lea 8*4($nptr),$nptr
+ andn %rax,%r13,%r13
+ andn %rax,%r14,%r14
+ andn %rax,%r15,%r15
+
+ neg %r8 # mov %r8,%cf
+ adc 8*0($tptr),%r12
+ adc 8*1($tptr),%r13
+ adc 8*2($tptr),%r14
+ adc 8*3($tptr),%r15
mov %r12,8*0($rptr)
- sbb 16*3($nptr),%r15
- lea 16*4($nptr),$nptr
+ lea 8*4($tptr),$tptr
mov %r13,8*1($rptr)
+ sbb %r8,%r8 # mov %cf,%r8
mov %r14,8*2($rptr)
mov %r15,8*3($rptr)
lea 8*4($rptr),$rptr
inc %rcx
jnz .Lsqrx4x_sub
-___
-}
-$code.=<<___;
+
neg %r9 # restore $num
ret
-.size bn_sqrx8x_internal,.-bn_sqrx8x_internal
+.size __bn_postx4x_internal,.-__bn_postx4x_internal
___
+}
}}}
{
my ($inp,$num,$tbl,$idx)=$win64?("%rcx","%edx","%r8", "%r9d") : # Win64 order
@@ -3249,56 +3382,91 @@ bn_scatter5:
.globl bn_gather5
.type bn_gather5,\@abi-omnipotent
-.align 16
+.align 32
bn_gather5:
-___
-$code.=<<___ if ($win64);
-.LSEH_begin_bn_gather5:
+.LSEH_begin_bn_gather5: # Win64 thing, but harmless in other cases
# I can't trust assembler to use specific encoding:-(
- .byte 0x48,0x83,0xec,0x28 #sub \$0x28,%rsp
- .byte 0x0f,0x29,0x34,0x24 #movaps %xmm6,(%rsp)
- .byte 0x0f,0x29,0x7c,0x24,0x10 #movdqa %xmm7,0x10(%rsp)
+ .byte 0x4c,0x8d,0x14,0x24 #lea (%rsp),%r10
+ .byte 0x48,0x81,0xec,0x08,0x01,0x00,0x00 #sub $0x108,%rsp
+ lea .Linc(%rip),%rax
+ and \$-16,%rsp # shouldn't be formally required
+
+ movd $idx,%xmm5
+ movdqa 0(%rax),%xmm0 # 00000001000000010000000000000000
+ movdqa 16(%rax),%xmm1 # 00000002000000020000000200000002
+ lea 128($tbl),%r11 # size optimization
+ lea 128(%rsp),%rax # size optimization
+
+ pshufd \$0,%xmm5,%xmm5 # broadcast $idx
+ movdqa %xmm1,%xmm4
+ movdqa %xmm1,%xmm2
___
+########################################################################
+# calculate mask by comparing 0..31 to $idx and save result to stack
+#
+for($i=0;$i<$STRIDE/16;$i+=4) {
$code.=<<___;
- mov $idx,%r11d
- shr \$`log($N/8)/log(2)`,$idx
- and \$`$N/8-1`,%r11
- not $idx
- lea .Lmagic_masks(%rip),%rax
- and \$`2**5/($N/8)-1`,$idx # 5 is "window size"
- lea 128($tbl,%r11,8),$tbl # pointer within 1st cache line
- movq 0(%rax,$idx,8),%xmm4 # set of masks denoting which
- movq 8(%rax,$idx,8),%xmm5 # cache line contains element
- movq 16(%rax,$idx,8),%xmm6 # denoted by 7th argument
- movq 24(%rax,$idx,8),%xmm7
+ paddd %xmm0,%xmm1
+ pcmpeqd %xmm5,%xmm0 # compare to 1,0
+___
+$code.=<<___ if ($i);
+ movdqa %xmm3,`16*($i-1)-128`(%rax)
+___
+$code.=<<___;
+ movdqa %xmm4,%xmm3
+
+ paddd %xmm1,%xmm2
+ pcmpeqd %xmm5,%xmm1 # compare to 3,2
+ movdqa %xmm0,`16*($i+0)-128`(%rax)
+ movdqa %xmm4,%xmm0
+
+ paddd %xmm2,%xmm3
+ pcmpeqd %xmm5,%xmm2 # compare to 5,4
+ movdqa %xmm1,`16*($i+1)-128`(%rax)
+ movdqa %xmm4,%xmm1
+
+ paddd %xmm3,%xmm0
+ pcmpeqd %xmm5,%xmm3 # compare to 7,6
+ movdqa %xmm2,`16*($i+2)-128`(%rax)
+ movdqa %xmm4,%xmm2
+___
+}
+$code.=<<___;
+ movdqa %xmm3,`16*($i-1)-128`(%rax)
jmp .Lgather
-.align 16
-.Lgather:
- movq `0*$STRIDE/4-128`($tbl),%xmm0
- movq `1*$STRIDE/4-128`($tbl),%xmm1
- pand %xmm4,%xmm0
- movq `2*$STRIDE/4-128`($tbl),%xmm2
- pand %xmm5,%xmm1
- movq `3*$STRIDE/4-128`($tbl),%xmm3
- pand %xmm6,%xmm2
- por %xmm1,%xmm0
- pand %xmm7,%xmm3
- .byte 0x67,0x67
- por %xmm2,%xmm0
- lea $STRIDE($tbl),$tbl
- por %xmm3,%xmm0
+.align 32
+.Lgather:
+ pxor %xmm4,%xmm4
+ pxor %xmm5,%xmm5
+___
+for($i=0;$i<$STRIDE/16;$i+=4) {
+$code.=<<___;
+ movdqa `16*($i+0)-128`(%r11),%xmm0
+ movdqa `16*($i+1)-128`(%r11),%xmm1
+ movdqa `16*($i+2)-128`(%r11),%xmm2
+ pand `16*($i+0)-128`(%rax),%xmm0
+ movdqa `16*($i+3)-128`(%r11),%xmm3
+ pand `16*($i+1)-128`(%rax),%xmm1
+ por %xmm0,%xmm4
+ pand `16*($i+2)-128`(%rax),%xmm2
+ por %xmm1,%xmm5
+ pand `16*($i+3)-128`(%rax),%xmm3
+ por %xmm2,%xmm4
+ por %xmm3,%xmm5
+___
+}
+$code.=<<___;
+ por %xmm5,%xmm4
+ lea $STRIDE(%r11),%r11
+ pshufd \$0x4e,%xmm4,%xmm0
+ por %xmm4,%xmm0
movq %xmm0,($out) # m0=bp[0]
lea 8($out),$out
sub \$1,$num
jnz .Lgather
-___
-$code.=<<___ if ($win64);
- movaps (%rsp),%xmm6
- movaps 0x10(%rsp),%xmm7
- lea 0x28(%rsp),%rsp
-___
-$code.=<<___;
+
+ lea (%r10),%rsp
ret
.LSEH_end_bn_gather5:
.size bn_gather5,.-bn_gather5
@@ -3306,9 +3474,9 @@ ___
}
$code.=<<___;
.align 64
-.Lmagic_masks:
- .long 0,0, 0,0, 0,0, -1,-1
- .long 0,0, 0,0, 0,0, 0,0
+.Linc:
+ .long 0,0, 1,1
+ .long 2,2, 2,2
.asciz "Montgomery Multiplication with scatter/gather for x86_64, CRYPTOGAMS by <appro\@openssl.org>"
___
@@ -3356,19 +3524,16 @@ mul_handler:
lea .Lmul_epilogue(%rip),%r10
cmp %r10,%rbx
- jb .Lbody_40
+ ja .Lbody_40
mov 192($context),%r10 # pull $num
mov 8(%rax,%r10,8),%rax # pull saved stack pointer
+
jmp .Lbody_proceed
.Lbody_40:
mov 40(%rax),%rax # pull saved stack pointer
.Lbody_proceed:
-
- movaps -88(%rax),%xmm0
- movaps -72(%rax),%xmm1
-
mov -8(%rax),%rbx
mov -16(%rax),%rbp
mov -24(%rax),%r12
@@ -3381,8 +3546,6 @@ mul_handler:
mov %r13,224($context) # restore context->R13
mov %r14,232($context) # restore context->R14
mov %r15,240($context) # restore context->R15
- movups %xmm0,512($context) # restore context->Xmm6
- movups %xmm1,528($context) # restore context->Xmm7
.Lcommon_seh_tail:
mov 8(%rax),%rdi
@@ -3493,10 +3656,9 @@ ___
$code.=<<___;
.align 8
.LSEH_info_bn_gather5:
- .byte 0x01,0x0d,0x05,0x00
- .byte 0x0d,0x78,0x01,0x00 #movaps 0x10(rsp),xmm7
- .byte 0x08,0x68,0x00,0x00 #movaps (rsp),xmm6
- .byte 0x04,0x42,0x00,0x00 #sub rsp,0x28
+ .byte 0x01,0x0b,0x03,0x0a
+ .byte 0x0b,0x01,0x21,0x00 # sub rsp,0x108
+ .byte 0x04,0xa3,0x00,0x00 # lea r10,(rsp)
.align 8
___
}
diff --git a/src/crypto/bn/bn.c b/src/crypto/bn/bn.c
index 543c1482..0ecaf825 100644
--- a/src/crypto/bn/bn.c
+++ b/src/crypto/bn/bn.c
@@ -266,6 +266,18 @@ int BN_set_word(BIGNUM *bn, BN_ULONG value) {
return 1;
}
+int bn_set_words(BIGNUM *bn, const BN_ULONG *words, size_t num) {
+ if (bn_wexpand(bn, num) == NULL) {
+ return 0;
+ }
+ memmove(bn->d, words, num * sizeof(BN_ULONG));
+ /* |bn_wexpand| verified that |num| isn't too large. */
+ bn->top = (int)num;
+ bn_correct_top(bn);
+ bn->neg = 0;
+ return 1;
+}
+
int BN_is_negative(const BIGNUM *bn) {
return bn->neg != 0;
}
@@ -295,7 +307,7 @@ BIGNUM *bn_wexpand(BIGNUM *bn, size_t words) {
return NULL;
}
- a = (BN_ULONG *)OPENSSL_malloc(sizeof(BN_ULONG) * words);
+ a = OPENSSL_malloc(sizeof(BN_ULONG) * words);
if (a == NULL) {
OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
return NULL;
diff --git a/src/crypto/bn/bn_asn1.c b/src/crypto/bn/bn_asn1.c
index 9d70ba8e..efb23355 100644
--- a/src/crypto/bn/bn_asn1.c
+++ b/src/crypto/bn/bn_asn1.c
@@ -18,7 +18,7 @@
#include <openssl/err.h>
-int BN_cbs2unsigned(CBS *cbs, BIGNUM *ret) {
+int BN_parse_asn1_unsigned(CBS *cbs, BIGNUM *ret) {
CBS child;
if (!CBS_get_asn1(cbs, &child, CBS_ASN1_INTEGER) ||
CBS_len(&child) == 0) {
@@ -42,7 +42,7 @@ int BN_cbs2unsigned(CBS *cbs, BIGNUM *ret) {
return BN_bin2bn(CBS_data(&child), CBS_len(&child), ret) != NULL;
}
-int BN_cbs2unsigned_buggy(CBS *cbs, BIGNUM *ret) {
+int BN_parse_asn1_unsigned_buggy(CBS *cbs, BIGNUM *ret) {
CBS child;
if (!CBS_get_asn1(cbs, &child, CBS_ASN1_INTEGER) ||
CBS_len(&child) == 0) {
@@ -58,7 +58,7 @@ int BN_cbs2unsigned_buggy(CBS *cbs, BIGNUM *ret) {
return BN_bin2bn(CBS_data(&child), CBS_len(&child), ret) != NULL;
}
-int BN_bn2cbb(CBB *cbb, const BIGNUM *bn) {
+int BN_marshal_asn1(CBB *cbb, const BIGNUM *bn) {
/* Negative numbers are unsupported. */
if (BN_is_negative(bn)) {
OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER);
@@ -66,28 +66,15 @@ int BN_bn2cbb(CBB *cbb, const BIGNUM *bn) {
}
CBB child;
- if (!CBB_add_asn1(cbb, &child, CBS_ASN1_INTEGER)) {
+ if (!CBB_add_asn1(cbb, &child, CBS_ASN1_INTEGER) ||
+ /* The number must be padded with a leading zero if the high bit would
+ * otherwise be set or if |bn| is zero. */
+ (BN_num_bits(bn) % 8 == 0 && !CBB_add_u8(&child, 0x00)) ||
+ !BN_bn2cbb_padded(&child, BN_num_bytes(bn), bn) ||
+ !CBB_flush(cbb)) {
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 e7e04f18..fe8cfd05 100644
--- a/src/crypto/bn/bn_test.cc
+++ b/src/crypto/bn/bn_test.cc
@@ -1799,8 +1799,8 @@ static const ASN1InvalidTest kASN1InvalidTests[] = {
{"\x02\x00", 2},
};
-// kASN1BuggyTests are incorrect encodings and how |BN_cbs2unsigned_buggy|
-// should interpret them.
+// kASN1BuggyTests contains incorrect encodings and the corresponding, expected
+// results of |BN_parse_asn1_unsigned_buggy| given that input.
static const ASN1Test kASN1BuggyTests[] = {
// Negative numbers.
{"128", "\x02\x01\x80", 3},
@@ -1823,7 +1823,7 @@ static bool test_asn1() {
}
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) {
+ if (!BN_parse_asn1_unsigned(&cbs, bn2.get()) || CBS_len(&cbs) != 0) {
fprintf(stderr, "Parsing ASN.1 INTEGER failed.\n");
return false;
}
@@ -1838,7 +1838,7 @@ static bool test_asn1() {
size_t der_len;
CBB_zero(&cbb);
if (!CBB_init(&cbb, 0) ||
- !BN_bn2cbb(&cbb, bn.get()) ||
+ !BN_marshal_asn1(&cbb, bn.get()) ||
!CBB_finish(&cbb, &der, &der_len)) {
CBB_cleanup(&cbb);
return false;
@@ -1850,9 +1850,9 @@ static bool test_asn1() {
return false;
}
- // |BN_cbs2unsigned_buggy| parses all valid input.
+ // |BN_parse_asn1_unsigned_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) {
+ if (!BN_parse_asn1_unsigned_buggy(&cbs, bn2.get()) || CBS_len(&cbs) != 0) {
fprintf(stderr, "Parsing ASN.1 INTEGER failed.\n");
return false;
}
@@ -1869,16 +1869,16 @@ static bool test_asn1() {
}
CBS cbs;
CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
- if (BN_cbs2unsigned(&cbs, bn.get())) {
+ if (BN_parse_asn1_unsigned(&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|.
+ // |BN_parse_asn1_unsigned_buggy|.
CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
- if (BN_cbs2unsigned_buggy(&cbs, bn.get())) {
+ if (BN_parse_asn1_unsigned_buggy(&cbs, bn.get())) {
fprintf(stderr, "Parsed invalid input.\n");
return false;
}
@@ -1886,7 +1886,7 @@ static bool test_asn1() {
}
for (const ASN1Test &test : kASN1BuggyTests) {
- // These broken encodings are rejected by |BN_cbs2unsigned|.
+ // These broken encodings are rejected by |BN_parse_asn1_unsigned|.
ScopedBIGNUM bn(BN_new());
if (!bn) {
return false;
@@ -1894,20 +1894,20 @@ static bool test_asn1() {
CBS cbs;
CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
- if (BN_cbs2unsigned(&cbs, bn.get())) {
+ if (BN_parse_asn1_unsigned(&cbs, bn.get())) {
fprintf(stderr, "Parsed invalid input.\n");
return false;
}
ERR_clear_error();
- // However |BN_cbs2unsigned_buggy| accepts them.
+ // However |BN_parse_asn1_unsigned_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) {
+ if (!BN_parse_asn1_unsigned_buggy(&cbs, bn.get()) || CBS_len(&cbs) != 0) {
fprintf(stderr, "Parsing (invalid) ASN.1 INTEGER failed.\n");
return false;
}
@@ -1926,7 +1926,7 @@ static bool test_asn1() {
CBB cbb;
CBB_zero(&cbb);
if (!CBB_init(&cbb, 0) ||
- BN_bn2cbb(&cbb, bn.get())) {
+ BN_marshal_asn1(&cbb, bn.get())) {
fprintf(stderr, "Serialized negative number.\n");
CBB_cleanup(&cbb);
return false;
diff --git a/src/crypto/bn/convert.c b/src/crypto/bn/convert.c
index 1f7af64b..9125bf84 100644
--- a/src/crypto/bn/convert.c
+++ b/src/crypto/bn/convert.c
@@ -208,7 +208,7 @@ char *BN_bn2hex(const BIGNUM *bn) {
char *buf;
char *p;
- buf = (char *)OPENSSL_malloc(bn->top * BN_BYTES * 2 + 2);
+ buf = OPENSSL_malloc(bn->top * BN_BYTES * 2 + 2);
if (buf == NULL) {
OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
return NULL;
@@ -385,9 +385,8 @@ char *BN_bn2dec(const BIGNUM *a) {
*/
i = BN_num_bits(a) * 3;
num = i / 10 + i / 1000 + 1 + 1;
- bn_data =
- (BN_ULONG *)OPENSSL_malloc((num / BN_DEC_NUM + 1) * sizeof(BN_ULONG));
- buf = (char *)OPENSSL_malloc(num + 3);
+ bn_data = OPENSSL_malloc((num / BN_DEC_NUM + 1) * sizeof(BN_ULONG));
+ buf = OPENSSL_malloc(num + 3);
if ((buf == NULL) || (bn_data == NULL)) {
OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
goto err;
@@ -578,12 +577,14 @@ BIGNUM *BN_mpi2bn(const uint8_t *in, size_t len, BIGNUM *out) {
return NULL;
}
+ int out_is_alloced = 0;
if (out == NULL) {
out = BN_new();
- }
- if (out == NULL) {
- OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
- return NULL;
+ if (out == NULL) {
+ OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ out_is_alloced = 1;
}
if (in_len == 0) {
@@ -593,6 +594,9 @@ BIGNUM *BN_mpi2bn(const uint8_t *in, size_t len, BIGNUM *out) {
in += 4;
if (BN_bin2bn(in, in_len, out) == NULL) {
+ if (out_is_alloced) {
+ BN_free(out);
+ }
return NULL;
}
out->neg = ((*in) & 0x80) != 0;
diff --git a/src/crypto/bn/div.c b/src/crypto/bn/div.c
index f9e144a3..6f672914 100644
--- a/src/crypto/bn/div.c
+++ b/src/crypto/bn/div.c
@@ -56,55 +56,126 @@
#include <openssl/bn.h>
+#include <assert.h>
#include <limits.h>
#include <openssl/err.h>
#include "internal.h"
-#define asm __asm__
-
-#if !defined(OPENSSL_NO_ASM)
-# if defined(__GNUC__) && __GNUC__>=2
-# if defined(OPENSSL_X86)
- /*
- * There were two reasons for implementing this template:
- * - GNU C generates a call to a function (__udivdi3 to be exact)
- * in reply to ((((BN_ULLONG)n0)<<BN_BITS2)|n1)/d0 (I fail to
- * understand why...);
- * - divl doesn't only calculate quotient, but also leaves
- * remainder in %edx which we can definitely use here:-)
- *
- * <appro@fy.chalmers.se>
- */
-#undef div_asm
-# define div_asm(n0,n1,d0) \
- ({ asm volatile ( \
- "divl %4" \
- : "=a"(q), "=d"(rem) \
- : "a"(n1), "d"(n0), "g"(d0) \
- : "cc"); \
- q; \
- })
-# define REMAINDER_IS_ALREADY_CALCULATED
-# elif defined(OPENSSL_X86_64)
- /*
- * Same story here, but it's 128-bit by 64-bit division. Wow!
- * <appro@fy.chalmers.se>
- */
-# undef div_asm
-# define div_asm(n0,n1,d0) \
- ({ asm volatile ( \
- "divq %4" \
- : "=a"(q), "=d"(rem) \
- : "a"(n1), "d"(n0), "g"(d0) \
- : "cc"); \
- q; \
- })
-# define REMAINDER_IS_ALREADY_CALCULATED
-# endif /* __<cpu> */
-# endif /* __GNUC__ */
-#endif /* OPENSSL_NO_ASM */
+#if !defined(BN_ULLONG)
+/* bn_div_words divides a double-width |h|,|l| by |d| and returns the result,
+ * which must fit in a |BN_ULONG|. */
+static BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) {
+ BN_ULONG dh, dl, q, ret = 0, th, tl, t;
+ int i, count = 2;
+
+ if (d == 0) {
+ return BN_MASK2;
+ }
+
+ i = BN_num_bits_word(d);
+ assert((i == BN_BITS2) || (h <= (BN_ULONG)1 << i));
+
+ i = BN_BITS2 - i;
+ if (h >= d) {
+ h -= d;
+ }
+
+ if (i) {
+ d <<= i;
+ h = (h << i) | (l >> (BN_BITS2 - i));
+ l <<= i;
+ }
+ dh = (d & BN_MASK2h) >> BN_BITS4;
+ dl = (d & BN_MASK2l);
+ for (;;) {
+ if ((h >> BN_BITS4) == dh) {
+ q = BN_MASK2l;
+ } else {
+ q = h / dh;
+ }
+
+ th = q * dh;
+ tl = dl * q;
+ for (;;) {
+ t = h - th;
+ if ((t & BN_MASK2h) ||
+ ((tl) <= ((t << BN_BITS4) | ((l & BN_MASK2h) >> BN_BITS4)))) {
+ break;
+ }
+ q--;
+ th -= dh;
+ tl -= dl;
+ }
+ t = (tl >> BN_BITS4);
+ tl = (tl << BN_BITS4) & BN_MASK2h;
+ th += t;
+
+ if (l < tl) {
+ th++;
+ }
+ l -= tl;
+ if (h < th) {
+ h += d;
+ q--;
+ }
+ h -= th;
+
+ if (--count == 0) {
+ break;
+ }
+
+ ret = q << BN_BITS4;
+ h = ((h << BN_BITS4) | (l >> BN_BITS4)) & BN_MASK2;
+ l = (l & BN_MASK2l) << BN_BITS4;
+ }
+
+ ret |= q;
+ return ret;
+}
+#endif /* !defined(BN_ULLONG) */
+
+static inline void bn_div_rem_words(BN_ULONG *quotient_out, BN_ULONG *rem_out,
+ BN_ULONG n0, BN_ULONG n1, BN_ULONG d0) {
+ /* GCC and Clang generate function calls to |__udivdi3| and |__umoddi3| when
+ * the |BN_ULLONG|-based C code is used.
+ *
+ * GCC bugs:
+ * * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=14224
+ * * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43721
+ * * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54183
+ * * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58897
+ * * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65668
+ *
+ * Clang bugs:
+ * * https://llvm.org/bugs/show_bug.cgi?id=6397
+ * * https://llvm.org/bugs/show_bug.cgi?id=12418
+ *
+ * These issues aren't specific to x86 and x86_64, so it might be worthwhile
+ * to add more assembly language implementations. */
+#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86) && defined(__GNUC__)
+ __asm__ volatile (
+ "divl %4"
+ : "=a"(*quotient_out), "=d"(*rem_out)
+ : "a"(n1), "d"(n0), "g"(d0)
+ : "cc" );
+#elif !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && defined(__GNUC__)
+ __asm__ volatile (
+ "divq %4"
+ : "=a"(*quotient_out), "=d"(*rem_out)
+ : "a"(n1), "d"(n0), "g"(d0)
+ : "cc" );
+#else
+#if defined(BN_ULLONG)
+ BN_ULLONG n = (((BN_ULLONG)n0) << BN_BITS2) | n1;
+ *quotient_out = (BN_ULONG)(n / d0);
+#else
+ *quotient_out = bn_div_words(n0, n1, d0);
+#endif
+ *rem_out = n1 - (*quotient_out * d0);
+#endif
+}
/* BN_div computes dv := num / divisor, rounding towards
* zero, and sets up rm such that dv*divisor + rm = num holds.
@@ -260,23 +331,10 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
q = BN_MASK2;
} else {
/* n0 < d0 */
-#ifdef BN_ULLONG
- BN_ULLONG t2;
-
-#if defined(BN_ULLONG) && !defined(div_asm)
- q = (BN_ULONG)(((((BN_ULLONG)n0) << BN_BITS2) | n1) / d0);
-#else
- q = div_asm(n0, n1, d0);
-#endif
-
-#ifndef REMAINDER_IS_ALREADY_CALCULATED
- /* rem doesn't have to be BN_ULLONG. The least we know it's less that d0,
- * isn't it? */
- rem = (n1 - q * d0) & BN_MASK2;
-#endif
-
- t2 = (BN_ULLONG)d1 * q;
+ bn_div_rem_words(&q, &rem, n0, n1, d0);
+#ifdef BN_ULLONG
+ BN_ULLONG t2 = (BN_ULLONG)d1 * q;
for (;;) {
if (t2 <= ((((BN_ULLONG)rem) << BN_BITS2) | wnump[-2])) {
break;
@@ -290,33 +348,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
}
#else /* !BN_ULLONG */
BN_ULONG t2l, t2h;
-
-#if defined(div_asm)
- q = div_asm(n0, n1, d0);
-#else
- q = bn_div_words(n0, n1, d0);
-#endif
-
-#ifndef REMAINDER_IS_ALREADY_CALCULATED
- rem = (n1 - q * d0) & BN_MASK2;
-#endif
-
-#if defined(BN_UMULT_LOHI)
BN_UMULT_LOHI(t2l, t2h, d1, q);
-#elif defined(BN_UMULT_HIGH)
- t2l = d1 * q;
- t2h = BN_UMULT_HIGH(d1, q);
-#else
- {
- BN_ULONG ql, qh;
- t2l = LBITS(d1);
- t2h = HBITS(d1);
- ql = LBITS(q);
- qh = HBITS(q);
- mul64(t2l, t2h, ql, qh); /* t2=(BN_ULLONG)d1*q; */
- }
-#endif
-
for (;;) {
if ((t2h < rem) || ((t2h == rem) && (t2l <= wnump[-2]))) {
break;
@@ -576,7 +608,7 @@ BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w) {
return 0;
}
- /* normalize input (so bn_div_words doesn't complain) */
+ /* normalize input for |bn_div_rem_words|. */
j = BN_BITS2 - BN_num_bits_word(w);
w <<= j;
if (!BN_lshift(a, a, j)) {
@@ -584,10 +616,10 @@ BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w) {
}
for (i = a->top - 1; i >= 0; i--) {
- BN_ULONG l, d;
-
- l = a->d[i];
- d = bn_div_words(ret, l, w);
+ BN_ULONG l = a->d[i];
+ BN_ULONG d;
+ BN_ULONG unused_rem;
+ bn_div_rem_words(&d, &unused_rem, ret, l, w);
ret = (l - ((d * w) & BN_MASK2)) & BN_MASK2;
a->d[i] = d;
}
diff --git a/src/crypto/bn/exponentiation.c b/src/crypto/bn/exponentiation.c
index 72a8db4b..bb7a2f40 100644
--- a/src/crypto/bn/exponentiation.c
+++ b/src/crypto/bn/exponentiation.c
@@ -209,6 +209,7 @@ static void BN_RECP_CTX_init(BN_RECP_CTX *recp) {
BN_init(&recp->N);
BN_init(&recp->Nr);
recp->num_bits = 0;
+ recp->shift = 0;
recp->flags = 0;
}
@@ -787,29 +788,65 @@ err:
* pattern as far as cache lines are concerned. The following functions are
* used to transfer a BIGNUM from/to that table. */
static int copy_to_prebuf(const BIGNUM *b, int top, unsigned char *buf, int idx,
- int width) {
- size_t i, j;
+ int window) {
+ int i, j;
+ const int width = 1 << window;
+ BN_ULONG *table = (BN_ULONG *) buf;
if (top > b->top) {
top = b->top; /* this works because 'buf' is explicitly zeroed */
}
- for (i = 0, j = idx; i < top * sizeof b->d[0]; i++, j += width) {
- buf[j] = ((unsigned char *)b->d)[i];
+
+ for (i = 0, j = idx; i < top; i++, j += width) {
+ table[j] = b->d[i];
}
return 1;
}
static int copy_from_prebuf(BIGNUM *b, int top, unsigned char *buf, int idx,
- int width) {
- size_t i, j;
+ int window) {
+ int i, j;
+ const int width = 1 << window;
+ volatile BN_ULONG *table = (volatile BN_ULONG *)buf;
if (bn_wexpand(b, top) == NULL) {
return 0;
}
- for (i = 0, j = idx; i < top * sizeof b->d[0]; i++, j += width) {
- ((unsigned char *)b->d)[i] = buf[j];
+ if (window <= 3) {
+ for (i = 0; i < top; i++, table += width) {
+ BN_ULONG acc = 0;
+
+ for (j = 0; j < width; j++) {
+ acc |= table[j] & ((BN_ULONG)0 - (constant_time_eq_int(j, idx) & 1));
+ }
+
+ b->d[i] = acc;
+ }
+ } else {
+ int xstride = 1 << (window - 2);
+ BN_ULONG y0, y1, y2, y3;
+
+ i = idx >> (window - 2); /* equivalent of idx / xstride */
+ idx &= xstride - 1; /* equivalent of idx % xstride */
+
+ y0 = (BN_ULONG)0 - (constant_time_eq_int(i, 0) & 1);
+ y1 = (BN_ULONG)0 - (constant_time_eq_int(i, 1) & 1);
+ y2 = (BN_ULONG)0 - (constant_time_eq_int(i, 2) & 1);
+ y3 = (BN_ULONG)0 - (constant_time_eq_int(i, 3) & 1);
+
+ for (i = 0; i < top; i++, table += width) {
+ BN_ULONG acc = 0;
+
+ for (j = 0; j < xstride; j++) {
+ acc |= ((table[j + 0 * xstride] & y0) | (table[j + 1 * xstride] & y1) |
+ (table[j + 2 * xstride] & y2) | (table[j + 3 * xstride] & y3)) &
+ ((BN_ULONG)0 - (constant_time_eq_int(j, idx) & 1));
+ }
+
+ b->d[i] = acc;
+ }
}
b->top = top;
@@ -891,8 +928,6 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
return BN_one(rr);
}
- BN_CTX_start(ctx);
-
/* Allocate a montgomery context if it was not supplied by the caller. */
if (mont == NULL) {
new_mont = BN_MONT_CTX_new();
@@ -935,9 +970,8 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
#if defined(OPENSSL_BN_ASM_MONT5)
if (window >= 5) {
window = 5; /* ~5% improvement for RSA2048 sign, and even for RSA4096 */
- if ((top & 7) == 0) {
- powerbufLen += 2 * top * sizeof(m->d[0]);
- }
+ /* reserve space for mont->N.d[] copy */
+ powerbufLen += top * sizeof(mont->N.d[0]);
}
#endif
@@ -954,7 +988,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
} else
#endif
{
- if ((powerbufFree = (unsigned char *)OPENSSL_malloc(
+ if ((powerbufFree = OPENSSL_malloc(
powerbufLen + MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH)) == NULL) {
goto err;
}
@@ -1008,7 +1042,8 @@ 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) {
- const BN_ULONG *np = mont->N.d, *n0 = mont->n0, *np2;
+ const BN_ULONG *n0 = mont->n0;
+ BN_ULONG *np;
/* BN_to_montgomery can contaminate words above .top
* [in BN_DEBUG[_DEBUG] build]... */
@@ -1019,14 +1054,9 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
tmp.d[i] = 0;
}
- if (top & 7) {
- np2 = np;
- } else {
- BN_ULONG *np_double = am.d + top;
- for (i = 0; i < top; i++) {
- np_double[2 * i] = np[i];
- }
- np2 = np_double;
+ /* copy mont->N.d[] to improve cache locality */
+ for (np = am.d + top, i = 0; i < top; i++) {
+ np[i] = mont->N.d[i];
}
bn_scatter5(tmp.d, top, powerbuf, 0);
@@ -1041,7 +1071,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
}
for (i = 3; i < 8; i += 2) {
int j;
- bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np2, n0, top, i - 1);
+ bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1);
bn_scatter5(tmp.d, top, powerbuf, i);
for (j = 2 * i; j < 32; j *= 2) {
bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
@@ -1049,13 +1079,13 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
}
}
for (; i < 16; i += 2) {
- bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np2, n0, top, i - 1);
+ bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1);
bn_scatter5(tmp.d, top, powerbuf, i);
bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
bn_scatter5(tmp.d, top, powerbuf, 2 * i);
}
for (; i < 32; i += 2) {
- bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np2, n0, top, i - 1);
+ bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1);
bn_scatter5(tmp.d, top, powerbuf, i);
}
@@ -1103,7 +1133,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
wvalue >>= (bits - 4) & 7;
wvalue &= 0x1f;
bits -= 5;
- bn_power5(tmp.d, tmp.d, powerbuf, np2, n0, top, wvalue);
+ bn_power5(tmp.d, tmp.d, powerbuf, np, n0, top, wvalue);
}
while (bits >= 0) {
/* Read five bits from |bits-4| through |bits|, inclusive. */
@@ -1112,11 +1142,11 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
wvalue >>= first_bit & 7;
wvalue &= 0x1f;
bits -= 5;
- bn_power5(tmp.d, tmp.d, powerbuf, np2, n0, top, wvalue);
+ bn_power5(tmp.d, tmp.d, powerbuf, np, n0, top, wvalue);
}
}
- ret = bn_from_montgomery(tmp.d, tmp.d, NULL, np2, n0, top);
+ ret = bn_from_montgomery(tmp.d, tmp.d, NULL, np, n0, top);
tmp.top = top;
bn_correct_top(&tmp);
if (ret) {
@@ -1128,8 +1158,8 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
} else
#endif
{
- if (!copy_to_prebuf(&tmp, top, powerbuf, 0, numPowers) ||
- !copy_to_prebuf(&am, top, powerbuf, 1, numPowers)) {
+ if (!copy_to_prebuf(&tmp, top, powerbuf, 0, window) ||
+ !copy_to_prebuf(&am, top, powerbuf, 1, window)) {
goto err;
}
@@ -1140,13 +1170,13 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
*/
if (window > 1) {
if (!BN_mod_mul_montgomery(&tmp, &am, &am, mont, ctx) ||
- !copy_to_prebuf(&tmp, top, powerbuf, 2, numPowers)) {
+ !copy_to_prebuf(&tmp, top, powerbuf, 2, window)) {
goto err;
}
for (i = 3; i < numPowers; i++) {
/* Calculate a^i = a^(i-1) * a */
if (!BN_mod_mul_montgomery(&tmp, &am, &tmp, mont, ctx) ||
- !copy_to_prebuf(&tmp, top, powerbuf, i, numPowers)) {
+ !copy_to_prebuf(&tmp, top, powerbuf, i, window)) {
goto err;
}
}
@@ -1156,7 +1186,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
for (wvalue = 0, i = bits % window; i >= 0; i--, bits--) {
wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
}
- if (!copy_from_prebuf(&tmp, top, powerbuf, wvalue, numPowers)) {
+ if (!copy_from_prebuf(&tmp, top, powerbuf, wvalue, window)) {
goto err;
}
@@ -1175,7 +1205,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
}
/* Fetch the appropriate pre-computed value from the pre-buf */
- if (!copy_from_prebuf(&am, top, powerbuf, wvalue, numPowers)) {
+ if (!copy_from_prebuf(&am, top, powerbuf, wvalue, window)) {
goto err;
}
@@ -1198,7 +1228,6 @@ err:
OPENSSL_cleanse(powerbuf, powerbufLen);
OPENSSL_free(powerbufFree);
}
- BN_CTX_end(ctx);
return (ret);
}
diff --git a/src/crypto/bn/generic.c b/src/crypto/bn/generic.c
index 7303ca5b..f552d99f 100644
--- a/src/crypto/bn/generic.c
+++ b/src/crypto/bn/generic.c
@@ -61,13 +61,10 @@
#include "internal.h"
-/* Generic implementations of most operations are needed for:
- * - Configurations without inline assembly.
- * - Architectures other than x86 or x86_64.
- * - Windows x84_64; x86_64-gcc.c does not build on MSVC. */
+/* This file has two other implementations: x86 assembly language in
+ * asm/bn-586.pl and x86_64 inline assembly in asm/x86_64-gcc.c. */
#if defined(OPENSSL_NO_ASM) || \
- (!defined(OPENSSL_X86_64) && !defined(OPENSSL_X86)) || \
- (defined(OPENSSL_X86_64) && defined(OPENSSL_WINDOWS))
+ !(defined(OPENSSL_X86) || (defined(OPENSSL_X86_64) && defined(__GNUC__)))
#ifdef BN_ULLONG
#define mul_add(r, a, w, c) \
@@ -94,7 +91,8 @@
(r1) = Hw(t); \
}
-#elif defined(BN_UMULT_LOHI)
+#else
+
#define mul_add(r, a, w, c) \
{ \
BN_ULONG high, low, ret, tmp = (a); \
@@ -124,102 +122,8 @@
BN_UMULT_LOHI(r0, r1, tmp, tmp); \
}
-#else
-
-/*************************************************************
- * No long long type
- */
-
-#define LBITS(a) ((a) & BN_MASK2l)
-#define HBITS(a) (((a) >> BN_BITS4) & BN_MASK2l)
-#define L2HBITS(a) (((a) << BN_BITS4) & BN_MASK2)
-
-#define LLBITS(a) ((a) & BN_MASKl)
-#define LHBITS(a) (((a) >> BN_BITS2) & BN_MASKl)
-#define LL2HBITS(a) ((BN_ULLONG)((a) & BN_MASKl) << BN_BITS2)
-
-#define mul64(l, h, bl, bh) \
- { \
- BN_ULONG m, m1, lt, ht; \
- \
- lt = l; \
- ht = h; \
- m = (bh) * (lt); \
- lt = (bl) * (lt); \
- m1 = (bl) * (ht); \
- ht = (bh) * (ht); \
- m = (m + m1) & BN_MASK2; \
- if (m < m1) \
- ht += L2HBITS((BN_ULONG)1); \
- ht += HBITS(m); \
- m1 = L2HBITS(m); \
- lt = (lt + m1) & BN_MASK2; \
- if (lt < m1) \
- ht++; \
- (l) = lt; \
- (h) = ht; \
- }
-
-#define sqr64(lo, ho, in) \
- { \
- BN_ULONG l, h, m; \
- \
- h = (in); \
- l = LBITS(h); \
- h = HBITS(h); \
- m = (l) * (h); \
- l *= l; \
- h *= h; \
- h += (m & BN_MASK2h1) >> (BN_BITS4 - 1); \
- m = (m & BN_MASK2l) << (BN_BITS4 + 1); \
- l = (l + m) & BN_MASK2; \
- if (l < m) \
- h++; \
- (lo) = l; \
- (ho) = h; \
- }
-
-#define mul_add(r, a, bl, bh, c) \
- { \
- BN_ULONG l, h; \
- \
- h = (a); \
- l = LBITS(h); \
- h = HBITS(h); \
- mul64(l, h, (bl), (bh)); \
- \
- /* non-multiply part */ \
- l = (l + (c)) & BN_MASK2; \
- if (l < (c)) \
- h++; \
- (c) = (r); \
- l = (l + (c)) & BN_MASK2; \
- if (l < (c)) \
- h++; \
- (c) = h & BN_MASK2; \
- (r) = l; \
- }
-
-#define mul(r, a, bl, bh, c) \
- { \
- BN_ULONG l, h; \
- \
- h = (a); \
- l = LBITS(h); \
- h = HBITS(h); \
- mul64(l, h, (bl), (bh)); \
- \
- /* non-multiply part */ \
- l += (c); \
- if ((l & BN_MASK2) < (c)) \
- h++; \
- (c) = h & BN_MASK2; \
- (r) = l & BN_MASK2; \
- }
#endif /* !BN_ULLONG */
-#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) {
BN_ULONG c1 = 0;
@@ -298,174 +202,6 @@ void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n) {
}
}
-#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) {
- BN_ULONG c = 0;
- BN_ULONG bl, bh;
-
- assert(num >= 0);
- if (num <= 0) {
- return (BN_ULONG)0;
- }
-
- bl = LBITS(w);
- bh = HBITS(w);
-
- while (num & ~3) {
- mul_add(rp[0], ap[0], bl, bh, c);
- mul_add(rp[1], ap[1], bl, bh, c);
- mul_add(rp[2], ap[2], bl, bh, c);
- mul_add(rp[3], ap[3], bl, bh, c);
- ap += 4;
- rp += 4;
- num -= 4;
- }
- while (num) {
- mul_add(rp[0], ap[0], bl, bh, c);
- ap++;
- rp++;
- num--;
- }
- return c;
-}
-
-BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w) {
- BN_ULONG carry = 0;
- BN_ULONG bl, bh;
-
- assert(num >= 0);
- if (num <= 0) {
- return (BN_ULONG)0;
- }
-
- bl = LBITS(w);
- bh = HBITS(w);
-
- while (num & ~3) {
- mul(rp[0], ap[0], bl, bh, carry);
- mul(rp[1], ap[1], bl, bh, carry);
- mul(rp[2], ap[2], bl, bh, carry);
- mul(rp[3], ap[3], bl, bh, carry);
- ap += 4;
- rp += 4;
- num -= 4;
- }
- while (num) {
- mul(rp[0], ap[0], bl, bh, carry);
- ap++;
- rp++;
- num--;
- }
- return carry;
-}
-
-void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n) {
- assert(n >= 0);
- if (n <= 0) {
- return;
- }
-
- while (n & ~3) {
- sqr64(r[0], r[1], a[0]);
- sqr64(r[2], r[3], a[1]);
- sqr64(r[4], r[5], a[2]);
- sqr64(r[6], r[7], a[3]);
- a += 4;
- r += 8;
- n -= 4;
- }
- while (n) {
- sqr64(r[0], r[1], a[0]);
- a++;
- r += 2;
- n--;
- }
-}
-
-#endif /* !(defined(BN_ULLONG) || defined(BN_UMULT_HIGH)) */
-
-#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);
-}
-
-#else
-
-/* Divide h,l by d and return the result. */
-BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) {
- BN_ULONG dh, dl, q, ret = 0, th, tl, t;
- int i, count = 2;
-
- if (d == 0) {
- return BN_MASK2;
- }
-
- i = BN_num_bits_word(d);
- assert((i == BN_BITS2) || (h <= (BN_ULONG)1 << i));
-
- i = BN_BITS2 - i;
- if (h >= d) {
- h -= d;
- }
-
- if (i) {
- d <<= i;
- h = (h << i) | (l >> (BN_BITS2 - i));
- l <<= i;
- }
- dh = (d & BN_MASK2h) >> BN_BITS4;
- dl = (d & BN_MASK2l);
- for (;;) {
- if ((h >> BN_BITS4) == dh) {
- q = BN_MASK2l;
- } else {
- q = h / dh;
- }
-
- th = q * dh;
- tl = dl * q;
- for (;;) {
- t = h - th;
- if ((t & BN_MASK2h) ||
- ((tl) <= ((t << BN_BITS4) | ((l & BN_MASK2h) >> BN_BITS4)))) {
- break;
- }
- q--;
- th -= dh;
- tl -= dl;
- }
- t = (tl >> BN_BITS4);
- tl = (tl << BN_BITS4) & BN_MASK2h;
- th += t;
-
- if (l < tl) {
- th++;
- }
- l -= tl;
- if (h < th) {
- h += d;
- q--;
- }
- h -= th;
-
- if (--count == 0) {
- break;
- }
-
- ret = q << BN_BITS4;
- h = ((h << BN_BITS4) | (l >> BN_BITS4)) & BN_MASK2;
- l = (l & BN_MASK2l) << BN_BITS4;
- }
-
- ret |= q;
- return ret;
-}
-
-#endif /* !defined(BN_ULLONG) */
-
#ifdef BN_ULLONG
BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
int n) {
@@ -673,7 +409,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)
-#elif defined(BN_UMULT_LOHI)
+#else
/* Keep in mind that additions to hi can not overflow, because the high word of
* a multiplication result cannot be all-ones. */
@@ -716,58 +452,6 @@ 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_ULLONG */
-
-/* Keep in mind that additions to hi can not overflow, because
- * the high word of a multiplication result cannot be all-ones. */
-
-#define mul_add_c(a, b, c0, c1, c2) \
- do { \
- BN_ULONG lo = LBITS(a), hi = HBITS(a); \
- BN_ULONG bl = LBITS(b), bh = HBITS(b); \
- mul64(lo, hi, bl, bh); \
- c0 = (c0 + lo) & BN_MASK2; \
- if (c0 < lo) \
- hi++; \
- c1 = (c1 + hi) & BN_MASK2; \
- if (c1 < hi) \
- c2++; \
- } while (0)
-
-#define mul_add_c2(a, b, c0, c1, c2) \
- do { \
- BN_ULONG tt; \
- BN_ULONG lo = LBITS(a), hi = HBITS(a); \
- BN_ULONG bl = LBITS(b), bh = HBITS(b); \
- mul64(lo, hi, bl, bh); \
- tt = hi; \
- c0 = (c0 + lo) & BN_MASK2; \
- if (c0 < lo) \
- tt++; \
- c1 = (c1 + tt) & BN_MASK2; \
- if (c1 < tt) \
- c2++; \
- c0 = (c0 + lo) & BN_MASK2; \
- if (c0 < lo) \
- hi++; \
- c1 = (c1 + hi) & BN_MASK2; \
- if (c1 < hi) \
- c2++; \
- } while (0)
-
-#define sqr_add_c(a, i, c0, c1, c2) \
- do { \
- BN_ULONG lo, hi; \
- sqr64(lo, hi, (a)[i]); \
- c0 = (c0 + lo) & BN_MASK2; \
- if (c0 < lo) \
- hi++; \
- c1 = (c1 + hi) & BN_MASK2; \
- if (c1 < hi) \
- c2++; \
- } while (0)
-
-#define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2)
#endif /* !BN_ULLONG */
void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
diff --git a/src/crypto/bn/internal.h b/src/crypto/bn/internal.h
index 72ef4e95..0a2982c7 100644
--- a/src/crypto/bn/internal.h
+++ b/src/crypto/bn/internal.h
@@ -125,13 +125,15 @@
#include <openssl/base.h>
-#if defined(OPENSSL_X86_64) && defined(_MSC_VER) && _MSC_VER >= 1400
+#if defined(OPENSSL_X86_64) && defined(_MSC_VER)
#pragma warning(push, 3)
#include <intrin.h>
#pragma warning(pop)
#pragma intrinsic(__umulh, _umul128)
#endif
+#include "../internal.h"
+
#if defined(__cplusplus)
extern "C" {
#endif
@@ -144,7 +146,7 @@ BIGNUM *bn_expand(BIGNUM *bn, size_t bits);
#if !defined(_MSC_VER)
/* MSVC doesn't support two-word integers on 64-bit. */
-#define BN_ULLONG __uint128_t
+#define BN_ULLONG uint128_t
#endif
#define BN_BITS2 64
@@ -179,14 +181,6 @@ BIGNUM *bn_expand(BIGNUM *bn, size_t bits);
#endif
-/* Pentium pro 16,16,16,32,64 */
-/* Alpha 16,16,16,16.64 */
-#define BN_MULL_SIZE_NORMAL (16) /* 32 */
-#define BN_MUL_RECURSIVE_SIZE_NORMAL (16) /* 32 less than */
-#define BN_SQR_RECURSIVE_SIZE_NORMAL (16) /* 32 */
-#define BN_MUL_LOW_RECURSIVE_SIZE_NORMAL (32) /* 32 */
-#define BN_MONT_CTX_SET_SIZE_WORD (64) /* 32 */
-
#define STATIC_BIGNUM(x) \
{ \
(BN_ULONG *)x, sizeof(x) / sizeof(BN_ULONG), \
@@ -198,10 +192,14 @@ BIGNUM *bn_expand(BIGNUM *bn, size_t bits);
#define Hw(t) (((BN_ULONG)((t)>>BN_BITS2))&BN_MASK2)
#endif
+
+/* bn_set_words sets |bn| to the value encoded in the |num| words in |words|,
+ * least significant word first. */
+int bn_set_words(BIGNUM *bn, const BN_ULONG *words, size_t num);
+
BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w);
BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w);
void bn_sqr_words(BN_ULONG *rp, const BN_ULONG *ap, int num);
-BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d);
BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int num);
BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int num);
@@ -223,67 +221,12 @@ 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_ULLONG)
-
-#define LBITS(a) ((a) & BN_MASK2l)
-#define HBITS(a) (((a) >> BN_BITS4) & BN_MASK2l)
-#define L2HBITS(a) (((a) << BN_BITS4) & BN_MASK2)
-
-#define LLBITS(a) ((a) & BN_MASKl)
-#define LHBITS(a) (((a) >> BN_BITS2) & BN_MASKl)
-#define LL2HBITS(a) ((BN_ULLONG)((a) & BN_MASKl) << BN_BITS2)
-
-#define mul64(l, h, bl, bh) \
- { \
- BN_ULONG m, m1, lt, ht; \
- \
- lt = l; \
- ht = h; \
- m = (bh) * (lt); \
- lt = (bl) * (lt); \
- m1 = (bl) * (ht); \
- ht = (bh) * (ht); \
- m = (m + m1) & BN_MASK2; \
- if (m < m1) \
- ht += L2HBITS((BN_ULONG)1); \
- ht += HBITS(m); \
- m1 = L2HBITS(m); \
- lt = (lt + m1) & BN_MASK2; \
- if (lt < m1) \
- ht++; \
- (l) = lt; \
- (h) = ht; \
- }
-
-#endif /* !defined(BN_ULLONG) */
+#if defined(OPENSSL_X86_64) && defined(_MSC_VER)
+#define BN_UMULT_LOHI(low, high, a, b) ((low) = _umul128((a), (b), &(high)))
+#endif
-#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64)
-# if defined(__GNUC__) && __GNUC__ >= 2
-# define BN_UMULT_HIGH(a,b) ({ \
- register BN_ULONG ret,discard; \
- __asm__ ("mulq %3" \
- : "=a"(discard),"=d"(ret) \
- : "a"(a), "g"(b) \
- : "cc"); \
- ret; })
-# define BN_UMULT_LOHI(low,high,a,b) \
- __asm__ ("mulq %3" \
- : "=a"(low),"=d"(high) \
- : "a"(a),"g"(b) \
- : "cc");
-# elif defined(_MSC_VER) && _MSC_VER >= 1400
-# define BN_UMULT_HIGH(a, b) __umulh((a), (b))
-# define BN_UMULT_LOHI(low, high, a, b) ((low) = _umul128((a), (b), &(high)))
-# endif
-#elif !defined(OPENSSL_NO_ASM) && defined(OPENSSL_AARCH64)
-# if defined(__GNUC__) && __GNUC__>=2
-# define BN_UMULT_HIGH(a,b) ({ \
- register BN_ULONG ret; \
- __asm__ ("umulh %0,%1,%2" \
- : "=r"(ret) \
- : "r"(a), "r"(b)); \
- ret; })
-# endif
+#if !defined(BN_ULLONG) && !defined(BN_UMULT_LOHI)
+#error "Either BN_ULLONG or BN_UMULT_LOHI must be defined on every platform."
#endif
diff --git a/src/crypto/bn/montgomery.c b/src/crypto/bn/montgomery.c
index 18da0dad..f56998e0 100644
--- a/src/crypto/bn/montgomery.c
+++ b/src/crypto/bn/montgomery.c
@@ -289,14 +289,14 @@ err:
return ret;
}
-BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, CRYPTO_MUTEX *lock,
- const BIGNUM *mod, BN_CTX *bn_ctx) {
+int BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, CRYPTO_MUTEX *lock,
+ const BIGNUM *mod, BN_CTX *bn_ctx) {
CRYPTO_MUTEX_lock_read(lock);
BN_MONT_CTX *ctx = *pmont;
CRYPTO_MUTEX_unlock(lock);
if (ctx) {
- return ctx;
+ return 1;
}
CRYPTO_MUTEX_lock_write(lock);
@@ -318,7 +318,7 @@ BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, CRYPTO_MUTEX *lock,
out:
CRYPTO_MUTEX_unlock(lock);
- return ctx;
+ return ctx != NULL;
}
int BN_to_montgomery(BIGNUM *ret, const BIGNUM *a, const BN_MONT_CTX *mont,
@@ -326,14 +326,12 @@ int BN_to_montgomery(BIGNUM *ret, const BIGNUM *a, const BN_MONT_CTX *mont,
return BN_mod_mul_montgomery(ret, a, &mont->RR, mont, ctx);
}
-#if 0
static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r,
const BN_MONT_CTX *mont) {
- const BIGNUM *n;
BN_ULONG *ap, *np, *rp, n0, v, carry;
int nl, max, i;
- n = &mont->N;
+ const BIGNUM *n = &mont->N;
nl = n->top;
if (nl == 0) {
ret->top = 0;
@@ -376,13 +374,13 @@ static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r,
{
BN_ULONG *nrp;
- size_t m;
+ uintptr_t m;
v = bn_sub_words(rp, ap, np, nl) - carry;
/* if subtraction result is real, then trick unconditional memcpy below to
* perform in-place "refresh" instead of actual copy. */
- m = (0 - (size_t)v);
- nrp = (BN_ULONG *)(((intptr_t)rp & ~m) | ((intptr_t)ap & m));
+ m = (0u - (uintptr_t)v);
+ nrp = (BN_ULONG *)(((uintptr_t)rp & ~m) | ((uintptr_t)ap & m));
for (i = 0, nl -= 4; i < nl; i += 4) {
BN_ULONG t1, t2, t3, t4;
@@ -411,104 +409,25 @@ static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r,
return 1;
}
-#endif
-
-#define PTR_SIZE_INT size_t
-
-static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, const BN_MONT_CTX *mont)
- {
- BIGNUM *n;
- BN_ULONG *ap,*np,*rp,n0,v,carry;
- int nl,max,i;
-
- n= (BIGNUM*) &(mont->N);
- nl=n->top;
- if (nl == 0) { ret->top=0; return(1); }
- max=(2*nl); /* carry is stored separately */
- if (bn_wexpand(r,max) == NULL) return(0);
-
- r->neg^=n->neg;
- np=n->d;
- rp=r->d;
-
- /* clear the top words of T */
-#if 1
- for (i=r->top; i<max; i++) /* memset? XXX */
- rp[i]=0;
-#else
- memset(&(rp[r->top]),0,(max-r->top)*sizeof(BN_ULONG));
-#endif
-
- r->top=max;
- n0=mont->n0[0];
-
- for (carry=0, i=0; i<nl; i++, rp++)
- {
- v=bn_mul_add_words(rp,np,nl,(rp[0]*n0)&BN_MASK2);
- v = (v+carry+rp[nl])&BN_MASK2;
- carry |= (v != rp[nl]);
- carry &= (v <= rp[nl]);
- rp[nl]=v;
- }
-
- if (bn_wexpand(ret,nl) == NULL) return(0);
- ret->top=nl;
- ret->neg=r->neg;
-
- rp=ret->d;
- ap=&(r->d[nl]);
-
- {
- BN_ULONG *nrp;
- size_t m;
-
- v=bn_sub_words(rp,ap,np,nl)-carry;
- /* if subtraction result is real, then
- * trick unconditional memcpy below to perform in-place
- * "refresh" instead of actual copy. */
- m=(0-(size_t)v);
- nrp=(BN_ULONG *)(((PTR_SIZE_INT)rp&~m)|((PTR_SIZE_INT)ap&m));
-
- for (i=0,nl-=4; i<nl; i+=4)
- {
- BN_ULONG t1,t2,t3,t4;
-
- t1=nrp[i+0];
- t2=nrp[i+1];
- t3=nrp[i+2]; ap[i+0]=0;
- t4=nrp[i+3]; ap[i+1]=0;
- rp[i+0]=t1; ap[i+2]=0;
- rp[i+1]=t2; ap[i+3]=0;
- rp[i+2]=t3;
- rp[i+3]=t4;
- }
- for (nl+=4; i<nl; i++)
- rp[i]=nrp[i], ap[i]=0;
- }
- bn_correct_top(r);
- bn_correct_top(ret);
-
- return(1);
- }
-
-int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, const BN_MONT_CTX *mont,
+int BN_from_montgomery(BIGNUM *r, const BIGNUM *a, const BN_MONT_CTX *mont,
BN_CTX *ctx) {
- int retn = 0;
+ int ret = 0;
BIGNUM *t;
BN_CTX_start(ctx);
t = BN_CTX_get(ctx);
- if (t == NULL) {
- return 0;
+ if (t == NULL ||
+ !BN_copy(t, a)) {
+ goto err;
}
- if (BN_copy(t, a)) {
- retn = BN_from_montgomery_word(ret, t, mont);
- }
+ ret = BN_from_montgomery_word(r, t, mont);
+
+err:
BN_CTX_end(ctx);
- return retn;
+ return ret;
}
int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
diff --git a/src/crypto/bn/mul.c b/src/crypto/bn/mul.c
index 029a59e2..06e53ee0 100644
--- a/src/crypto/bn/mul.c
+++ b/src/crypto/bn/mul.c
@@ -62,7 +62,12 @@
#include "internal.h"
-void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb) {
+#define BN_MUL_RECURSIVE_SIZE_NORMAL 16
+#define BN_SQR_RECURSIVE_SIZE_NORMAL BN_MUL_RECURSIVE_SIZE_NORMAL
+
+
+static void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b,
+ int nb) {
BN_ULONG *rr;
if (na < nb) {
@@ -107,31 +112,6 @@ void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb) {
}
}
-void bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n) {
- bn_mul_words(r, a, n, b[0]);
-
- for (;;) {
- if (--n <= 0) {
- return;
- }
- bn_mul_add_words(&(r[1]), a, n, b[1]);
- if (--n <= 0) {
- return;
- }
- bn_mul_add_words(&(r[2]), a, n, b[2]);
- if (--n <= 0) {
- return;
- }
- bn_mul_add_words(&(r[3]), a, n, b[3]);
- if (--n <= 0) {
- return;
- }
- bn_mul_add_words(&(r[4]), a, n, b[4]);
- r += 4;
- b += 4;
- }
-}
-
#if !defined(OPENSSL_X86) || defined(OPENSSL_NO_ASM)
/* Here follows specialised variants of bn_add_words() and bn_sub_words(). They
* have the property performing operations on arrays of different sizes. The
@@ -618,7 +598,8 @@ int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) {
}
}
- if ((al >= BN_MULL_SIZE_NORMAL) && (bl >= BN_MULL_SIZE_NORMAL)) {
+ static const int kMulNormalSize = 16;
+ if (al >= kMulNormalSize && bl >= kMulNormalSize) {
if (i >= -1 && i <= 1) {
/* Find out the power of two lower or equal
to the longest of the two numbers */
diff --git a/src/crypto/bn/rsaz_exp.c b/src/crypto/bn/rsaz_exp.c
index c8027520..30f08e5f 100644
--- a/src/crypto/bn/rsaz_exp.c
+++ b/src/crypto/bn/rsaz_exp.c
@@ -48,6 +48,9 @@
#include <openssl/mem.h>
+#include "../internal.h"
+
+
/*
* See crypto/bn/asm/rsaz-avx2.pl for further details.
*/
@@ -58,42 +61,30 @@ void rsaz_1024_scatter5_avx2(void *tbl,const void *val,int i);
void rsaz_1024_gather5_avx2(void *val,const void *tbl,int i);
void rsaz_1024_red2norm_avx2(void *norm,const void *red);
-#if defined(__GNUC__)
-# define ALIGN64 __attribute__((aligned(64)))
-#elif defined(_MSC_VER)
-# define ALIGN64 __declspec(align(64))
-#elif defined(__SUNPRO_C)
-# define ALIGN64
-# pragma align 64(one,two80)
-#else
-# define ALIGN64 /* not fatal, might hurt performance a little */
-#endif
-
-ALIGN64 static const BN_ULONG one[40] =
+alignas(64) static const BN_ULONG one[40] =
{1,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,0,0,0,0,0,0,0,0};
-ALIGN64 static const BN_ULONG two80[40] =
+alignas(64) static const BN_ULONG two80[40] =
{0,0,1<<22,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,0,0,0,0,0,0};
void RSAZ_1024_mod_exp_avx2(BN_ULONG result_norm[16],
const BN_ULONG base_norm[16], const BN_ULONG exponent[16],
const BN_ULONG m_norm[16], const BN_ULONG RR[16], BN_ULONG k0)
{
- unsigned char storage[320*3+32*9*16+64]; /* 5.5KB */
- unsigned char *p_str = storage + (64-((size_t)storage%64));
+ alignas(64) uint8_t storage[(320 * 3) + (32 * 9 * 16)]; /* 5.5KB */
unsigned char *a_inv, *m, *result,
- *table_s = p_str+320*3,
+ *table_s = storage + (320 * 3),
*R2 = table_s; /* borrow */
int index;
int wvalue;
- if ((((size_t)p_str&4095)+320)>>12) {
- result = p_str;
- a_inv = p_str + 320;
- m = p_str + 320*2; /* should not cross page */
+ if (((((uintptr_t)storage & 4095) + 320) >> 12) != 0) {
+ result = storage;
+ a_inv = storage + 320;
+ m = storage + (320 * 2); /* should not cross page */
} else {
- m = p_str; /* should not cross page */
- result = p_str + 320;
- a_inv = p_str + 320*2;
+ m = storage; /* should not cross page */
+ result = storage + 320;
+ a_inv = storage + (320 * 2);
}
rsaz_1024_norm2red_avx2(m, m_norm);
@@ -224,8 +215,9 @@ void RSAZ_1024_mod_exp_avx2(BN_ULONG result_norm[16],
rsaz_1024_scatter5_avx2(table_s,result,31);
#endif
+ const uint8_t *p_str = (const uint8_t *)exponent;
+
/* load first window */
- p_str = (unsigned char*)exponent;
wvalue = p_str[127] >> 3;
rsaz_1024_gather5_avx2(result,table_s,wvalue);
@@ -235,7 +227,7 @@ void RSAZ_1024_mod_exp_avx2(BN_ULONG result_norm[16],
rsaz_1024_sqr_avx2(result, result, m, k0, 5);
- wvalue = *((unsigned short*)&p_str[index/8]);
+ wvalue = *((const unsigned short*)&p_str[index / 8]);
wvalue = (wvalue>> (index%8)) & 31;
index-=5;
@@ -274,11 +266,10 @@ void RSAZ_512_mod_exp(BN_ULONG result[8],
const BN_ULONG base[8], const BN_ULONG exponent[8],
const BN_ULONG m[8], BN_ULONG k0, const BN_ULONG RR[8])
{
- unsigned char storage[16*8*8+64*2+64]; /* 1.2KB */
- unsigned char *table = storage + (64-((size_t)storage%64));
+ alignas(64) uint8_t storage[(16*8*8) + (64 * 2)]; /* 1.2KB */
+ unsigned char *table = storage;
BN_ULONG *a_inv = (BN_ULONG *)(table+16*8*8),
*temp = (BN_ULONG *)(table+16*8*8+8*8);
- unsigned char *p_str = (unsigned char*)exponent;
int index;
unsigned int wvalue;
@@ -300,6 +291,8 @@ void RSAZ_512_mod_exp(BN_ULONG result[8],
for (index=3; index<16; index++)
rsaz_512_mul_scatter4(temp, a_inv, m, k0, table, index);
+ const uint8_t *p_str = (const uint8_t *)exponent;
+
/* load first window */
wvalue = p_str[63];
diff --git a/src/crypto/bytestring/CMakeLists.txt b/src/crypto/bytestring/CMakeLists.txt
index 33d3c217..362e702f 100644
--- a/src/crypto/bytestring/CMakeLists.txt
+++ b/src/crypto/bytestring/CMakeLists.txt
@@ -5,6 +5,7 @@ add_library(
OBJECT
+ asn1_compat.c
ber.c
cbs.c
cbb.c
diff --git a/src/crypto/bytestring/asn1_compat.c b/src/crypto/bytestring/asn1_compat.c
new file mode 100644
index 00000000..b17d2d12
--- /dev/null
+++ b/src/crypto/bytestring/asn1_compat.c
@@ -0,0 +1,51 @@
+/* Copyright (c) 2016, 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/bytestring.h>
+
+#include <assert.h>
+#include <limits.h>
+#include <string.h>
+
+#include <openssl/mem.h>
+
+#include "internal.h"
+
+
+int CBB_finish_i2d(CBB *cbb, uint8_t **outp) {
+ assert(cbb->base->can_resize);
+
+ uint8_t *der;
+ size_t der_len;
+ if (!CBB_finish(cbb, &der, &der_len)) {
+ CBB_cleanup(cbb);
+ return -1;
+ }
+ if (der_len > INT_MAX) {
+ 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/bytestring/ber.c b/src/crypto/bytestring/ber.c
index 9e8daaa5..04fcac6a 100644
--- a/src/crypto/bytestring/ber.c
+++ b/src/crypto/bytestring/ber.c
@@ -14,6 +14,7 @@
#include <openssl/bytestring.h>
+#include <assert.h>
#include <string.h>
#include "internal.h"
@@ -24,11 +25,37 @@
* input could otherwise cause the stack to overflow. */
static const unsigned kMaxDepth = 2048;
+/* is_string_type returns one if |tag| is a string type and zero otherwise. It
+ * ignores the constructed bit. */
+static int is_string_type(unsigned tag) {
+ if ((tag & 0xc0) != 0) {
+ return 0;
+ }
+ switch (tag & 0x1f) {
+ case CBS_ASN1_BITSTRING:
+ case CBS_ASN1_OCTETSTRING:
+ case CBS_ASN1_UTF8STRING:
+ case CBS_ASN1_NUMERICSTRING:
+ case CBS_ASN1_PRINTABLESTRING:
+ case CBS_ASN1_T16STRING:
+ case CBS_ASN1_VIDEOTEXSTRING:
+ case CBS_ASN1_IA5STRING:
+ case CBS_ASN1_GRAPHICSTRING:
+ case CBS_ASN1_VISIBLESTRING:
+ case CBS_ASN1_GENERALSTRING:
+ case CBS_ASN1_UNIVERSALSTRING:
+ case CBS_ASN1_BMPSTRING:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
/* cbs_find_ber walks an ASN.1 structure in |orig_in| and sets |*ber_found|
- * depending on whether an indefinite length element was found. The value of
- * |in| is not changed. It returns one on success (i.e. |*ber_found| was set)
- * and zero on error. */
-static int cbs_find_ber(CBS *orig_in, char *ber_found, unsigned depth) {
+ * depending on whether an indefinite length element or constructed string was
+ * found. The value of |orig_in| is not changed. It returns one on success (i.e.
+ * |*ber_found| was set) and zero on error. */
+static int cbs_find_ber(const CBS *orig_in, char *ber_found, unsigned depth) {
CBS in;
if (depth > kMaxDepth) {
@@ -49,10 +76,16 @@ static int cbs_find_ber(CBS *orig_in, char *ber_found, unsigned depth) {
if (CBS_len(&contents) == header_len &&
header_len > 0 &&
CBS_data(&contents)[header_len-1] == 0x80) {
+ /* Found an indefinite-length element. */
*ber_found = 1;
return 1;
}
if (tag & CBS_ASN1_CONSTRUCTED) {
+ if (is_string_type(tag)) {
+ /* Constructed strings are only legal in BER and require conversion. */
+ *ber_found = 1;
+ return 1;
+ }
if (!CBS_skip(&contents, header_len) ||
!cbs_find_ber(&contents, ber_found, depth + 1)) {
return 0;
@@ -63,16 +96,6 @@ static int cbs_find_ber(CBS *orig_in, char *ber_found, unsigned depth) {
return 1;
}
-/* is_primitive_type returns true if |tag| likely a primitive type. Normally
- * one can just test the "constructed" bit in the tag but, in BER, even
- * primitive tags can have the constructed bit if they have indefinite
- * length. */
-static char is_primitive_type(unsigned tag) {
- return (tag & 0xc0) == 0 &&
- (tag & 0x1f) != (CBS_ASN1_SEQUENCE & 0x1f) &&
- (tag & 0x1f) != (CBS_ASN1_SET & 0x1f);
-}
-
/* is_eoc returns true if |header_len| and |contents|, as returned by
* |CBS_get_any_ber_asn1_element|, indicate an "end of contents" (EOC) value. */
static char is_eoc(size_t header_len, CBS *contents) {
@@ -81,92 +104,65 @@ static char is_eoc(size_t header_len, CBS *contents) {
}
/* cbs_convert_ber reads BER data from |in| and writes DER data to |out|. If
- * |squash_header| is set then the top-level of elements from |in| will not
- * have their headers written. This is used when concatenating the fragments of
- * an indefinite length, primitive value. If |looking_for_eoc| is set then any
- * EOC elements found will cause the function to return after consuming it.
- * It returns one on success and zero on error. */
-static int cbs_convert_ber(CBS *in, CBB *out, char squash_header,
+ * |string_tag| is non-zero, then all elements must match |string_tag| up to the
+ * constructed bit and primitive element bodies are written to |out| without
+ * element headers. This is used when concatenating the fragments of a
+ * constructed string. If |looking_for_eoc| is set then any EOC elements found
+ * will cause the function to return after consuming it. It returns one on
+ * success and zero on error. */
+static int cbs_convert_ber(CBS *in, CBB *out, unsigned string_tag,
char looking_for_eoc, unsigned depth) {
+ assert(!(string_tag & CBS_ASN1_CONSTRUCTED));
+
if (depth > kMaxDepth) {
return 0;
}
while (CBS_len(in) > 0) {
CBS contents;
- unsigned tag;
+ unsigned tag, child_string_tag = string_tag;
size_t header_len;
CBB *out_contents, out_contents_storage;
if (!CBS_get_any_ber_asn1_element(in, &contents, &tag, &header_len)) {
return 0;
}
- out_contents = out;
- if (CBS_len(&contents) == header_len) {
- if (is_eoc(header_len, &contents)) {
- return looking_for_eoc;
- }
+ if (is_eoc(header_len, &contents)) {
+ return looking_for_eoc;
+ }
- if (header_len > 0 && CBS_data(&contents)[header_len - 1] == 0x80) {
- /* This is an indefinite length element. If it's a SEQUENCE or SET then
- * we just need to write the out the contents as normal, but with a
- * concrete length prefix.
- *
- * If it's a something else then the contents will be a series of BER
- * elements of the same type which need to be concatenated. */
- const char context_specific = (tag & 0xc0) == 0x80;
- 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, 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. */
- if (context_specific && (tag & CBS_ASN1_CONSTRUCTED)) {
- CBS in_copy, inner_contents;
- unsigned inner_tag;
- size_t inner_header_len;
-
- CBS_init(&in_copy, CBS_data(in), CBS_len(in));
- if (!CBS_get_any_ber_asn1_element(&in_copy, &inner_contents,
- &inner_tag, &inner_header_len)) {
- return 0;
- }
- if (CBS_len(&inner_contents) > inner_header_len &&
- is_primitive_type(inner_tag)) {
- squash_child_headers = 1;
- }
- }
-
- if (!squash_header) {
- unsigned out_tag = tag;
- if (squash_child_headers) {
- out_tag &= ~CBS_ASN1_CONSTRUCTED;
- }
- if (!CBB_add_asn1(out, &out_contents_storage, out_tag)) {
- return 0;
- }
- out_contents = &out_contents_storage;
- }
-
- if (!cbs_convert_ber(in, out_contents,
- squash_child_headers,
- 1 /* looking for eoc */, depth + 1)) {
- return 0;
- }
- if (out_contents != out && !CBB_flush(out)) {
- return 0;
- }
- continue;
+ if (string_tag != 0) {
+ /* This is part of a constructed string. All elements must match
+ * |string_tag| up to the constructed bit and get appended to |out|
+ * without a child element. */
+ if ((tag & ~CBS_ASN1_CONSTRUCTED) != string_tag) {
+ return 0;
+ }
+ out_contents = out;
+ } else {
+ unsigned out_tag = tag;
+ if ((tag & CBS_ASN1_CONSTRUCTED) && is_string_type(tag)) {
+ /* If a constructed string, clear the constructed bit and inform
+ * children to concatenate bodies. */
+ out_tag &= ~CBS_ASN1_CONSTRUCTED;
+ child_string_tag = out_tag;
+ }
+ if (!CBB_add_asn1(out, &out_contents_storage, out_tag)) {
+ return 0;
}
+ out_contents = &out_contents_storage;
}
- if (!squash_header) {
- if (!CBB_add_asn1(out, &out_contents_storage, tag)) {
+ if (CBS_len(&contents) == header_len && header_len > 0 &&
+ CBS_data(&contents)[header_len - 1] == 0x80) {
+ /* This is an indefinite length element. */
+ if (!cbs_convert_ber(in, out_contents, child_string_tag,
+ 1 /* looking for eoc */, depth + 1) ||
+ !CBB_flush(out)) {
return 0;
}
- out_contents = &out_contents_storage;
+ continue;
}
if (!CBS_skip(&contents, header_len)) {
@@ -174,18 +170,20 @@ static int cbs_convert_ber(CBS *in, CBB *out, char squash_header,
}
if (tag & CBS_ASN1_CONSTRUCTED) {
- if (!cbs_convert_ber(&contents, out_contents, 0 /* don't squash header */,
+ /* Recurse into children. */
+ if (!cbs_convert_ber(&contents, out_contents, child_string_tag,
0 /* not looking for eoc */, depth + 1)) {
return 0;
}
} else {
+ /* Copy primitive contents as-is. */
if (!CBB_add_bytes(out_contents, CBS_data(&contents),
CBS_len(&contents))) {
return 0;
}
}
- if (out_contents != out && !CBB_flush(out)) {
+ if (!CBB_flush(out)) {
return 0;
}
}
@@ -209,13 +207,57 @@ int CBS_asn1_ber_to_der(CBS *in, uint8_t **out, size_t *out_len) {
return 1;
}
- if (!CBB_init(&cbb, CBS_len(in))) {
- return 0;
- }
- if (!cbs_convert_ber(in, &cbb, 0, 0, 0)) {
+ if (!CBB_init(&cbb, CBS_len(in)) ||
+ !cbs_convert_ber(in, &cbb, 0, 0, 0) ||
+ !CBB_finish(&cbb, out, out_len)) {
CBB_cleanup(&cbb);
return 0;
}
- return CBB_finish(&cbb, out, out_len);
+ return 1;
+}
+
+int CBS_get_asn1_implicit_string(CBS *in, CBS *out, uint8_t **out_storage,
+ unsigned outer_tag, unsigned inner_tag) {
+ assert(!(outer_tag & CBS_ASN1_CONSTRUCTED));
+ assert(!(inner_tag & CBS_ASN1_CONSTRUCTED));
+ assert(is_string_type(inner_tag));
+
+ if (CBS_peek_asn1_tag(in, outer_tag)) {
+ /* Normal implicitly-tagged string. */
+ *out_storage = NULL;
+ return CBS_get_asn1(in, out, outer_tag);
+ }
+
+ /* Otherwise, try to parse an implicitly-tagged constructed string.
+ * |CBS_asn1_ber_to_der| is assumed to have run, so only allow one level deep
+ * of nesting. */
+ CBB result;
+ CBS child;
+ if (!CBB_init(&result, CBS_len(in)) ||
+ !CBS_get_asn1(in, &child, outer_tag | CBS_ASN1_CONSTRUCTED)) {
+ goto err;
+ }
+
+ while (CBS_len(&child) > 0) {
+ CBS chunk;
+ if (!CBS_get_asn1(&child, &chunk, inner_tag) ||
+ !CBB_add_bytes(&result, CBS_data(&chunk), CBS_len(&chunk))) {
+ goto err;
+ }
+ }
+
+ uint8_t *data;
+ size_t len;
+ if (!CBB_finish(&result, &data, &len)) {
+ goto err;
+ }
+
+ CBS_init(out, data, len);
+ *out_storage = data;
+ return 1;
+
+err:
+ CBB_cleanup(&result);
+ return 0;
}
diff --git a/src/crypto/bytestring/bytestring_test.cc b/src/crypto/bytestring/bytestring_test.cc
index 188c63d5..84ecffcd 100644
--- a/src/crypto/bytestring/bytestring_test.cc
+++ b/src/crypto/bytestring/bytestring_test.cc
@@ -579,7 +579,7 @@ static bool TestBerConvert() {
static const uint8_t kIndefBER[] = {0x30, 0x80, 0x01, 0x01, 0x02, 0x00, 0x00};
static const uint8_t kIndefDER[] = {0x30, 0x03, 0x01, 0x01, 0x02};
- // kOctetStringBER contains an indefinite length OCTETSTRING with two parts.
+ // kOctetStringBER contains an indefinite length OCTET STRING with two parts.
// These parts need to be concatenated in DER form.
static const uint8_t kOctetStringBER[] = {0x24, 0x80, 0x04, 0x02, 0, 1,
0x04, 0x02, 2, 3, 0x00, 0x00};
@@ -609,6 +609,16 @@ static bool TestBerConvert() {
0x6e, 0x10, 0x9b, 0xb8, 0x02, 0x02, 0x07, 0xd0,
};
+ // kConstructedStringBER contains a deeply-nested constructed OCTET STRING.
+ // The BER conversion collapses this to one level deep, but not completely.
+ static const uint8_t kConstructedStringBER[] = {
+ 0xa0, 0x10, 0x24, 0x06, 0x04, 0x01, 0x00, 0x04, 0x01,
+ 0x01, 0x24, 0x06, 0x04, 0x01, 0x02, 0x04, 0x01, 0x03,
+ };
+ static const uint8_t kConstructedStringDER[] = {
+ 0xa0, 0x08, 0x04, 0x02, 0x00, 0x01, 0x04, 0x02, 0x02, 0x03,
+ };
+
return DoBerConvert("kSimpleBER", kSimpleBER, sizeof(kSimpleBER),
kSimpleBER, sizeof(kSimpleBER)) &&
DoBerConvert("kIndefBER", kIndefDER, sizeof(kIndefDER), kIndefBER,
@@ -617,7 +627,59 @@ static bool TestBerConvert() {
sizeof(kOctetStringDER), kOctetStringBER,
sizeof(kOctetStringBER)) &&
DoBerConvert("kNSSBER", kNSSDER, sizeof(kNSSDER), kNSSBER,
- sizeof(kNSSBER));
+ sizeof(kNSSBER)) &&
+ DoBerConvert("kConstructedStringBER", kConstructedStringDER,
+ sizeof(kConstructedStringDER), kConstructedStringBER,
+ sizeof(kConstructedStringBER));
+}
+
+struct ImplicitStringTest {
+ const char *in;
+ size_t in_len;
+ bool ok;
+ const char *out;
+ size_t out_len;
+};
+
+static const ImplicitStringTest kImplicitStringTests[] = {
+ // A properly-encoded string.
+ {"\x80\x03\x61\x61\x61", 5, true, "aaa", 3},
+ // An implicit-tagged string.
+ {"\xa0\x09\x04\x01\x61\x04\x01\x61\x04\x01\x61", 11, true, "aaa", 3},
+ // |CBS_get_asn1_implicit_string| only accepts one level deep of nesting.
+ {"\xa0\x0b\x24\x06\x04\x01\x61\x04\x01\x61\x04\x01\x61", 13, false, nullptr,
+ 0},
+ // The outer tag must match.
+ {"\x81\x03\x61\x61\x61", 5, false, nullptr, 0},
+ {"\xa1\x09\x04\x01\x61\x04\x01\x61\x04\x01\x61", 11, false, nullptr, 0},
+ // The inner tag must match.
+ {"\xa1\x09\x0c\x01\x61\x0c\x01\x61\x0c\x01\x61", 11, false, nullptr, 0},
+};
+
+static bool TestImplicitString() {
+ for (const auto &test : kImplicitStringTests) {
+ uint8_t *storage = nullptr;
+ CBS in, out;
+ CBS_init(&in, reinterpret_cast<const uint8_t *>(test.in), test.in_len);
+ int ok = CBS_get_asn1_implicit_string(&in, &out, &storage,
+ CBS_ASN1_CONTEXT_SPECIFIC | 0,
+ CBS_ASN1_OCTETSTRING);
+ ScopedOpenSSLBytes scoper(storage);
+
+ if (static_cast<bool>(ok) != test.ok) {
+ fprintf(stderr, "CBS_get_asn1_implicit_string unexpectedly %s\n",
+ ok ? "succeeded" : "failed");
+ return false;
+ }
+
+ if (ok && (CBS_len(&out) != test.out_len ||
+ memcmp(CBS_data(&out), test.out, test.out_len) != 0)) {
+ fprintf(stderr, "CBS_get_asn1_implicit_string gave the wrong output\n");
+ return false;
+ }
+ }
+
+ return true;
}
struct ASN1Uint64Test {
@@ -747,6 +809,7 @@ int main(void) {
!TestCBBDiscardChild() ||
!TestCBBASN1() ||
!TestBerConvert() ||
+ !TestImplicitString() ||
!TestASN1Uint64() ||
!TestGetOptionalASN1Bool() ||
!TestZero() ||
diff --git a/src/crypto/bytestring/cbs.c b/src/crypto/bytestring/cbs.c
index 5e0c538a..ed54b499 100644
--- a/src/crypto/bytestring/cbs.c
+++ b/src/crypto/bytestring/cbs.c
@@ -181,8 +181,14 @@ static int cbs_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
return 0;
}
+ /* ITU-T X.690 section 8.1.2.3 specifies the format for identifiers with a tag
+ * number no greater than 30.
+ *
+ * If the number portion is 31 (0x1f, the largest value that fits in the
+ * allotted bits), then the tag is more than one byte long and the
+ * continuation bytes contain the tag number. This parser only supports tag
+ * numbers less than 31 (and thus single-byte tags). */
if ((tag & 0x1f) == 0x1f) {
- /* Long form tags are not supported. */
return 0;
}
@@ -191,6 +197,8 @@ static int cbs_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
}
size_t len;
+ /* The format for the length encoding is specified in ITU-T X.690 section
+ * 8.1.3. */
if ((length_byte & 0x80) == 0) {
/* Short form length. */
len = ((size_t) length_byte) + 2;
@@ -198,7 +206,9 @@ static int cbs_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
*out_header_len = 2;
}
} else {
- /* Long form length. */
+ /* The high bit indicate that this is the long form, while the next 7 bits
+ * encode the number of subsequent octets used to encode the length (ITU-T
+ * X.690 clause 8.1.3.5.b). */
const size_t num_bytes = length_byte & 0x7f;
uint32_t len32;
@@ -210,12 +220,18 @@ static int cbs_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
return CBS_get_bytes(cbs, out, 2);
}
+ /* ITU-T X.690 clause 8.1.3.5.c specifies that the value 0xff shall not be
+ * used as the first byte of the length. If this parser encounters that
+ * value, num_bytes will be parsed as 127, which will fail the check below.
+ */
if (num_bytes == 0 || num_bytes > 4) {
return 0;
}
if (!cbs_get_u(&header, &len32, num_bytes)) {
return 0;
}
+ /* ITU-T X.690 section 10.1 (DER length forms) requires encoding the length
+ * with the minimum number of octets. */
if (len32 < 128) {
/* Length should have used short-form encoding. */
return 0;
diff --git a/src/crypto/bytestring/internal.h b/src/crypto/bytestring/internal.h
index b4ea7e51..2fed4139 100644
--- a/src/crypto/bytestring/internal.h
+++ b/src/crypto/bytestring/internal.h
@@ -22,22 +22,51 @@ extern "C" {
#endif
-/* CBS_asn1_ber_to_der reads an ASN.1 structure from |in|. If it finds
- * indefinite-length elements then it attempts to convert the BER data to DER
- * and sets |*out| and |*out_length| to describe a malloced buffer containing
- * the DER data. Additionally, |*in| will be advanced over the ASN.1 data.
+/* CBS_asn1_ber_to_der reads a BER element from |in|. If it finds
+ * indefinite-length elements or constructed strings then it converts the BER
+ * data to DER and sets |*out| and |*out_length| to describe a malloced buffer
+ * containing the DER data. Additionally, |*in| will be advanced over the BER
+ * element.
*
- * If it doesn't find any indefinite-length elements then it sets |*out| to
- * NULL and |*in| is unmodified.
+ * If it doesn't find any indefinite-length elements or constructed strings then
+ * it sets |*out| to NULL and |*in| is unmodified.
*
- * A sufficiently complex ASN.1 structure will break this function because it's
- * not possible to generically convert BER to DER without knowledge of the
- * structure itself. However, this sufficies to handle the PKCS#7 and #12 output
- * from NSS.
+ * This function should successfully process any valid BER input, however it
+ * will not convert all of BER's deviations from DER. BER is ambiguous between
+ * implicitly-tagged SEQUENCEs of strings and implicitly-tagged constructed
+ * strings. Implicitly-tagged strings must be parsed with
+ * |CBS_get_ber_implicitly_tagged_string| instead of |CBS_get_asn1|. The caller
+ * must also account for BER variations in the contents of a primitive.
*
* 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_asn1_implicit_string parses a BER string of primitive type
+ * |inner_tag| implicitly-tagged with |outer_tag|. It sets |out| to the
+ * contents. If concatenation was needed, it sets |*out_storage| to a buffer
+ * which the caller must release with |OPENSSL_free|. Otherwise, it sets
+ * |*out_storage| to NULL.
+ *
+ * This function does not parse all of BER. It requires the string be
+ * definite-length. Constructed strings are allowed, but all children of the
+ * outermost element must be primitive. The caller should use
+ * |CBS_asn1_ber_to_der| before running this function.
+ *
+ * It returns one on success and zero otherwise. */
+OPENSSL_EXPORT int CBS_get_asn1_implicit_string(CBS *in, CBS *out,
+ uint8_t **out_storage,
+ unsigned outer_tag,
+ unsigned inner_tag);
+
+/* CBB_finish_i2d calls |CBB_finish| on |cbb| which must have been initialized
+ * with |CBB_init|. 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. On
+ * error, it calls |CBB_cleanup| on |cbb|.
+ *
+ * This function may be used to help implement legacy i2d ASN.1 functions. */
+int CBB_finish_i2d(CBB *cbb, uint8_t **outp);
+
#if defined(__cplusplus)
} /* extern C */
diff --git a/src/crypto/chacha/CMakeLists.txt b/src/crypto/chacha/CMakeLists.txt
index 266e8699..39d1defb 100644
--- a/src/crypto/chacha/CMakeLists.txt
+++ b/src/crypto/chacha/CMakeLists.txt
@@ -4,7 +4,31 @@ if (${ARCH} STREQUAL "arm")
set(
CHACHA_ARCH_SOURCES
- chacha_vec_arm.S
+ chacha-armv4.${ASM_EXT}
+ )
+endif()
+
+if (${ARCH} STREQUAL "aarch64")
+ set(
+ CHACHA_ARCH_SOURCES
+
+ chacha-armv8.${ASM_EXT}
+ )
+endif()
+
+if (${ARCH} STREQUAL "x86")
+ set(
+ CHACHA_ARCH_SOURCES
+
+ chacha-x86.${ASM_EXT}
+ )
+endif()
+
+if (${ARCH} STREQUAL "x86_64")
+ set(
+ CHACHA_ARCH_SOURCES
+
+ chacha-x86_64.${ASM_EXT}
)
endif()
@@ -13,8 +37,22 @@ add_library(
OBJECT
- chacha_generic.c
- chacha_vec.c
+ chacha.c
${CHACHA_ARCH_SOURCES}
)
+
+add_executable(
+ chacha_test
+
+ chacha_test.cc
+ $<TARGET_OBJECTS:test_support>
+)
+
+target_link_libraries(chacha_test crypto)
+add_dependencies(all_tests chacha_test)
+
+perlasm(chacha-armv4.${ASM_EXT} asm/chacha-armv4.pl)
+perlasm(chacha-armv8.${ASM_EXT} asm/chacha-armv8.pl)
+perlasm(chacha-x86.${ASM_EXT} asm/chacha-x86.pl)
+perlasm(chacha-x86_64.${ASM_EXT} asm/chacha-x86_64.pl) \ No newline at end of file
diff --git a/src/crypto/chacha/asm/chacha-armv4.pl b/src/crypto/chacha/asm/chacha-armv4.pl
new file mode 100755
index 00000000..b190445d
--- /dev/null
+++ b/src/crypto/chacha/asm/chacha-armv4.pl
@@ -0,0 +1,1151 @@
+#!/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/.
+# ====================================================================
+#
+# December 2014
+#
+# ChaCha20 for ARMv4.
+#
+# Performance in cycles per byte out of large buffer.
+#
+# IALU/gcc-4.4 1xNEON 3xNEON+1xIALU
+#
+# Cortex-A5 19.3(*)/+95% 21.8 14.1
+# Cortex-A8 10.5(*)/+160% 13.9 6.35
+# Cortex-A9 12.9(**)/+110% 14.3 6.50
+# Cortex-A15 11.0/+40% 16.0 5.00
+# Snapdragon S4 11.5/+125% 13.6 4.90
+#
+# (*) most "favourable" result for aligned data on little-endian
+# processor, result for misaligned data is 10-15% lower;
+# (**) this result is a trade-off: it can be improved by 20%,
+# but then Snapdragon S4 and Cortex-A8 results get
+# 20-25% worse;
+
+$flavour = shift;
+if ($flavour=~/^\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; }
+else { while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {} }
+
+if ($flavour && $flavour ne "void") {
+ $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 STDOUT,"| \"$^X\" $xlate $flavour $output";
+} else {
+ open STDOUT,">$output";
+}
+
+sub AUTOLOAD() # thunk [simplified] x86-style perlasm
+{ my $opcode = $AUTOLOAD; $opcode =~ s/.*:://; $opcode =~ s/_/\./;
+ my $arg = pop;
+ $arg = "#$arg" if ($arg*1 eq $arg);
+ $code .= "\t$opcode\t".join(',',@_,$arg)."\n";
+}
+
+my @x=map("r$_",(0..7,"x","x","x","x",12,"x",14,"x"));
+my @t=map("r$_",(8..11));
+
+sub ROUND {
+my ($a0,$b0,$c0,$d0)=@_;
+my ($a1,$b1,$c1,$d1)=map(($_&~3)+(($_+1)&3),($a0,$b0,$c0,$d0));
+my ($a2,$b2,$c2,$d2)=map(($_&~3)+(($_+1)&3),($a1,$b1,$c1,$d1));
+my ($a3,$b3,$c3,$d3)=map(($_&~3)+(($_+1)&3),($a2,$b2,$c2,$d2));
+my $odd = $d0&1;
+my ($xc,$xc_) = (@t[0..1]);
+my ($xd,$xd_) = $odd ? (@t[2],@x[$d1]) : (@x[$d0],@t[2]);
+my @ret;
+
+ # Consider order in which variables are addressed by their
+ # index:
+ #
+ # a b c d
+ #
+ # 0 4 8 12 < even round
+ # 1 5 9 13
+ # 2 6 10 14
+ # 3 7 11 15
+ # 0 5 10 15 < odd round
+ # 1 6 11 12
+ # 2 7 8 13
+ # 3 4 9 14
+ #
+ # 'a', 'b' are permanently allocated in registers, @x[0..7],
+ # while 'c's and pair of 'd's are maintained in memory. If
+ # you observe 'c' column, you'll notice that pair of 'c's is
+ # invariant between rounds. This means that we have to reload
+ # them once per round, in the middle. This is why you'll see
+ # bunch of 'c' stores and loads in the middle, but none in
+ # the beginning or end. If you observe 'd' column, you'll
+ # notice that 15 and 13 are reused in next pair of rounds.
+ # This is why these two are chosen for offloading to memory,
+ # to make loads count more.
+ push @ret,(
+ "&add (@x[$a0],@x[$a0],@x[$b0])",
+ "&mov ($xd,$xd,'ror#16')",
+ "&add (@x[$a1],@x[$a1],@x[$b1])",
+ "&mov ($xd_,$xd_,'ror#16')",
+ "&eor ($xd,$xd,@x[$a0],'ror#16')",
+ "&eor ($xd_,$xd_,@x[$a1],'ror#16')",
+
+ "&add ($xc,$xc,$xd)",
+ "&mov (@x[$b0],@x[$b0],'ror#20')",
+ "&add ($xc_,$xc_,$xd_)",
+ "&mov (@x[$b1],@x[$b1],'ror#20')",
+ "&eor (@x[$b0],@x[$b0],$xc,'ror#20')",
+ "&eor (@x[$b1],@x[$b1],$xc_,'ror#20')",
+
+ "&add (@x[$a0],@x[$a0],@x[$b0])",
+ "&mov ($xd,$xd,'ror#24')",
+ "&add (@x[$a1],@x[$a1],@x[$b1])",
+ "&mov ($xd_,$xd_,'ror#24')",
+ "&eor ($xd,$xd,@x[$a0],'ror#24')",
+ "&eor ($xd_,$xd_,@x[$a1],'ror#24')",
+
+ "&add ($xc,$xc,$xd)",
+ "&mov (@x[$b0],@x[$b0],'ror#25')" );
+ push @ret,(
+ "&str ($xd,'[sp,#4*(16+$d0)]')",
+ "&ldr ($xd,'[sp,#4*(16+$d2)]')" ) if ($odd);
+ push @ret,(
+ "&add ($xc_,$xc_,$xd_)",
+ "&mov (@x[$b1],@x[$b1],'ror#25')" );
+ push @ret,(
+ "&str ($xd_,'[sp,#4*(16+$d1)]')",
+ "&ldr ($xd_,'[sp,#4*(16+$d3)]')" ) if (!$odd);
+ push @ret,(
+ "&eor (@x[$b0],@x[$b0],$xc,'ror#25')",
+ "&eor (@x[$b1],@x[$b1],$xc_,'ror#25')" );
+
+ $xd=@x[$d2] if (!$odd);
+ $xd_=@x[$d3] if ($odd);
+ push @ret,(
+ "&str ($xc,'[sp,#4*(16+$c0)]')",
+ "&ldr ($xc,'[sp,#4*(16+$c2)]')",
+ "&add (@x[$a2],@x[$a2],@x[$b2])",
+ "&mov ($xd,$xd,'ror#16')",
+ "&str ($xc_,'[sp,#4*(16+$c1)]')",
+ "&ldr ($xc_,'[sp,#4*(16+$c3)]')",
+ "&add (@x[$a3],@x[$a3],@x[$b3])",
+ "&mov ($xd_,$xd_,'ror#16')",
+ "&eor ($xd,$xd,@x[$a2],'ror#16')",
+ "&eor ($xd_,$xd_,@x[$a3],'ror#16')",
+
+ "&add ($xc,$xc,$xd)",
+ "&mov (@x[$b2],@x[$b2],'ror#20')",
+ "&add ($xc_,$xc_,$xd_)",
+ "&mov (@x[$b3],@x[$b3],'ror#20')",
+ "&eor (@x[$b2],@x[$b2],$xc,'ror#20')",
+ "&eor (@x[$b3],@x[$b3],$xc_,'ror#20')",
+
+ "&add (@x[$a2],@x[$a2],@x[$b2])",
+ "&mov ($xd,$xd,'ror#24')",
+ "&add (@x[$a3],@x[$a3],@x[$b3])",
+ "&mov ($xd_,$xd_,'ror#24')",
+ "&eor ($xd,$xd,@x[$a2],'ror#24')",
+ "&eor ($xd_,$xd_,@x[$a3],'ror#24')",
+
+ "&add ($xc,$xc,$xd)",
+ "&mov (@x[$b2],@x[$b2],'ror#25')",
+ "&add ($xc_,$xc_,$xd_)",
+ "&mov (@x[$b3],@x[$b3],'ror#25')",
+ "&eor (@x[$b2],@x[$b2],$xc,'ror#25')",
+ "&eor (@x[$b3],@x[$b3],$xc_,'ror#25')" );
+
+ @ret;
+}
+
+$code.=<<___;
+#include <openssl/arm_arch.h>
+
+.text
+#if defined(__thumb2__)
+.syntax unified
+.thumb
+#else
+.code 32
+#endif
+
+#if defined(__thumb2__) || defined(__clang__)
+#define ldrhsb ldrbhs
+#endif
+
+.align 5
+.Lsigma:
+.long 0x61707865,0x3320646e,0x79622d32,0x6b206574 @ endian-neutral
+.Lone:
+.long 1,0,0,0
+#if __ARM_MAX_ARCH__>=7
+.LOPENSSL_armcap:
+.word OPENSSL_armcap_P-.LChaCha20_ctr32
+#else
+.word -1
+#endif
+
+.globl ChaCha20_ctr32
+.type ChaCha20_ctr32,%function
+.align 5
+ChaCha20_ctr32:
+.LChaCha20_ctr32:
+ ldr r12,[sp,#0] @ pull pointer to counter and nonce
+ stmdb sp!,{r0-r2,r4-r11,lr}
+#if __ARM_ARCH__<7 && !defined(__thumb2__)
+ sub r14,pc,#16 @ ChaCha20_ctr32
+#else
+ adr r14,.LChaCha20_ctr32
+#endif
+ cmp r2,#0 @ len==0?
+#ifdef __thumb2__
+ itt eq
+#endif
+ addeq sp,sp,#4*3
+ beq .Lno_data
+#if __ARM_MAX_ARCH__>=7
+ cmp r2,#192 @ test len
+ bls .Lshort
+ ldr r4,[r14,#-32]
+ ldr r4,[r14,r4]
+# ifdef __APPLE__
+ ldr r4,[r4]
+# endif
+ tst r4,#ARMV7_NEON
+ bne .LChaCha20_neon
+.Lshort:
+#endif
+ ldmia r12,{r4-r7} @ load counter and nonce
+ sub sp,sp,#4*(16) @ off-load area
+ sub r14,r14,#64 @ .Lsigma
+ stmdb sp!,{r4-r7} @ copy counter and nonce
+ ldmia r3,{r4-r11} @ load key
+ ldmia r14,{r0-r3} @ load sigma
+ stmdb sp!,{r4-r11} @ copy key
+ stmdb sp!,{r0-r3} @ copy sigma
+ str r10,[sp,#4*(16+10)] @ off-load "@x[10]"
+ str r11,[sp,#4*(16+11)] @ off-load "@x[11]"
+ b .Loop_outer_enter
+
+.align 4
+.Loop_outer:
+ ldmia sp,{r0-r9} @ load key material
+ str @t[3],[sp,#4*(32+2)] @ save len
+ str r12, [sp,#4*(32+1)] @ save inp
+ str r14, [sp,#4*(32+0)] @ save out
+.Loop_outer_enter:
+ ldr @t[3], [sp,#4*(15)]
+ ldr @x[12],[sp,#4*(12)] @ modulo-scheduled load
+ ldr @t[2], [sp,#4*(13)]
+ ldr @x[14],[sp,#4*(14)]
+ str @t[3], [sp,#4*(16+15)]
+ mov @t[3],#10
+ b .Loop
+
+.align 4
+.Loop:
+ subs @t[3],@t[3],#1
+___
+ foreach (&ROUND(0, 4, 8,12)) { eval; }
+ foreach (&ROUND(0, 5,10,15)) { eval; }
+$code.=<<___;
+ bne .Loop
+
+ ldr @t[3],[sp,#4*(32+2)] @ load len
+
+ str @t[0], [sp,#4*(16+8)] @ modulo-scheduled store
+ str @t[1], [sp,#4*(16+9)]
+ str @x[12],[sp,#4*(16+12)]
+ str @t[2], [sp,#4*(16+13)]
+ str @x[14],[sp,#4*(16+14)]
+
+ @ at this point we have first half of 512-bit result in
+ @ @x[0-7] and second half at sp+4*(16+8)
+
+ cmp @t[3],#64 @ done yet?
+#ifdef __thumb2__
+ itete lo
+#endif
+ addlo r12,sp,#4*(0) @ shortcut or ...
+ ldrhs r12,[sp,#4*(32+1)] @ ... load inp
+ addlo r14,sp,#4*(0) @ shortcut or ...
+ ldrhs r14,[sp,#4*(32+0)] @ ... load out
+
+ ldr @t[0],[sp,#4*(0)] @ load key material
+ ldr @t[1],[sp,#4*(1)]
+
+#if __ARM_ARCH__>=6 || !defined(__ARMEB__)
+# if __ARM_ARCH__<7
+ orr @t[2],r12,r14
+ tst @t[2],#3 @ are input and output aligned?
+ ldr @t[2],[sp,#4*(2)]
+ bne .Lunaligned
+ cmp @t[3],#64 @ restore flags
+# else
+ ldr @t[2],[sp,#4*(2)]
+# endif
+ ldr @t[3],[sp,#4*(3)]
+
+ add @x[0],@x[0],@t[0] @ accumulate key material
+ add @x[1],@x[1],@t[1]
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhs @t[0],[r12],#16 @ load input
+ ldrhs @t[1],[r12,#-12]
+
+ add @x[2],@x[2],@t[2]
+ add @x[3],@x[3],@t[3]
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhs @t[2],[r12,#-8]
+ ldrhs @t[3],[r12,#-4]
+# if __ARM_ARCH__>=6 && defined(__ARMEB__)
+ rev @x[0],@x[0]
+ rev @x[1],@x[1]
+ rev @x[2],@x[2]
+ rev @x[3],@x[3]
+# endif
+# ifdef __thumb2__
+ itt hs
+# endif
+ eorhs @x[0],@x[0],@t[0] @ xor with input
+ eorhs @x[1],@x[1],@t[1]
+ add @t[0],sp,#4*(4)
+ str @x[0],[r14],#16 @ store output
+# ifdef __thumb2__
+ itt hs
+# endif
+ eorhs @x[2],@x[2],@t[2]
+ eorhs @x[3],@x[3],@t[3]
+ ldmia @t[0],{@t[0]-@t[3]} @ load key material
+ str @x[1],[r14,#-12]
+ str @x[2],[r14,#-8]
+ str @x[3],[r14,#-4]
+
+ add @x[4],@x[4],@t[0] @ accumulate key material
+ add @x[5],@x[5],@t[1]
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhs @t[0],[r12],#16 @ load input
+ ldrhs @t[1],[r12,#-12]
+ add @x[6],@x[6],@t[2]
+ add @x[7],@x[7],@t[3]
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhs @t[2],[r12,#-8]
+ ldrhs @t[3],[r12,#-4]
+# if __ARM_ARCH__>=6 && defined(__ARMEB__)
+ rev @x[4],@x[4]
+ rev @x[5],@x[5]
+ rev @x[6],@x[6]
+ rev @x[7],@x[7]
+# endif
+# ifdef __thumb2__
+ itt hs
+# endif
+ eorhs @x[4],@x[4],@t[0]
+ eorhs @x[5],@x[5],@t[1]
+ add @t[0],sp,#4*(8)
+ str @x[4],[r14],#16 @ store output
+# ifdef __thumb2__
+ itt hs
+# endif
+ eorhs @x[6],@x[6],@t[2]
+ eorhs @x[7],@x[7],@t[3]
+ str @x[5],[r14,#-12]
+ ldmia @t[0],{@t[0]-@t[3]} @ load key material
+ str @x[6],[r14,#-8]
+ add @x[0],sp,#4*(16+8)
+ str @x[7],[r14,#-4]
+
+ ldmia @x[0],{@x[0]-@x[7]} @ load second half
+
+ add @x[0],@x[0],@t[0] @ accumulate key material
+ add @x[1],@x[1],@t[1]
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhs @t[0],[r12],#16 @ load input
+ ldrhs @t[1],[r12,#-12]
+# ifdef __thumb2__
+ itt hi
+# endif
+ strhi @t[2],[sp,#4*(16+10)] @ copy "@x[10]" while at it
+ strhi @t[3],[sp,#4*(16+11)] @ copy "@x[11]" while at it
+ add @x[2],@x[2],@t[2]
+ add @x[3],@x[3],@t[3]
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhs @t[2],[r12,#-8]
+ ldrhs @t[3],[r12,#-4]
+# if __ARM_ARCH__>=6 && defined(__ARMEB__)
+ rev @x[0],@x[0]
+ rev @x[1],@x[1]
+ rev @x[2],@x[2]
+ rev @x[3],@x[3]
+# endif
+# ifdef __thumb2__
+ itt hs
+# endif
+ eorhs @x[0],@x[0],@t[0]
+ eorhs @x[1],@x[1],@t[1]
+ add @t[0],sp,#4*(12)
+ str @x[0],[r14],#16 @ store output
+# ifdef __thumb2__
+ itt hs
+# endif
+ eorhs @x[2],@x[2],@t[2]
+ eorhs @x[3],@x[3],@t[3]
+ str @x[1],[r14,#-12]
+ ldmia @t[0],{@t[0]-@t[3]} @ load key material
+ str @x[2],[r14,#-8]
+ str @x[3],[r14,#-4]
+
+ add @x[4],@x[4],@t[0] @ accumulate key material
+ add @x[5],@x[5],@t[1]
+# ifdef __thumb2__
+ itt hi
+# endif
+ addhi @t[0],@t[0],#1 @ next counter value
+ strhi @t[0],[sp,#4*(12)] @ save next counter value
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhs @t[0],[r12],#16 @ load input
+ ldrhs @t[1],[r12,#-12]
+ add @x[6],@x[6],@t[2]
+ add @x[7],@x[7],@t[3]
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhs @t[2],[r12,#-8]
+ ldrhs @t[3],[r12,#-4]
+# if __ARM_ARCH__>=6 && defined(__ARMEB__)
+ rev @x[4],@x[4]
+ rev @x[5],@x[5]
+ rev @x[6],@x[6]
+ rev @x[7],@x[7]
+# endif
+# ifdef __thumb2__
+ itt hs
+# endif
+ eorhs @x[4],@x[4],@t[0]
+ eorhs @x[5],@x[5],@t[1]
+# ifdef __thumb2__
+ it ne
+# endif
+ ldrne @t[0],[sp,#4*(32+2)] @ re-load len
+# ifdef __thumb2__
+ itt hs
+# endif
+ eorhs @x[6],@x[6],@t[2]
+ eorhs @x[7],@x[7],@t[3]
+ str @x[4],[r14],#16 @ store output
+ str @x[5],[r14,#-12]
+# ifdef __thumb2__
+ it hs
+# endif
+ subhs @t[3],@t[0],#64 @ len-=64
+ str @x[6],[r14,#-8]
+ str @x[7],[r14,#-4]
+ bhi .Loop_outer
+
+ beq .Ldone
+# if __ARM_ARCH__<7
+ b .Ltail
+
+.align 4
+.Lunaligned: @ unaligned endian-neutral path
+ cmp @t[3],#64 @ restore flags
+# endif
+#endif
+#if __ARM_ARCH__<7
+ ldr @t[3],[sp,#4*(3)]
+___
+for ($i=0;$i<16;$i+=4) {
+my $j=$i&0x7;
+
+$code.=<<___ if ($i==4);
+ add @x[0],sp,#4*(16+8)
+___
+$code.=<<___ if ($i==8);
+ ldmia @x[0],{@x[0]-@x[7]} @ load second half
+# ifdef __thumb2__
+ itt hi
+# endif
+ strhi @t[2],[sp,#4*(16+10)] @ copy "@x[10]"
+ strhi @t[3],[sp,#4*(16+11)] @ copy "@x[11]"
+___
+$code.=<<___;
+ add @x[$j+0],@x[$j+0],@t[0] @ accumulate key material
+___
+$code.=<<___ if ($i==12);
+# ifdef __thumb2__
+ itt hi
+# endif
+ addhi @t[0],@t[0],#1 @ next counter value
+ strhi @t[0],[sp,#4*(12)] @ save next counter value
+___
+$code.=<<___;
+ add @x[$j+1],@x[$j+1],@t[1]
+ add @x[$j+2],@x[$j+2],@t[2]
+# ifdef __thumb2__
+ itete lo
+# endif
+ eorlo @t[0],@t[0],@t[0] @ zero or ...
+ ldrhsb @t[0],[r12],#16 @ ... load input
+ eorlo @t[1],@t[1],@t[1]
+ ldrhsb @t[1],[r12,#-12]
+
+ add @x[$j+3],@x[$j+3],@t[3]
+# ifdef __thumb2__
+ itete lo
+# endif
+ eorlo @t[2],@t[2],@t[2]
+ ldrhsb @t[2],[r12,#-8]
+ eorlo @t[3],@t[3],@t[3]
+ ldrhsb @t[3],[r12,#-4]
+
+ eor @x[$j+0],@t[0],@x[$j+0] @ xor with input (or zero)
+ eor @x[$j+1],@t[1],@x[$j+1]
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhsb @t[0],[r12,#-15] @ load more input
+ ldrhsb @t[1],[r12,#-11]
+ eor @x[$j+2],@t[2],@x[$j+2]
+ strb @x[$j+0],[r14],#16 @ store output
+ eor @x[$j+3],@t[3],@x[$j+3]
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhsb @t[2],[r12,#-7]
+ ldrhsb @t[3],[r12,#-3]
+ strb @x[$j+1],[r14,#-12]
+ eor @x[$j+0],@t[0],@x[$j+0],lsr#8
+ strb @x[$j+2],[r14,#-8]
+ eor @x[$j+1],@t[1],@x[$j+1],lsr#8
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhsb @t[0],[r12,#-14] @ load more input
+ ldrhsb @t[1],[r12,#-10]
+ strb @x[$j+3],[r14,#-4]
+ eor @x[$j+2],@t[2],@x[$j+2],lsr#8
+ strb @x[$j+0],[r14,#-15]
+ eor @x[$j+3],@t[3],@x[$j+3],lsr#8
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhsb @t[2],[r12,#-6]
+ ldrhsb @t[3],[r12,#-2]
+ strb @x[$j+1],[r14,#-11]
+ eor @x[$j+0],@t[0],@x[$j+0],lsr#8
+ strb @x[$j+2],[r14,#-7]
+ eor @x[$j+1],@t[1],@x[$j+1],lsr#8
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhsb @t[0],[r12,#-13] @ load more input
+ ldrhsb @t[1],[r12,#-9]
+ strb @x[$j+3],[r14,#-3]
+ eor @x[$j+2],@t[2],@x[$j+2],lsr#8
+ strb @x[$j+0],[r14,#-14]
+ eor @x[$j+3],@t[3],@x[$j+3],lsr#8
+# ifdef __thumb2__
+ itt hs
+# endif
+ ldrhsb @t[2],[r12,#-5]
+ ldrhsb @t[3],[r12,#-1]
+ strb @x[$j+1],[r14,#-10]
+ strb @x[$j+2],[r14,#-6]
+ eor @x[$j+0],@t[0],@x[$j+0],lsr#8
+ strb @x[$j+3],[r14,#-2]
+ eor @x[$j+1],@t[1],@x[$j+1],lsr#8
+ strb @x[$j+0],[r14,#-13]
+ eor @x[$j+2],@t[2],@x[$j+2],lsr#8
+ strb @x[$j+1],[r14,#-9]
+ eor @x[$j+3],@t[3],@x[$j+3],lsr#8
+ strb @x[$j+2],[r14,#-5]
+ strb @x[$j+3],[r14,#-1]
+___
+$code.=<<___ if ($i<12);
+ add @t[0],sp,#4*(4+$i)
+ ldmia @t[0],{@t[0]-@t[3]} @ load key material
+___
+}
+$code.=<<___;
+# ifdef __thumb2__
+ it ne
+# endif
+ ldrne @t[0],[sp,#4*(32+2)] @ re-load len
+# ifdef __thumb2__
+ it hs
+# endif
+ subhs @t[3],@t[0],#64 @ len-=64
+ bhi .Loop_outer
+
+ beq .Ldone
+#endif
+
+.Ltail:
+ ldr r12,[sp,#4*(32+1)] @ load inp
+ add @t[1],sp,#4*(0)
+ ldr r14,[sp,#4*(32+0)] @ load out
+
+.Loop_tail:
+ ldrb @t[2],[@t[1]],#1 @ read buffer on stack
+ ldrb @t[3],[r12],#1 @ read input
+ subs @t[0],@t[0],#1
+ eor @t[3],@t[3],@t[2]
+ strb @t[3],[r14],#1 @ store output
+ bne .Loop_tail
+
+.Ldone:
+ add sp,sp,#4*(32+3)
+.Lno_data:
+ ldmia sp!,{r4-r11,pc}
+.size ChaCha20_ctr32,.-ChaCha20_ctr32
+___
+
+{{{
+my ($a0,$b0,$c0,$d0,$a1,$b1,$c1,$d1,$a2,$b2,$c2,$d2,$t0,$t1,$t2,$t3) =
+ map("q$_",(0..15));
+
+sub NEONROUND {
+my $odd = pop;
+my ($a,$b,$c,$d,$t)=@_;
+
+ (
+ "&vadd_i32 ($a,$a,$b)",
+ "&veor ($d,$d,$a)",
+ "&vrev32_16 ($d,$d)", # vrot ($d,16)
+
+ "&vadd_i32 ($c,$c,$d)",
+ "&veor ($t,$b,$c)",
+ "&vshr_u32 ($b,$t,20)",
+ "&vsli_32 ($b,$t,12)",
+
+ "&vadd_i32 ($a,$a,$b)",
+ "&veor ($t,$d,$a)",
+ "&vshr_u32 ($d,$t,24)",
+ "&vsli_32 ($d,$t,8)",
+
+ "&vadd_i32 ($c,$c,$d)",
+ "&veor ($t,$b,$c)",
+ "&vshr_u32 ($b,$t,25)",
+ "&vsli_32 ($b,$t,7)",
+
+ "&vext_8 ($c,$c,$c,8)",
+ "&vext_8 ($b,$b,$b,$odd?12:4)",
+ "&vext_8 ($d,$d,$d,$odd?4:12)"
+ );
+}
+
+$code.=<<___;
+#if __ARM_MAX_ARCH__>=7
+.arch armv7-a
+.fpu neon
+
+.type ChaCha20_neon,%function
+.align 5
+ChaCha20_neon:
+ ldr r12,[sp,#0] @ pull pointer to counter and nonce
+ stmdb sp!,{r0-r2,r4-r11,lr}
+.LChaCha20_neon:
+ adr r14,.Lsigma
+ vstmdb sp!,{d8-d15} @ ABI spec says so
+ stmdb sp!,{r0-r3}
+
+ vld1.32 {$b0-$c0},[r3] @ load key
+ ldmia r3,{r4-r11} @ load key
+
+ sub sp,sp,#4*(16+16)
+ vld1.32 {$d0},[r12] @ load counter and nonce
+ add r12,sp,#4*8
+ ldmia r14,{r0-r3} @ load sigma
+ vld1.32 {$a0},[r14]! @ load sigma
+ vld1.32 {$t0},[r14] @ one
+ vst1.32 {$c0-$d0},[r12] @ copy 1/2key|counter|nonce
+ vst1.32 {$a0-$b0},[sp] @ copy sigma|1/2key
+
+ str r10,[sp,#4*(16+10)] @ off-load "@x[10]"
+ str r11,[sp,#4*(16+11)] @ off-load "@x[11]"
+ vshl.i32 $t1#lo,$t0#lo,#1 @ two
+ vstr $t0#lo,[sp,#4*(16+0)]
+ vshl.i32 $t2#lo,$t0#lo,#2 @ four
+ vstr $t1#lo,[sp,#4*(16+2)]
+ vmov $a1,$a0
+ vstr $t2#lo,[sp,#4*(16+4)]
+ vmov $a2,$a0
+ vmov $b1,$b0
+ vmov $b2,$b0
+ b .Loop_neon_enter
+
+.align 4
+.Loop_neon_outer:
+ ldmia sp,{r0-r9} @ load key material
+ cmp @t[3],#64*2 @ if len<=64*2
+ bls .Lbreak_neon @ switch to integer-only
+ vmov $a1,$a0
+ str @t[3],[sp,#4*(32+2)] @ save len
+ vmov $a2,$a0
+ str r12, [sp,#4*(32+1)] @ save inp
+ vmov $b1,$b0
+ str r14, [sp,#4*(32+0)] @ save out
+ vmov $b2,$b0
+.Loop_neon_enter:
+ ldr @t[3], [sp,#4*(15)]
+ vadd.i32 $d1,$d0,$t0 @ counter+1
+ ldr @x[12],[sp,#4*(12)] @ modulo-scheduled load
+ vmov $c1,$c0
+ ldr @t[2], [sp,#4*(13)]
+ vmov $c2,$c0
+ ldr @x[14],[sp,#4*(14)]
+ vadd.i32 $d2,$d1,$t0 @ counter+2
+ str @t[3], [sp,#4*(16+15)]
+ mov @t[3],#10
+ add @x[12],@x[12],#3 @ counter+3
+ b .Loop_neon
+
+.align 4
+.Loop_neon:
+ subs @t[3],@t[3],#1
+___
+ my @thread0=&NEONROUND($a0,$b0,$c0,$d0,$t0,0);
+ my @thread1=&NEONROUND($a1,$b1,$c1,$d1,$t1,0);
+ my @thread2=&NEONROUND($a2,$b2,$c2,$d2,$t2,0);
+ my @thread3=&ROUND(0,4,8,12);
+
+ foreach (@thread0) {
+ eval; eval(shift(@thread3));
+ eval(shift(@thread1)); eval(shift(@thread3));
+ eval(shift(@thread2)); eval(shift(@thread3));
+ }
+
+ @thread0=&NEONROUND($a0,$b0,$c0,$d0,$t0,1);
+ @thread1=&NEONROUND($a1,$b1,$c1,$d1,$t1,1);
+ @thread2=&NEONROUND($a2,$b2,$c2,$d2,$t2,1);
+ @thread3=&ROUND(0,5,10,15);
+
+ foreach (@thread0) {
+ eval; eval(shift(@thread3));
+ eval(shift(@thread1)); eval(shift(@thread3));
+ eval(shift(@thread2)); eval(shift(@thread3));
+ }
+$code.=<<___;
+ bne .Loop_neon
+
+ add @t[3],sp,#32
+ vld1.32 {$t0-$t1},[sp] @ load key material
+ vld1.32 {$t2-$t3},[@t[3]]
+
+ ldr @t[3],[sp,#4*(32+2)] @ load len
+
+ str @t[0], [sp,#4*(16+8)] @ modulo-scheduled store
+ str @t[1], [sp,#4*(16+9)]
+ str @x[12],[sp,#4*(16+12)]
+ str @t[2], [sp,#4*(16+13)]
+ str @x[14],[sp,#4*(16+14)]
+
+ @ at this point we have first half of 512-bit result in
+ @ @x[0-7] and second half at sp+4*(16+8)
+
+ ldr r12,[sp,#4*(32+1)] @ load inp
+ ldr r14,[sp,#4*(32+0)] @ load out
+
+ vadd.i32 $a0,$a0,$t0 @ accumulate key material
+ vadd.i32 $a1,$a1,$t0
+ vadd.i32 $a2,$a2,$t0
+ vldr $t0#lo,[sp,#4*(16+0)] @ one
+
+ vadd.i32 $b0,$b0,$t1
+ vadd.i32 $b1,$b1,$t1
+ vadd.i32 $b2,$b2,$t1
+ vldr $t1#lo,[sp,#4*(16+2)] @ two
+
+ vadd.i32 $c0,$c0,$t2
+ vadd.i32 $c1,$c1,$t2
+ vadd.i32 $c2,$c2,$t2
+ vadd.i32 $d1#lo,$d1#lo,$t0#lo @ counter+1
+ vadd.i32 $d2#lo,$d2#lo,$t1#lo @ counter+2
+
+ vadd.i32 $d0,$d0,$t3
+ vadd.i32 $d1,$d1,$t3
+ vadd.i32 $d2,$d2,$t3
+
+ cmp @t[3],#64*4
+ blo .Ltail_neon
+
+ vld1.8 {$t0-$t1},[r12]! @ load input
+ mov @t[3],sp
+ vld1.8 {$t2-$t3},[r12]!
+ veor $a0,$a0,$t0 @ xor with input
+ veor $b0,$b0,$t1
+ vld1.8 {$t0-$t1},[r12]!
+ veor $c0,$c0,$t2
+ veor $d0,$d0,$t3
+ vld1.8 {$t2-$t3},[r12]!
+
+ veor $a1,$a1,$t0
+ vst1.8 {$a0-$b0},[r14]! @ store output
+ veor $b1,$b1,$t1
+ vld1.8 {$t0-$t1},[r12]!
+ veor $c1,$c1,$t2
+ vst1.8 {$c0-$d0},[r14]!
+ veor $d1,$d1,$t3
+ vld1.8 {$t2-$t3},[r12]!
+
+ veor $a2,$a2,$t0
+ vld1.32 {$a0-$b0},[@t[3]]! @ load for next iteration
+ veor $t0#hi,$t0#hi,$t0#hi
+ vldr $t0#lo,[sp,#4*(16+4)] @ four
+ veor $b2,$b2,$t1
+ vld1.32 {$c0-$d0},[@t[3]]
+ veor $c2,$c2,$t2
+ vst1.8 {$a1-$b1},[r14]!
+ veor $d2,$d2,$t3
+ vst1.8 {$c1-$d1},[r14]!
+
+ vadd.i32 $d0#lo,$d0#lo,$t0#lo @ next counter value
+ vldr $t0#lo,[sp,#4*(16+0)] @ one
+
+ ldmia sp,{@t[0]-@t[3]} @ load key material
+ add @x[0],@x[0],@t[0] @ accumulate key material
+ ldr @t[0],[r12],#16 @ load input
+ vst1.8 {$a2-$b2},[r14]!
+ add @x[1],@x[1],@t[1]
+ ldr @t[1],[r12,#-12]
+ vst1.8 {$c2-$d2},[r14]!
+ add @x[2],@x[2],@t[2]
+ ldr @t[2],[r12,#-8]
+ add @x[3],@x[3],@t[3]
+ ldr @t[3],[r12,#-4]
+# ifdef __ARMEB__
+ rev @x[0],@x[0]
+ rev @x[1],@x[1]
+ rev @x[2],@x[2]
+ rev @x[3],@x[3]
+# endif
+ eor @x[0],@x[0],@t[0] @ xor with input
+ add @t[0],sp,#4*(4)
+ eor @x[1],@x[1],@t[1]
+ str @x[0],[r14],#16 @ store output
+ eor @x[2],@x[2],@t[2]
+ str @x[1],[r14,#-12]
+ eor @x[3],@x[3],@t[3]
+ ldmia @t[0],{@t[0]-@t[3]} @ load key material
+ str @x[2],[r14,#-8]
+ str @x[3],[r14,#-4]
+
+ add @x[4],@x[4],@t[0] @ accumulate key material
+ ldr @t[0],[r12],#16 @ load input
+ add @x[5],@x[5],@t[1]
+ ldr @t[1],[r12,#-12]
+ add @x[6],@x[6],@t[2]
+ ldr @t[2],[r12,#-8]
+ add @x[7],@x[7],@t[3]
+ ldr @t[3],[r12,#-4]
+# ifdef __ARMEB__
+ rev @x[4],@x[4]
+ rev @x[5],@x[5]
+ rev @x[6],@x[6]
+ rev @x[7],@x[7]
+# endif
+ eor @x[4],@x[4],@t[0]
+ add @t[0],sp,#4*(8)
+ eor @x[5],@x[5],@t[1]
+ str @x[4],[r14],#16 @ store output
+ eor @x[6],@x[6],@t[2]
+ str @x[5],[r14,#-12]
+ eor @x[7],@x[7],@t[3]
+ ldmia @t[0],{@t[0]-@t[3]} @ load key material
+ str @x[6],[r14,#-8]
+ add @x[0],sp,#4*(16+8)
+ str @x[7],[r14,#-4]
+
+ ldmia @x[0],{@x[0]-@x[7]} @ load second half
+
+ add @x[0],@x[0],@t[0] @ accumulate key material
+ ldr @t[0],[r12],#16 @ load input
+ add @x[1],@x[1],@t[1]
+ ldr @t[1],[r12,#-12]
+# ifdef __thumb2__
+ it hi
+# endif
+ strhi @t[2],[sp,#4*(16+10)] @ copy "@x[10]" while at it
+ add @x[2],@x[2],@t[2]
+ ldr @t[2],[r12,#-8]
+# ifdef __thumb2__
+ it hi
+# endif
+ strhi @t[3],[sp,#4*(16+11)] @ copy "@x[11]" while at it
+ add @x[3],@x[3],@t[3]
+ ldr @t[3],[r12,#-4]
+# ifdef __ARMEB__
+ rev @x[0],@x[0]
+ rev @x[1],@x[1]
+ rev @x[2],@x[2]
+ rev @x[3],@x[3]
+# endif
+ eor @x[0],@x[0],@t[0]
+ add @t[0],sp,#4*(12)
+ eor @x[1],@x[1],@t[1]
+ str @x[0],[r14],#16 @ store output
+ eor @x[2],@x[2],@t[2]
+ str @x[1],[r14,#-12]
+ eor @x[3],@x[3],@t[3]
+ ldmia @t[0],{@t[0]-@t[3]} @ load key material
+ str @x[2],[r14,#-8]
+ str @x[3],[r14,#-4]
+
+ add @x[4],@x[4],@t[0] @ accumulate key material
+ add @t[0],@t[0],#4 @ next counter value
+ add @x[5],@x[5],@t[1]
+ str @t[0],[sp,#4*(12)] @ save next counter value
+ ldr @t[0],[r12],#16 @ load input
+ add @x[6],@x[6],@t[2]
+ add @x[4],@x[4],#3 @ counter+3
+ ldr @t[1],[r12,#-12]
+ add @x[7],@x[7],@t[3]
+ ldr @t[2],[r12,#-8]
+ ldr @t[3],[r12,#-4]
+# ifdef __ARMEB__
+ rev @x[4],@x[4]
+ rev @x[5],@x[5]
+ rev @x[6],@x[6]
+ rev @x[7],@x[7]
+# endif
+ eor @x[4],@x[4],@t[0]
+# ifdef __thumb2__
+ it hi
+# endif
+ ldrhi @t[0],[sp,#4*(32+2)] @ re-load len
+ eor @x[5],@x[5],@t[1]
+ eor @x[6],@x[6],@t[2]
+ str @x[4],[r14],#16 @ store output
+ eor @x[7],@x[7],@t[3]
+ str @x[5],[r14,#-12]
+ sub @t[3],@t[0],#64*4 @ len-=64*4
+ str @x[6],[r14,#-8]
+ str @x[7],[r14,#-4]
+ bhi .Loop_neon_outer
+
+ b .Ldone_neon
+
+.align 4
+.Lbreak_neon:
+ @ harmonize NEON and integer-only stack frames: load data
+ @ from NEON frame, but save to integer-only one; distance
+ @ between the two is 4*(32+4+16-32)=4*(20).
+
+ str @t[3], [sp,#4*(20+32+2)] @ save len
+ add @t[3],sp,#4*(32+4)
+ str r12, [sp,#4*(20+32+1)] @ save inp
+ str r14, [sp,#4*(20+32+0)] @ save out
+
+ ldr @x[12],[sp,#4*(16+10)]
+ ldr @x[14],[sp,#4*(16+11)]
+ vldmia @t[3],{d8-d15} @ fulfill ABI requirement
+ str @x[12],[sp,#4*(20+16+10)] @ copy "@x[10]"
+ str @x[14],[sp,#4*(20+16+11)] @ copy "@x[11]"
+
+ ldr @t[3], [sp,#4*(15)]
+ ldr @x[12],[sp,#4*(12)] @ modulo-scheduled load
+ ldr @t[2], [sp,#4*(13)]
+ ldr @x[14],[sp,#4*(14)]
+ str @t[3], [sp,#4*(20+16+15)]
+ add @t[3],sp,#4*(20)
+ vst1.32 {$a0-$b0},[@t[3]]! @ copy key
+ add sp,sp,#4*(20) @ switch frame
+ vst1.32 {$c0-$d0},[@t[3]]
+ mov @t[3],#10
+ b .Loop @ go integer-only
+
+.align 4
+.Ltail_neon:
+ cmp @t[3],#64*3
+ bhs .L192_or_more_neon
+ cmp @t[3],#64*2
+ bhs .L128_or_more_neon
+ cmp @t[3],#64*1
+ bhs .L64_or_more_neon
+
+ add @t[0],sp,#4*(8)
+ vst1.8 {$a0-$b0},[sp]
+ add @t[2],sp,#4*(0)
+ vst1.8 {$c0-$d0},[@t[0]]
+ b .Loop_tail_neon
+
+.align 4
+.L64_or_more_neon:
+ vld1.8 {$t0-$t1},[r12]!
+ vld1.8 {$t2-$t3},[r12]!
+ veor $a0,$a0,$t0
+ veor $b0,$b0,$t1
+ veor $c0,$c0,$t2
+ veor $d0,$d0,$t3
+ vst1.8 {$a0-$b0},[r14]!
+ vst1.8 {$c0-$d0},[r14]!
+
+ beq .Ldone_neon
+
+ add @t[0],sp,#4*(8)
+ vst1.8 {$a1-$b1},[sp]
+ add @t[2],sp,#4*(0)
+ vst1.8 {$c1-$d1},[@t[0]]
+ sub @t[3],@t[3],#64*1 @ len-=64*1
+ b .Loop_tail_neon
+
+.align 4
+.L128_or_more_neon:
+ vld1.8 {$t0-$t1},[r12]!
+ vld1.8 {$t2-$t3},[r12]!
+ veor $a0,$a0,$t0
+ veor $b0,$b0,$t1
+ vld1.8 {$t0-$t1},[r12]!
+ veor $c0,$c0,$t2
+ veor $d0,$d0,$t3
+ vld1.8 {$t2-$t3},[r12]!
+
+ veor $a1,$a1,$t0
+ veor $b1,$b1,$t1
+ vst1.8 {$a0-$b0},[r14]!
+ veor $c1,$c1,$t2
+ vst1.8 {$c0-$d0},[r14]!
+ veor $d1,$d1,$t3
+ vst1.8 {$a1-$b1},[r14]!
+ vst1.8 {$c1-$d1},[r14]!
+
+ beq .Ldone_neon
+
+ add @t[0],sp,#4*(8)
+ vst1.8 {$a2-$b2},[sp]
+ add @t[2],sp,#4*(0)
+ vst1.8 {$c2-$d2},[@t[0]]
+ sub @t[3],@t[3],#64*2 @ len-=64*2
+ b .Loop_tail_neon
+
+.align 4
+.L192_or_more_neon:
+ vld1.8 {$t0-$t1},[r12]!
+ vld1.8 {$t2-$t3},[r12]!
+ veor $a0,$a0,$t0
+ veor $b0,$b0,$t1
+ vld1.8 {$t0-$t1},[r12]!
+ veor $c0,$c0,$t2
+ veor $d0,$d0,$t3
+ vld1.8 {$t2-$t3},[r12]!
+
+ veor $a1,$a1,$t0
+ veor $b1,$b1,$t1
+ vld1.8 {$t0-$t1},[r12]!
+ veor $c1,$c1,$t2
+ vst1.8 {$a0-$b0},[r14]!
+ veor $d1,$d1,$t3
+ vld1.8 {$t2-$t3},[r12]!
+
+ veor $a2,$a2,$t0
+ vst1.8 {$c0-$d0},[r14]!
+ veor $b2,$b2,$t1
+ vst1.8 {$a1-$b1},[r14]!
+ veor $c2,$c2,$t2
+ vst1.8 {$c1-$d1},[r14]!
+ veor $d2,$d2,$t3
+ vst1.8 {$a2-$b2},[r14]!
+ vst1.8 {$c2-$d2},[r14]!
+
+ beq .Ldone_neon
+
+ ldmia sp,{@t[0]-@t[3]} @ load key material
+ add @x[0],@x[0],@t[0] @ accumulate key material
+ add @t[0],sp,#4*(4)
+ add @x[1],@x[1],@t[1]
+ add @x[2],@x[2],@t[2]
+ add @x[3],@x[3],@t[3]
+ ldmia @t[0],{@t[0]-@t[3]} @ load key material
+
+ add @x[4],@x[4],@t[0] @ accumulate key material
+ add @t[0],sp,#4*(8)
+ add @x[5],@x[5],@t[1]
+ add @x[6],@x[6],@t[2]
+ add @x[7],@x[7],@t[3]
+ ldmia @t[0],{@t[0]-@t[3]} @ load key material
+# ifdef __ARMEB__
+ rev @x[0],@x[0]
+ rev @x[1],@x[1]
+ rev @x[2],@x[2]
+ rev @x[3],@x[3]
+ rev @x[4],@x[4]
+ rev @x[5],@x[5]
+ rev @x[6],@x[6]
+ rev @x[7],@x[7]
+# endif
+ stmia sp,{@x[0]-@x[7]}
+ add @x[0],sp,#4*(16+8)
+
+ ldmia @x[0],{@x[0]-@x[7]} @ load second half
+
+ add @x[0],@x[0],@t[0] @ accumulate key material
+ add @t[0],sp,#4*(12)
+ add @x[1],@x[1],@t[1]
+ add @x[2],@x[2],@t[2]
+ add @x[3],@x[3],@t[3]
+ ldmia @t[0],{@t[0]-@t[3]} @ load key material
+
+ add @x[4],@x[4],@t[0] @ accumulate key material
+ add @t[0],sp,#4*(8)
+ add @x[5],@x[5],@t[1]
+ add @x[4],@x[4],#3 @ counter+3
+ add @x[6],@x[6],@t[2]
+ add @x[7],@x[7],@t[3]
+ ldr @t[3],[sp,#4*(32+2)] @ re-load len
+# ifdef __ARMEB__
+ rev @x[0],@x[0]
+ rev @x[1],@x[1]
+ rev @x[2],@x[2]
+ rev @x[3],@x[3]
+ rev @x[4],@x[4]
+ rev @x[5],@x[5]
+ rev @x[6],@x[6]
+ rev @x[7],@x[7]
+# endif
+ stmia @t[0],{@x[0]-@x[7]}
+ add @t[2],sp,#4*(0)
+ sub @t[3],@t[3],#64*3 @ len-=64*3
+
+.Loop_tail_neon:
+ ldrb @t[0],[@t[2]],#1 @ read buffer on stack
+ ldrb @t[1],[r12],#1 @ read input
+ subs @t[3],@t[3],#1
+ eor @t[0],@t[0],@t[1]
+ strb @t[0],[r14],#1 @ store ouput
+ bne .Loop_tail_neon
+
+.Ldone_neon:
+ add sp,sp,#4*(32+4)
+ vldmia sp,{d8-d15}
+ add sp,sp,#4*(16+3)
+ ldmia sp!,{r4-r11,pc}
+.size ChaCha20_neon,.-ChaCha20_neon
+.comm OPENSSL_armcap_P,4,4
+#endif
+___
+}}}
+
+foreach (split("\n",$code)) {
+ s/\`([^\`]*)\`/eval $1/geo;
+
+ s/\bq([0-9]+)#(lo|hi)/sprintf "d%d",2*$1+($2 eq "hi")/geo;
+
+ print $_,"\n";
+}
+close STDOUT;
diff --git a/src/crypto/chacha/asm/chacha-armv8.pl b/src/crypto/chacha/asm/chacha-armv8.pl
new file mode 100755
index 00000000..215d9657
--- /dev/null
+++ b/src/crypto/chacha/asm/chacha-armv8.pl
@@ -0,0 +1,1127 @@
+#!/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 2015
+#
+# ChaCha20 for ARMv8.
+#
+# Performance in cycles per byte out of large buffer.
+#
+# IALU/gcc-4.9 3xNEON+1xIALU 6xNEON+2xIALU
+#
+# Apple A7 5.50/+49% 3.33 1.70
+# Cortex-A53 8.40/+80% 4.72 4.72(*)
+# Cortex-A57 8.06/+43% 4.90 4.43(**)
+# Denver 4.50/+82% 2.63 2.67(*)
+# X-Gene 9.50/+46% 8.82 8.89(*)
+#
+# (*) it's expected that doubling interleave factor doesn't help
+# all processors, only those with higher NEON latency and
+# higher instruction issue rate;
+# (**) expected improvement was actually higher;
+
+$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;
+
+sub AUTOLOAD() # thunk [simplified] x86-style perlasm
+{ my $opcode = $AUTOLOAD; $opcode =~ s/.*:://; $opcode =~ s/_/\./;
+ my $arg = pop;
+ $arg = "#$arg" if ($arg*1 eq $arg);
+ $code .= "\t$opcode\t".join(',',@_,$arg)."\n";
+}
+
+my ($out,$inp,$len,$key,$ctr) = map("x$_",(0..4));
+
+my @x=map("x$_",(5..17,19..21));
+my @d=map("x$_",(22..28,30));
+
+sub ROUND {
+my ($a0,$b0,$c0,$d0)=@_;
+my ($a1,$b1,$c1,$d1)=map(($_&~3)+(($_+1)&3),($a0,$b0,$c0,$d0));
+my ($a2,$b2,$c2,$d2)=map(($_&~3)+(($_+1)&3),($a1,$b1,$c1,$d1));
+my ($a3,$b3,$c3,$d3)=map(($_&~3)+(($_+1)&3),($a2,$b2,$c2,$d2));
+
+ (
+ "&add_32 (@x[$a0],@x[$a0],@x[$b0])",
+ "&add_32 (@x[$a1],@x[$a1],@x[$b1])",
+ "&add_32 (@x[$a2],@x[$a2],@x[$b2])",
+ "&add_32 (@x[$a3],@x[$a3],@x[$b3])",
+ "&eor_32 (@x[$d0],@x[$d0],@x[$a0])",
+ "&eor_32 (@x[$d1],@x[$d1],@x[$a1])",
+ "&eor_32 (@x[$d2],@x[$d2],@x[$a2])",
+ "&eor_32 (@x[$d3],@x[$d3],@x[$a3])",
+ "&ror_32 (@x[$d0],@x[$d0],16)",
+ "&ror_32 (@x[$d1],@x[$d1],16)",
+ "&ror_32 (@x[$d2],@x[$d2],16)",
+ "&ror_32 (@x[$d3],@x[$d3],16)",
+
+ "&add_32 (@x[$c0],@x[$c0],@x[$d0])",
+ "&add_32 (@x[$c1],@x[$c1],@x[$d1])",
+ "&add_32 (@x[$c2],@x[$c2],@x[$d2])",
+ "&add_32 (@x[$c3],@x[$c3],@x[$d3])",
+ "&eor_32 (@x[$b0],@x[$b0],@x[$c0])",
+ "&eor_32 (@x[$b1],@x[$b1],@x[$c1])",
+ "&eor_32 (@x[$b2],@x[$b2],@x[$c2])",
+ "&eor_32 (@x[$b3],@x[$b3],@x[$c3])",
+ "&ror_32 (@x[$b0],@x[$b0],20)",
+ "&ror_32 (@x[$b1],@x[$b1],20)",
+ "&ror_32 (@x[$b2],@x[$b2],20)",
+ "&ror_32 (@x[$b3],@x[$b3],20)",
+
+ "&add_32 (@x[$a0],@x[$a0],@x[$b0])",
+ "&add_32 (@x[$a1],@x[$a1],@x[$b1])",
+ "&add_32 (@x[$a2],@x[$a2],@x[$b2])",
+ "&add_32 (@x[$a3],@x[$a3],@x[$b3])",
+ "&eor_32 (@x[$d0],@x[$d0],@x[$a0])",
+ "&eor_32 (@x[$d1],@x[$d1],@x[$a1])",
+ "&eor_32 (@x[$d2],@x[$d2],@x[$a2])",
+ "&eor_32 (@x[$d3],@x[$d3],@x[$a3])",
+ "&ror_32 (@x[$d0],@x[$d0],24)",
+ "&ror_32 (@x[$d1],@x[$d1],24)",
+ "&ror_32 (@x[$d2],@x[$d2],24)",
+ "&ror_32 (@x[$d3],@x[$d3],24)",
+
+ "&add_32 (@x[$c0],@x[$c0],@x[$d0])",
+ "&add_32 (@x[$c1],@x[$c1],@x[$d1])",
+ "&add_32 (@x[$c2],@x[$c2],@x[$d2])",
+ "&add_32 (@x[$c3],@x[$c3],@x[$d3])",
+ "&eor_32 (@x[$b0],@x[$b0],@x[$c0])",
+ "&eor_32 (@x[$b1],@x[$b1],@x[$c1])",
+ "&eor_32 (@x[$b2],@x[$b2],@x[$c2])",
+ "&eor_32 (@x[$b3],@x[$b3],@x[$c3])",
+ "&ror_32 (@x[$b0],@x[$b0],25)",
+ "&ror_32 (@x[$b1],@x[$b1],25)",
+ "&ror_32 (@x[$b2],@x[$b2],25)",
+ "&ror_32 (@x[$b3],@x[$b3],25)"
+ );
+}
+
+$code.=<<___;
+#include <openssl/arm_arch.h>
+
+.text
+
+.extern OPENSSL_armcap_P
+
+.align 5
+.Lsigma:
+.quad 0x3320646e61707865,0x6b20657479622d32 // endian-neutral
+.Lone:
+.long 1,0,0,0
+.LOPENSSL_armcap_P:
+#ifdef __ILP32__
+.long OPENSSL_armcap_P-.
+#else
+.quad OPENSSL_armcap_P-.
+#endif
+.asciz "ChaCha20 for ARMv8, CRYPTOGAMS by <appro\@openssl.org>"
+
+.globl ChaCha20_ctr32
+.type ChaCha20_ctr32,%function
+.align 5
+ChaCha20_ctr32:
+ cbz $len,.Labort
+ adr @x[0],.LOPENSSL_armcap_P
+ cmp $len,#192
+ b.lo .Lshort
+#ifdef __ILP32__
+ ldrsw @x[1],[@x[0]]
+#else
+ ldr @x[1],[@x[0]]
+#endif
+ ldr w17,[@x[1],@x[0]]
+ tst w17,#ARMV7_NEON
+ b.ne ChaCha20_neon
+
+.Lshort:
+ stp x29,x30,[sp,#-96]!
+ add x29,sp,#0
+
+ adr @x[0],.Lsigma
+ stp x19,x20,[sp,#16]
+ stp x21,x22,[sp,#32]
+ stp x23,x24,[sp,#48]
+ stp x25,x26,[sp,#64]
+ stp x27,x28,[sp,#80]
+ sub sp,sp,#64
+
+ ldp @d[0],@d[1],[@x[0]] // load sigma
+ ldp @d[2],@d[3],[$key] // load key
+ ldp @d[4],@d[5],[$key,#16]
+ ldp @d[6],@d[7],[$ctr] // load counter
+#ifdef __ARMEB__
+ ror @d[2],@d[2],#32
+ ror @d[3],@d[3],#32
+ ror @d[4],@d[4],#32
+ ror @d[5],@d[5],#32
+ ror @d[6],@d[6],#32
+ ror @d[7],@d[7],#32
+#endif
+
+.Loop_outer:
+ mov.32 @x[0],@d[0] // unpack key block
+ lsr @x[1],@d[0],#32
+ mov.32 @x[2],@d[1]
+ lsr @x[3],@d[1],#32
+ mov.32 @x[4],@d[2]
+ lsr @x[5],@d[2],#32
+ mov.32 @x[6],@d[3]
+ lsr @x[7],@d[3],#32
+ mov.32 @x[8],@d[4]
+ lsr @x[9],@d[4],#32
+ mov.32 @x[10],@d[5]
+ lsr @x[11],@d[5],#32
+ mov.32 @x[12],@d[6]
+ lsr @x[13],@d[6],#32
+ mov.32 @x[14],@d[7]
+ lsr @x[15],@d[7],#32
+
+ mov $ctr,#10
+ subs $len,$len,#64
+.Loop:
+ sub $ctr,$ctr,#1
+___
+ foreach (&ROUND(0, 4, 8,12)) { eval; }
+ foreach (&ROUND(0, 5,10,15)) { eval; }
+$code.=<<___;
+ cbnz $ctr,.Loop
+
+ add.32 @x[0],@x[0],@d[0] // accumulate key block
+ add @x[1],@x[1],@d[0],lsr#32
+ add.32 @x[2],@x[2],@d[1]
+ add @x[3],@x[3],@d[1],lsr#32
+ add.32 @x[4],@x[4],@d[2]
+ add @x[5],@x[5],@d[2],lsr#32
+ add.32 @x[6],@x[6],@d[3]
+ add @x[7],@x[7],@d[3],lsr#32
+ add.32 @x[8],@x[8],@d[4]
+ add @x[9],@x[9],@d[4],lsr#32
+ add.32 @x[10],@x[10],@d[5]
+ add @x[11],@x[11],@d[5],lsr#32
+ add.32 @x[12],@x[12],@d[6]
+ add @x[13],@x[13],@d[6],lsr#32
+ add.32 @x[14],@x[14],@d[7]
+ add @x[15],@x[15],@d[7],lsr#32
+
+ b.lo .Ltail
+
+ add @x[0],@x[0],@x[1],lsl#32 // pack
+ add @x[2],@x[2],@x[3],lsl#32
+ ldp @x[1],@x[3],[$inp,#0] // load input
+ add @x[4],@x[4],@x[5],lsl#32
+ add @x[6],@x[6],@x[7],lsl#32
+ ldp @x[5],@x[7],[$inp,#16]
+ add @x[8],@x[8],@x[9],lsl#32
+ add @x[10],@x[10],@x[11],lsl#32
+ ldp @x[9],@x[11],[$inp,#32]
+ add @x[12],@x[12],@x[13],lsl#32
+ add @x[14],@x[14],@x[15],lsl#32
+ ldp @x[13],@x[15],[$inp,#48]
+ add $inp,$inp,#64
+#ifdef __ARMEB__
+ rev @x[0],@x[0]
+ rev @x[2],@x[2]
+ rev @x[4],@x[4]
+ rev @x[6],@x[6]
+ rev @x[8],@x[8]
+ rev @x[10],@x[10]
+ rev @x[12],@x[12]
+ rev @x[14],@x[14]
+#endif
+ eor @x[0],@x[0],@x[1]
+ eor @x[2],@x[2],@x[3]
+ eor @x[4],@x[4],@x[5]
+ eor @x[6],@x[6],@x[7]
+ eor @x[8],@x[8],@x[9]
+ eor @x[10],@x[10],@x[11]
+ eor @x[12],@x[12],@x[13]
+ eor @x[14],@x[14],@x[15]
+
+ stp @x[0],@x[2],[$out,#0] // store output
+ add @d[6],@d[6],#1 // increment counter
+ stp @x[4],@x[6],[$out,#16]
+ stp @x[8],@x[10],[$out,#32]
+ stp @x[12],@x[14],[$out,#48]
+ add $out,$out,#64
+
+ b.hi .Loop_outer
+
+ ldp x19,x20,[x29,#16]
+ add sp,sp,#64
+ ldp x21,x22,[x29,#32]
+ ldp x23,x24,[x29,#48]
+ ldp x25,x26,[x29,#64]
+ ldp x27,x28,[x29,#80]
+ ldp x29,x30,[sp],#96
+.Labort:
+ ret
+
+.align 4
+.Ltail:
+ add $len,$len,#64
+.Less_than_64:
+ sub $out,$out,#1
+ add $inp,$inp,$len
+ add $out,$out,$len
+ add $ctr,sp,$len
+ neg $len,$len
+
+ add @x[0],@x[0],@x[1],lsl#32 // pack
+ add @x[2],@x[2],@x[3],lsl#32
+ add @x[4],@x[4],@x[5],lsl#32
+ add @x[6],@x[6],@x[7],lsl#32
+ add @x[8],@x[8],@x[9],lsl#32
+ add @x[10],@x[10],@x[11],lsl#32
+ add @x[12],@x[12],@x[13],lsl#32
+ add @x[14],@x[14],@x[15],lsl#32
+#ifdef __ARMEB__
+ rev @x[0],@x[0]
+ rev @x[2],@x[2]
+ rev @x[4],@x[4]
+ rev @x[6],@x[6]
+ rev @x[8],@x[8]
+ rev @x[10],@x[10]
+ rev @x[12],@x[12]
+ rev @x[14],@x[14]
+#endif
+ stp @x[0],@x[2],[sp,#0]
+ stp @x[4],@x[6],[sp,#16]
+ stp @x[8],@x[10],[sp,#32]
+ stp @x[12],@x[14],[sp,#48]
+
+.Loop_tail:
+ ldrb w10,[$inp,$len]
+ ldrb w11,[$ctr,$len]
+ add $len,$len,#1
+ eor w10,w10,w11
+ strb w10,[$out,$len]
+ cbnz $len,.Loop_tail
+
+ stp xzr,xzr,[sp,#0]
+ stp xzr,xzr,[sp,#16]
+ stp xzr,xzr,[sp,#32]
+ stp xzr,xzr,[sp,#48]
+
+ ldp x19,x20,[x29,#16]
+ add sp,sp,#64
+ ldp x21,x22,[x29,#32]
+ ldp x23,x24,[x29,#48]
+ ldp x25,x26,[x29,#64]
+ ldp x27,x28,[x29,#80]
+ ldp x29,x30,[sp],#96
+ ret
+.size ChaCha20_ctr32,.-ChaCha20_ctr32
+___
+
+{{{
+my ($A0,$B0,$C0,$D0,$A1,$B1,$C1,$D1,$A2,$B2,$C2,$D2,$T0,$T1,$T2,$T3) =
+ map("v$_.4s",(0..7,16..23));
+my (@K)=map("v$_.4s",(24..30));
+my $ONE="v31.4s";
+
+sub NEONROUND {
+my $odd = pop;
+my ($a,$b,$c,$d,$t)=@_;
+
+ (
+ "&add ('$a','$a','$b')",
+ "&eor ('$d','$d','$a')",
+ "&rev32_16 ('$d','$d')", # vrot ($d,16)
+
+ "&add ('$c','$c','$d')",
+ "&eor ('$t','$b','$c')",
+ "&ushr ('$b','$t',20)",
+ "&sli ('$b','$t',12)",
+
+ "&add ('$a','$a','$b')",
+ "&eor ('$t','$d','$a')",
+ "&ushr ('$d','$t',24)",
+ "&sli ('$d','$t',8)",
+
+ "&add ('$c','$c','$d')",
+ "&eor ('$t','$b','$c')",
+ "&ushr ('$b','$t',25)",
+ "&sli ('$b','$t',7)",
+
+ "&ext ('$c','$c','$c',8)",
+ "&ext ('$d','$d','$d',$odd?4:12)",
+ "&ext ('$b','$b','$b',$odd?12:4)"
+ );
+}
+
+$code.=<<___;
+
+.type ChaCha20_neon,%function
+.align 5
+ChaCha20_neon:
+ stp x29,x30,[sp,#-96]!
+ add x29,sp,#0
+
+ adr @x[0],.Lsigma
+ stp x19,x20,[sp,#16]
+ stp x21,x22,[sp,#32]
+ stp x23,x24,[sp,#48]
+ stp x25,x26,[sp,#64]
+ stp x27,x28,[sp,#80]
+ cmp $len,#512
+ b.hs .L512_or_more_neon
+
+ sub sp,sp,#64
+
+ ldp @d[0],@d[1],[@x[0]] // load sigma
+ ld1 {@K[0]},[@x[0]],#16
+ ldp @d[2],@d[3],[$key] // load key
+ ldp @d[4],@d[5],[$key,#16]
+ ld1 {@K[1],@K[2]},[$key]
+ ldp @d[6],@d[7],[$ctr] // load counter
+ ld1 {@K[3]},[$ctr]
+ ld1 {$ONE},[@x[0]]
+#ifdef __ARMEB__
+ rev64 @K[0],@K[0]
+ ror @d[2],@d[2],#32
+ ror @d[3],@d[3],#32
+ ror @d[4],@d[4],#32
+ ror @d[5],@d[5],#32
+ ror @d[6],@d[6],#32
+ ror @d[7],@d[7],#32
+#endif
+ add @K[3],@K[3],$ONE // += 1
+ add @K[4],@K[3],$ONE
+ add @K[5],@K[4],$ONE
+ shl $ONE,$ONE,#2 // 1 -> 4
+
+.Loop_outer_neon:
+ mov.32 @x[0],@d[0] // unpack key block
+ lsr @x[1],@d[0],#32
+ mov $A0,@K[0]
+ mov.32 @x[2],@d[1]
+ lsr @x[3],@d[1],#32
+ mov $A1,@K[0]
+ mov.32 @x[4],@d[2]
+ lsr @x[5],@d[2],#32
+ mov $A2,@K[0]
+ mov.32 @x[6],@d[3]
+ mov $B0,@K[1]
+ lsr @x[7],@d[3],#32
+ mov $B1,@K[1]
+ mov.32 @x[8],@d[4]
+ mov $B2,@K[1]
+ lsr @x[9],@d[4],#32
+ mov $D0,@K[3]
+ mov.32 @x[10],@d[5]
+ mov $D1,@K[4]
+ lsr @x[11],@d[5],#32
+ mov $D2,@K[5]
+ mov.32 @x[12],@d[6]
+ mov $C0,@K[2]
+ lsr @x[13],@d[6],#32
+ mov $C1,@K[2]
+ mov.32 @x[14],@d[7]
+ mov $C2,@K[2]
+ lsr @x[15],@d[7],#32
+
+ mov $ctr,#10
+ subs $len,$len,#256
+.Loop_neon:
+ sub $ctr,$ctr,#1
+___
+ my @thread0=&NEONROUND($A0,$B0,$C0,$D0,$T0,0);
+ my @thread1=&NEONROUND($A1,$B1,$C1,$D1,$T1,0);
+ my @thread2=&NEONROUND($A2,$B2,$C2,$D2,$T2,0);
+ my @thread3=&ROUND(0,4,8,12);
+
+ foreach (@thread0) {
+ eval; eval(shift(@thread3));
+ eval(shift(@thread1)); eval(shift(@thread3));
+ eval(shift(@thread2)); eval(shift(@thread3));
+ }
+
+ @thread0=&NEONROUND($A0,$B0,$C0,$D0,$T0,1);
+ @thread1=&NEONROUND($A1,$B1,$C1,$D1,$T1,1);
+ @thread2=&NEONROUND($A2,$B2,$C2,$D2,$T2,1);
+ @thread3=&ROUND(0,5,10,15);
+
+ foreach (@thread0) {
+ eval; eval(shift(@thread3));
+ eval(shift(@thread1)); eval(shift(@thread3));
+ eval(shift(@thread2)); eval(shift(@thread3));
+ }
+$code.=<<___;
+ cbnz $ctr,.Loop_neon
+
+ add.32 @x[0],@x[0],@d[0] // accumulate key block
+ add $A0,$A0,@K[0]
+ add @x[1],@x[1],@d[0],lsr#32
+ add $A1,$A1,@K[0]
+ add.32 @x[2],@x[2],@d[1]
+ add $A2,$A2,@K[0]
+ add @x[3],@x[3],@d[1],lsr#32
+ add $C0,$C0,@K[2]
+ add.32 @x[4],@x[4],@d[2]
+ add $C1,$C1,@K[2]
+ add @x[5],@x[5],@d[2],lsr#32
+ add $C2,$C2,@K[2]
+ add.32 @x[6],@x[6],@d[3]
+ add $D0,$D0,@K[3]
+ add @x[7],@x[7],@d[3],lsr#32
+ add.32 @x[8],@x[8],@d[4]
+ add $D1,$D1,@K[4]
+ add @x[9],@x[9],@d[4],lsr#32
+ add.32 @x[10],@x[10],@d[5]
+ add $D2,$D2,@K[5]
+ add @x[11],@x[11],@d[5],lsr#32
+ add.32 @x[12],@x[12],@d[6]
+ add $B0,$B0,@K[1]
+ add @x[13],@x[13],@d[6],lsr#32
+ add.32 @x[14],@x[14],@d[7]
+ add $B1,$B1,@K[1]
+ add @x[15],@x[15],@d[7],lsr#32
+ add $B2,$B2,@K[1]
+
+ b.lo .Ltail_neon
+
+ add @x[0],@x[0],@x[1],lsl#32 // pack
+ add @x[2],@x[2],@x[3],lsl#32
+ ldp @x[1],@x[3],[$inp,#0] // load input
+ add @x[4],@x[4],@x[5],lsl#32
+ add @x[6],@x[6],@x[7],lsl#32
+ ldp @x[5],@x[7],[$inp,#16]
+ add @x[8],@x[8],@x[9],lsl#32
+ add @x[10],@x[10],@x[11],lsl#32
+ ldp @x[9],@x[11],[$inp,#32]
+ add @x[12],@x[12],@x[13],lsl#32
+ add @x[14],@x[14],@x[15],lsl#32
+ ldp @x[13],@x[15],[$inp,#48]
+ add $inp,$inp,#64
+#ifdef __ARMEB__
+ rev @x[0],@x[0]
+ rev @x[2],@x[2]
+ rev @x[4],@x[4]
+ rev @x[6],@x[6]
+ rev @x[8],@x[8]
+ rev @x[10],@x[10]
+ rev @x[12],@x[12]
+ rev @x[14],@x[14]
+#endif
+ ld1.8 {$T0-$T3},[$inp],#64
+ eor @x[0],@x[0],@x[1]
+ eor @x[2],@x[2],@x[3]
+ eor @x[4],@x[4],@x[5]
+ eor @x[6],@x[6],@x[7]
+ eor @x[8],@x[8],@x[9]
+ eor $A0,$A0,$T0
+ eor @x[10],@x[10],@x[11]
+ eor $B0,$B0,$T1
+ eor @x[12],@x[12],@x[13]
+ eor $C0,$C0,$T2
+ eor @x[14],@x[14],@x[15]
+ eor $D0,$D0,$T3
+ ld1.8 {$T0-$T3},[$inp],#64
+
+ stp @x[0],@x[2],[$out,#0] // store output
+ add @d[6],@d[6],#4 // increment counter
+ stp @x[4],@x[6],[$out,#16]
+ add @K[3],@K[3],$ONE // += 4
+ stp @x[8],@x[10],[$out,#32]
+ add @K[4],@K[4],$ONE
+ stp @x[12],@x[14],[$out,#48]
+ add @K[5],@K[5],$ONE
+ add $out,$out,#64
+
+ st1.8 {$A0-$D0},[$out],#64
+ ld1.8 {$A0-$D0},[$inp],#64
+
+ eor $A1,$A1,$T0
+ eor $B1,$B1,$T1
+ eor $C1,$C1,$T2
+ eor $D1,$D1,$T3
+ st1.8 {$A1-$D1},[$out],#64
+
+ eor $A2,$A2,$A0
+ eor $B2,$B2,$B0
+ eor $C2,$C2,$C0
+ eor $D2,$D2,$D0
+ st1.8 {$A2-$D2},[$out],#64
+
+ b.hi .Loop_outer_neon
+
+ ldp x19,x20,[x29,#16]
+ add sp,sp,#64
+ ldp x21,x22,[x29,#32]
+ ldp x23,x24,[x29,#48]
+ ldp x25,x26,[x29,#64]
+ ldp x27,x28,[x29,#80]
+ ldp x29,x30,[sp],#96
+ ret
+
+.Ltail_neon:
+ add $len,$len,#256
+ cmp $len,#64
+ b.lo .Less_than_64
+
+ add @x[0],@x[0],@x[1],lsl#32 // pack
+ add @x[2],@x[2],@x[3],lsl#32
+ ldp @x[1],@x[3],[$inp,#0] // load input
+ add @x[4],@x[4],@x[5],lsl#32
+ add @x[6],@x[6],@x[7],lsl#32
+ ldp @x[5],@x[7],[$inp,#16]
+ add @x[8],@x[8],@x[9],lsl#32
+ add @x[10],@x[10],@x[11],lsl#32
+ ldp @x[9],@x[11],[$inp,#32]
+ add @x[12],@x[12],@x[13],lsl#32
+ add @x[14],@x[14],@x[15],lsl#32
+ ldp @x[13],@x[15],[$inp,#48]
+ add $inp,$inp,#64
+#ifdef __ARMEB__
+ rev @x[0],@x[0]
+ rev @x[2],@x[2]
+ rev @x[4],@x[4]
+ rev @x[6],@x[6]
+ rev @x[8],@x[8]
+ rev @x[10],@x[10]
+ rev @x[12],@x[12]
+ rev @x[14],@x[14]
+#endif
+ eor @x[0],@x[0],@x[1]
+ eor @x[2],@x[2],@x[3]
+ eor @x[4],@x[4],@x[5]
+ eor @x[6],@x[6],@x[7]
+ eor @x[8],@x[8],@x[9]
+ eor @x[10],@x[10],@x[11]
+ eor @x[12],@x[12],@x[13]
+ eor @x[14],@x[14],@x[15]
+
+ stp @x[0],@x[2],[$out,#0] // store output
+ add @d[6],@d[6],#4 // increment counter
+ stp @x[4],@x[6],[$out,#16]
+ stp @x[8],@x[10],[$out,#32]
+ stp @x[12],@x[14],[$out,#48]
+ add $out,$out,#64
+ b.eq .Ldone_neon
+ sub $len,$len,#64
+ cmp $len,#64
+ b.lo .Less_than_128
+
+ ld1.8 {$T0-$T3},[$inp],#64
+ eor $A0,$A0,$T0
+ eor $B0,$B0,$T1
+ eor $C0,$C0,$T2
+ eor $D0,$D0,$T3
+ st1.8 {$A0-$D0},[$out],#64
+ b.eq .Ldone_neon
+ sub $len,$len,#64
+ cmp $len,#64
+ b.lo .Less_than_192
+
+ ld1.8 {$T0-$T3},[$inp],#64
+ eor $A1,$A1,$T0
+ eor $B1,$B1,$T1
+ eor $C1,$C1,$T2
+ eor $D1,$D1,$T3
+ st1.8 {$A1-$D1},[$out],#64
+ b.eq .Ldone_neon
+ sub $len,$len,#64
+
+ st1.8 {$A2-$D2},[sp]
+ b .Last_neon
+
+.Less_than_128:
+ st1.8 {$A0-$D0},[sp]
+ b .Last_neon
+.Less_than_192:
+ st1.8 {$A1-$D1},[sp]
+ b .Last_neon
+
+.align 4
+.Last_neon:
+ sub $out,$out,#1
+ add $inp,$inp,$len
+ add $out,$out,$len
+ add $ctr,sp,$len
+ neg $len,$len
+
+.Loop_tail_neon:
+ ldrb w10,[$inp,$len]
+ ldrb w11,[$ctr,$len]
+ add $len,$len,#1
+ eor w10,w10,w11
+ strb w10,[$out,$len]
+ cbnz $len,.Loop_tail_neon
+
+ stp xzr,xzr,[sp,#0]
+ stp xzr,xzr,[sp,#16]
+ stp xzr,xzr,[sp,#32]
+ stp xzr,xzr,[sp,#48]
+
+.Ldone_neon:
+ ldp x19,x20,[x29,#16]
+ add sp,sp,#64
+ ldp x21,x22,[x29,#32]
+ ldp x23,x24,[x29,#48]
+ ldp x25,x26,[x29,#64]
+ ldp x27,x28,[x29,#80]
+ ldp x29,x30,[sp],#96
+ ret
+.size ChaCha20_neon,.-ChaCha20_neon
+___
+{
+my ($T0,$T1,$T2,$T3,$T4,$T5)=@K;
+my ($A0,$B0,$C0,$D0,$A1,$B1,$C1,$D1,$A2,$B2,$C2,$D2,
+ $A3,$B3,$C3,$D3,$A4,$B4,$C4,$D4,$A5,$B5,$C5,$D5) = map("v$_.4s",(0..23));
+
+$code.=<<___;
+.type ChaCha20_512_neon,%function
+.align 5
+ChaCha20_512_neon:
+ stp x29,x30,[sp,#-96]!
+ add x29,sp,#0
+
+ adr @x[0],.Lsigma
+ stp x19,x20,[sp,#16]
+ stp x21,x22,[sp,#32]
+ stp x23,x24,[sp,#48]
+ stp x25,x26,[sp,#64]
+ stp x27,x28,[sp,#80]
+
+.L512_or_more_neon:
+ sub sp,sp,#128+64
+
+ ldp @d[0],@d[1],[@x[0]] // load sigma
+ ld1 {@K[0]},[@x[0]],#16
+ ldp @d[2],@d[3],[$key] // load key
+ ldp @d[4],@d[5],[$key,#16]
+ ld1 {@K[1],@K[2]},[$key]
+ ldp @d[6],@d[7],[$ctr] // load counter
+ ld1 {@K[3]},[$ctr]
+ ld1 {$ONE},[@x[0]]
+#ifdef __ARMEB__
+ rev64 @K[0],@K[0]
+ ror @d[2],@d[2],#32
+ ror @d[3],@d[3],#32
+ ror @d[4],@d[4],#32
+ ror @d[5],@d[5],#32
+ ror @d[6],@d[6],#32
+ ror @d[7],@d[7],#32
+#endif
+ add @K[3],@K[3],$ONE // += 1
+ stp @K[0],@K[1],[sp,#0] // off-load key block, invariant part
+ add @K[3],@K[3],$ONE // not typo
+ str @K[2],[sp,#32]
+ add @K[4],@K[3],$ONE
+ add @K[5],@K[4],$ONE
+ add @K[6],@K[5],$ONE
+ shl $ONE,$ONE,#2 // 1 -> 4
+
+ stp d8,d9,[sp,#128+0] // meet ABI requirements
+ stp d10,d11,[sp,#128+16]
+ stp d12,d13,[sp,#128+32]
+ stp d14,d15,[sp,#128+48]
+
+ sub $len,$len,#512 // not typo
+
+.Loop_outer_512_neon:
+ mov $A0,@K[0]
+ mov $A1,@K[0]
+ mov $A2,@K[0]
+ mov $A3,@K[0]
+ mov $A4,@K[0]
+ mov $A5,@K[0]
+ mov $B0,@K[1]
+ mov.32 @x[0],@d[0] // unpack key block
+ mov $B1,@K[1]
+ lsr @x[1],@d[0],#32
+ mov $B2,@K[1]
+ mov.32 @x[2],@d[1]
+ mov $B3,@K[1]
+ lsr @x[3],@d[1],#32
+ mov $B4,@K[1]
+ mov.32 @x[4],@d[2]
+ mov $B5,@K[1]
+ lsr @x[5],@d[2],#32
+ mov $D0,@K[3]
+ mov.32 @x[6],@d[3]
+ mov $D1,@K[4]
+ lsr @x[7],@d[3],#32
+ mov $D2,@K[5]
+ mov.32 @x[8],@d[4]
+ mov $D3,@K[6]
+ lsr @x[9],@d[4],#32
+ mov $C0,@K[2]
+ mov.32 @x[10],@d[5]
+ mov $C1,@K[2]
+ lsr @x[11],@d[5],#32
+ add $D4,$D0,$ONE // +4
+ mov.32 @x[12],@d[6]
+ add $D5,$D1,$ONE // +4
+ lsr @x[13],@d[6],#32
+ mov $C2,@K[2]
+ mov.32 @x[14],@d[7]
+ mov $C3,@K[2]
+ lsr @x[15],@d[7],#32
+ mov $C4,@K[2]
+ stp @K[3],@K[4],[sp,#48] // off-load key block, variable part
+ mov $C5,@K[2]
+ str @K[5],[sp,#80]
+
+ mov $ctr,#5
+ subs $len,$len,#512
+.Loop_upper_neon:
+ sub $ctr,$ctr,#1
+___
+ my @thread0=&NEONROUND($A0,$B0,$C0,$D0,$T0,0);
+ my @thread1=&NEONROUND($A1,$B1,$C1,$D1,$T1,0);
+ my @thread2=&NEONROUND($A2,$B2,$C2,$D2,$T2,0);
+ my @thread3=&NEONROUND($A3,$B3,$C3,$D3,$T3,0);
+ my @thread4=&NEONROUND($A4,$B4,$C4,$D4,$T4,0);
+ my @thread5=&NEONROUND($A5,$B5,$C5,$D5,$T5,0);
+ my @thread67=(&ROUND(0,4,8,12),&ROUND(0,5,10,15));
+ my $diff = ($#thread0+1)*6 - $#thread67 - 1;
+ my $i = 0;
+
+ foreach (@thread0) {
+ eval; eval(shift(@thread67));
+ eval(shift(@thread1)); eval(shift(@thread67));
+ eval(shift(@thread2)); eval(shift(@thread67));
+ eval(shift(@thread3)); eval(shift(@thread67));
+ eval(shift(@thread4)); eval(shift(@thread67));
+ eval(shift(@thread5)); eval(shift(@thread67));
+ }
+
+ @thread0=&NEONROUND($A0,$B0,$C0,$D0,$T0,1);
+ @thread1=&NEONROUND($A1,$B1,$C1,$D1,$T1,1);
+ @thread2=&NEONROUND($A2,$B2,$C2,$D2,$T2,1);
+ @thread3=&NEONROUND($A3,$B3,$C3,$D3,$T3,1);
+ @thread4=&NEONROUND($A4,$B4,$C4,$D4,$T4,1);
+ @thread5=&NEONROUND($A5,$B5,$C5,$D5,$T5,1);
+ @thread67=(&ROUND(0,4,8,12),&ROUND(0,5,10,15));
+
+ foreach (@thread0) {
+ eval; eval(shift(@thread67));
+ eval(shift(@thread1)); eval(shift(@thread67));
+ eval(shift(@thread2)); eval(shift(@thread67));
+ eval(shift(@thread3)); eval(shift(@thread67));
+ eval(shift(@thread4)); eval(shift(@thread67));
+ eval(shift(@thread5)); eval(shift(@thread67));
+ }
+$code.=<<___;
+ cbnz $ctr,.Loop_upper_neon
+
+ add.32 @x[0],@x[0],@d[0] // accumulate key block
+ add @x[1],@x[1],@d[0],lsr#32
+ add.32 @x[2],@x[2],@d[1]
+ add @x[3],@x[3],@d[1],lsr#32
+ add.32 @x[4],@x[4],@d[2]
+ add @x[5],@x[5],@d[2],lsr#32
+ add.32 @x[6],@x[6],@d[3]
+ add @x[7],@x[7],@d[3],lsr#32
+ add.32 @x[8],@x[8],@d[4]
+ add @x[9],@x[9],@d[4],lsr#32
+ add.32 @x[10],@x[10],@d[5]
+ add @x[11],@x[11],@d[5],lsr#32
+ add.32 @x[12],@x[12],@d[6]
+ add @x[13],@x[13],@d[6],lsr#32
+ add.32 @x[14],@x[14],@d[7]
+ add @x[15],@x[15],@d[7],lsr#32
+
+ add @x[0],@x[0],@x[1],lsl#32 // pack
+ add @x[2],@x[2],@x[3],lsl#32
+ ldp @x[1],@x[3],[$inp,#0] // load input
+ add @x[4],@x[4],@x[5],lsl#32
+ add @x[6],@x[6],@x[7],lsl#32
+ ldp @x[5],@x[7],[$inp,#16]
+ add @x[8],@x[8],@x[9],lsl#32
+ add @x[10],@x[10],@x[11],lsl#32
+ ldp @x[9],@x[11],[$inp,#32]
+ add @x[12],@x[12],@x[13],lsl#32
+ add @x[14],@x[14],@x[15],lsl#32
+ ldp @x[13],@x[15],[$inp,#48]
+ add $inp,$inp,#64
+#ifdef __ARMEB__
+ rev @x[0],@x[0]
+ rev @x[2],@x[2]
+ rev @x[4],@x[4]
+ rev @x[6],@x[6]
+ rev @x[8],@x[8]
+ rev @x[10],@x[10]
+ rev @x[12],@x[12]
+ rev @x[14],@x[14]
+#endif
+ eor @x[0],@x[0],@x[1]
+ eor @x[2],@x[2],@x[3]
+ eor @x[4],@x[4],@x[5]
+ eor @x[6],@x[6],@x[7]
+ eor @x[8],@x[8],@x[9]
+ eor @x[10],@x[10],@x[11]
+ eor @x[12],@x[12],@x[13]
+ eor @x[14],@x[14],@x[15]
+
+ stp @x[0],@x[2],[$out,#0] // store output
+ add @d[6],@d[6],#1 // increment counter
+ mov.32 @x[0],@d[0] // unpack key block
+ lsr @x[1],@d[0],#32
+ stp @x[4],@x[6],[$out,#16]
+ mov.32 @x[2],@d[1]
+ lsr @x[3],@d[1],#32
+ stp @x[8],@x[10],[$out,#32]
+ mov.32 @x[4],@d[2]
+ lsr @x[5],@d[2],#32
+ stp @x[12],@x[14],[$out,#48]
+ add $out,$out,#64
+ mov.32 @x[6],@d[3]
+ lsr @x[7],@d[3],#32
+ mov.32 @x[8],@d[4]
+ lsr @x[9],@d[4],#32
+ mov.32 @x[10],@d[5]
+ lsr @x[11],@d[5],#32
+ mov.32 @x[12],@d[6]
+ lsr @x[13],@d[6],#32
+ mov.32 @x[14],@d[7]
+ lsr @x[15],@d[7],#32
+
+ mov $ctr,#5
+.Loop_lower_neon:
+ sub $ctr,$ctr,#1
+___
+ @thread0=&NEONROUND($A0,$B0,$C0,$D0,$T0,0);
+ @thread1=&NEONROUND($A1,$B1,$C1,$D1,$T1,0);
+ @thread2=&NEONROUND($A2,$B2,$C2,$D2,$T2,0);
+ @thread3=&NEONROUND($A3,$B3,$C3,$D3,$T3,0);
+ @thread4=&NEONROUND($A4,$B4,$C4,$D4,$T4,0);
+ @thread5=&NEONROUND($A5,$B5,$C5,$D5,$T5,0);
+ @thread67=(&ROUND(0,4,8,12),&ROUND(0,5,10,15));
+
+ foreach (@thread0) {
+ eval; eval(shift(@thread67));
+ eval(shift(@thread1)); eval(shift(@thread67));
+ eval(shift(@thread2)); eval(shift(@thread67));
+ eval(shift(@thread3)); eval(shift(@thread67));
+ eval(shift(@thread4)); eval(shift(@thread67));
+ eval(shift(@thread5)); eval(shift(@thread67));
+ }
+
+ @thread0=&NEONROUND($A0,$B0,$C0,$D0,$T0,1);
+ @thread1=&NEONROUND($A1,$B1,$C1,$D1,$T1,1);
+ @thread2=&NEONROUND($A2,$B2,$C2,$D2,$T2,1);
+ @thread3=&NEONROUND($A3,$B3,$C3,$D3,$T3,1);
+ @thread4=&NEONROUND($A4,$B4,$C4,$D4,$T4,1);
+ @thread5=&NEONROUND($A5,$B5,$C5,$D5,$T5,1);
+ @thread67=(&ROUND(0,4,8,12),&ROUND(0,5,10,15));
+
+ foreach (@thread0) {
+ eval; eval(shift(@thread67));
+ eval(shift(@thread1)); eval(shift(@thread67));
+ eval(shift(@thread2)); eval(shift(@thread67));
+ eval(shift(@thread3)); eval(shift(@thread67));
+ eval(shift(@thread4)); eval(shift(@thread67));
+ eval(shift(@thread5)); eval(shift(@thread67));
+ }
+$code.=<<___;
+ cbnz $ctr,.Loop_lower_neon
+
+ add.32 @x[0],@x[0],@d[0] // accumulate key block
+ ldp @K[0],@K[1],[sp,#0]
+ add @x[1],@x[1],@d[0],lsr#32
+ ldp @K[2],@K[3],[sp,#32]
+ add.32 @x[2],@x[2],@d[1]
+ ldp @K[4],@K[5],[sp,#64]
+ add @x[3],@x[3],@d[1],lsr#32
+ add $A0,$A0,@K[0]
+ add.32 @x[4],@x[4],@d[2]
+ add $A1,$A1,@K[0]
+ add @x[5],@x[5],@d[2],lsr#32
+ add $A2,$A2,@K[0]
+ add.32 @x[6],@x[6],@d[3]
+ add $A3,$A3,@K[0]
+ add @x[7],@x[7],@d[3],lsr#32
+ add $A4,$A4,@K[0]
+ add.32 @x[8],@x[8],@d[4]
+ add $A5,$A5,@K[0]
+ add @x[9],@x[9],@d[4],lsr#32
+ add $C0,$C0,@K[2]
+ add.32 @x[10],@x[10],@d[5]
+ add $C1,$C1,@K[2]
+ add @x[11],@x[11],@d[5],lsr#32
+ add $C2,$C2,@K[2]
+ add.32 @x[12],@x[12],@d[6]
+ add $C3,$C3,@K[2]
+ add @x[13],@x[13],@d[6],lsr#32
+ add $C4,$C4,@K[2]
+ add.32 @x[14],@x[14],@d[7]
+ add $C5,$C5,@K[2]
+ add @x[15],@x[15],@d[7],lsr#32
+ add $D4,$D4,$ONE // +4
+ add @x[0],@x[0],@x[1],lsl#32 // pack
+ add $D5,$D5,$ONE // +4
+ add @x[2],@x[2],@x[3],lsl#32
+ add $D0,$D0,@K[3]
+ ldp @x[1],@x[3],[$inp,#0] // load input
+ add $D1,$D1,@K[4]
+ add @x[4],@x[4],@x[5],lsl#32
+ add $D2,$D2,@K[5]
+ add @x[6],@x[6],@x[7],lsl#32
+ add $D3,$D3,@K[6]
+ ldp @x[5],@x[7],[$inp,#16]
+ add $D4,$D4,@K[3]
+ add @x[8],@x[8],@x[9],lsl#32
+ add $D5,$D5,@K[4]
+ add @x[10],@x[10],@x[11],lsl#32
+ add $B0,$B0,@K[1]
+ ldp @x[9],@x[11],[$inp,#32]
+ add $B1,$B1,@K[1]
+ add @x[12],@x[12],@x[13],lsl#32
+ add $B2,$B2,@K[1]
+ add @x[14],@x[14],@x[15],lsl#32
+ add $B3,$B3,@K[1]
+ ldp @x[13],@x[15],[$inp,#48]
+ add $B4,$B4,@K[1]
+ add $inp,$inp,#64
+ add $B5,$B5,@K[1]
+
+#ifdef __ARMEB__
+ rev @x[0],@x[0]
+ rev @x[2],@x[2]
+ rev @x[4],@x[4]
+ rev @x[6],@x[6]
+ rev @x[8],@x[8]
+ rev @x[10],@x[10]
+ rev @x[12],@x[12]
+ rev @x[14],@x[14]
+#endif
+ ld1.8 {$T0-$T3},[$inp],#64
+ eor @x[0],@x[0],@x[1]
+ eor @x[2],@x[2],@x[3]
+ eor @x[4],@x[4],@x[5]
+ eor @x[6],@x[6],@x[7]
+ eor @x[8],@x[8],@x[9]
+ eor $A0,$A0,$T0
+ eor @x[10],@x[10],@x[11]
+ eor $B0,$B0,$T1
+ eor @x[12],@x[12],@x[13]
+ eor $C0,$C0,$T2
+ eor @x[14],@x[14],@x[15]
+ eor $D0,$D0,$T3
+ ld1.8 {$T0-$T3},[$inp],#64
+
+ stp @x[0],@x[2],[$out,#0] // store output
+ add @d[6],@d[6],#7 // increment counter
+ stp @x[4],@x[6],[$out,#16]
+ stp @x[8],@x[10],[$out,#32]
+ stp @x[12],@x[14],[$out,#48]
+ add $out,$out,#64
+ st1.8 {$A0-$D0},[$out],#64
+
+ ld1.8 {$A0-$D0},[$inp],#64
+ eor $A1,$A1,$T0
+ eor $B1,$B1,$T1
+ eor $C1,$C1,$T2
+ eor $D1,$D1,$T3
+ st1.8 {$A1-$D1},[$out],#64
+
+ ld1.8 {$A1-$D1},[$inp],#64
+ eor $A2,$A2,$A0
+ ldp @K[0],@K[1],[sp,#0]
+ eor $B2,$B2,$B0
+ ldp @K[2],@K[3],[sp,#32]
+ eor $C2,$C2,$C0
+ eor $D2,$D2,$D0
+ st1.8 {$A2-$D2},[$out],#64
+
+ ld1.8 {$A2-$D2},[$inp],#64
+ eor $A3,$A3,$A1
+ eor $B3,$B3,$B1
+ eor $C3,$C3,$C1
+ eor $D3,$D3,$D1
+ st1.8 {$A3-$D3},[$out],#64
+
+ ld1.8 {$A3-$D3},[$inp],#64
+ eor $A4,$A4,$A2
+ eor $B4,$B4,$B2
+ eor $C4,$C4,$C2
+ eor $D4,$D4,$D2
+ st1.8 {$A4-$D4},[$out],#64
+
+ shl $A0,$ONE,#1 // 4 -> 8
+ eor $A5,$A5,$A3
+ eor $B5,$B5,$B3
+ eor $C5,$C5,$C3
+ eor $D5,$D5,$D3
+ st1.8 {$A5-$D5},[$out],#64
+
+ add @K[3],@K[3],$A0 // += 8
+ add @K[4],@K[4],$A0
+ add @K[5],@K[5],$A0
+ add @K[6],@K[6],$A0
+
+ b.hs .Loop_outer_512_neon
+
+ adds $len,$len,#512
+ ushr $A0,$ONE,#2 // 4 -> 1
+
+ ldp d8,d9,[sp,#128+0] // meet ABI requirements
+ ldp d10,d11,[sp,#128+16]
+ ldp d12,d13,[sp,#128+32]
+ ldp d14,d15,[sp,#128+48]
+
+ stp @K[0],$ONE,[sp,#0] // wipe off-load area
+ stp @K[0],$ONE,[sp,#32]
+ stp @K[0],$ONE,[sp,#64]
+
+ b.eq .Ldone_512_neon
+
+ cmp $len,#192
+ sub @K[3],@K[3],$A0 // -= 1
+ sub @K[4],@K[4],$A0
+ sub @K[5],@K[5],$A0
+ add sp,sp,#128
+ b.hs .Loop_outer_neon
+
+ eor @K[1],@K[1],@K[1]
+ eor @K[2],@K[2],@K[2]
+ eor @K[3],@K[3],@K[3]
+ eor @K[4],@K[4],@K[4]
+ eor @K[5],@K[5],@K[5]
+ eor @K[6],@K[6],@K[6]
+ b .Loop_outer
+
+.Ldone_512_neon:
+ ldp x19,x20,[x29,#16]
+ add sp,sp,#128+64
+ ldp x21,x22,[x29,#32]
+ ldp x23,x24,[x29,#48]
+ ldp x25,x26,[x29,#64]
+ ldp x27,x28,[x29,#80]
+ ldp x29,x30,[sp],#96
+ ret
+.size ChaCha20_512_neon,.-ChaCha20_512_neon
+___
+}
+}}}
+
+foreach (split("\n",$code)) {
+ s/\`([^\`]*)\`/eval $1/geo;
+
+ (s/\b([a-z]+)\.32\b/$1/ and (s/x([0-9]+)/w$1/g or 1)) or
+ (m/\b(eor|ext|mov)\b/ and (s/\.4s/\.16b/g or 1)) or
+ (s/\b((?:ld|st)1)\.8\b/$1/ and (s/\.4s/\.16b/g or 1)) or
+ (m/\b(ld|st)[rp]\b/ and (s/v([0-9]+)\.4s/q$1/g or 1)) or
+ (s/\brev32\.16\b/rev32/ and (s/\.4s/\.8h/g or 1));
+
+ #s/\bq([0-9]+)#(lo|hi)/sprintf "d%d",2*$1+($2 eq "hi")/geo;
+
+ print $_,"\n";
+}
+close STDOUT; # flush
diff --git a/src/crypto/chacha/asm/chacha-x86.pl b/src/crypto/chacha/asm/chacha-x86.pl
new file mode 100755
index 00000000..e5760297
--- /dev/null
+++ b/src/crypto/chacha/asm/chacha-x86.pl
@@ -0,0 +1,769 @@
+#!/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/.
+# ====================================================================
+#
+# January 2015
+#
+# ChaCha20 for x86.
+#
+# Performance in cycles per byte out of large buffer.
+#
+# 1xIALU/gcc 4xSSSE3
+# Pentium 17.5/+80%
+# PIII 14.2/+60%
+# P4 18.6/+84%
+# Core2 9.56/+89% 4.83
+# Westmere 9.50/+45% 3.35
+# Sandy Bridge 10.7/+47% 3.24
+# Haswell 8.22/+50% 2.89
+# Silvermont 17.8/+36% 8.53
+# Sledgehammer 10.2/+54%
+# Bulldozer 13.5/+50% 4.39(*)
+#
+# (*) Bulldozer actually executes 4xXOP code path that delivers 3.50;
+#
+# Modified from upstream OpenSSL to remove the XOP code.
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC,"${dir}","${dir}../../perlasm");
+require "x86asm.pl";
+
+&asm_init($ARGV[0],"chacha-x86.pl",$ARGV[$#ARGV] eq "386");
+
+$xmm=$ymm=0;
+for (@ARGV) { $xmm=1 if (/-DOPENSSL_IA32_SSE2/); }
+
+$ymm=$xmm;
+
+$a="eax";
+($b,$b_)=("ebx","ebp");
+($c,$c_)=("ecx","esi");
+($d,$d_)=("edx","edi");
+
+sub QUARTERROUND {
+my ($ai,$bi,$ci,$di,$i)=@_;
+my ($an,$bn,$cn,$dn)=map(($_&~3)+(($_+1)&3),($ai,$bi,$ci,$di)); # next
+my ($ap,$bp,$cp,$dp)=map(($_&~3)+(($_-1)&3),($ai,$bi,$ci,$di)); # previous
+
+ # a b c d
+ #
+ # 0 4 8 12 < even round
+ # 1 5 9 13
+ # 2 6 10 14
+ # 3 7 11 15
+ # 0 5 10 15 < odd round
+ # 1 6 11 12
+ # 2 7 8 13
+ # 3 4 9 14
+
+ if ($i==0) {
+ my $j=4;
+ ($ap,$bp,$cp,$dp)=map(($_&~3)+(($_-$j--)&3),($ap,$bp,$cp,$dp));
+ } elsif ($i==3) {
+ my $j=0;
+ ($an,$bn,$cn,$dn)=map(($_&~3)+(($_+$j++)&3),($an,$bn,$cn,$dn));
+ } elsif ($i==4) {
+ my $j=4;
+ ($ap,$bp,$cp,$dp)=map(($_&~3)+(($_+$j--)&3),($ap,$bp,$cp,$dp));
+ } elsif ($i==7) {
+ my $j=0;
+ ($an,$bn,$cn,$dn)=map(($_&~3)+(($_-$j++)&3),($an,$bn,$cn,$dn));
+ }
+
+ #&add ($a,$b); # see elsewhere
+ &xor ($d,$a);
+ &mov (&DWP(4*$cp,"esp"),$c_) if ($ai>0 && $ai<3);
+ &rol ($d,16);
+ &mov (&DWP(4*$bp,"esp"),$b_) if ($i!=0);
+ &add ($c,$d);
+ &mov ($c_,&DWP(4*$cn,"esp")) if ($ai>0 && $ai<3);
+ &xor ($b,$c);
+ &mov ($d_,&DWP(4*$dn,"esp")) if ($di!=$dn);
+ &rol ($b,12);
+ &mov ($b_,&DWP(4*$bn,"esp")) if ($i<7);
+ &mov ($b_,&DWP(128,"esp")) if ($i==7); # loop counter
+ &add ($a,$b);
+ &xor ($d,$a);
+ &mov (&DWP(4*$ai,"esp"),$a);
+ &rol ($d,8);
+ &mov ($a,&DWP(4*$an,"esp"));
+ &add ($c,$d);
+ &mov (&DWP(4*$di,"esp"),$d) if ($di!=$dn);
+ &mov ($d_,$d) if ($di==$dn);
+ &xor ($b,$c);
+ &add ($a,$b_) if ($i<7); # elsewhere
+ &rol ($b,7);
+
+ ($b,$b_)=($b_,$b);
+ ($c,$c_)=($c_,$c);
+ ($d,$d_)=($d_,$d);
+}
+
+&static_label("ssse3_shortcut");
+&static_label("ssse3_data");
+&static_label("pic_point");
+
+&function_begin("ChaCha20_ctr32");
+ &xor ("eax","eax");
+ &cmp ("eax",&wparam(2)); # len==0?
+ &je (&label("no_data"));
+if ($xmm) {
+ &call (&label("pic_point"));
+&set_label("pic_point");
+ &blindpop("eax");
+ &picmeup("ebp","OPENSSL_ia32cap_P","eax",&label("pic_point"));
+ &test (&DWP(0,"ebp"),1<<24); # test FXSR bit
+ &jz (&label("x86"));
+ &test (&DWP(4,"ebp"),1<<9); # test SSSE3 bit
+ &jz (&label("x86"));
+ &jmp (&label("ssse3_shortcut"));
+&set_label("x86");
+}
+ &mov ("esi",&wparam(3)); # key
+ &mov ("edi",&wparam(4)); # counter and nonce
+
+ &stack_push(33);
+
+ &mov ("eax",&DWP(4*0,"esi")); # copy key
+ &mov ("ebx",&DWP(4*1,"esi"));
+ &mov ("ecx",&DWP(4*2,"esi"));
+ &mov ("edx",&DWP(4*3,"esi"));
+ &mov (&DWP(64+4*4,"esp"),"eax");
+ &mov (&DWP(64+4*5,"esp"),"ebx");
+ &mov (&DWP(64+4*6,"esp"),"ecx");
+ &mov (&DWP(64+4*7,"esp"),"edx");
+ &mov ("eax",&DWP(4*4,"esi"));
+ &mov ("ebx",&DWP(4*5,"esi"));
+ &mov ("ecx",&DWP(4*6,"esi"));
+ &mov ("edx",&DWP(4*7,"esi"));
+ &mov (&DWP(64+4*8,"esp"),"eax");
+ &mov (&DWP(64+4*9,"esp"),"ebx");
+ &mov (&DWP(64+4*10,"esp"),"ecx");
+ &mov (&DWP(64+4*11,"esp"),"edx");
+ &mov ("eax",&DWP(4*0,"edi")); # copy counter and nonce
+ &mov ("ebx",&DWP(4*1,"edi"));
+ &mov ("ecx",&DWP(4*2,"edi"));
+ &mov ("edx",&DWP(4*3,"edi"));
+ &sub ("eax",1);
+ &mov (&DWP(64+4*12,"esp"),"eax");
+ &mov (&DWP(64+4*13,"esp"),"ebx");
+ &mov (&DWP(64+4*14,"esp"),"ecx");
+ &mov (&DWP(64+4*15,"esp"),"edx");
+ &jmp (&label("entry"));
+
+&set_label("outer_loop",16);
+ &mov (&wparam(1),$b); # save input
+ &mov (&wparam(0),$a); # save output
+ &mov (&wparam(2),$c); # save len
+&set_label("entry");
+ &mov ($a,0x61707865);
+ &mov (&DWP(4*1,"esp"),0x3320646e);
+ &mov (&DWP(4*2,"esp"),0x79622d32);
+ &mov (&DWP(4*3,"esp"),0x6b206574);
+
+ &mov ($b, &DWP(64+4*5,"esp")); # copy key material
+ &mov ($b_,&DWP(64+4*6,"esp"));
+ &mov ($c, &DWP(64+4*10,"esp"));
+ &mov ($c_,&DWP(64+4*11,"esp"));
+ &mov ($d, &DWP(64+4*13,"esp"));
+ &mov ($d_,&DWP(64+4*14,"esp"));
+ &mov (&DWP(4*5,"esp"),$b);
+ &mov (&DWP(4*6,"esp"),$b_);
+ &mov (&DWP(4*10,"esp"),$c);
+ &mov (&DWP(4*11,"esp"),$c_);
+ &mov (&DWP(4*13,"esp"),$d);
+ &mov (&DWP(4*14,"esp"),$d_);
+
+ &mov ($b, &DWP(64+4*7,"esp"));
+ &mov ($d_,&DWP(64+4*15,"esp"));
+ &mov ($d, &DWP(64+4*12,"esp"));
+ &mov ($b_,&DWP(64+4*4,"esp"));
+ &mov ($c, &DWP(64+4*8,"esp"));
+ &mov ($c_,&DWP(64+4*9,"esp"));
+ &add ($d,1); # counter value
+ &mov (&DWP(4*7,"esp"),$b);
+ &mov (&DWP(4*15,"esp"),$d_);
+ &mov (&DWP(64+4*12,"esp"),$d); # save counter value
+
+ &mov ($b,10); # loop counter
+ &jmp (&label("loop"));
+
+&set_label("loop",16);
+ &add ($a,$b_); # elsewhere
+ &mov (&DWP(128,"esp"),$b); # save loop counter
+ &mov ($b,$b_);
+ &QUARTERROUND(0, 4, 8, 12, 0);
+ &QUARTERROUND(1, 5, 9, 13, 1);
+ &QUARTERROUND(2, 6,10, 14, 2);
+ &QUARTERROUND(3, 7,11, 15, 3);
+ &QUARTERROUND(0, 5,10, 15, 4);
+ &QUARTERROUND(1, 6,11, 12, 5);
+ &QUARTERROUND(2, 7, 8, 13, 6);
+ &QUARTERROUND(3, 4, 9, 14, 7);
+ &dec ($b);
+ &jnz (&label("loop"));
+
+ &mov ($b,&wparam(2)); # load len
+
+ &add ($a,0x61707865); # accumulate key material
+ &add ($b_,&DWP(64+4*4,"esp"));
+ &add ($c, &DWP(64+4*8,"esp"));
+ &add ($c_,&DWP(64+4*9,"esp"));
+
+ &cmp ($b,64);
+ &jb (&label("tail"));
+
+ &mov ($b,&wparam(1)); # load input pointer
+ &add ($d, &DWP(64+4*12,"esp"));
+ &add ($d_,&DWP(64+4*14,"esp"));
+
+ &xor ($a, &DWP(4*0,$b)); # xor with input
+ &xor ($b_,&DWP(4*4,$b));
+ &mov (&DWP(4*0,"esp"),$a); # off-load for later write
+ &mov ($a,&wparam(0)); # load output pointer
+ &xor ($c, &DWP(4*8,$b));
+ &xor ($c_,&DWP(4*9,$b));
+ &xor ($d, &DWP(4*12,$b));
+ &xor ($d_,&DWP(4*14,$b));
+ &mov (&DWP(4*4,"esp"),$b_);
+ &mov ($b_,&DWP(4*0,"esp"));
+ &mov (&DWP(4*8,"esp"),$c);
+ &mov (&DWP(4*9,"esp"),$c_);
+ &mov (&DWP(4*12,"esp"),$d);
+ &mov (&DWP(4*14,"esp"),$d_);
+
+ &mov (&DWP(4*0,$a),$b_); # write output in order
+ &mov ($b_,&DWP(4*1,"esp"));
+ &mov ($c, &DWP(4*2,"esp"));
+ &mov ($c_,&DWP(4*3,"esp"));
+ &mov ($d, &DWP(4*5,"esp"));
+ &mov ($d_,&DWP(4*6,"esp"));
+ &add ($b_,0x3320646e); # accumulate key material
+ &add ($c, 0x79622d32);
+ &add ($c_,0x6b206574);
+ &add ($d, &DWP(64+4*5,"esp"));
+ &add ($d_,&DWP(64+4*6,"esp"));
+ &xor ($b_,&DWP(4*1,$b));
+ &xor ($c, &DWP(4*2,$b));
+ &xor ($c_,&DWP(4*3,$b));
+ &xor ($d, &DWP(4*5,$b));
+ &xor ($d_,&DWP(4*6,$b));
+ &mov (&DWP(4*1,$a),$b_);
+ &mov ($b_,&DWP(4*4,"esp"));
+ &mov (&DWP(4*2,$a),$c);
+ &mov (&DWP(4*3,$a),$c_);
+ &mov (&DWP(4*4,$a),$b_);
+ &mov (&DWP(4*5,$a),$d);
+ &mov (&DWP(4*6,$a),$d_);
+
+ &mov ($c,&DWP(4*7,"esp"));
+ &mov ($d,&DWP(4*8,"esp"));
+ &mov ($d_,&DWP(4*9,"esp"));
+ &add ($c,&DWP(64+4*7,"esp"));
+ &mov ($b_, &DWP(4*10,"esp"));
+ &xor ($c,&DWP(4*7,$b));
+ &mov ($c_,&DWP(4*11,"esp"));
+ &mov (&DWP(4*7,$a),$c);
+ &mov (&DWP(4*8,$a),$d);
+ &mov (&DWP(4*9,$a),$d_);
+
+ &add ($b_, &DWP(64+4*10,"esp"));
+ &add ($c_,&DWP(64+4*11,"esp"));
+ &xor ($b_, &DWP(4*10,$b));
+ &xor ($c_,&DWP(4*11,$b));
+ &mov (&DWP(4*10,$a),$b_);
+ &mov (&DWP(4*11,$a),$c_);
+
+ &mov ($c,&DWP(4*12,"esp"));
+ &mov ($c_,&DWP(4*14,"esp"));
+ &mov ($d, &DWP(4*13,"esp"));
+ &mov ($d_,&DWP(4*15,"esp"));
+ &add ($d, &DWP(64+4*13,"esp"));
+ &add ($d_,&DWP(64+4*15,"esp"));
+ &xor ($d, &DWP(4*13,$b));
+ &xor ($d_,&DWP(4*15,$b));
+ &lea ($b,&DWP(4*16,$b));
+ &mov (&DWP(4*12,$a),$c);
+ &mov ($c,&wparam(2)); # len
+ &mov (&DWP(4*13,$a),$d);
+ &mov (&DWP(4*14,$a),$c_);
+ &mov (&DWP(4*15,$a),$d_);
+ &lea ($a,&DWP(4*16,$a));
+ &sub ($c,64);
+ &jnz (&label("outer_loop"));
+
+ &jmp (&label("done"));
+
+&set_label("tail");
+ &add ($d, &DWP(64+4*12,"esp"));
+ &add ($d_,&DWP(64+4*14,"esp"));
+ &mov (&DWP(4*0,"esp"),$a);
+ &mov (&DWP(4*4,"esp"),$b_);
+ &mov (&DWP(4*8,"esp"),$c);
+ &mov (&DWP(4*9,"esp"),$c_);
+ &mov (&DWP(4*12,"esp"),$d);
+ &mov (&DWP(4*14,"esp"),$d_);
+
+ &mov ($b_,&DWP(4*1,"esp"));
+ &mov ($c, &DWP(4*2,"esp"));
+ &mov ($c_,&DWP(4*3,"esp"));
+ &mov ($d, &DWP(4*5,"esp"));
+ &mov ($d_,&DWP(4*6,"esp"));
+ &add ($b_,0x3320646e); # accumulate key material
+ &add ($c, 0x79622d32);
+ &add ($c_,0x6b206574);
+ &add ($d, &DWP(64+4*5,"esp"));
+ &add ($d_,&DWP(64+4*6,"esp"));
+ &mov (&DWP(4*1,"esp"),$b_);
+ &mov (&DWP(4*2,"esp"),$c);
+ &mov (&DWP(4*3,"esp"),$c_);
+ &mov (&DWP(4*5,"esp"),$d);
+ &mov (&DWP(4*6,"esp"),$d_);
+
+ &mov ($b_,&DWP(4*7,"esp"));
+ &mov ($c, &DWP(4*10,"esp"));
+ &mov ($c_,&DWP(4*11,"esp"));
+ &mov ($d, &DWP(4*13,"esp"));
+ &mov ($d_,&DWP(4*15,"esp"));
+ &add ($b_,&DWP(64+4*7,"esp"));
+ &add ($c, &DWP(64+4*10,"esp"));
+ &add ($c_,&DWP(64+4*11,"esp"));
+ &add ($d, &DWP(64+4*13,"esp"));
+ &add ($d_,&DWP(64+4*15,"esp"));
+ &mov (&DWP(4*7,"esp"),$b_);
+ &mov ($b_,&wparam(1)); # load input
+ &mov (&DWP(4*10,"esp"),$c);
+ &mov ($c,&wparam(0)); # load output
+ &mov (&DWP(4*11,"esp"),$c_);
+ &xor ($c_,$c_);
+ &mov (&DWP(4*13,"esp"),$d);
+ &mov (&DWP(4*15,"esp"),$d_);
+
+ &xor ("eax","eax");
+ &xor ("edx","edx");
+&set_label("tail_loop");
+ &movb ("al",&BP(0,$c_,$b_));
+ &movb ("dl",&BP(0,"esp",$c_));
+ &lea ($c_,&DWP(1,$c_));
+ &xor ("al","dl");
+ &mov (&BP(-1,$c,$c_),"al");
+ &dec ($b);
+ &jnz (&label("tail_loop"));
+
+&set_label("done");
+ &stack_pop(33);
+&set_label("no_data");
+&function_end("ChaCha20_ctr32");
+
+if ($xmm) {
+my ($xa,$xa_,$xb,$xb_,$xc,$xc_,$xd,$xd_)=map("xmm$_",(0..7));
+my ($out,$inp,$len)=("edi","esi","ecx");
+
+sub QUARTERROUND_SSSE3 {
+my ($ai,$bi,$ci,$di,$i)=@_;
+my ($an,$bn,$cn,$dn)=map(($_&~3)+(($_+1)&3),($ai,$bi,$ci,$di)); # next
+my ($ap,$bp,$cp,$dp)=map(($_&~3)+(($_-1)&3),($ai,$bi,$ci,$di)); # previous
+
+ # a b c d
+ #
+ # 0 4 8 12 < even round
+ # 1 5 9 13
+ # 2 6 10 14
+ # 3 7 11 15
+ # 0 5 10 15 < odd round
+ # 1 6 11 12
+ # 2 7 8 13
+ # 3 4 9 14
+
+ if ($i==0) {
+ my $j=4;
+ ($ap,$bp,$cp,$dp)=map(($_&~3)+(($_-$j--)&3),($ap,$bp,$cp,$dp));
+ } elsif ($i==3) {
+ my $j=0;
+ ($an,$bn,$cn,$dn)=map(($_&~3)+(($_+$j++)&3),($an,$bn,$cn,$dn));
+ } elsif ($i==4) {
+ my $j=4;
+ ($ap,$bp,$cp,$dp)=map(($_&~3)+(($_+$j--)&3),($ap,$bp,$cp,$dp));
+ } elsif ($i==7) {
+ my $j=0;
+ ($an,$bn,$cn,$dn)=map(($_&~3)+(($_-$j++)&3),($an,$bn,$cn,$dn));
+ }
+
+ #&paddd ($xa,$xb); # see elsewhere
+ #&pxor ($xd,$xa); # see elsewhere
+ &movdqa(&QWP(16*$cp-128,"ebx"),$xc_) if ($ai>0 && $ai<3);
+ &pshufb ($xd,&QWP(0,"eax")); # rot16
+ &movdqa(&QWP(16*$bp-128,"ebx"),$xb_) if ($i!=0);
+ &paddd ($xc,$xd);
+ &movdqa($xc_,&QWP(16*$cn-128,"ebx")) if ($ai>0 && $ai<3);
+ &pxor ($xb,$xc);
+ &movdqa($xb_,&QWP(16*$bn-128,"ebx")) if ($i<7);
+ &movdqa ($xa_,$xb); # borrow as temporary
+ &pslld ($xb,12);
+ &psrld ($xa_,20);
+ &por ($xb,$xa_);
+ &movdqa($xa_,&QWP(16*$an-128,"ebx"));
+ &paddd ($xa,$xb);
+ &movdqa($xd_,&QWP(16*$dn-128,"ebx")) if ($di!=$dn);
+ &pxor ($xd,$xa);
+ &movdqa (&QWP(16*$ai-128,"ebx"),$xa);
+ &pshufb ($xd,&QWP(16,"eax")); # rot8
+ &paddd ($xc,$xd);
+ &movdqa (&QWP(16*$di-128,"ebx"),$xd) if ($di!=$dn);
+ &movdqa ($xd_,$xd) if ($di==$dn);
+ &pxor ($xb,$xc);
+ &paddd ($xa_,$xb_) if ($i<7); # elsewhere
+ &movdqa ($xa,$xb); # borrow as temporary
+ &pslld ($xb,7);
+ &psrld ($xa,25);
+ &pxor ($xd_,$xa_) if ($i<7); # elsewhere
+ &por ($xb,$xa);
+
+ ($xa,$xa_)=($xa_,$xa);
+ ($xb,$xb_)=($xb_,$xb);
+ ($xc,$xc_)=($xc_,$xc);
+ ($xd,$xd_)=($xd_,$xd);
+}
+
+&function_begin("ChaCha20_ssse3");
+&set_label("ssse3_shortcut");
+ &mov ($out,&wparam(0));
+ &mov ($inp,&wparam(1));
+ &mov ($len,&wparam(2));
+ &mov ("edx",&wparam(3)); # key
+ &mov ("ebx",&wparam(4)); # counter and nonce
+
+ &mov ("ebp","esp");
+ &stack_push (131);
+ &and ("esp",-64);
+ &mov (&DWP(512,"esp"),"ebp");
+
+ &lea ("eax",&DWP(&label("ssse3_data")."-".
+ &label("pic_point"),"eax"));
+ &movdqu ("xmm3",&QWP(0,"ebx")); # counter and nonce
+
+ &cmp ($len,64*4);
+ &jb (&label("1x"));
+
+ &mov (&DWP(512+4,"esp"),"edx"); # offload pointers
+ &mov (&DWP(512+8,"esp"),"ebx");
+ &sub ($len,64*4); # bias len
+ &lea ("ebp",&DWP(256+128,"esp")); # size optimization
+
+ &movdqu ("xmm7",&QWP(0,"edx")); # key
+ &pshufd ("xmm0","xmm3",0x00);
+ &pshufd ("xmm1","xmm3",0x55);
+ &pshufd ("xmm2","xmm3",0xaa);
+ &pshufd ("xmm3","xmm3",0xff);
+ &paddd ("xmm0",&QWP(16*3,"eax")); # fix counters
+ &pshufd ("xmm4","xmm7",0x00);
+ &pshufd ("xmm5","xmm7",0x55);
+ &psubd ("xmm0",&QWP(16*4,"eax"));
+ &pshufd ("xmm6","xmm7",0xaa);
+ &pshufd ("xmm7","xmm7",0xff);
+ &movdqa (&QWP(16*12-128,"ebp"),"xmm0");
+ &movdqa (&QWP(16*13-128,"ebp"),"xmm1");
+ &movdqa (&QWP(16*14-128,"ebp"),"xmm2");
+ &movdqa (&QWP(16*15-128,"ebp"),"xmm3");
+ &movdqu ("xmm3",&QWP(16,"edx")); # key
+ &movdqa (&QWP(16*4-128,"ebp"),"xmm4");
+ &movdqa (&QWP(16*5-128,"ebp"),"xmm5");
+ &movdqa (&QWP(16*6-128,"ebp"),"xmm6");
+ &movdqa (&QWP(16*7-128,"ebp"),"xmm7");
+ &movdqa ("xmm7",&QWP(16*2,"eax")); # sigma
+ &lea ("ebx",&DWP(128,"esp")); # size optimization
+
+ &pshufd ("xmm0","xmm3",0x00);
+ &pshufd ("xmm1","xmm3",0x55);
+ &pshufd ("xmm2","xmm3",0xaa);
+ &pshufd ("xmm3","xmm3",0xff);
+ &pshufd ("xmm4","xmm7",0x00);
+ &pshufd ("xmm5","xmm7",0x55);
+ &pshufd ("xmm6","xmm7",0xaa);
+ &pshufd ("xmm7","xmm7",0xff);
+ &movdqa (&QWP(16*8-128,"ebp"),"xmm0");
+ &movdqa (&QWP(16*9-128,"ebp"),"xmm1");
+ &movdqa (&QWP(16*10-128,"ebp"),"xmm2");
+ &movdqa (&QWP(16*11-128,"ebp"),"xmm3");
+ &movdqa (&QWP(16*0-128,"ebp"),"xmm4");
+ &movdqa (&QWP(16*1-128,"ebp"),"xmm5");
+ &movdqa (&QWP(16*2-128,"ebp"),"xmm6");
+ &movdqa (&QWP(16*3-128,"ebp"),"xmm7");
+
+ &lea ($inp,&DWP(128,$inp)); # size optimization
+ &lea ($out,&DWP(128,$out)); # size optimization
+ &jmp (&label("outer_loop"));
+
+&set_label("outer_loop",16);
+ #&movdqa ("xmm0",&QWP(16*0-128,"ebp")); # copy key material
+ &movdqa ("xmm1",&QWP(16*1-128,"ebp"));
+ &movdqa ("xmm2",&QWP(16*2-128,"ebp"));
+ &movdqa ("xmm3",&QWP(16*3-128,"ebp"));
+ #&movdqa ("xmm4",&QWP(16*4-128,"ebp"));
+ &movdqa ("xmm5",&QWP(16*5-128,"ebp"));
+ &movdqa ("xmm6",&QWP(16*6-128,"ebp"));
+ &movdqa ("xmm7",&QWP(16*7-128,"ebp"));
+ #&movdqa (&QWP(16*0-128,"ebx"),"xmm0");
+ &movdqa (&QWP(16*1-128,"ebx"),"xmm1");
+ &movdqa (&QWP(16*2-128,"ebx"),"xmm2");
+ &movdqa (&QWP(16*3-128,"ebx"),"xmm3");
+ #&movdqa (&QWP(16*4-128,"ebx"),"xmm4");
+ &movdqa (&QWP(16*5-128,"ebx"),"xmm5");
+ &movdqa (&QWP(16*6-128,"ebx"),"xmm6");
+ &movdqa (&QWP(16*7-128,"ebx"),"xmm7");
+ #&movdqa ("xmm0",&QWP(16*8-128,"ebp"));
+ #&movdqa ("xmm1",&QWP(16*9-128,"ebp"));
+ &movdqa ("xmm2",&QWP(16*10-128,"ebp"));
+ &movdqa ("xmm3",&QWP(16*11-128,"ebp"));
+ &movdqa ("xmm4",&QWP(16*12-128,"ebp"));
+ &movdqa ("xmm5",&QWP(16*13-128,"ebp"));
+ &movdqa ("xmm6",&QWP(16*14-128,"ebp"));
+ &movdqa ("xmm7",&QWP(16*15-128,"ebp"));
+ &paddd ("xmm4",&QWP(16*4,"eax")); # counter value
+ #&movdqa (&QWP(16*8-128,"ebx"),"xmm0");
+ #&movdqa (&QWP(16*9-128,"ebx"),"xmm1");
+ &movdqa (&QWP(16*10-128,"ebx"),"xmm2");
+ &movdqa (&QWP(16*11-128,"ebx"),"xmm3");
+ &movdqa (&QWP(16*12-128,"ebx"),"xmm4");
+ &movdqa (&QWP(16*13-128,"ebx"),"xmm5");
+ &movdqa (&QWP(16*14-128,"ebx"),"xmm6");
+ &movdqa (&QWP(16*15-128,"ebx"),"xmm7");
+ &movdqa (&QWP(16*12-128,"ebp"),"xmm4"); # save counter value
+
+ &movdqa ($xa, &QWP(16*0-128,"ebp"));
+ &movdqa ($xd, "xmm4");
+ &movdqa ($xb_,&QWP(16*4-128,"ebp"));
+ &movdqa ($xc, &QWP(16*8-128,"ebp"));
+ &movdqa ($xc_,&QWP(16*9-128,"ebp"));
+
+ &mov ("edx",10); # loop counter
+ &nop ();
+
+&set_label("loop",16);
+ &paddd ($xa,$xb_); # elsewhere
+ &movdqa ($xb,$xb_);
+ &pxor ($xd,$xa); # elsewhere
+ &QUARTERROUND_SSSE3(0, 4, 8, 12, 0);
+ &QUARTERROUND_SSSE3(1, 5, 9, 13, 1);
+ &QUARTERROUND_SSSE3(2, 6,10, 14, 2);
+ &QUARTERROUND_SSSE3(3, 7,11, 15, 3);
+ &QUARTERROUND_SSSE3(0, 5,10, 15, 4);
+ &QUARTERROUND_SSSE3(1, 6,11, 12, 5);
+ &QUARTERROUND_SSSE3(2, 7, 8, 13, 6);
+ &QUARTERROUND_SSSE3(3, 4, 9, 14, 7);
+ &dec ("edx");
+ &jnz (&label("loop"));
+
+ &movdqa (&QWP(16*4-128,"ebx"),$xb_);
+ &movdqa (&QWP(16*8-128,"ebx"),$xc);
+ &movdqa (&QWP(16*9-128,"ebx"),$xc_);
+ &movdqa (&QWP(16*12-128,"ebx"),$xd);
+ &movdqa (&QWP(16*14-128,"ebx"),$xd_);
+
+ my ($xa0,$xa1,$xa2,$xa3,$xt0,$xt1,$xt2,$xt3)=map("xmm$_",(0..7));
+
+ for($i=0;$i<256;$i+=64) {
+ #&movdqa ($xa0,&QWP($i+16*0-128,"ebx")); # it's there
+ &movdqa ($xa1,&QWP($i+16*1-128,"ebx"));
+ &movdqa ($xa2,&QWP($i+16*2-128,"ebx"));
+ &movdqa ($xa3,&QWP($i+16*3-128,"ebx"));
+
+ &paddd ($xa0,&QWP($i+16*0-128,"ebp")); # accumulate key material
+ &paddd ($xa1,&QWP($i+16*1-128,"ebp"));
+ &paddd ($xa2,&QWP($i+16*2-128,"ebp"));
+ &paddd ($xa3,&QWP($i+16*3-128,"ebp"));
+
+ &movdqa ($xt2,$xa0); # "de-interlace" data
+ &punpckldq ($xa0,$xa1);
+ &movdqa ($xt3,$xa2);
+ &punpckldq ($xa2,$xa3);
+ &punpckhdq ($xt2,$xa1);
+ &punpckhdq ($xt3,$xa3);
+ &movdqa ($xa1,$xa0);
+ &punpcklqdq ($xa0,$xa2); # "a0"
+ &movdqa ($xa3,$xt2);
+ &punpcklqdq ($xt2,$xt3); # "a2"
+ &punpckhqdq ($xa1,$xa2); # "a1"
+ &punpckhqdq ($xa3,$xt3); # "a3"
+
+ #($xa2,$xt2)=($xt2,$xa2);
+
+ &movdqa (&QWP($i+16*0-128,"ebx"),$xa0);
+ &movdqa ($xa0,&QWP($i+16*4-128,"ebx")) if ($i<192);
+ &movdqa (&QWP($i+16*1-128,"ebx"),$xa1);
+ &movdqa (&QWP($i+16*2-128,"ebx"),$xt2);
+ &movdqa (&QWP($i+16*3-128,"ebx"),$xa3);
+ }
+ for($i=0;$i<256;$i+=64) {
+ my $j = 16*($i/64);
+ &movdqu ($xa0,&QWP($i+16*0-128,$inp)); # load input
+ &movdqu ($xa1,&QWP($i+16*1-128,$inp));
+ &movdqu ($xa2,&QWP($i+16*2-128,$inp));
+ &movdqu ($xa3,&QWP($i+16*3-128,$inp));
+ &pxor ($xa0,&QWP($j+64*0-128,"ebx"));
+ &pxor ($xa1,&QWP($j+64*1-128,"ebx"));
+ &pxor ($xa2,&QWP($j+64*2-128,"ebx"));
+ &pxor ($xa3,&QWP($j+64*3-128,"ebx"));
+ &movdqu (&QWP($i+16*0-128,$out),$xa0); # write output
+ &movdqu (&QWP($i+16*1-128,$out),$xa1);
+ &movdqu (&QWP($i+16*2-128,$out),$xa2);
+ &movdqu (&QWP($i+16*3-128,$out),$xa3);
+ }
+ &lea ($inp,&DWP(256,$inp));
+ &lea ($out,&DWP(256,$out));
+ &sub ($len,64*4);
+ &jnc (&label("outer_loop"));
+
+ &add ($len,64*4);
+ &jz (&label("done"));
+
+ &mov ("ebx",&DWP(512+8,"esp")); # restore pointers
+ &lea ($inp,&DWP(-128,$inp));
+ &mov ("edx",&DWP(512+4,"esp"));
+ &lea ($out,&DWP(-128,$out));
+
+ &movd ("xmm2",&DWP(16*12-128,"ebp")); # counter value
+ &movdqu ("xmm3",&QWP(0,"ebx"));
+ &paddd ("xmm2",&QWP(16*6,"eax")); # +four
+ &pand ("xmm3",&QWP(16*7,"eax"));
+ &por ("xmm3","xmm2"); # counter value
+{
+my ($a,$b,$c,$d,$t,$t1,$rot16,$rot24)=map("xmm$_",(0..7));
+
+sub SSSE3ROUND { # critical path is 20 "SIMD ticks" per round
+ &paddd ($a,$b);
+ &pxor ($d,$a);
+ &pshufb ($d,$rot16);
+
+ &paddd ($c,$d);
+ &pxor ($b,$c);
+ &movdqa ($t,$b);
+ &psrld ($b,20);
+ &pslld ($t,12);
+ &por ($b,$t);
+
+ &paddd ($a,$b);
+ &pxor ($d,$a);
+ &pshufb ($d,$rot24);
+
+ &paddd ($c,$d);
+ &pxor ($b,$c);
+ &movdqa ($t,$b);
+ &psrld ($b,25);
+ &pslld ($t,7);
+ &por ($b,$t);
+}
+
+&set_label("1x");
+ &movdqa ($a,&QWP(16*2,"eax")); # sigma
+ &movdqu ($b,&QWP(0,"edx"));
+ &movdqu ($c,&QWP(16,"edx"));
+ #&movdqu ($d,&QWP(0,"ebx")); # already loaded
+ &movdqa ($rot16,&QWP(0,"eax"));
+ &movdqa ($rot24,&QWP(16,"eax"));
+ &mov (&DWP(16*3,"esp"),"ebp");
+
+ &movdqa (&QWP(16*0,"esp"),$a);
+ &movdqa (&QWP(16*1,"esp"),$b);
+ &movdqa (&QWP(16*2,"esp"),$c);
+ &movdqa (&QWP(16*3,"esp"),$d);
+ &mov ("edx",10);
+ &jmp (&label("loop1x"));
+
+&set_label("outer1x",16);
+ &movdqa ($d,&QWP(16*5,"eax")); # one
+ &movdqa ($a,&QWP(16*0,"esp"));
+ &movdqa ($b,&QWP(16*1,"esp"));
+ &movdqa ($c,&QWP(16*2,"esp"));
+ &paddd ($d,&QWP(16*3,"esp"));
+ &mov ("edx",10);
+ &movdqa (&QWP(16*3,"esp"),$d);
+ &jmp (&label("loop1x"));
+
+&set_label("loop1x",16);
+ &SSSE3ROUND();
+ &pshufd ($c,$c,0b01001110);
+ &pshufd ($b,$b,0b00111001);
+ &pshufd ($d,$d,0b10010011);
+ &nop ();
+
+ &SSSE3ROUND();
+ &pshufd ($c,$c,0b01001110);
+ &pshufd ($b,$b,0b10010011);
+ &pshufd ($d,$d,0b00111001);
+
+ &dec ("edx");
+ &jnz (&label("loop1x"));
+
+ &paddd ($a,&QWP(16*0,"esp"));
+ &paddd ($b,&QWP(16*1,"esp"));
+ &paddd ($c,&QWP(16*2,"esp"));
+ &paddd ($d,&QWP(16*3,"esp"));
+
+ &cmp ($len,64);
+ &jb (&label("tail"));
+
+ &movdqu ($t,&QWP(16*0,$inp));
+ &movdqu ($t1,&QWP(16*1,$inp));
+ &pxor ($a,$t); # xor with input
+ &movdqu ($t,&QWP(16*2,$inp));
+ &pxor ($b,$t1);
+ &movdqu ($t1,&QWP(16*3,$inp));
+ &pxor ($c,$t);
+ &pxor ($d,$t1);
+ &lea ($inp,&DWP(16*4,$inp)); # inp+=64
+
+ &movdqu (&QWP(16*0,$out),$a); # write output
+ &movdqu (&QWP(16*1,$out),$b);
+ &movdqu (&QWP(16*2,$out),$c);
+ &movdqu (&QWP(16*3,$out),$d);
+ &lea ($out,&DWP(16*4,$out)); # inp+=64
+
+ &sub ($len,64);
+ &jnz (&label("outer1x"));
+
+ &jmp (&label("done"));
+
+&set_label("tail");
+ &movdqa (&QWP(16*0,"esp"),$a);
+ &movdqa (&QWP(16*1,"esp"),$b);
+ &movdqa (&QWP(16*2,"esp"),$c);
+ &movdqa (&QWP(16*3,"esp"),$d);
+
+ &xor ("eax","eax");
+ &xor ("edx","edx");
+ &xor ("ebp","ebp");
+
+&set_label("tail_loop");
+ &movb ("al",&BP(0,"esp","ebp"));
+ &movb ("dl",&BP(0,$inp,"ebp"));
+ &lea ("ebp",&DWP(1,"ebp"));
+ &xor ("al","dl");
+ &movb (&BP(-1,$out,"ebp"),"al");
+ &dec ($len);
+ &jnz (&label("tail_loop"));
+}
+&set_label("done");
+ &mov ("esp",&DWP(512,"esp"));
+&function_end("ChaCha20_ssse3");
+
+&align (64);
+&set_label("ssse3_data");
+&data_byte(0x2,0x3,0x0,0x1, 0x6,0x7,0x4,0x5, 0xa,0xb,0x8,0x9, 0xe,0xf,0xc,0xd);
+&data_byte(0x3,0x0,0x1,0x2, 0x7,0x4,0x5,0x6, 0xb,0x8,0x9,0xa, 0xf,0xc,0xd,0xe);
+&data_word(0x61707865,0x3320646e,0x79622d32,0x6b206574);
+&data_word(0,1,2,3);
+&data_word(4,4,4,4);
+&data_word(1,0,0,0);
+&data_word(4,0,0,0);
+&data_word(0,-1,-1,-1);
+&align (64);
+}
+&asciz ("ChaCha20 for x86, CRYPTOGAMS by <appro\@openssl.org>");
+
+&asm_finish();
diff --git a/src/crypto/chacha/asm/chacha-x86_64.pl b/src/crypto/chacha/asm/chacha-x86_64.pl
new file mode 100755
index 00000000..55b726d2
--- /dev/null
+++ b/src/crypto/chacha/asm/chacha-x86_64.pl
@@ -0,0 +1,1767 @@
+#!/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/.
+# ====================================================================
+#
+# November 2014
+#
+# ChaCha20 for x86_64.
+#
+# Performance in cycles per byte out of large buffer.
+#
+# IALU/gcc 4.8(i) 1xSSSE3/SSE2 4xSSSE3 8xAVX2
+#
+# P4 9.48/+99% -/22.7(ii) -
+# Core2 7.83/+55% 7.90/8.08 4.35
+# Westmere 7.19/+50% 5.60/6.70 3.00
+# Sandy Bridge 8.31/+42% 5.45/6.76 2.72
+# Ivy Bridge 6.71/+46% 5.40/6.49 2.41
+# Haswell 5.92/+43% 5.20/6.45 2.42 1.23
+# Silvermont 12.0/+33% 7.75/7.40 7.03(iii)
+# Sledgehammer 7.28/+52% -/14.2(ii) -
+# Bulldozer 9.66/+28% 9.85/11.1 3.06(iv)
+# VIA Nano 10.5/+46% 6.72/8.60 6.05
+#
+# (i) compared to older gcc 3.x one can observe >2x improvement on
+# most platforms;
+# (ii) as it can be seen, SSE2 performance is too low on legacy
+# processors; NxSSE2 results are naturally better, but not
+# impressively better than IALU ones, which is why you won't
+# find SSE2 code below;
+# (iii) this is not optimal result for Atom because of MSROM
+# limitations, SSE2 can do better, but gain is considered too
+# low to justify the [maintenance] effort;
+# (iv) Bulldozer actually executes 4xXOP code path that delivers 2.20;
+#
+# Modified from upstream OpenSSL to remove the XOP code.
+
+$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";
+
+$avx = 2;
+
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
+
+# input parameter block
+($out,$inp,$len,$key,$counter)=("%rdi","%rsi","%rdx","%rcx","%r8");
+
+$code.=<<___;
+.text
+
+.extern OPENSSL_ia32cap_P
+
+.align 64
+.Lzero:
+.long 0,0,0,0
+.Lone:
+.long 1,0,0,0
+.Linc:
+.long 0,1,2,3
+.Lfour:
+.long 4,4,4,4
+.Lincy:
+.long 0,2,4,6,1,3,5,7
+.Leight:
+.long 8,8,8,8,8,8,8,8
+.Lrot16:
+.byte 0x2,0x3,0x0,0x1, 0x6,0x7,0x4,0x5, 0xa,0xb,0x8,0x9, 0xe,0xf,0xc,0xd
+.Lrot24:
+.byte 0x3,0x0,0x1,0x2, 0x7,0x4,0x5,0x6, 0xb,0x8,0x9,0xa, 0xf,0xc,0xd,0xe
+.Lsigma:
+.asciz "expand 32-byte k"
+.asciz "ChaCha20 for x86_64, CRYPTOGAMS by <appro\@openssl.org>"
+___
+
+sub AUTOLOAD() # thunk [simplified] 32-bit style perlasm
+{ my $opcode = $AUTOLOAD; $opcode =~ s/.*:://;
+ my $arg = pop;
+ $arg = "\$$arg" if ($arg*1 eq $arg);
+ $code .= "\t$opcode\t".join(',',$arg,reverse @_)."\n";
+}
+
+@x=("%eax","%ebx","%ecx","%edx",map("%r${_}d",(8..11)),
+ "%nox","%nox","%nox","%nox",map("%r${_}d",(12..15)));
+@t=("%esi","%edi");
+
+sub ROUND { # critical path is 24 cycles per round
+my ($a0,$b0,$c0,$d0)=@_;
+my ($a1,$b1,$c1,$d1)=map(($_&~3)+(($_+1)&3),($a0,$b0,$c0,$d0));
+my ($a2,$b2,$c2,$d2)=map(($_&~3)+(($_+1)&3),($a1,$b1,$c1,$d1));
+my ($a3,$b3,$c3,$d3)=map(($_&~3)+(($_+1)&3),($a2,$b2,$c2,$d2));
+my ($xc,$xc_)=map("\"$_\"",@t);
+my @x=map("\"$_\"",@x);
+
+ # Consider order in which variables are addressed by their
+ # index:
+ #
+ # a b c d
+ #
+ # 0 4 8 12 < even round
+ # 1 5 9 13
+ # 2 6 10 14
+ # 3 7 11 15
+ # 0 5 10 15 < odd round
+ # 1 6 11 12
+ # 2 7 8 13
+ # 3 4 9 14
+ #
+ # 'a', 'b' and 'd's are permanently allocated in registers,
+ # @x[0..7,12..15], while 'c's are maintained in memory. If
+ # you observe 'c' column, you'll notice that pair of 'c's is
+ # invariant between rounds. This means that we have to reload
+ # them once per round, in the middle. This is why you'll see
+ # bunch of 'c' stores and loads in the middle, but none in
+ # the beginning or end.
+
+ # Normally instructions would be interleaved to favour in-order
+ # execution. Generally out-of-order cores manage it gracefully,
+ # but not this time for some reason. As in-order execution
+ # cores are dying breed, old Atom is the only one around,
+ # instructions are left uninterleaved. Besides, Atom is better
+ # off executing 1xSSSE3 code anyway...
+
+ (
+ "&add (@x[$a0],@x[$b0])", # Q1
+ "&xor (@x[$d0],@x[$a0])",
+ "&rol (@x[$d0],16)",
+ "&add (@x[$a1],@x[$b1])", # Q2
+ "&xor (@x[$d1],@x[$a1])",
+ "&rol (@x[$d1],16)",
+
+ "&add ($xc,@x[$d0])",
+ "&xor (@x[$b0],$xc)",
+ "&rol (@x[$b0],12)",
+ "&add ($xc_,@x[$d1])",
+ "&xor (@x[$b1],$xc_)",
+ "&rol (@x[$b1],12)",
+
+ "&add (@x[$a0],@x[$b0])",
+ "&xor (@x[$d0],@x[$a0])",
+ "&rol (@x[$d0],8)",
+ "&add (@x[$a1],@x[$b1])",
+ "&xor (@x[$d1],@x[$a1])",
+ "&rol (@x[$d1],8)",
+
+ "&add ($xc,@x[$d0])",
+ "&xor (@x[$b0],$xc)",
+ "&rol (@x[$b0],7)",
+ "&add ($xc_,@x[$d1])",
+ "&xor (@x[$b1],$xc_)",
+ "&rol (@x[$b1],7)",
+
+ "&mov (\"4*$c0(%rsp)\",$xc)", # reload pair of 'c's
+ "&mov (\"4*$c1(%rsp)\",$xc_)",
+ "&mov ($xc,\"4*$c2(%rsp)\")",
+ "&mov ($xc_,\"4*$c3(%rsp)\")",
+
+ "&add (@x[$a2],@x[$b2])", # Q3
+ "&xor (@x[$d2],@x[$a2])",
+ "&rol (@x[$d2],16)",
+ "&add (@x[$a3],@x[$b3])", # Q4
+ "&xor (@x[$d3],@x[$a3])",
+ "&rol (@x[$d3],16)",
+
+ "&add ($xc,@x[$d2])",
+ "&xor (@x[$b2],$xc)",
+ "&rol (@x[$b2],12)",
+ "&add ($xc_,@x[$d3])",
+ "&xor (@x[$b3],$xc_)",
+ "&rol (@x[$b3],12)",
+
+ "&add (@x[$a2],@x[$b2])",
+ "&xor (@x[$d2],@x[$a2])",
+ "&rol (@x[$d2],8)",
+ "&add (@x[$a3],@x[$b3])",
+ "&xor (@x[$d3],@x[$a3])",
+ "&rol (@x[$d3],8)",
+
+ "&add ($xc,@x[$d2])",
+ "&xor (@x[$b2],$xc)",
+ "&rol (@x[$b2],7)",
+ "&add ($xc_,@x[$d3])",
+ "&xor (@x[$b3],$xc_)",
+ "&rol (@x[$b3],7)"
+ );
+}
+
+########################################################################
+# Generic code path that handles all lengths on pre-SSSE3 processors.
+$code.=<<___;
+.globl ChaCha20_ctr32
+.type ChaCha20_ctr32,\@function,5
+.align 64
+ChaCha20_ctr32:
+ cmp \$0,$len
+ je .Lno_data
+ mov OPENSSL_ia32cap_P+4(%rip),%r10
+ test \$`1<<(41-32)`,%r10d
+ jnz .LChaCha20_ssse3
+
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+ sub \$64+24,%rsp
+
+ #movdqa .Lsigma(%rip),%xmm0
+ movdqu ($key),%xmm1
+ movdqu 16($key),%xmm2
+ movdqu ($counter),%xmm3
+ movdqa .Lone(%rip),%xmm4
+
+ #movdqa %xmm0,4*0(%rsp) # key[0]
+ movdqa %xmm1,4*4(%rsp) # key[1]
+ movdqa %xmm2,4*8(%rsp) # key[2]
+ movdqa %xmm3,4*12(%rsp) # key[3]
+ mov $len,%rbp # reassign $len
+ jmp .Loop_outer
+
+.align 32
+.Loop_outer:
+ mov \$0x61707865,@x[0] # 'expa'
+ mov \$0x3320646e,@x[1] # 'nd 3'
+ mov \$0x79622d32,@x[2] # '2-by'
+ mov \$0x6b206574,@x[3] # 'te k'
+ mov 4*4(%rsp),@x[4]
+ mov 4*5(%rsp),@x[5]
+ mov 4*6(%rsp),@x[6]
+ mov 4*7(%rsp),@x[7]
+ movd %xmm3,@x[12]
+ mov 4*13(%rsp),@x[13]
+ mov 4*14(%rsp),@x[14]
+ mov 4*15(%rsp),@x[15]
+
+ mov %rbp,64+0(%rsp) # save len
+ mov \$10,%ebp
+ mov $inp,64+8(%rsp) # save inp
+ movq %xmm2,%rsi # "@x[8]"
+ mov $out,64+16(%rsp) # save out
+ mov %rsi,%rdi
+ shr \$32,%rdi # "@x[9]"
+ jmp .Loop
+
+.align 32
+.Loop:
+___
+ foreach (&ROUND (0, 4, 8,12)) { eval; }
+ foreach (&ROUND (0, 5,10,15)) { eval; }
+ &dec ("%ebp");
+ &jnz (".Loop");
+
+$code.=<<___;
+ mov @t[1],4*9(%rsp) # modulo-scheduled
+ mov @t[0],4*8(%rsp)
+ mov 64(%rsp),%rbp # load len
+ movdqa %xmm2,%xmm1
+ mov 64+8(%rsp),$inp # load inp
+ paddd %xmm4,%xmm3 # increment counter
+ mov 64+16(%rsp),$out # load out
+
+ add \$0x61707865,@x[0] # 'expa'
+ add \$0x3320646e,@x[1] # 'nd 3'
+ add \$0x79622d32,@x[2] # '2-by'
+ add \$0x6b206574,@x[3] # 'te k'
+ add 4*4(%rsp),@x[4]
+ add 4*5(%rsp),@x[5]
+ add 4*6(%rsp),@x[6]
+ add 4*7(%rsp),@x[7]
+ add 4*12(%rsp),@x[12]
+ add 4*13(%rsp),@x[13]
+ add 4*14(%rsp),@x[14]
+ add 4*15(%rsp),@x[15]
+ paddd 4*8(%rsp),%xmm1
+
+ cmp \$64,%rbp
+ jb .Ltail
+
+ xor 4*0($inp),@x[0] # xor with input
+ xor 4*1($inp),@x[1]
+ xor 4*2($inp),@x[2]
+ xor 4*3($inp),@x[3]
+ xor 4*4($inp),@x[4]
+ xor 4*5($inp),@x[5]
+ xor 4*6($inp),@x[6]
+ xor 4*7($inp),@x[7]
+ movdqu 4*8($inp),%xmm0
+ xor 4*12($inp),@x[12]
+ xor 4*13($inp),@x[13]
+ xor 4*14($inp),@x[14]
+ xor 4*15($inp),@x[15]
+ lea 4*16($inp),$inp # inp+=64
+ pxor %xmm1,%xmm0
+
+ movdqa %xmm2,4*8(%rsp)
+ movd %xmm3,4*12(%rsp)
+
+ mov @x[0],4*0($out) # write output
+ mov @x[1],4*1($out)
+ mov @x[2],4*2($out)
+ mov @x[3],4*3($out)
+ mov @x[4],4*4($out)
+ mov @x[5],4*5($out)
+ mov @x[6],4*6($out)
+ mov @x[7],4*7($out)
+ movdqu %xmm0,4*8($out)
+ mov @x[12],4*12($out)
+ mov @x[13],4*13($out)
+ mov @x[14],4*14($out)
+ mov @x[15],4*15($out)
+ lea 4*16($out),$out # out+=64
+
+ sub \$64,%rbp
+ jnz .Loop_outer
+
+ jmp .Ldone
+
+.align 16
+.Ltail:
+ mov @x[0],4*0(%rsp)
+ mov @x[1],4*1(%rsp)
+ xor %rbx,%rbx
+ mov @x[2],4*2(%rsp)
+ mov @x[3],4*3(%rsp)
+ mov @x[4],4*4(%rsp)
+ mov @x[5],4*5(%rsp)
+ mov @x[6],4*6(%rsp)
+ mov @x[7],4*7(%rsp)
+ movdqa %xmm1,4*8(%rsp)
+ mov @x[12],4*12(%rsp)
+ mov @x[13],4*13(%rsp)
+ mov @x[14],4*14(%rsp)
+ mov @x[15],4*15(%rsp)
+
+.Loop_tail:
+ movzb ($inp,%rbx),%eax
+ movzb (%rsp,%rbx),%edx
+ lea 1(%rbx),%rbx
+ xor %edx,%eax
+ mov %al,-1($out,%rbx)
+ dec %rbp
+ jnz .Loop_tail
+
+.Ldone:
+ add \$64+24,%rsp
+ pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+.Lno_data:
+ ret
+.size ChaCha20_ctr32,.-ChaCha20_ctr32
+___
+
+########################################################################
+# SSSE3 code path that handles shorter lengths
+{
+my ($a,$b,$c,$d,$t,$t1,$rot16,$rot24)=map("%xmm$_",(0..7));
+
+sub SSSE3ROUND { # critical path is 20 "SIMD ticks" per round
+ &paddd ($a,$b);
+ &pxor ($d,$a);
+ &pshufb ($d,$rot16);
+
+ &paddd ($c,$d);
+ &pxor ($b,$c);
+ &movdqa ($t,$b);
+ &psrld ($b,20);
+ &pslld ($t,12);
+ &por ($b,$t);
+
+ &paddd ($a,$b);
+ &pxor ($d,$a);
+ &pshufb ($d,$rot24);
+
+ &paddd ($c,$d);
+ &pxor ($b,$c);
+ &movdqa ($t,$b);
+ &psrld ($b,25);
+ &pslld ($t,7);
+ &por ($b,$t);
+}
+
+my $xframe = $win64 ? 32+32+8 : 24;
+
+$code.=<<___;
+.type ChaCha20_ssse3,\@function,5
+.align 32
+ChaCha20_ssse3:
+.LChaCha20_ssse3:
+___
+$code.=<<___;
+ cmp \$128,$len # we might throw away some data,
+ ja .LChaCha20_4x # but overall it won't be slower
+
+.Ldo_sse3_after_all:
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+
+ sub \$64+$xframe,%rsp
+___
+$code.=<<___ if ($win64);
+ movaps %xmm6,64+32(%rsp)
+ movaps %xmm7,64+48(%rsp)
+___
+$code.=<<___;
+ movdqa .Lsigma(%rip),$a
+ movdqu ($key),$b
+ movdqu 16($key),$c
+ movdqu ($counter),$d
+ movdqa .Lrot16(%rip),$rot16
+ movdqa .Lrot24(%rip),$rot24
+
+ movdqa $a,0x00(%rsp)
+ movdqa $b,0x10(%rsp)
+ movdqa $c,0x20(%rsp)
+ movdqa $d,0x30(%rsp)
+ mov \$10,%ebp
+ jmp .Loop_ssse3
+
+.align 32
+.Loop_outer_ssse3:
+ movdqa .Lone(%rip),$d
+ movdqa 0x00(%rsp),$a
+ movdqa 0x10(%rsp),$b
+ movdqa 0x20(%rsp),$c
+ paddd 0x30(%rsp),$d
+ mov \$10,%ebp
+ movdqa $d,0x30(%rsp)
+ jmp .Loop_ssse3
+
+.align 32
+.Loop_ssse3:
+___
+ &SSSE3ROUND();
+ &pshufd ($c,$c,0b01001110);
+ &pshufd ($b,$b,0b00111001);
+ &pshufd ($d,$d,0b10010011);
+ &nop ();
+
+ &SSSE3ROUND();
+ &pshufd ($c,$c,0b01001110);
+ &pshufd ($b,$b,0b10010011);
+ &pshufd ($d,$d,0b00111001);
+
+ &dec ("%ebp");
+ &jnz (".Loop_ssse3");
+
+$code.=<<___;
+ paddd 0x00(%rsp),$a
+ paddd 0x10(%rsp),$b
+ paddd 0x20(%rsp),$c
+ paddd 0x30(%rsp),$d
+
+ cmp \$64,$len
+ jb .Ltail_ssse3
+
+ movdqu 0x00($inp),$t
+ movdqu 0x10($inp),$t1
+ pxor $t,$a # xor with input
+ movdqu 0x20($inp),$t
+ pxor $t1,$b
+ movdqu 0x30($inp),$t1
+ lea 0x40($inp),$inp # inp+=64
+ pxor $t,$c
+ pxor $t1,$d
+
+ movdqu $a,0x00($out) # write output
+ movdqu $b,0x10($out)
+ movdqu $c,0x20($out)
+ movdqu $d,0x30($out)
+ lea 0x40($out),$out # out+=64
+
+ sub \$64,$len
+ jnz .Loop_outer_ssse3
+
+ jmp .Ldone_ssse3
+
+.align 16
+.Ltail_ssse3:
+ movdqa $a,0x00(%rsp)
+ movdqa $b,0x10(%rsp)
+ movdqa $c,0x20(%rsp)
+ movdqa $d,0x30(%rsp)
+ xor %rbx,%rbx
+
+.Loop_tail_ssse3:
+ movzb ($inp,%rbx),%eax
+ movzb (%rsp,%rbx),%ecx
+ lea 1(%rbx),%rbx
+ xor %ecx,%eax
+ mov %al,-1($out,%rbx)
+ dec $len
+ jnz .Loop_tail_ssse3
+
+.Ldone_ssse3:
+___
+$code.=<<___ if ($win64);
+ movaps 64+32(%rsp),%xmm6
+ movaps 64+48(%rsp),%xmm7
+___
+$code.=<<___;
+ add \$64+$xframe,%rsp
+ pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ ret
+.size ChaCha20_ssse3,.-ChaCha20_ssse3
+___
+}
+
+########################################################################
+# SSSE3 code path that handles longer messages.
+{
+# assign variables to favor Atom front-end
+my ($xd0,$xd1,$xd2,$xd3, $xt0,$xt1,$xt2,$xt3,
+ $xa0,$xa1,$xa2,$xa3, $xb0,$xb1,$xb2,$xb3)=map("%xmm$_",(0..15));
+my @xx=($xa0,$xa1,$xa2,$xa3, $xb0,$xb1,$xb2,$xb3,
+ "%nox","%nox","%nox","%nox", $xd0,$xd1,$xd2,$xd3);
+
+sub SSSE3_lane_ROUND {
+my ($a0,$b0,$c0,$d0)=@_;
+my ($a1,$b1,$c1,$d1)=map(($_&~3)+(($_+1)&3),($a0,$b0,$c0,$d0));
+my ($a2,$b2,$c2,$d2)=map(($_&~3)+(($_+1)&3),($a1,$b1,$c1,$d1));
+my ($a3,$b3,$c3,$d3)=map(($_&~3)+(($_+1)&3),($a2,$b2,$c2,$d2));
+my ($xc,$xc_,$t0,$t1)=map("\"$_\"",$xt0,$xt1,$xt2,$xt3);
+my @x=map("\"$_\"",@xx);
+
+ # Consider order in which variables are addressed by their
+ # index:
+ #
+ # a b c d
+ #
+ # 0 4 8 12 < even round
+ # 1 5 9 13
+ # 2 6 10 14
+ # 3 7 11 15
+ # 0 5 10 15 < odd round
+ # 1 6 11 12
+ # 2 7 8 13
+ # 3 4 9 14
+ #
+ # 'a', 'b' and 'd's are permanently allocated in registers,
+ # @x[0..7,12..15], while 'c's are maintained in memory. If
+ # you observe 'c' column, you'll notice that pair of 'c's is
+ # invariant between rounds. This means that we have to reload
+ # them once per round, in the middle. This is why you'll see
+ # bunch of 'c' stores and loads in the middle, but none in
+ # the beginning or end.
+
+ (
+ "&paddd (@x[$a0],@x[$b0])", # Q1
+ "&paddd (@x[$a1],@x[$b1])", # Q2
+ "&pxor (@x[$d0],@x[$a0])",
+ "&pxor (@x[$d1],@x[$a1])",
+ "&pshufb (@x[$d0],$t1)",
+ "&pshufb (@x[$d1],$t1)",
+
+ "&paddd ($xc,@x[$d0])",
+ "&paddd ($xc_,@x[$d1])",
+ "&pxor (@x[$b0],$xc)",
+ "&pxor (@x[$b1],$xc_)",
+ "&movdqa ($t0,@x[$b0])",
+ "&pslld (@x[$b0],12)",
+ "&psrld ($t0,20)",
+ "&movdqa ($t1,@x[$b1])",
+ "&pslld (@x[$b1],12)",
+ "&por (@x[$b0],$t0)",
+ "&psrld ($t1,20)",
+ "&movdqa ($t0,'(%r11)')", # .Lrot24(%rip)
+ "&por (@x[$b1],$t1)",
+
+ "&paddd (@x[$a0],@x[$b0])",
+ "&paddd (@x[$a1],@x[$b1])",
+ "&pxor (@x[$d0],@x[$a0])",
+ "&pxor (@x[$d1],@x[$a1])",
+ "&pshufb (@x[$d0],$t0)",
+ "&pshufb (@x[$d1],$t0)",
+
+ "&paddd ($xc,@x[$d0])",
+ "&paddd ($xc_,@x[$d1])",
+ "&pxor (@x[$b0],$xc)",
+ "&pxor (@x[$b1],$xc_)",
+ "&movdqa ($t1,@x[$b0])",
+ "&pslld (@x[$b0],7)",
+ "&psrld ($t1,25)",
+ "&movdqa ($t0,@x[$b1])",
+ "&pslld (@x[$b1],7)",
+ "&por (@x[$b0],$t1)",
+ "&psrld ($t0,25)",
+ "&movdqa ($t1,'(%r10)')", # .Lrot16(%rip)
+ "&por (@x[$b1],$t0)",
+
+ "&movdqa (\"`16*($c0-8)`(%rsp)\",$xc)", # reload pair of 'c's
+ "&movdqa (\"`16*($c1-8)`(%rsp)\",$xc_)",
+ "&movdqa ($xc,\"`16*($c2-8)`(%rsp)\")",
+ "&movdqa ($xc_,\"`16*($c3-8)`(%rsp)\")",
+
+ "&paddd (@x[$a2],@x[$b2])", # Q3
+ "&paddd (@x[$a3],@x[$b3])", # Q4
+ "&pxor (@x[$d2],@x[$a2])",
+ "&pxor (@x[$d3],@x[$a3])",
+ "&pshufb (@x[$d2],$t1)",
+ "&pshufb (@x[$d3],$t1)",
+
+ "&paddd ($xc,@x[$d2])",
+ "&paddd ($xc_,@x[$d3])",
+ "&pxor (@x[$b2],$xc)",
+ "&pxor (@x[$b3],$xc_)",
+ "&movdqa ($t0,@x[$b2])",
+ "&pslld (@x[$b2],12)",
+ "&psrld ($t0,20)",
+ "&movdqa ($t1,@x[$b3])",
+ "&pslld (@x[$b3],12)",
+ "&por (@x[$b2],$t0)",
+ "&psrld ($t1,20)",
+ "&movdqa ($t0,'(%r11)')", # .Lrot24(%rip)
+ "&por (@x[$b3],$t1)",
+
+ "&paddd (@x[$a2],@x[$b2])",
+ "&paddd (@x[$a3],@x[$b3])",
+ "&pxor (@x[$d2],@x[$a2])",
+ "&pxor (@x[$d3],@x[$a3])",
+ "&pshufb (@x[$d2],$t0)",
+ "&pshufb (@x[$d3],$t0)",
+
+ "&paddd ($xc,@x[$d2])",
+ "&paddd ($xc_,@x[$d3])",
+ "&pxor (@x[$b2],$xc)",
+ "&pxor (@x[$b3],$xc_)",
+ "&movdqa ($t1,@x[$b2])",
+ "&pslld (@x[$b2],7)",
+ "&psrld ($t1,25)",
+ "&movdqa ($t0,@x[$b3])",
+ "&pslld (@x[$b3],7)",
+ "&por (@x[$b2],$t1)",
+ "&psrld ($t0,25)",
+ "&movdqa ($t1,'(%r10)')", # .Lrot16(%rip)
+ "&por (@x[$b3],$t0)"
+ );
+}
+
+my $xframe = $win64 ? 0xa0 : 0;
+
+$code.=<<___;
+.type ChaCha20_4x,\@function,5
+.align 32
+ChaCha20_4x:
+.LChaCha20_4x:
+ mov %r10,%r11
+___
+$code.=<<___ if ($avx>1);
+ shr \$32,%r10 # OPENSSL_ia32cap_P+8
+ test \$`1<<5`,%r10 # test AVX2
+ jnz .LChaCha20_8x
+___
+$code.=<<___;
+ cmp \$192,$len
+ ja .Lproceed4x
+
+ and \$`1<<26|1<<22`,%r11 # isolate XSAVE+MOVBE
+ cmp \$`1<<22`,%r11 # check for MOVBE without XSAVE
+ je .Ldo_sse3_after_all # to detect Atom
+
+.Lproceed4x:
+ lea -0x78(%rsp),%r11
+ sub \$0x148+$xframe,%rsp
+___
+ ################ stack layout
+ # +0x00 SIMD equivalent of @x[8-12]
+ # ...
+ # +0x40 constant copy of key[0-2] smashed by lanes
+ # ...
+ # +0x100 SIMD counters (with nonce smashed by lanes)
+ # ...
+ # +0x140
+$code.=<<___ if ($win64);
+ movaps %xmm6,-0x30(%r11)
+ movaps %xmm7,-0x20(%r11)
+ movaps %xmm8,-0x10(%r11)
+ movaps %xmm9,0x00(%r11)
+ movaps %xmm10,0x10(%r11)
+ movaps %xmm11,0x20(%r11)
+ movaps %xmm12,0x30(%r11)
+ movaps %xmm13,0x40(%r11)
+ movaps %xmm14,0x50(%r11)
+ movaps %xmm15,0x60(%r11)
+___
+$code.=<<___;
+ movdqa .Lsigma(%rip),$xa3 # key[0]
+ movdqu ($key),$xb3 # key[1]
+ movdqu 16($key),$xt3 # key[2]
+ movdqu ($counter),$xd3 # key[3]
+ lea 0x100(%rsp),%rcx # size optimization
+ lea .Lrot16(%rip),%r10
+ lea .Lrot24(%rip),%r11
+
+ pshufd \$0x00,$xa3,$xa0 # smash key by lanes...
+ pshufd \$0x55,$xa3,$xa1
+ movdqa $xa0,0x40(%rsp) # ... and offload
+ pshufd \$0xaa,$xa3,$xa2
+ movdqa $xa1,0x50(%rsp)
+ pshufd \$0xff,$xa3,$xa3
+ movdqa $xa2,0x60(%rsp)
+ movdqa $xa3,0x70(%rsp)
+
+ pshufd \$0x00,$xb3,$xb0
+ pshufd \$0x55,$xb3,$xb1
+ movdqa $xb0,0x80-0x100(%rcx)
+ pshufd \$0xaa,$xb3,$xb2
+ movdqa $xb1,0x90-0x100(%rcx)
+ pshufd \$0xff,$xb3,$xb3
+ movdqa $xb2,0xa0-0x100(%rcx)
+ movdqa $xb3,0xb0-0x100(%rcx)
+
+ pshufd \$0x00,$xt3,$xt0 # "$xc0"
+ pshufd \$0x55,$xt3,$xt1 # "$xc1"
+ movdqa $xt0,0xc0-0x100(%rcx)
+ pshufd \$0xaa,$xt3,$xt2 # "$xc2"
+ movdqa $xt1,0xd0-0x100(%rcx)
+ pshufd \$0xff,$xt3,$xt3 # "$xc3"
+ movdqa $xt2,0xe0-0x100(%rcx)
+ movdqa $xt3,0xf0-0x100(%rcx)
+
+ pshufd \$0x00,$xd3,$xd0
+ pshufd \$0x55,$xd3,$xd1
+ paddd .Linc(%rip),$xd0 # don't save counters yet
+ pshufd \$0xaa,$xd3,$xd2
+ movdqa $xd1,0x110-0x100(%rcx)
+ pshufd \$0xff,$xd3,$xd3
+ movdqa $xd2,0x120-0x100(%rcx)
+ movdqa $xd3,0x130-0x100(%rcx)
+
+ jmp .Loop_enter4x
+
+.align 32
+.Loop_outer4x:
+ movdqa 0x40(%rsp),$xa0 # re-load smashed key
+ movdqa 0x50(%rsp),$xa1
+ movdqa 0x60(%rsp),$xa2
+ movdqa 0x70(%rsp),$xa3
+ movdqa 0x80-0x100(%rcx),$xb0
+ movdqa 0x90-0x100(%rcx),$xb1
+ movdqa 0xa0-0x100(%rcx),$xb2
+ movdqa 0xb0-0x100(%rcx),$xb3
+ movdqa 0xc0-0x100(%rcx),$xt0 # "$xc0"
+ movdqa 0xd0-0x100(%rcx),$xt1 # "$xc1"
+ movdqa 0xe0-0x100(%rcx),$xt2 # "$xc2"
+ movdqa 0xf0-0x100(%rcx),$xt3 # "$xc3"
+ movdqa 0x100-0x100(%rcx),$xd0
+ movdqa 0x110-0x100(%rcx),$xd1
+ movdqa 0x120-0x100(%rcx),$xd2
+ movdqa 0x130-0x100(%rcx),$xd3
+ paddd .Lfour(%rip),$xd0 # next SIMD counters
+
+.Loop_enter4x:
+ movdqa $xt2,0x20(%rsp) # SIMD equivalent of "@x[10]"
+ movdqa $xt3,0x30(%rsp) # SIMD equivalent of "@x[11]"
+ movdqa (%r10),$xt3 # .Lrot16(%rip)
+ mov \$10,%eax
+ movdqa $xd0,0x100-0x100(%rcx) # save SIMD counters
+ jmp .Loop4x
+
+.align 32
+.Loop4x:
+___
+ foreach (&SSSE3_lane_ROUND(0, 4, 8,12)) { eval; }
+ foreach (&SSSE3_lane_ROUND(0, 5,10,15)) { eval; }
+$code.=<<___;
+ dec %eax
+ jnz .Loop4x
+
+ paddd 0x40(%rsp),$xa0 # accumulate key material
+ paddd 0x50(%rsp),$xa1
+ paddd 0x60(%rsp),$xa2
+ paddd 0x70(%rsp),$xa3
+
+ movdqa $xa0,$xt2 # "de-interlace" data
+ punpckldq $xa1,$xa0
+ movdqa $xa2,$xt3
+ punpckldq $xa3,$xa2
+ punpckhdq $xa1,$xt2
+ punpckhdq $xa3,$xt3
+ movdqa $xa0,$xa1
+ punpcklqdq $xa2,$xa0 # "a0"
+ movdqa $xt2,$xa3
+ punpcklqdq $xt3,$xt2 # "a2"
+ punpckhqdq $xa2,$xa1 # "a1"
+ punpckhqdq $xt3,$xa3 # "a3"
+___
+ ($xa2,$xt2)=($xt2,$xa2);
+$code.=<<___;
+ paddd 0x80-0x100(%rcx),$xb0
+ paddd 0x90-0x100(%rcx),$xb1
+ paddd 0xa0-0x100(%rcx),$xb2
+ paddd 0xb0-0x100(%rcx),$xb3
+
+ movdqa $xa0,0x00(%rsp) # offload $xaN
+ movdqa $xa1,0x10(%rsp)
+ movdqa 0x20(%rsp),$xa0 # "xc2"
+ movdqa 0x30(%rsp),$xa1 # "xc3"
+
+ movdqa $xb0,$xt2
+ punpckldq $xb1,$xb0
+ movdqa $xb2,$xt3
+ punpckldq $xb3,$xb2
+ punpckhdq $xb1,$xt2
+ punpckhdq $xb3,$xt3
+ movdqa $xb0,$xb1
+ punpcklqdq $xb2,$xb0 # "b0"
+ movdqa $xt2,$xb3
+ punpcklqdq $xt3,$xt2 # "b2"
+ punpckhqdq $xb2,$xb1 # "b1"
+ punpckhqdq $xt3,$xb3 # "b3"
+___
+ ($xb2,$xt2)=($xt2,$xb2);
+ my ($xc0,$xc1,$xc2,$xc3)=($xt0,$xt1,$xa0,$xa1);
+$code.=<<___;
+ paddd 0xc0-0x100(%rcx),$xc0
+ paddd 0xd0-0x100(%rcx),$xc1
+ paddd 0xe0-0x100(%rcx),$xc2
+ paddd 0xf0-0x100(%rcx),$xc3
+
+ movdqa $xa2,0x20(%rsp) # keep offloading $xaN
+ movdqa $xa3,0x30(%rsp)
+
+ movdqa $xc0,$xt2
+ punpckldq $xc1,$xc0
+ movdqa $xc2,$xt3
+ punpckldq $xc3,$xc2
+ punpckhdq $xc1,$xt2
+ punpckhdq $xc3,$xt3
+ movdqa $xc0,$xc1
+ punpcklqdq $xc2,$xc0 # "c0"
+ movdqa $xt2,$xc3
+ punpcklqdq $xt3,$xt2 # "c2"
+ punpckhqdq $xc2,$xc1 # "c1"
+ punpckhqdq $xt3,$xc3 # "c3"
+___
+ ($xc2,$xt2)=($xt2,$xc2);
+ ($xt0,$xt1)=($xa2,$xa3); # use $xaN as temporary
+$code.=<<___;
+ paddd 0x100-0x100(%rcx),$xd0
+ paddd 0x110-0x100(%rcx),$xd1
+ paddd 0x120-0x100(%rcx),$xd2
+ paddd 0x130-0x100(%rcx),$xd3
+
+ movdqa $xd0,$xt2
+ punpckldq $xd1,$xd0
+ movdqa $xd2,$xt3
+ punpckldq $xd3,$xd2
+ punpckhdq $xd1,$xt2
+ punpckhdq $xd3,$xt3
+ movdqa $xd0,$xd1
+ punpcklqdq $xd2,$xd0 # "d0"
+ movdqa $xt2,$xd3
+ punpcklqdq $xt3,$xt2 # "d2"
+ punpckhqdq $xd2,$xd1 # "d1"
+ punpckhqdq $xt3,$xd3 # "d3"
+___
+ ($xd2,$xt2)=($xt2,$xd2);
+$code.=<<___;
+ cmp \$64*4,$len
+ jb .Ltail4x
+
+ movdqu 0x00($inp),$xt0 # xor with input
+ movdqu 0x10($inp),$xt1
+ movdqu 0x20($inp),$xt2
+ movdqu 0x30($inp),$xt3
+ pxor 0x00(%rsp),$xt0 # $xaN is offloaded, remember?
+ pxor $xb0,$xt1
+ pxor $xc0,$xt2
+ pxor $xd0,$xt3
+
+ movdqu $xt0,0x00($out)
+ movdqu 0x40($inp),$xt0
+ movdqu $xt1,0x10($out)
+ movdqu 0x50($inp),$xt1
+ movdqu $xt2,0x20($out)
+ movdqu 0x60($inp),$xt2
+ movdqu $xt3,0x30($out)
+ movdqu 0x70($inp),$xt3
+ lea 0x80($inp),$inp # size optimization
+ pxor 0x10(%rsp),$xt0
+ pxor $xb1,$xt1
+ pxor $xc1,$xt2
+ pxor $xd1,$xt3
+
+ movdqu $xt0,0x40($out)
+ movdqu 0x00($inp),$xt0
+ movdqu $xt1,0x50($out)
+ movdqu 0x10($inp),$xt1
+ movdqu $xt2,0x60($out)
+ movdqu 0x20($inp),$xt2
+ movdqu $xt3,0x70($out)
+ lea 0x80($out),$out # size optimization
+ movdqu 0x30($inp),$xt3
+ pxor 0x20(%rsp),$xt0
+ pxor $xb2,$xt1
+ pxor $xc2,$xt2
+ pxor $xd2,$xt3
+
+ movdqu $xt0,0x00($out)
+ movdqu 0x40($inp),$xt0
+ movdqu $xt1,0x10($out)
+ movdqu 0x50($inp),$xt1
+ movdqu $xt2,0x20($out)
+ movdqu 0x60($inp),$xt2
+ movdqu $xt3,0x30($out)
+ movdqu 0x70($inp),$xt3
+ lea 0x80($inp),$inp # inp+=64*4
+ pxor 0x30(%rsp),$xt0
+ pxor $xb3,$xt1
+ pxor $xc3,$xt2
+ pxor $xd3,$xt3
+ movdqu $xt0,0x40($out)
+ movdqu $xt1,0x50($out)
+ movdqu $xt2,0x60($out)
+ movdqu $xt3,0x70($out)
+ lea 0x80($out),$out # out+=64*4
+
+ sub \$64*4,$len
+ jnz .Loop_outer4x
+
+ jmp .Ldone4x
+
+.Ltail4x:
+ cmp \$192,$len
+ jae .L192_or_more4x
+ cmp \$128,$len
+ jae .L128_or_more4x
+ cmp \$64,$len
+ jae .L64_or_more4x
+
+ #movdqa 0x00(%rsp),$xt0 # $xaN is offloaded, remember?
+ xor %r10,%r10
+ #movdqa $xt0,0x00(%rsp)
+ movdqa $xb0,0x10(%rsp)
+ movdqa $xc0,0x20(%rsp)
+ movdqa $xd0,0x30(%rsp)
+ jmp .Loop_tail4x
+
+.align 32
+.L64_or_more4x:
+ movdqu 0x00($inp),$xt0 # xor with input
+ movdqu 0x10($inp),$xt1
+ movdqu 0x20($inp),$xt2
+ movdqu 0x30($inp),$xt3
+ pxor 0x00(%rsp),$xt0 # $xaxN is offloaded, remember?
+ pxor $xb0,$xt1
+ pxor $xc0,$xt2
+ pxor $xd0,$xt3
+ movdqu $xt0,0x00($out)
+ movdqu $xt1,0x10($out)
+ movdqu $xt2,0x20($out)
+ movdqu $xt3,0x30($out)
+ je .Ldone4x
+
+ movdqa 0x10(%rsp),$xt0 # $xaN is offloaded, remember?
+ lea 0x40($inp),$inp # inp+=64*1
+ xor %r10,%r10
+ movdqa $xt0,0x00(%rsp)
+ movdqa $xb1,0x10(%rsp)
+ lea 0x40($out),$out # out+=64*1
+ movdqa $xc1,0x20(%rsp)
+ sub \$64,$len # len-=64*1
+ movdqa $xd1,0x30(%rsp)
+ jmp .Loop_tail4x
+
+.align 32
+.L128_or_more4x:
+ movdqu 0x00($inp),$xt0 # xor with input
+ movdqu 0x10($inp),$xt1
+ movdqu 0x20($inp),$xt2
+ movdqu 0x30($inp),$xt3
+ pxor 0x00(%rsp),$xt0 # $xaN is offloaded, remember?
+ pxor $xb0,$xt1
+ pxor $xc0,$xt2
+ pxor $xd0,$xt3
+
+ movdqu $xt0,0x00($out)
+ movdqu 0x40($inp),$xt0
+ movdqu $xt1,0x10($out)
+ movdqu 0x50($inp),$xt1
+ movdqu $xt2,0x20($out)
+ movdqu 0x60($inp),$xt2
+ movdqu $xt3,0x30($out)
+ movdqu 0x70($inp),$xt3
+ pxor 0x10(%rsp),$xt0
+ pxor $xb1,$xt1
+ pxor $xc1,$xt2
+ pxor $xd1,$xt3
+ movdqu $xt0,0x40($out)
+ movdqu $xt1,0x50($out)
+ movdqu $xt2,0x60($out)
+ movdqu $xt3,0x70($out)
+ je .Ldone4x
+
+ movdqa 0x20(%rsp),$xt0 # $xaN is offloaded, remember?
+ lea 0x80($inp),$inp # inp+=64*2
+ xor %r10,%r10
+ movdqa $xt0,0x00(%rsp)
+ movdqa $xb2,0x10(%rsp)
+ lea 0x80($out),$out # out+=64*2
+ movdqa $xc2,0x20(%rsp)
+ sub \$128,$len # len-=64*2
+ movdqa $xd2,0x30(%rsp)
+ jmp .Loop_tail4x
+
+.align 32
+.L192_or_more4x:
+ movdqu 0x00($inp),$xt0 # xor with input
+ movdqu 0x10($inp),$xt1
+ movdqu 0x20($inp),$xt2
+ movdqu 0x30($inp),$xt3
+ pxor 0x00(%rsp),$xt0 # $xaN is offloaded, remember?
+ pxor $xb0,$xt1
+ pxor $xc0,$xt2
+ pxor $xd0,$xt3
+
+ movdqu $xt0,0x00($out)
+ movdqu 0x40($inp),$xt0
+ movdqu $xt1,0x10($out)
+ movdqu 0x50($inp),$xt1
+ movdqu $xt2,0x20($out)
+ movdqu 0x60($inp),$xt2
+ movdqu $xt3,0x30($out)
+ movdqu 0x70($inp),$xt3
+ lea 0x80($inp),$inp # size optimization
+ pxor 0x10(%rsp),$xt0
+ pxor $xb1,$xt1
+ pxor $xc1,$xt2
+ pxor $xd1,$xt3
+
+ movdqu $xt0,0x40($out)
+ movdqu 0x00($inp),$xt0
+ movdqu $xt1,0x50($out)
+ movdqu 0x10($inp),$xt1
+ movdqu $xt2,0x60($out)
+ movdqu 0x20($inp),$xt2
+ movdqu $xt3,0x70($out)
+ lea 0x80($out),$out # size optimization
+ movdqu 0x30($inp),$xt3
+ pxor 0x20(%rsp),$xt0
+ pxor $xb2,$xt1
+ pxor $xc2,$xt2
+ pxor $xd2,$xt3
+ movdqu $xt0,0x00($out)
+ movdqu $xt1,0x10($out)
+ movdqu $xt2,0x20($out)
+ movdqu $xt3,0x30($out)
+ je .Ldone4x
+
+ movdqa 0x30(%rsp),$xt0 # $xaN is offloaded, remember?
+ lea 0x40($inp),$inp # inp+=64*3
+ xor %r10,%r10
+ movdqa $xt0,0x00(%rsp)
+ movdqa $xb3,0x10(%rsp)
+ lea 0x40($out),$out # out+=64*3
+ movdqa $xc3,0x20(%rsp)
+ sub \$192,$len # len-=64*3
+ movdqa $xd3,0x30(%rsp)
+
+.Loop_tail4x:
+ movzb ($inp,%r10),%eax
+ movzb (%rsp,%r10),%ecx
+ lea 1(%r10),%r10
+ xor %ecx,%eax
+ mov %al,-1($out,%r10)
+ dec $len
+ jnz .Loop_tail4x
+
+.Ldone4x:
+___
+$code.=<<___ if ($win64);
+ lea 0x140+0x30(%rsp),%r11
+ movaps -0x30(%r11),%xmm6
+ movaps -0x20(%r11),%xmm7
+ movaps -0x10(%r11),%xmm8
+ movaps 0x00(%r11),%xmm9
+ movaps 0x10(%r11),%xmm10
+ movaps 0x20(%r11),%xmm11
+ movaps 0x30(%r11),%xmm12
+ movaps 0x40(%r11),%xmm13
+ movaps 0x50(%r11),%xmm14
+ movaps 0x60(%r11),%xmm15
+___
+$code.=<<___;
+ add \$0x148+$xframe,%rsp
+ ret
+.size ChaCha20_4x,.-ChaCha20_4x
+___
+}
+
+########################################################################
+# AVX2 code path
+if ($avx>1) {
+my ($xb0,$xb1,$xb2,$xb3, $xd0,$xd1,$xd2,$xd3,
+ $xa0,$xa1,$xa2,$xa3, $xt0,$xt1,$xt2,$xt3)=map("%ymm$_",(0..15));
+my @xx=($xa0,$xa1,$xa2,$xa3, $xb0,$xb1,$xb2,$xb3,
+ "%nox","%nox","%nox","%nox", $xd0,$xd1,$xd2,$xd3);
+
+sub AVX2_lane_ROUND {
+my ($a0,$b0,$c0,$d0)=@_;
+my ($a1,$b1,$c1,$d1)=map(($_&~3)+(($_+1)&3),($a0,$b0,$c0,$d0));
+my ($a2,$b2,$c2,$d2)=map(($_&~3)+(($_+1)&3),($a1,$b1,$c1,$d1));
+my ($a3,$b3,$c3,$d3)=map(($_&~3)+(($_+1)&3),($a2,$b2,$c2,$d2));
+my ($xc,$xc_,$t0,$t1)=map("\"$_\"",$xt0,$xt1,$xt2,$xt3);
+my @x=map("\"$_\"",@xx);
+
+ # Consider order in which variables are addressed by their
+ # index:
+ #
+ # a b c d
+ #
+ # 0 4 8 12 < even round
+ # 1 5 9 13
+ # 2 6 10 14
+ # 3 7 11 15
+ # 0 5 10 15 < odd round
+ # 1 6 11 12
+ # 2 7 8 13
+ # 3 4 9 14
+ #
+ # 'a', 'b' and 'd's are permanently allocated in registers,
+ # @x[0..7,12..15], while 'c's are maintained in memory. If
+ # you observe 'c' column, you'll notice that pair of 'c's is
+ # invariant between rounds. This means that we have to reload
+ # them once per round, in the middle. This is why you'll see
+ # bunch of 'c' stores and loads in the middle, but none in
+ # the beginning or end.
+
+ (
+ "&vpaddd (@x[$a0],@x[$a0],@x[$b0])", # Q1
+ "&vpxor (@x[$d0],@x[$a0],@x[$d0])",
+ "&vpshufb (@x[$d0],@x[$d0],$t1)",
+ "&vpaddd (@x[$a1],@x[$a1],@x[$b1])", # Q2
+ "&vpxor (@x[$d1],@x[$a1],@x[$d1])",
+ "&vpshufb (@x[$d1],@x[$d1],$t1)",
+
+ "&vpaddd ($xc,$xc,@x[$d0])",
+ "&vpxor (@x[$b0],$xc,@x[$b0])",
+ "&vpslld ($t0,@x[$b0],12)",
+ "&vpsrld (@x[$b0],@x[$b0],20)",
+ "&vpor (@x[$b0],$t0,@x[$b0])",
+ "&vbroadcasti128($t0,'(%r11)')", # .Lrot24(%rip)
+ "&vpaddd ($xc_,$xc_,@x[$d1])",
+ "&vpxor (@x[$b1],$xc_,@x[$b1])",
+ "&vpslld ($t1,@x[$b1],12)",
+ "&vpsrld (@x[$b1],@x[$b1],20)",
+ "&vpor (@x[$b1],$t1,@x[$b1])",
+
+ "&vpaddd (@x[$a0],@x[$a0],@x[$b0])",
+ "&vpxor (@x[$d0],@x[$a0],@x[$d0])",
+ "&vpshufb (@x[$d0],@x[$d0],$t0)",
+ "&vpaddd (@x[$a1],@x[$a1],@x[$b1])",
+ "&vpxor (@x[$d1],@x[$a1],@x[$d1])",
+ "&vpshufb (@x[$d1],@x[$d1],$t0)",
+
+ "&vpaddd ($xc,$xc,@x[$d0])",
+ "&vpxor (@x[$b0],$xc,@x[$b0])",
+ "&vpslld ($t1,@x[$b0],7)",
+ "&vpsrld (@x[$b0],@x[$b0],25)",
+ "&vpor (@x[$b0],$t1,@x[$b0])",
+ "&vbroadcasti128($t1,'(%r10)')", # .Lrot16(%rip)
+ "&vpaddd ($xc_,$xc_,@x[$d1])",
+ "&vpxor (@x[$b1],$xc_,@x[$b1])",
+ "&vpslld ($t0,@x[$b1],7)",
+ "&vpsrld (@x[$b1],@x[$b1],25)",
+ "&vpor (@x[$b1],$t0,@x[$b1])",
+
+ "&vmovdqa (\"`32*($c0-8)`(%rsp)\",$xc)", # reload pair of 'c's
+ "&vmovdqa (\"`32*($c1-8)`(%rsp)\",$xc_)",
+ "&vmovdqa ($xc,\"`32*($c2-8)`(%rsp)\")",
+ "&vmovdqa ($xc_,\"`32*($c3-8)`(%rsp)\")",
+
+ "&vpaddd (@x[$a2],@x[$a2],@x[$b2])", # Q3
+ "&vpxor (@x[$d2],@x[$a2],@x[$d2])",
+ "&vpshufb (@x[$d2],@x[$d2],$t1)",
+ "&vpaddd (@x[$a3],@x[$a3],@x[$b3])", # Q4
+ "&vpxor (@x[$d3],@x[$a3],@x[$d3])",
+ "&vpshufb (@x[$d3],@x[$d3],$t1)",
+
+ "&vpaddd ($xc,$xc,@x[$d2])",
+ "&vpxor (@x[$b2],$xc,@x[$b2])",
+ "&vpslld ($t0,@x[$b2],12)",
+ "&vpsrld (@x[$b2],@x[$b2],20)",
+ "&vpor (@x[$b2],$t0,@x[$b2])",
+ "&vbroadcasti128($t0,'(%r11)')", # .Lrot24(%rip)
+ "&vpaddd ($xc_,$xc_,@x[$d3])",
+ "&vpxor (@x[$b3],$xc_,@x[$b3])",
+ "&vpslld ($t1,@x[$b3],12)",
+ "&vpsrld (@x[$b3],@x[$b3],20)",
+ "&vpor (@x[$b3],$t1,@x[$b3])",
+
+ "&vpaddd (@x[$a2],@x[$a2],@x[$b2])",
+ "&vpxor (@x[$d2],@x[$a2],@x[$d2])",
+ "&vpshufb (@x[$d2],@x[$d2],$t0)",
+ "&vpaddd (@x[$a3],@x[$a3],@x[$b3])",
+ "&vpxor (@x[$d3],@x[$a3],@x[$d3])",
+ "&vpshufb (@x[$d3],@x[$d3],$t0)",
+
+ "&vpaddd ($xc,$xc,@x[$d2])",
+ "&vpxor (@x[$b2],$xc,@x[$b2])",
+ "&vpslld ($t1,@x[$b2],7)",
+ "&vpsrld (@x[$b2],@x[$b2],25)",
+ "&vpor (@x[$b2],$t1,@x[$b2])",
+ "&vbroadcasti128($t1,'(%r10)')", # .Lrot16(%rip)
+ "&vpaddd ($xc_,$xc_,@x[$d3])",
+ "&vpxor (@x[$b3],$xc_,@x[$b3])",
+ "&vpslld ($t0,@x[$b3],7)",
+ "&vpsrld (@x[$b3],@x[$b3],25)",
+ "&vpor (@x[$b3],$t0,@x[$b3])"
+ );
+}
+
+my $xframe = $win64 ? 0xb0 : 8;
+
+$code.=<<___;
+.type ChaCha20_8x,\@function,5
+.align 32
+ChaCha20_8x:
+.LChaCha20_8x:
+ mov %rsp,%r10
+ sub \$0x280+$xframe,%rsp
+ and \$-32,%rsp
+___
+$code.=<<___ if ($win64);
+ lea 0x290+0x30(%rsp),%r11
+ movaps %xmm6,-0x30(%r11)
+ movaps %xmm7,-0x20(%r11)
+ movaps %xmm8,-0x10(%r11)
+ movaps %xmm9,0x00(%r11)
+ movaps %xmm10,0x10(%r11)
+ movaps %xmm11,0x20(%r11)
+ movaps %xmm12,0x30(%r11)
+ movaps %xmm13,0x40(%r11)
+ movaps %xmm14,0x50(%r11)
+ movaps %xmm15,0x60(%r11)
+___
+$code.=<<___;
+ vzeroupper
+ mov %r10,0x280(%rsp)
+
+ ################ stack layout
+ # +0x00 SIMD equivalent of @x[8-12]
+ # ...
+ # +0x80 constant copy of key[0-2] smashed by lanes
+ # ...
+ # +0x200 SIMD counters (with nonce smashed by lanes)
+ # ...
+ # +0x280 saved %rsp
+
+ vbroadcasti128 .Lsigma(%rip),$xa3 # key[0]
+ vbroadcasti128 ($key),$xb3 # key[1]
+ vbroadcasti128 16($key),$xt3 # key[2]
+ vbroadcasti128 ($counter),$xd3 # key[3]
+ lea 0x100(%rsp),%rcx # size optimization
+ lea 0x200(%rsp),%rax # size optimization
+ lea .Lrot16(%rip),%r10
+ lea .Lrot24(%rip),%r11
+
+ vpshufd \$0x00,$xa3,$xa0 # smash key by lanes...
+ vpshufd \$0x55,$xa3,$xa1
+ vmovdqa $xa0,0x80-0x100(%rcx) # ... and offload
+ vpshufd \$0xaa,$xa3,$xa2
+ vmovdqa $xa1,0xa0-0x100(%rcx)
+ vpshufd \$0xff,$xa3,$xa3
+ vmovdqa $xa2,0xc0-0x100(%rcx)
+ vmovdqa $xa3,0xe0-0x100(%rcx)
+
+ vpshufd \$0x00,$xb3,$xb0
+ vpshufd \$0x55,$xb3,$xb1
+ vmovdqa $xb0,0x100-0x100(%rcx)
+ vpshufd \$0xaa,$xb3,$xb2
+ vmovdqa $xb1,0x120-0x100(%rcx)
+ vpshufd \$0xff,$xb3,$xb3
+ vmovdqa $xb2,0x140-0x100(%rcx)
+ vmovdqa $xb3,0x160-0x100(%rcx)
+
+ vpshufd \$0x00,$xt3,$xt0 # "xc0"
+ vpshufd \$0x55,$xt3,$xt1 # "xc1"
+ vmovdqa $xt0,0x180-0x200(%rax)
+ vpshufd \$0xaa,$xt3,$xt2 # "xc2"
+ vmovdqa $xt1,0x1a0-0x200(%rax)
+ vpshufd \$0xff,$xt3,$xt3 # "xc3"
+ vmovdqa $xt2,0x1c0-0x200(%rax)
+ vmovdqa $xt3,0x1e0-0x200(%rax)
+
+ vpshufd \$0x00,$xd3,$xd0
+ vpshufd \$0x55,$xd3,$xd1
+ vpaddd .Lincy(%rip),$xd0,$xd0 # don't save counters yet
+ vpshufd \$0xaa,$xd3,$xd2
+ vmovdqa $xd1,0x220-0x200(%rax)
+ vpshufd \$0xff,$xd3,$xd3
+ vmovdqa $xd2,0x240-0x200(%rax)
+ vmovdqa $xd3,0x260-0x200(%rax)
+
+ jmp .Loop_enter8x
+
+.align 32
+.Loop_outer8x:
+ vmovdqa 0x80-0x100(%rcx),$xa0 # re-load smashed key
+ vmovdqa 0xa0-0x100(%rcx),$xa1
+ vmovdqa 0xc0-0x100(%rcx),$xa2
+ vmovdqa 0xe0-0x100(%rcx),$xa3
+ vmovdqa 0x100-0x100(%rcx),$xb0
+ vmovdqa 0x120-0x100(%rcx),$xb1
+ vmovdqa 0x140-0x100(%rcx),$xb2
+ vmovdqa 0x160-0x100(%rcx),$xb3
+ vmovdqa 0x180-0x200(%rax),$xt0 # "xc0"
+ vmovdqa 0x1a0-0x200(%rax),$xt1 # "xc1"
+ vmovdqa 0x1c0-0x200(%rax),$xt2 # "xc2"
+ vmovdqa 0x1e0-0x200(%rax),$xt3 # "xc3"
+ vmovdqa 0x200-0x200(%rax),$xd0
+ vmovdqa 0x220-0x200(%rax),$xd1
+ vmovdqa 0x240-0x200(%rax),$xd2
+ vmovdqa 0x260-0x200(%rax),$xd3
+ vpaddd .Leight(%rip),$xd0,$xd0 # next SIMD counters
+
+.Loop_enter8x:
+ vmovdqa $xt2,0x40(%rsp) # SIMD equivalent of "@x[10]"
+ vmovdqa $xt3,0x60(%rsp) # SIMD equivalent of "@x[11]"
+ vbroadcasti128 (%r10),$xt3
+ vmovdqa $xd0,0x200-0x200(%rax) # save SIMD counters
+ mov \$10,%eax
+ jmp .Loop8x
+
+.align 32
+.Loop8x:
+___
+ foreach (&AVX2_lane_ROUND(0, 4, 8,12)) { eval; }
+ foreach (&AVX2_lane_ROUND(0, 5,10,15)) { eval; }
+$code.=<<___;
+ dec %eax
+ jnz .Loop8x
+
+ lea 0x200(%rsp),%rax # size optimization
+ vpaddd 0x80-0x100(%rcx),$xa0,$xa0 # accumulate key
+ vpaddd 0xa0-0x100(%rcx),$xa1,$xa1
+ vpaddd 0xc0-0x100(%rcx),$xa2,$xa2
+ vpaddd 0xe0-0x100(%rcx),$xa3,$xa3
+
+ vpunpckldq $xa1,$xa0,$xt2 # "de-interlace" data
+ vpunpckldq $xa3,$xa2,$xt3
+ vpunpckhdq $xa1,$xa0,$xa0
+ vpunpckhdq $xa3,$xa2,$xa2
+ vpunpcklqdq $xt3,$xt2,$xa1 # "a0"
+ vpunpckhqdq $xt3,$xt2,$xt2 # "a1"
+ vpunpcklqdq $xa2,$xa0,$xa3 # "a2"
+ vpunpckhqdq $xa2,$xa0,$xa0 # "a3"
+___
+ ($xa0,$xa1,$xa2,$xa3,$xt2)=($xa1,$xt2,$xa3,$xa0,$xa2);
+$code.=<<___;
+ vpaddd 0x100-0x100(%rcx),$xb0,$xb0
+ vpaddd 0x120-0x100(%rcx),$xb1,$xb1
+ vpaddd 0x140-0x100(%rcx),$xb2,$xb2
+ vpaddd 0x160-0x100(%rcx),$xb3,$xb3
+
+ vpunpckldq $xb1,$xb0,$xt2
+ vpunpckldq $xb3,$xb2,$xt3
+ vpunpckhdq $xb1,$xb0,$xb0
+ vpunpckhdq $xb3,$xb2,$xb2
+ vpunpcklqdq $xt3,$xt2,$xb1 # "b0"
+ vpunpckhqdq $xt3,$xt2,$xt2 # "b1"
+ vpunpcklqdq $xb2,$xb0,$xb3 # "b2"
+ vpunpckhqdq $xb2,$xb0,$xb0 # "b3"
+___
+ ($xb0,$xb1,$xb2,$xb3,$xt2)=($xb1,$xt2,$xb3,$xb0,$xb2);
+$code.=<<___;
+ vperm2i128 \$0x20,$xb0,$xa0,$xt3 # "de-interlace" further
+ vperm2i128 \$0x31,$xb0,$xa0,$xb0
+ vperm2i128 \$0x20,$xb1,$xa1,$xa0
+ vperm2i128 \$0x31,$xb1,$xa1,$xb1
+ vperm2i128 \$0x20,$xb2,$xa2,$xa1
+ vperm2i128 \$0x31,$xb2,$xa2,$xb2
+ vperm2i128 \$0x20,$xb3,$xa3,$xa2
+ vperm2i128 \$0x31,$xb3,$xa3,$xb3
+___
+ ($xa0,$xa1,$xa2,$xa3,$xt3)=($xt3,$xa0,$xa1,$xa2,$xa3);
+ my ($xc0,$xc1,$xc2,$xc3)=($xt0,$xt1,$xa0,$xa1);
+$code.=<<___;
+ vmovdqa $xa0,0x00(%rsp) # offload $xaN
+ vmovdqa $xa1,0x20(%rsp)
+ vmovdqa 0x40(%rsp),$xc2 # $xa0
+ vmovdqa 0x60(%rsp),$xc3 # $xa1
+
+ vpaddd 0x180-0x200(%rax),$xc0,$xc0
+ vpaddd 0x1a0-0x200(%rax),$xc1,$xc1
+ vpaddd 0x1c0-0x200(%rax),$xc2,$xc2
+ vpaddd 0x1e0-0x200(%rax),$xc3,$xc3
+
+ vpunpckldq $xc1,$xc0,$xt2
+ vpunpckldq $xc3,$xc2,$xt3
+ vpunpckhdq $xc1,$xc0,$xc0
+ vpunpckhdq $xc3,$xc2,$xc2
+ vpunpcklqdq $xt3,$xt2,$xc1 # "c0"
+ vpunpckhqdq $xt3,$xt2,$xt2 # "c1"
+ vpunpcklqdq $xc2,$xc0,$xc3 # "c2"
+ vpunpckhqdq $xc2,$xc0,$xc0 # "c3"
+___
+ ($xc0,$xc1,$xc2,$xc3,$xt2)=($xc1,$xt2,$xc3,$xc0,$xc2);
+$code.=<<___;
+ vpaddd 0x200-0x200(%rax),$xd0,$xd0
+ vpaddd 0x220-0x200(%rax),$xd1,$xd1
+ vpaddd 0x240-0x200(%rax),$xd2,$xd2
+ vpaddd 0x260-0x200(%rax),$xd3,$xd3
+
+ vpunpckldq $xd1,$xd0,$xt2
+ vpunpckldq $xd3,$xd2,$xt3
+ vpunpckhdq $xd1,$xd0,$xd0
+ vpunpckhdq $xd3,$xd2,$xd2
+ vpunpcklqdq $xt3,$xt2,$xd1 # "d0"
+ vpunpckhqdq $xt3,$xt2,$xt2 # "d1"
+ vpunpcklqdq $xd2,$xd0,$xd3 # "d2"
+ vpunpckhqdq $xd2,$xd0,$xd0 # "d3"
+___
+ ($xd0,$xd1,$xd2,$xd3,$xt2)=($xd1,$xt2,$xd3,$xd0,$xd2);
+$code.=<<___;
+ vperm2i128 \$0x20,$xd0,$xc0,$xt3 # "de-interlace" further
+ vperm2i128 \$0x31,$xd0,$xc0,$xd0
+ vperm2i128 \$0x20,$xd1,$xc1,$xc0
+ vperm2i128 \$0x31,$xd1,$xc1,$xd1
+ vperm2i128 \$0x20,$xd2,$xc2,$xc1
+ vperm2i128 \$0x31,$xd2,$xc2,$xd2
+ vperm2i128 \$0x20,$xd3,$xc3,$xc2
+ vperm2i128 \$0x31,$xd3,$xc3,$xd3
+___
+ ($xc0,$xc1,$xc2,$xc3,$xt3)=($xt3,$xc0,$xc1,$xc2,$xc3);
+ ($xb0,$xb1,$xb2,$xb3,$xc0,$xc1,$xc2,$xc3)=
+ ($xc0,$xc1,$xc2,$xc3,$xb0,$xb1,$xb2,$xb3);
+ ($xa0,$xa1)=($xt2,$xt3);
+$code.=<<___;
+ vmovdqa 0x00(%rsp),$xa0 # $xaN was offloaded, remember?
+ vmovdqa 0x20(%rsp),$xa1
+
+ cmp \$64*8,$len
+ jb .Ltail8x
+
+ vpxor 0x00($inp),$xa0,$xa0 # xor with input
+ vpxor 0x20($inp),$xb0,$xb0
+ vpxor 0x40($inp),$xc0,$xc0
+ vpxor 0x60($inp),$xd0,$xd0
+ lea 0x80($inp),$inp # size optimization
+ vmovdqu $xa0,0x00($out)
+ vmovdqu $xb0,0x20($out)
+ vmovdqu $xc0,0x40($out)
+ vmovdqu $xd0,0x60($out)
+ lea 0x80($out),$out # size optimization
+
+ vpxor 0x00($inp),$xa1,$xa1
+ vpxor 0x20($inp),$xb1,$xb1
+ vpxor 0x40($inp),$xc1,$xc1
+ vpxor 0x60($inp),$xd1,$xd1
+ lea 0x80($inp),$inp # size optimization
+ vmovdqu $xa1,0x00($out)
+ vmovdqu $xb1,0x20($out)
+ vmovdqu $xc1,0x40($out)
+ vmovdqu $xd1,0x60($out)
+ lea 0x80($out),$out # size optimization
+
+ vpxor 0x00($inp),$xa2,$xa2
+ vpxor 0x20($inp),$xb2,$xb2
+ vpxor 0x40($inp),$xc2,$xc2
+ vpxor 0x60($inp),$xd2,$xd2
+ lea 0x80($inp),$inp # size optimization
+ vmovdqu $xa2,0x00($out)
+ vmovdqu $xb2,0x20($out)
+ vmovdqu $xc2,0x40($out)
+ vmovdqu $xd2,0x60($out)
+ lea 0x80($out),$out # size optimization
+
+ vpxor 0x00($inp),$xa3,$xa3
+ vpxor 0x20($inp),$xb3,$xb3
+ vpxor 0x40($inp),$xc3,$xc3
+ vpxor 0x60($inp),$xd3,$xd3
+ lea 0x80($inp),$inp # size optimization
+ vmovdqu $xa3,0x00($out)
+ vmovdqu $xb3,0x20($out)
+ vmovdqu $xc3,0x40($out)
+ vmovdqu $xd3,0x60($out)
+ lea 0x80($out),$out # size optimization
+
+ sub \$64*8,$len
+ jnz .Loop_outer8x
+
+ jmp .Ldone8x
+
+.Ltail8x:
+ cmp \$448,$len
+ jae .L448_or_more8x
+ cmp \$384,$len
+ jae .L384_or_more8x
+ cmp \$320,$len
+ jae .L320_or_more8x
+ cmp \$256,$len
+ jae .L256_or_more8x
+ cmp \$192,$len
+ jae .L192_or_more8x
+ cmp \$128,$len
+ jae .L128_or_more8x
+ cmp \$64,$len
+ jae .L64_or_more8x
+
+ xor %r10,%r10
+ vmovdqa $xa0,0x00(%rsp)
+ vmovdqa $xb0,0x20(%rsp)
+ jmp .Loop_tail8x
+
+.align 32
+.L64_or_more8x:
+ vpxor 0x00($inp),$xa0,$xa0 # xor with input
+ vpxor 0x20($inp),$xb0,$xb0
+ vmovdqu $xa0,0x00($out)
+ vmovdqu $xb0,0x20($out)
+ je .Ldone8x
+
+ lea 0x40($inp),$inp # inp+=64*1
+ xor %r10,%r10
+ vmovdqa $xc0,0x00(%rsp)
+ lea 0x40($out),$out # out+=64*1
+ sub \$64,$len # len-=64*1
+ vmovdqa $xd0,0x20(%rsp)
+ jmp .Loop_tail8x
+
+.align 32
+.L128_or_more8x:
+ vpxor 0x00($inp),$xa0,$xa0 # xor with input
+ vpxor 0x20($inp),$xb0,$xb0
+ vpxor 0x40($inp),$xc0,$xc0
+ vpxor 0x60($inp),$xd0,$xd0
+ vmovdqu $xa0,0x00($out)
+ vmovdqu $xb0,0x20($out)
+ vmovdqu $xc0,0x40($out)
+ vmovdqu $xd0,0x60($out)
+ je .Ldone8x
+
+ lea 0x80($inp),$inp # inp+=64*2
+ xor %r10,%r10
+ vmovdqa $xa1,0x00(%rsp)
+ lea 0x80($out),$out # out+=64*2
+ sub \$128,$len # len-=64*2
+ vmovdqa $xb1,0x20(%rsp)
+ jmp .Loop_tail8x
+
+.align 32
+.L192_or_more8x:
+ vpxor 0x00($inp),$xa0,$xa0 # xor with input
+ vpxor 0x20($inp),$xb0,$xb0
+ vpxor 0x40($inp),$xc0,$xc0
+ vpxor 0x60($inp),$xd0,$xd0
+ vpxor 0x80($inp),$xa1,$xa1
+ vpxor 0xa0($inp),$xb1,$xb1
+ vmovdqu $xa0,0x00($out)
+ vmovdqu $xb0,0x20($out)
+ vmovdqu $xc0,0x40($out)
+ vmovdqu $xd0,0x60($out)
+ vmovdqu $xa1,0x80($out)
+ vmovdqu $xb1,0xa0($out)
+ je .Ldone8x
+
+ lea 0xc0($inp),$inp # inp+=64*3
+ xor %r10,%r10
+ vmovdqa $xc1,0x00(%rsp)
+ lea 0xc0($out),$out # out+=64*3
+ sub \$192,$len # len-=64*3
+ vmovdqa $xd1,0x20(%rsp)
+ jmp .Loop_tail8x
+
+.align 32
+.L256_or_more8x:
+ vpxor 0x00($inp),$xa0,$xa0 # xor with input
+ vpxor 0x20($inp),$xb0,$xb0
+ vpxor 0x40($inp),$xc0,$xc0
+ vpxor 0x60($inp),$xd0,$xd0
+ vpxor 0x80($inp),$xa1,$xa1
+ vpxor 0xa0($inp),$xb1,$xb1
+ vpxor 0xc0($inp),$xc1,$xc1
+ vpxor 0xe0($inp),$xd1,$xd1
+ vmovdqu $xa0,0x00($out)
+ vmovdqu $xb0,0x20($out)
+ vmovdqu $xc0,0x40($out)
+ vmovdqu $xd0,0x60($out)
+ vmovdqu $xa1,0x80($out)
+ vmovdqu $xb1,0xa0($out)
+ vmovdqu $xc1,0xc0($out)
+ vmovdqu $xd1,0xe0($out)
+ je .Ldone8x
+
+ lea 0x100($inp),$inp # inp+=64*4
+ xor %r10,%r10
+ vmovdqa $xa2,0x00(%rsp)
+ lea 0x100($out),$out # out+=64*4
+ sub \$256,$len # len-=64*4
+ vmovdqa $xb2,0x20(%rsp)
+ jmp .Loop_tail8x
+
+.align 32
+.L320_or_more8x:
+ vpxor 0x00($inp),$xa0,$xa0 # xor with input
+ vpxor 0x20($inp),$xb0,$xb0
+ vpxor 0x40($inp),$xc0,$xc0
+ vpxor 0x60($inp),$xd0,$xd0
+ vpxor 0x80($inp),$xa1,$xa1
+ vpxor 0xa0($inp),$xb1,$xb1
+ vpxor 0xc0($inp),$xc1,$xc1
+ vpxor 0xe0($inp),$xd1,$xd1
+ vpxor 0x100($inp),$xa2,$xa2
+ vpxor 0x120($inp),$xb2,$xb2
+ vmovdqu $xa0,0x00($out)
+ vmovdqu $xb0,0x20($out)
+ vmovdqu $xc0,0x40($out)
+ vmovdqu $xd0,0x60($out)
+ vmovdqu $xa1,0x80($out)
+ vmovdqu $xb1,0xa0($out)
+ vmovdqu $xc1,0xc0($out)
+ vmovdqu $xd1,0xe0($out)
+ vmovdqu $xa2,0x100($out)
+ vmovdqu $xb2,0x120($out)
+ je .Ldone8x
+
+ lea 0x140($inp),$inp # inp+=64*5
+ xor %r10,%r10
+ vmovdqa $xc2,0x00(%rsp)
+ lea 0x140($out),$out # out+=64*5
+ sub \$320,$len # len-=64*5
+ vmovdqa $xd2,0x20(%rsp)
+ jmp .Loop_tail8x
+
+.align 32
+.L384_or_more8x:
+ vpxor 0x00($inp),$xa0,$xa0 # xor with input
+ vpxor 0x20($inp),$xb0,$xb0
+ vpxor 0x40($inp),$xc0,$xc0
+ vpxor 0x60($inp),$xd0,$xd0
+ vpxor 0x80($inp),$xa1,$xa1
+ vpxor 0xa0($inp),$xb1,$xb1
+ vpxor 0xc0($inp),$xc1,$xc1
+ vpxor 0xe0($inp),$xd1,$xd1
+ vpxor 0x100($inp),$xa2,$xa2
+ vpxor 0x120($inp),$xb2,$xb2
+ vpxor 0x140($inp),$xc2,$xc2
+ vpxor 0x160($inp),$xd2,$xd2
+ vmovdqu $xa0,0x00($out)
+ vmovdqu $xb0,0x20($out)
+ vmovdqu $xc0,0x40($out)
+ vmovdqu $xd0,0x60($out)
+ vmovdqu $xa1,0x80($out)
+ vmovdqu $xb1,0xa0($out)
+ vmovdqu $xc1,0xc0($out)
+ vmovdqu $xd1,0xe0($out)
+ vmovdqu $xa2,0x100($out)
+ vmovdqu $xb2,0x120($out)
+ vmovdqu $xc2,0x140($out)
+ vmovdqu $xd2,0x160($out)
+ je .Ldone8x
+
+ lea 0x180($inp),$inp # inp+=64*6
+ xor %r10,%r10
+ vmovdqa $xa3,0x00(%rsp)
+ lea 0x180($out),$out # out+=64*6
+ sub \$384,$len # len-=64*6
+ vmovdqa $xb3,0x20(%rsp)
+ jmp .Loop_tail8x
+
+.align 32
+.L448_or_more8x:
+ vpxor 0x00($inp),$xa0,$xa0 # xor with input
+ vpxor 0x20($inp),$xb0,$xb0
+ vpxor 0x40($inp),$xc0,$xc0
+ vpxor 0x60($inp),$xd0,$xd0
+ vpxor 0x80($inp),$xa1,$xa1
+ vpxor 0xa0($inp),$xb1,$xb1
+ vpxor 0xc0($inp),$xc1,$xc1
+ vpxor 0xe0($inp),$xd1,$xd1
+ vpxor 0x100($inp),$xa2,$xa2
+ vpxor 0x120($inp),$xb2,$xb2
+ vpxor 0x140($inp),$xc2,$xc2
+ vpxor 0x160($inp),$xd2,$xd2
+ vpxor 0x180($inp),$xa3,$xa3
+ vpxor 0x1a0($inp),$xb3,$xb3
+ vmovdqu $xa0,0x00($out)
+ vmovdqu $xb0,0x20($out)
+ vmovdqu $xc0,0x40($out)
+ vmovdqu $xd0,0x60($out)
+ vmovdqu $xa1,0x80($out)
+ vmovdqu $xb1,0xa0($out)
+ vmovdqu $xc1,0xc0($out)
+ vmovdqu $xd1,0xe0($out)
+ vmovdqu $xa2,0x100($out)
+ vmovdqu $xb2,0x120($out)
+ vmovdqu $xc2,0x140($out)
+ vmovdqu $xd2,0x160($out)
+ vmovdqu $xa3,0x180($out)
+ vmovdqu $xb3,0x1a0($out)
+ je .Ldone8x
+
+ lea 0x1c0($inp),$inp # inp+=64*7
+ xor %r10,%r10
+ vmovdqa $xc3,0x00(%rsp)
+ lea 0x1c0($out),$out # out+=64*7
+ sub \$448,$len # len-=64*7
+ vmovdqa $xd3,0x20(%rsp)
+
+.Loop_tail8x:
+ movzb ($inp,%r10),%eax
+ movzb (%rsp,%r10),%ecx
+ lea 1(%r10),%r10
+ xor %ecx,%eax
+ mov %al,-1($out,%r10)
+ dec $len
+ jnz .Loop_tail8x
+
+.Ldone8x:
+ vzeroall
+___
+$code.=<<___ if ($win64);
+ lea 0x290+0x30(%rsp),%r11
+ movaps -0x30(%r11),%xmm6
+ movaps -0x20(%r11),%xmm7
+ movaps -0x10(%r11),%xmm8
+ movaps 0x00(%r11),%xmm9
+ movaps 0x10(%r11),%xmm10
+ movaps 0x20(%r11),%xmm11
+ movaps 0x30(%r11),%xmm12
+ movaps 0x40(%r11),%xmm13
+ movaps 0x50(%r11),%xmm14
+ movaps 0x60(%r11),%xmm15
+___
+$code.=<<___;
+ mov 0x280(%rsp),%rsp
+ ret
+.size ChaCha20_8x,.-ChaCha20_8x
+___
+}
+
+foreach (split("\n",$code)) {
+ s/\`([^\`]*)\`/eval $1/geo;
+
+ s/%x#%y/%x/go;
+
+ print $_,"\n";
+}
+
+close STDOUT;
diff --git a/src/crypto/chacha/chacha_generic.c b/src/crypto/chacha/chacha.c
index f262033c..afe1b2ad 100644
--- a/src/crypto/chacha/chacha_generic.c
+++ b/src/crypto/chacha/chacha.c
@@ -21,7 +21,49 @@
#include <openssl/cpu.h>
-#if defined(OPENSSL_WINDOWS) || (!defined(OPENSSL_X86_64) && !defined(OPENSSL_X86)) || !defined(__SSE2__)
+#define U8TO32_LITTLE(p) \
+ (((uint32_t)((p)[0])) | ((uint32_t)((p)[1]) << 8) | \
+ ((uint32_t)((p)[2]) << 16) | ((uint32_t)((p)[3]) << 24))
+
+#if !defined(OPENSSL_NO_ASM) && \
+ (defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \
+ defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64))
+
+/* ChaCha20_ctr32 is defined in asm/chacha-*.pl. */
+void ChaCha20_ctr32(uint8_t *out, const uint8_t *in, size_t in_len,
+ const uint32_t key[8], const uint32_t counter[4]);
+
+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) {
+ uint32_t counter_nonce[4];
+ counter_nonce[0] = counter;
+ counter_nonce[1] = U8TO32_LITTLE(nonce + 0);
+ counter_nonce[2] = U8TO32_LITTLE(nonce + 4);
+ counter_nonce[3] = U8TO32_LITTLE(nonce + 8);
+
+ const uint32_t *key_ptr = (const uint32_t *)key;
+#if !defined(OPENSSL_X86) && !defined(OPENSSL_X86_64)
+ /* The assembly expects the key to be four-byte aligned. */
+ uint32_t key_u32[8];
+ if ((((uintptr_t)key) & 3) != 0) {
+ key_u32[0] = U8TO32_LITTLE(key + 0);
+ key_u32[1] = U8TO32_LITTLE(key + 4);
+ key_u32[2] = U8TO32_LITTLE(key + 8);
+ key_u32[3] = U8TO32_LITTLE(key + 12);
+ key_u32[4] = U8TO32_LITTLE(key + 16);
+ key_u32[5] = U8TO32_LITTLE(key + 20);
+ key_u32[6] = U8TO32_LITTLE(key + 24);
+ key_u32[7] = U8TO32_LITTLE(key + 28);
+
+ key_ptr = key_u32;
+ }
+#endif
+
+ ChaCha20_ctr32(out, in, in_len, key_ptr, counter_nonce);
+}
+
+#else
/* sigma contains the ChaCha constants, which happen to be an ASCII string. */
static const uint8_t sigma[16] = { 'e', 'x', 'p', 'a', 'n', 'd', ' ', '3',
@@ -40,10 +82,6 @@ static const uint8_t sigma[16] = { 'e', 'x', 'p', 'a', 'n', 'd', ' ', '3',
(p)[3] = (v >> 24) & 0xff; \
}
-#define U8TO32_LITTLE(p) \
- (((uint32_t)((p)[0])) | ((uint32_t)((p)[1]) << 8) | \
- ((uint32_t)((p)[2]) << 16) | ((uint32_t)((p)[3]) << 24))
-
/* QUARTERROUND updates a, b, c, d with a ChaCha "quarter" round. */
#define QUARTERROUND(a,b,c,d) \
x[a] = PLUS(x[a],x[b]); x[d] = ROTATE(XOR(x[d],x[a]),16); \
@@ -51,13 +89,6 @@ static const uint8_t sigma[16] = { 'e', 'x', 'p', 'a', 'n', 'd', ' ', '3',
x[a] = PLUS(x[a],x[b]); x[d] = ROTATE(XOR(x[d],x[a]), 8); \
x[c] = PLUS(x[c],x[d]); x[b] = ROTATE(XOR(x[b],x[c]), 7);
-#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[12],
- uint32_t counter);
-#endif
-
/* chacha_core performs 20 rounds of ChaCha on the input words in
* |input| and writes the 64 output bytes to |output|. */
static void chacha_core(uint8_t output[64], const uint32_t input[16]) {
@@ -91,13 +122,6 @@ void CRYPTO_chacha_20(uint8_t *out, const uint8_t *in, size_t in_len,
uint8_t buf[64];
size_t todo, i;
-#if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM)
- if (CRYPTO_is_NEON_capable()) {
- CRYPTO_chacha_20_neon(out, in, in_len, key, nonce, counter);
- return;
- }
-#endif
-
input[0] = U8TO32_LITTLE(sigma + 0);
input[1] = U8TO32_LITTLE(sigma + 4);
input[2] = U8TO32_LITTLE(sigma + 8);
@@ -137,4 +161,4 @@ void CRYPTO_chacha_20(uint8_t *out, const uint8_t *in, size_t in_len,
}
}
-#endif /* OPENSSL_WINDOWS || !OPENSSL_X86_64 && !OPENSSL_X86 || !__SSE2__ */
+#endif
diff --git a/src/crypto/chacha/chacha_test.cc b/src/crypto/chacha/chacha_test.cc
new file mode 100644
index 00000000..f364f982
--- /dev/null
+++ b/src/crypto/chacha/chacha_test.cc
@@ -0,0 +1,257 @@
+/* Copyright (c) 2016, 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 <stdint.h>
+#include <string.h>
+
+#include <memory>
+
+#include <openssl/crypto.h>
+#include <openssl/chacha.h>
+
+
+static const uint8_t kKey[32] = {
+ 0x98, 0xbe, 0xf1, 0x46, 0x9b, 0xe7, 0x26, 0x98, 0x37, 0xa4, 0x5b,
+ 0xfb, 0xc9, 0x2a, 0x5a, 0x6a, 0xc7, 0x62, 0x50, 0x7c, 0xf9, 0x64,
+ 0x43, 0xbf, 0x33, 0xb9, 0x6b, 0x1b, 0xd4, 0xc6, 0xf8, 0xf6,
+};
+
+static const uint8_t kNonce[12] = {
+ 0x44, 0xe7, 0x92, 0xd6, 0x33, 0x35, 0xab, 0xb1, 0x58, 0x2e, 0x92, 0x53,
+};
+
+static uint32_t kCounter = 42;
+
+static const uint8_t kInput[] = {
+ 0x58, 0x28, 0xd5, 0x30, 0x36, 0x2c, 0x60, 0x55, 0x29, 0xf8, 0xe1, 0x8c,
+ 0xae, 0x15, 0x15, 0x26, 0xf2, 0x3a, 0x73, 0xa0, 0xf3, 0x12, 0xa3, 0x88,
+ 0x5f, 0x2b, 0x74, 0x23, 0x3d, 0xc9, 0x05, 0x23, 0xc6, 0x54, 0x49, 0x1e,
+ 0x44, 0x88, 0x14, 0xd9, 0xda, 0x37, 0x15, 0xdc, 0xb7, 0xe4, 0x23, 0xb3,
+ 0x9d, 0x7e, 0x16, 0x68, 0x35, 0xfc, 0x02, 0x6d, 0xcc, 0x8a, 0xe5, 0xdd,
+ 0x5f, 0xe4, 0xd2, 0x56, 0x6f, 0x12, 0x9c, 0x9c, 0x7d, 0x6a, 0x38, 0x48,
+ 0xbd, 0xdf, 0xd9, 0xac, 0x1b, 0xa2, 0x4d, 0xc5, 0x43, 0x04, 0x3c, 0xd7,
+ 0x99, 0xe1, 0xa7, 0x13, 0x9c, 0x51, 0xc2, 0x6d, 0xf9, 0xcf, 0x07, 0x3b,
+ 0xe4, 0xbf, 0x93, 0xa3, 0xa9, 0xb4, 0xc5, 0xf0, 0x1a, 0xe4, 0x8d, 0x5f,
+ 0xc6, 0xc4, 0x7c, 0x69, 0x7a, 0xde, 0x1a, 0xc1, 0xc9, 0xcf, 0xc2, 0x4e,
+ 0x7a, 0x25, 0x2c, 0x32, 0xe9, 0x17, 0xba, 0x68, 0xf1, 0x37, 0x5d, 0x62,
+ 0x84, 0x46, 0xf5, 0x80, 0x7f, 0x1a, 0x71, 0xf7, 0xbe, 0x72, 0x4b, 0xb8,
+ 0x1c, 0xfe, 0x3e, 0xbd, 0xae, 0x0d, 0x73, 0x0d, 0x87, 0x4a, 0x31, 0xc3,
+ 0x3d, 0x46, 0x6f, 0xb3, 0xd7, 0x6b, 0xe3, 0xb8, 0x70, 0x17, 0x8e, 0x7a,
+ 0x6a, 0x0e, 0xbf, 0xa8, 0xbc, 0x2b, 0xdb, 0xfa, 0x4f, 0xb6, 0x26, 0x20,
+ 0xee, 0x63, 0xf0, 0x6d, 0x26, 0xac, 0x6a, 0x18, 0x37, 0x6e, 0x59, 0x81,
+ 0xd1, 0x60, 0xe6, 0x40, 0xd5, 0x6d, 0x68, 0xba, 0x8b, 0x65, 0x4a, 0xf9,
+ 0xf1, 0xae, 0x56, 0x24, 0x8f, 0xe3, 0x8e, 0xe7, 0x7e, 0x6f, 0xcf, 0x92,
+ 0xdf, 0xa9, 0x75, 0x3a, 0xd6, 0x2e, 0x1c, 0xaf, 0xf2, 0xd6, 0x8b, 0x39,
+ 0xad, 0xd2, 0x5d, 0xfb, 0xd7, 0xdf, 0x05, 0x57, 0x0d, 0xf7, 0xf6, 0x8f,
+ 0x2d, 0x14, 0xb0, 0x4e, 0x1a, 0x3c, 0x77, 0x04, 0xcd, 0x3c, 0x5c, 0x58,
+ 0x52, 0x10, 0x6f, 0xcf, 0x5c, 0x03, 0xc8, 0x5f, 0x85, 0x2b, 0x05, 0x82,
+ 0x60, 0xda, 0xcc, 0xcd, 0xd6, 0x88, 0xbf, 0xc0, 0x10, 0xb3, 0x6f, 0x54,
+ 0x54, 0x42, 0xbc, 0x4b, 0x77, 0x21, 0x4d, 0xee, 0x87, 0x45, 0x06, 0x4c,
+ 0x60, 0x38, 0xd2, 0x7e, 0x1d, 0x30, 0x6c, 0x55, 0xf0, 0x38, 0x80, 0x1c,
+ 0xde, 0x3d, 0xea, 0x68, 0x3e, 0xf6, 0x3e, 0x59, 0xcf, 0x0d, 0x08, 0xae,
+ 0x8c, 0x02, 0x0b, 0xc1, 0x72, 0x6a, 0xb4, 0x6d, 0xf3, 0xf7, 0xb3, 0xef,
+ 0x3a, 0xb1, 0x06, 0xf2, 0xf4, 0xd6, 0x69, 0x7b, 0x3e, 0xa2, 0x16, 0x31,
+ 0x31, 0x79, 0xb6, 0x33, 0xa9, 0xca, 0x8a, 0xa8, 0xbe, 0xf3, 0xe9, 0x38,
+ 0x28, 0xd1, 0xe1, 0x3b, 0x4e, 0x2e, 0x47, 0x35, 0xa4, 0x61, 0x14, 0x1e,
+ 0x42, 0x2c, 0x49, 0x55, 0xea, 0xe3, 0xb3, 0xce, 0x39, 0xd3, 0xb3, 0xef,
+ 0x4a, 0x4d, 0x78, 0x49, 0xbd, 0xf6, 0x7c, 0x0a, 0x2c, 0xd3, 0x26, 0xcb,
+ 0xd9, 0x6a, 0xad, 0x63, 0x93, 0xa7, 0x29, 0x92, 0xdc, 0x1f, 0xaf, 0x61,
+ 0x82, 0x80, 0x74, 0xb2, 0x9c, 0x4a, 0x86, 0x73, 0x50, 0xd8, 0xd1, 0xff,
+ 0xee, 0x1a, 0xe2, 0xdd, 0xa2, 0x61, 0xbd, 0x10, 0xc3, 0x5f, 0x67, 0x9f,
+ 0x29, 0xe4, 0xd3, 0x70, 0xe5, 0x67, 0x3a, 0xd2, 0x20, 0x00, 0xcc, 0x25,
+ 0x15, 0x96, 0x54, 0x45, 0x85, 0xed, 0x82, 0x88, 0x3b, 0x9f, 0x3b, 0xc3,
+ 0x04, 0xd4, 0x23, 0xb1, 0x0d, 0xdc, 0xc8, 0x26, 0x9d, 0x28, 0xb3, 0x25,
+ 0x4d, 0x52, 0xe5, 0x33, 0xf3, 0xed, 0x2c, 0xb8, 0x1a, 0xcf, 0xc3, 0x52,
+ 0xb4, 0x2f, 0xc7, 0x79, 0x96, 0x14, 0x7d, 0x72, 0x27, 0x72, 0x85, 0xea,
+ 0x6d, 0x41, 0xa0, 0x22, 0x13, 0x6d, 0x06, 0x83, 0xa4, 0xdd, 0x0f, 0x69,
+ 0xd2, 0x01, 0xcd, 0xc6, 0xb8, 0x64, 0x5c, 0x2c, 0x79, 0xd1, 0xc7, 0xd3,
+ 0x31, 0xdb, 0x2c, 0xff, 0xda, 0xd0, 0x69, 0x31, 0xad, 0x83, 0x5f, 0xed,
+ 0x6a, 0x97, 0xe4, 0x00, 0x43, 0xb0, 0x2e, 0x97, 0xae, 0x00, 0x5f, 0x5c,
+ 0xb9, 0xe8, 0x39, 0x80, 0x10, 0xca, 0x0c, 0xfa, 0xf0, 0xb5, 0xcd, 0xaa,
+ 0x27, 0x11, 0x60, 0xd9, 0x21, 0x86, 0x93, 0x91, 0x9f, 0x2d, 0x1a, 0x8e,
+ 0xde, 0x0b, 0xb5, 0xcb, 0x05, 0x24, 0x30, 0x45, 0x4d, 0x11, 0x75, 0xfd,
+ 0xe5, 0xa0, 0xa9, 0x4e, 0x3a, 0x8c, 0x3b, 0x52, 0x5a, 0x37, 0x18, 0x05,
+ 0x4a, 0x7a, 0x09, 0x6a, 0xe6, 0xd5, 0xa9, 0xa6, 0x71, 0x47, 0x4c, 0x50,
+ 0xe1, 0x3e, 0x8a, 0x21, 0x2b, 0x4f, 0x0e, 0xe3, 0xcb, 0x72, 0xc5, 0x28,
+ 0x3e, 0x5a, 0x33, 0xec, 0x48, 0x92, 0x2e, 0xa1, 0x24, 0x57, 0x09, 0x0f,
+ 0x01, 0x85, 0x3b, 0x34, 0x39, 0x7e, 0xc7, 0x90, 0x62, 0xe2, 0xdc, 0x5d,
+ 0x0a, 0x2c, 0x51, 0x26, 0x95, 0x3a, 0x95, 0x92, 0xa5, 0x39, 0x8f, 0x0c,
+ 0x83, 0x0b, 0x9d, 0x38, 0xab, 0x98, 0x2a, 0xc4, 0x01, 0xc4, 0x0d, 0x77,
+ 0x13, 0xcb, 0xca, 0xf1, 0x28, 0x31, 0x52, 0x75, 0x27, 0x2c, 0xf0, 0x04,
+ 0x86, 0xc8, 0xf3, 0x3d, 0xf2, 0x9d, 0x8f, 0x55, 0x52, 0x40, 0x3f, 0xaa,
+ 0x22, 0x7f, 0xe7, 0x69, 0x3b, 0xee, 0x44, 0x09, 0xde, 0xff, 0xb0, 0x69,
+ 0x3a, 0xae, 0x74, 0xe9, 0x9d, 0x33, 0xae, 0x8b, 0x6d, 0x60, 0x04, 0xff,
+ 0x53, 0x3f, 0x88, 0xe9, 0x63, 0x9b, 0xb1, 0x6d, 0x2c, 0x22, 0x15, 0x5a,
+ 0x15, 0xd9, 0xe5, 0xcb, 0x03, 0x78, 0x3c, 0xca, 0x59, 0x8c, 0xc8, 0xc2,
+ 0x86, 0xff, 0xd2, 0x79, 0xd6, 0xc6, 0xec, 0x5b, 0xbb, 0xa0, 0xae, 0x01,
+ 0x20, 0x09, 0x2e, 0x38, 0x5d, 0xda, 0x5d, 0xe0, 0x59, 0x4e, 0xe5, 0x8b,
+ 0x84, 0x8f, 0xb6, 0xe0, 0x56, 0x9f, 0x21, 0xa1, 0xcf, 0xb2, 0x0f, 0x2c,
+ 0x93, 0xf8, 0xcf, 0x37, 0xc1, 0x9f, 0x32, 0x98, 0x21, 0x65, 0x52, 0x66,
+ 0x6e, 0xd3, 0x71, 0x98, 0x55, 0xb9, 0x46, 0x9f, 0x1a, 0x35, 0xc4, 0x47,
+ 0x69, 0x62, 0x70, 0x4b, 0x77, 0x9e, 0xe4, 0x21, 0xe6, 0x32, 0x5a, 0x26,
+ 0x05, 0xba, 0x57, 0x53, 0xd7, 0x9b, 0x55, 0x3c, 0xbb, 0x53, 0x79, 0x60,
+ 0x9c, 0xc8, 0x4d, 0xf7, 0xf5, 0x1d, 0x54, 0x02, 0x91, 0x68, 0x0e, 0xaa,
+ 0xca, 0x5a, 0x78, 0x0c, 0x28, 0x9a, 0xc3, 0xac, 0x49, 0xc0, 0xf4, 0x85,
+ 0xee, 0x59, 0x76, 0x7e, 0x28, 0x4e, 0xf1, 0x5c, 0x63, 0xf7, 0xce, 0x0e,
+ 0x2c, 0x21, 0xa0, 0x58, 0xe9, 0x01, 0xfd, 0xeb, 0xd1, 0xaf, 0xe6, 0xef,
+ 0x93, 0xb3, 0x95, 0x51, 0x60, 0xa2, 0x74, 0x40, 0x15, 0xe5, 0xf4, 0x0a,
+ 0xca, 0x6d, 0x9a, 0x37, 0x42, 0x4d, 0x5a, 0x58, 0x49, 0x0f, 0xe9, 0x02,
+ 0xfc, 0x77, 0xd8, 0x59, 0xde, 0xdd, 0xad, 0x4b, 0x99, 0x2e, 0x64, 0x73,
+ 0xad, 0x42, 0x2f, 0xf3, 0x2c, 0x0d, 0x49, 0xe4, 0x2e, 0x6c, 0xa4, 0x73,
+ 0x75, 0x18, 0x14, 0x85, 0xbb, 0x64, 0xb4, 0xa1, 0xb0, 0x6e, 0x01, 0xc0,
+ 0xcf, 0x17, 0x9c, 0xc5, 0x28, 0xc3, 0x2d, 0x6c, 0x17, 0x2a, 0x3d, 0x06,
+ 0x5c, 0xf3, 0xb4, 0x49, 0x75, 0xad, 0x17, 0x69, 0xd4, 0xca, 0x65, 0xae,
+ 0x44, 0x71, 0xa5, 0xf6, 0x0d, 0x0f, 0x8e, 0x37, 0xc7, 0x43, 0xce, 0x6b,
+ 0x08, 0xe9, 0xd1, 0x34, 0x48, 0x8f, 0xc9, 0xfc, 0xf3, 0x5d, 0x2d, 0xec,
+ 0x62, 0xd3, 0xf0, 0xb3, 0xfe, 0x2e, 0x40, 0x55, 0x76, 0x54, 0xc7, 0xb4,
+ 0x61, 0x16, 0xcc, 0x7c, 0x1c, 0x19, 0x24, 0xe6, 0x4d, 0xd4, 0xc3, 0x77,
+ 0x67, 0x1f, 0x3c, 0x74, 0x79, 0xa1, 0xf8, 0x85, 0x88, 0x1d, 0x6f, 0xa4,
+ 0x7e, 0x2c, 0x21, 0x9f, 0x49, 0xf5, 0xaa, 0x4e, 0xf3, 0x4a, 0xfa, 0x9d,
+ 0xbe, 0xf6, 0xce, 0xda, 0xb5, 0xab, 0x39, 0xbd, 0x16, 0x41, 0xa9, 0x4a,
+ 0xac, 0x09, 0x01, 0xca,
+};
+static const uint8_t kOutput[] = {
+ 0x54, 0x30, 0x6a, 0x13, 0xda, 0x59, 0x6b, 0x6d, 0x59, 0x49, 0xc8, 0xc5,
+ 0xab, 0x26, 0xd4, 0x8a, 0xad, 0xc0, 0x3d, 0xaf, 0x14, 0xb9, 0x15, 0xb8,
+ 0xca, 0xdf, 0x17, 0xa7, 0x03, 0xd3, 0xc5, 0x06, 0x01, 0xef, 0x21, 0xdd,
+ 0xa3, 0x0b, 0x9e, 0x48, 0xb8, 0x5e, 0x0b, 0x87, 0x9f, 0x95, 0x23, 0x68,
+ 0x85, 0x69, 0xd2, 0x5d, 0xaf, 0x57, 0xe9, 0x27, 0x11, 0x3d, 0x49, 0xfa,
+ 0xf1, 0x08, 0xcc, 0x15, 0xec, 0x1d, 0x19, 0x16, 0x12, 0x9b, 0xc8, 0x66,
+ 0x1f, 0xfa, 0x2c, 0x93, 0xf4, 0x99, 0x11, 0x27, 0x31, 0x0e, 0xd8, 0x46,
+ 0x47, 0x40, 0x11, 0x70, 0x01, 0xca, 0xe8, 0x5b, 0xc5, 0x91, 0xc8, 0x3a,
+ 0xdc, 0xaa, 0xf3, 0x4b, 0x80, 0xe5, 0xbc, 0x03, 0xd0, 0x89, 0x72, 0xbc,
+ 0xce, 0x2a, 0x76, 0x0c, 0xf5, 0xda, 0x4c, 0x10, 0x06, 0x35, 0x41, 0xb1,
+ 0xe6, 0xb4, 0xaa, 0x7a, 0xef, 0xf0, 0x62, 0x4a, 0xc5, 0x9f, 0x2c, 0xaf,
+ 0xb8, 0x2f, 0xd9, 0xd1, 0x01, 0x7a, 0x36, 0x2f, 0x3e, 0x83, 0xa5, 0xeb,
+ 0x81, 0x70, 0xa0, 0x57, 0x17, 0x46, 0xea, 0x9e, 0xcb, 0x0e, 0x74, 0xd3,
+ 0x44, 0x57, 0x1d, 0x40, 0x06, 0xf8, 0xb7, 0xcb, 0x5f, 0xf4, 0x79, 0xbd,
+ 0x11, 0x19, 0xd6, 0xee, 0xf8, 0xb0, 0xaa, 0xdd, 0x00, 0x62, 0xad, 0x3b,
+ 0x88, 0x9a, 0x88, 0x5b, 0x1b, 0x07, 0xc9, 0xae, 0x9e, 0xa6, 0x94, 0xe5,
+ 0x55, 0xdb, 0x45, 0x23, 0xb9, 0x2c, 0xcd, 0x29, 0xd3, 0x54, 0xc3, 0x88,
+ 0x1e, 0x5f, 0x52, 0xf2, 0x09, 0x00, 0x26, 0x26, 0x1a, 0xed, 0xf5, 0xc2,
+ 0xa9, 0x7d, 0xf9, 0x21, 0x5a, 0xaf, 0x6d, 0xab, 0x8e, 0x16, 0x84, 0x96,
+ 0xb5, 0x4f, 0xcf, 0x1e, 0xa3, 0xaf, 0x08, 0x9f, 0x79, 0x86, 0xc3, 0xbe,
+ 0x0c, 0x70, 0xcb, 0x8f, 0xf3, 0xc5, 0xf8, 0xe8, 0x4b, 0x21, 0x7d, 0x18,
+ 0xa9, 0xed, 0x8b, 0xfb, 0x6b, 0x5a, 0x6f, 0x26, 0x0b, 0x56, 0x04, 0x7c,
+ 0xfe, 0x0e, 0x1e, 0xc1, 0x3f, 0x82, 0xc5, 0x73, 0xbd, 0x53, 0x0c, 0xf0,
+ 0xe2, 0xc9, 0xf3, 0x3d, 0x1b, 0x6d, 0xba, 0x70, 0xc1, 0x6d, 0xb6, 0x00,
+ 0x28, 0xe1, 0xc4, 0x78, 0x62, 0x04, 0xda, 0x23, 0x86, 0xc3, 0xda, 0x74,
+ 0x3d, 0x7c, 0xd6, 0x76, 0x29, 0xb2, 0x27, 0x2e, 0xb2, 0x35, 0x42, 0x60,
+ 0x82, 0xcf, 0x30, 0x2c, 0x59, 0xe4, 0xe3, 0xd0, 0x74, 0x1f, 0x58, 0xe8,
+ 0xda, 0x47, 0x45, 0x73, 0x1c, 0x05, 0x93, 0xae, 0x75, 0xbe, 0x1f, 0x81,
+ 0xd8, 0xb7, 0xb3, 0xff, 0xfc, 0x8b, 0x52, 0x9e, 0xed, 0x8b, 0x37, 0x9f,
+ 0xe0, 0xb8, 0xa2, 0x66, 0xe1, 0x6a, 0xc5, 0x1f, 0x1d, 0xf0, 0xde, 0x3f,
+ 0x3d, 0xb0, 0x28, 0xf3, 0xaa, 0x4e, 0x4d, 0x31, 0xb0, 0x26, 0x79, 0x2b,
+ 0x08, 0x0f, 0xe9, 0x2f, 0x79, 0xb3, 0xc8, 0xdd, 0xa7, 0x89, 0xa8, 0xa8,
+ 0x1d, 0x59, 0x0e, 0x4f, 0x1e, 0x93, 0x1f, 0x70, 0x7f, 0x4e, 0x7e, 0xfe,
+ 0xb8, 0xca, 0x63, 0xe0, 0xa6, 0x05, 0xcc, 0xd7, 0xde, 0x2a, 0x49, 0x31,
+ 0x78, 0x5c, 0x5f, 0x44, 0xb2, 0x9b, 0x91, 0x99, 0x14, 0x29, 0x63, 0x09,
+ 0x12, 0xdd, 0x02, 0xd9, 0x7b, 0xe9, 0xf5, 0x12, 0x07, 0xd0, 0xe7, 0xe6,
+ 0xe8, 0xdd, 0xda, 0xa4, 0x73, 0xc4, 0x8e, 0xbd, 0x7b, 0xb7, 0xbb, 0xcb,
+ 0x83, 0x2f, 0x43, 0xf6, 0x1c, 0x50, 0xae, 0x9b, 0x2e, 0x52, 0x80, 0x18,
+ 0x85, 0xa8, 0x23, 0x52, 0x7a, 0x6a, 0xf7, 0x42, 0x36, 0xca, 0x91, 0x5a,
+ 0x3d, 0x2a, 0xa0, 0x35, 0x7d, 0x70, 0xfc, 0x4c, 0x18, 0x7c, 0x57, 0x72,
+ 0xcf, 0x9b, 0x29, 0xd6, 0xd0, 0xb4, 0xd7, 0xe6, 0x89, 0x70, 0x69, 0x22,
+ 0x5e, 0x45, 0x09, 0x4d, 0x49, 0x87, 0x84, 0x5f, 0x8a, 0x5f, 0xe4, 0x15,
+ 0xd3, 0xe3, 0x72, 0xaf, 0xb2, 0x30, 0x9c, 0xc1, 0xff, 0x8e, 0x6d, 0x2a,
+ 0x76, 0x9e, 0x08, 0x03, 0x7e, 0xe0, 0xc3, 0xc2, 0x97, 0x06, 0x6b, 0x33,
+ 0x2b, 0x08, 0xe3, 0xd5, 0x0b, 0xd8, 0x32, 0x67, 0x61, 0x10, 0xed, 0x6b,
+ 0xed, 0x50, 0xef, 0xd7, 0x1c, 0x1b, 0xe0, 0x6d, 0xa1, 0x64, 0x19, 0x34,
+ 0x2f, 0xe4, 0xe8, 0x54, 0xbf, 0x84, 0x0e, 0xdf, 0x0e, 0x8b, 0xd8, 0xdd,
+ 0x77, 0x96, 0xb8, 0x54, 0xab, 0xf2, 0x95, 0x59, 0x0d, 0x0d, 0x0a, 0x15,
+ 0x6e, 0x01, 0xf2, 0x24, 0xab, 0xa0, 0xd8, 0xdf, 0x38, 0xea, 0x97, 0x58,
+ 0x76, 0x88, 0xbe, 0xaf, 0x45, 0xe3, 0x56, 0x4f, 0x68, 0xe8, 0x4b, 0xe7,
+ 0x2b, 0x22, 0x18, 0x96, 0x82, 0x89, 0x25, 0x34, 0xd1, 0xdd, 0x08, 0xea,
+ 0x7e, 0x21, 0xef, 0x57, 0x55, 0x43, 0xf7, 0xfa, 0xca, 0x1c, 0xde, 0x99,
+ 0x2e, 0x8b, 0xd8, 0xc3, 0xcf, 0x89, 0x4d, 0xfc, 0x3b, 0x7d, 0x4a, 0xc9,
+ 0x99, 0xc4, 0x31, 0xb6, 0x7a, 0xae, 0xf8, 0x49, 0xb2, 0x46, 0xc1, 0x60,
+ 0x05, 0x75, 0xf3, 0x3d, 0xf2, 0xc9, 0x84, 0xa4, 0xb9, 0x8a, 0x87, 0x2a,
+ 0x87, 0x5c, 0x0a, 0xbc, 0x51, 0x7d, 0x9a, 0xf5, 0xc9, 0x24, 0x2d, 0x5e,
+ 0xe6, 0xc6, 0xe3, 0xcd, 0x7e, 0xe4, 0xaf, 0x8a, 0x6c, 0x00, 0x04, 0xc8,
+ 0xd7, 0xa5, 0xad, 0xfa, 0xb2, 0x08, 0x4a, 0x26, 0x9b, 0x7c, 0xd0, 0xc6,
+ 0x13, 0xb1, 0xb9, 0x65, 0x3f, 0x70, 0x30, 0xf9, 0x98, 0x9d, 0x87, 0x99,
+ 0x57, 0x71, 0x3e, 0xb1, 0xc3, 0x24, 0xf0, 0xa6, 0xa2, 0x60, 0x9d, 0x66,
+ 0xd2, 0x5f, 0xae, 0xe3, 0x94, 0x87, 0xea, 0xd1, 0xea, 0x0d, 0x2a, 0x77,
+ 0xef, 0x31, 0xcc, 0xeb, 0xf9, 0x0c, 0xdc, 0x9c, 0x12, 0x80, 0xbb, 0xb0,
+ 0x8e, 0xab, 0x9a, 0x04, 0xcd, 0x4b, 0x95, 0x4f, 0x7a, 0x0b, 0x53, 0x7c,
+ 0x16, 0xcc, 0x0e, 0xb1, 0x73, 0x10, 0xdd, 0xaa, 0x76, 0x94, 0x90, 0xd9,
+ 0x8b, 0x66, 0x41, 0x31, 0xed, 0x8c, 0x7d, 0x74, 0xc4, 0x33, 0xfa, 0xc3,
+ 0x43, 0x8d, 0x10, 0xbc, 0x84, 0x4d, 0x0e, 0x95, 0x32, 0xdf, 0x17, 0x43,
+ 0x6d, 0xd2, 0x5e, 0x12, 0xb9, 0xed, 0x33, 0xd9, 0x97, 0x6f, 0x4a, 0xcd,
+ 0xc3, 0xcd, 0x81, 0x34, 0xbe, 0x7e, 0xa2, 0xd0, 0xa7, 0x91, 0x5d, 0x90,
+ 0xf6, 0x5e, 0x4a, 0x25, 0x0f, 0xcc, 0x24, 0xeb, 0xe1, 0xe4, 0x62, 0x6c,
+ 0x8f, 0x45, 0x36, 0x97, 0x5d, 0xda, 0x20, 0x2b, 0x86, 0x00, 0x8c, 0x94,
+ 0xa9, 0x6a, 0x69, 0xb2, 0xe9, 0xbb, 0x82, 0x8e, 0x41, 0x95, 0xb4, 0xb7,
+ 0xf1, 0x55, 0x52, 0x30, 0x39, 0x48, 0xb3, 0x25, 0x82, 0xa9, 0x10, 0x27,
+ 0x89, 0xb5, 0xe5, 0x1f, 0xab, 0x72, 0x3c, 0x70, 0x08, 0xce, 0xe6, 0x61,
+ 0xbf, 0x19, 0xc8, 0x90, 0x2b, 0x29, 0x30, 0x3e, 0xb8, 0x4c, 0x33, 0xf0,
+ 0xf0, 0x15, 0x2e, 0xb7, 0x25, 0xca, 0x99, 0x4b, 0x6f, 0x4b, 0x41, 0x50,
+ 0xee, 0x56, 0x99, 0xcf, 0x2b, 0xa4, 0xc4, 0x7c, 0x5c, 0xa6, 0xd4, 0x67,
+ 0x04, 0x5c, 0x5d, 0x5f, 0x26, 0x9e, 0x0f, 0xe2, 0x58, 0x68, 0x4c, 0x30,
+ 0xcd, 0xef, 0x46, 0xdb, 0x37, 0x6f, 0xbb, 0xc4, 0x80, 0xca, 0x8a, 0x54,
+ 0x5d, 0x71, 0x9d, 0x0c, 0xe8, 0xb8, 0x2c, 0x10, 0x90, 0x44, 0xa4, 0x88,
+ 0x3f, 0xbc, 0x15, 0x3c, 0xd2, 0xca, 0x0e, 0xc3, 0xe4, 0x6e, 0xef, 0xb0,
+ 0xcb, 0xfd, 0x61, 0x7c, 0x27, 0xf2, 0x25, 0xea, 0x71, 0x6d, 0xf7, 0x49,
+ 0x9c, 0x81, 0x27, 0xf0, 0x61, 0x33, 0xcf, 0x55, 0x68, 0xd3, 0x73, 0xa4,
+ 0xed, 0x35, 0x65, 0x2a, 0xf2, 0x3e, 0xcf, 0x90, 0x98, 0x54, 0x6d, 0x95,
+ 0x6a, 0x0c, 0x9c, 0x24, 0x0e, 0xb4, 0xb7, 0x9b, 0x8d, 0x6e, 0x1c, 0xbc,
+ 0xeb, 0x17, 0x10, 0x86, 0xda, 0x91, 0x6d, 0x89, 0x4c, 0xeb, 0xf5, 0x50,
+ 0x8f, 0x40, 0xcf, 0x4a,
+};
+
+static_assert(sizeof(kInput) == sizeof(kOutput),
+ "Input and output lengths don't match.");
+
+static bool TestChaCha20(size_t len) {
+ std::unique_ptr<uint8_t[]> buf(new uint8_t[len]);
+ CRYPTO_chacha_20(buf.get(), kInput, len, kKey, kNonce, kCounter);
+ if (memcmp(buf.get(), kOutput, len) != 0) {
+ fprintf(stderr, "Mismatch at length %u.\n", static_cast<unsigned>(len));
+ return false;
+ }
+
+ // Test in-place at various offsets.
+ static const size_t kOffsets[] = {
+ 0, 1, 2, 8, 15, 16, 17, 31, 32, 33, 63,
+ 64, 65, 95, 96, 97, 127, 128, 129, 255, 256, 257,
+ };
+ for (size_t offset : kOffsets) {
+ buf.reset(new uint8_t[len + offset]);
+ memcpy(buf.get() + offset, kInput, len);
+ CRYPTO_chacha_20(buf.get(), buf.get() + offset, len, kKey, kNonce,
+ kCounter);
+ if (memcmp(buf.get(), kOutput, len) != 0) {
+ fprintf(stderr, "Mismatch at length %u with in-place offset %u.\n",
+ static_cast<unsigned>(len), static_cast<unsigned>(offset));
+ return false;
+ }
+ }
+
+ return true;
+}
+
+int main(int argc, char **argv) {
+ CRYPTO_library_init();
+
+ // Run the test with the test vector at all lengths.
+ for (size_t len = 0; len <= sizeof(kInput); len++) {
+ if (!TestChaCha20(len)) {
+ return 1;
+ }
+ }
+
+ printf("PASS\n");
+ return 0;
+}
diff --git a/src/crypto/chacha/chacha_vec.c b/src/crypto/chacha/chacha_vec.c
deleted file mode 100644
index addbaa3d..00000000
--- a/src/crypto/chacha/chacha_vec.c
+++ /dev/null
@@ -1,323 +0,0 @@
-/* Copyright (c) 2014, Google Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
-
-/* ====================================================================
- *
- * When updating this file, also update chacha_vec_arm.S
- *
- * ==================================================================== */
-
-
-/* This implementation is by Ted Krovetz and was submitted to SUPERCOP and
- * marked as public domain. It was been altered to allow for non-aligned inputs
- * and to allow the block counter to be passed in specifically. */
-
-#include <openssl/chacha.h>
-
-#if defined(ASM_GEN) || \
- !defined(OPENSSL_WINDOWS) && \
- (defined(OPENSSL_X86_64) || defined(OPENSSL_X86)) && defined(__SSE2__)
-
-#define CHACHA_RNDS 20 /* 8 (high speed), 20 (conservative), 12 (middle) */
-
-/* Architecture-neutral way to specify 16-byte vector of ints */
-typedef unsigned vec __attribute__((vector_size(16)));
-
-/* This implementation is designed for Neon, SSE and AltiVec machines. The
- * following specify how to do certain vector operations efficiently on
- * each architecture, using intrinsics.
- * This implementation supports parallel processing of multiple blocks,
- * including potentially using general-purpose registers. */
-#if __ARM_NEON__
-#include <string.h>
-#include <arm_neon.h>
-#define GPR_TOO 1
-#define VBPI 2
-#define ONE (vec) vsetq_lane_u32(1, vdupq_n_u32(0), 0)
-#define LOAD_ALIGNED(m) (vec)(*((vec *)(m)))
-#define LOAD(m) ({ \
- memcpy(alignment_buffer, m, 16); \
- LOAD_ALIGNED(alignment_buffer); \
- })
-#define STORE(m, r) ({ \
- (*((vec *)(alignment_buffer))) = (r); \
- memcpy(m, alignment_buffer, 16); \
- })
-#define ROTV1(x) (vec) vextq_u32((uint32x4_t)x, (uint32x4_t)x, 1)
-#define ROTV2(x) (vec) vextq_u32((uint32x4_t)x, (uint32x4_t)x, 2)
-#define ROTV3(x) (vec) vextq_u32((uint32x4_t)x, (uint32x4_t)x, 3)
-#define ROTW16(x) (vec) vrev32q_u16((uint16x8_t)x)
-#if __clang__
-#define ROTW7(x) (x << ((vec) {7, 7, 7, 7})) ^ (x >> ((vec) {25, 25, 25, 25}))
-#define ROTW8(x) (x << ((vec) {8, 8, 8, 8})) ^ (x >> ((vec) {24, 24, 24, 24}))
-#define ROTW12(x) \
- (x << ((vec) {12, 12, 12, 12})) ^ (x >> ((vec) {20, 20, 20, 20}))
-#else
-#define ROTW7(x) \
- (vec) vsriq_n_u32(vshlq_n_u32((uint32x4_t)x, 7), (uint32x4_t)x, 25)
-#define ROTW8(x) \
- (vec) vsriq_n_u32(vshlq_n_u32((uint32x4_t)x, 8), (uint32x4_t)x, 24)
-#define ROTW12(x) \
- (vec) vsriq_n_u32(vshlq_n_u32((uint32x4_t)x, 12), (uint32x4_t)x, 20)
-#endif
-#elif __SSE2__
-#include <emmintrin.h>
-#define GPR_TOO 0
-#if __clang__
-#define VBPI 4
-#else
-#define VBPI 3
-#endif
-#define ONE (vec) _mm_set_epi32(0, 0, 0, 1)
-#define LOAD(m) (vec) _mm_loadu_si128((__m128i *)(m))
-#define LOAD_ALIGNED(m) (vec) _mm_load_si128((__m128i *)(m))
-#define STORE(m, r) _mm_storeu_si128((__m128i *)(m), (__m128i)(r))
-#define ROTV1(x) (vec) _mm_shuffle_epi32((__m128i)x, _MM_SHUFFLE(0, 3, 2, 1))
-#define ROTV2(x) (vec) _mm_shuffle_epi32((__m128i)x, _MM_SHUFFLE(1, 0, 3, 2))
-#define ROTV3(x) (vec) _mm_shuffle_epi32((__m128i)x, _MM_SHUFFLE(2, 1, 0, 3))
-#define ROTW7(x) \
- (vec)(_mm_slli_epi32((__m128i)x, 7) ^ _mm_srli_epi32((__m128i)x, 25))
-#define ROTW12(x) \
- (vec)(_mm_slli_epi32((__m128i)x, 12) ^ _mm_srli_epi32((__m128i)x, 20))
-#if __SSSE3__
-#include <tmmintrin.h>
-#define ROTW8(x) \
- (vec) _mm_shuffle_epi8((__m128i)x, _mm_set_epi8(14, 13, 12, 15, 10, 9, 8, \
- 11, 6, 5, 4, 7, 2, 1, 0, 3))
-#define ROTW16(x) \
- (vec) _mm_shuffle_epi8((__m128i)x, _mm_set_epi8(13, 12, 15, 14, 9, 8, 11, \
- 10, 5, 4, 7, 6, 1, 0, 3, 2))
-#else
-#define ROTW8(x) \
- (vec)(_mm_slli_epi32((__m128i)x, 8) ^ _mm_srli_epi32((__m128i)x, 24))
-#define ROTW16(x) \
- (vec)(_mm_slli_epi32((__m128i)x, 16) ^ _mm_srli_epi32((__m128i)x, 16))
-#endif
-#else
-#error-- Implementation supports only machines with neon or SSE2
-#endif
-
-#ifndef REVV_BE
-#define REVV_BE(x) (x)
-#endif
-
-#ifndef REVW_BE
-#define REVW_BE(x) (x)
-#endif
-
-#define BPI (VBPI + GPR_TOO) /* Blocks computed per loop iteration */
-
-#define DQROUND_VECTORS(a,b,c,d) \
- a += b; d ^= a; d = ROTW16(d); \
- c += d; b ^= c; b = ROTW12(b); \
- a += b; d ^= a; d = ROTW8(d); \
- c += d; b ^= c; b = ROTW7(b); \
- b = ROTV1(b); c = ROTV2(c); d = ROTV3(d); \
- a += b; d ^= a; d = ROTW16(d); \
- c += d; b ^= c; b = ROTW12(b); \
- a += b; d ^= a; d = ROTW8(d); \
- c += d; b ^= c; b = ROTW7(b); \
- b = ROTV3(b); c = ROTV2(c); d = ROTV1(d);
-
-#define QROUND_WORDS(a,b,c,d) \
- a = a+b; d ^= a; d = d<<16 | d>>16; \
- c = c+d; b ^= c; b = b<<12 | b>>20; \
- a = a+b; d ^= a; d = d<< 8 | d>>24; \
- c = c+d; b ^= c; b = b<< 7 | b>>25;
-
-#define WRITE_XOR(in, op, d, v0, v1, v2, v3) \
- STORE(op + d + 0, LOAD(in + d + 0) ^ REVV_BE(v0)); \
- STORE(op + d + 4, LOAD(in + d + 4) ^ REVV_BE(v1)); \
- STORE(op + d + 8, LOAD(in + d + 8) ^ REVV_BE(v2)); \
- STORE(op + d +12, LOAD(in + d +12) ^ REVV_BE(v3));
-
-#if __ARM_NEON__
-/* For ARM, we can't depend on NEON support, so this function is compiled with
- * a different name, along with the generic code, and can be enabled at
- * run-time. */
-void CRYPTO_chacha_20_neon(
-#else
-void CRYPTO_chacha_20(
-#endif
- uint8_t *out,
- const uint8_t *in,
- size_t inlen,
- const uint8_t key[32],
- 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[3];
- uint8_t alignment_buffer[16] __attribute__((aligned(16)));
-#endif
- vec s0, s1, s2, s3;
- __attribute__ ((aligned (16))) unsigned chacha_const[] =
- {0x61707865,0x3320646E,0x79622D32,0x6B206574};
- kp = (unsigned *)key;
-#if defined(__ARM_NEON__)
- memcpy(np, nonce, 12);
-#endif
- s0 = LOAD_ALIGNED(chacha_const);
- s1 = LOAD(&((vec*)kp)[0]);
- s2 = LOAD(&((vec*)kp)[1]);
- s3 = (vec){
- counter,
- ((uint32_t*)nonce)[0],
- ((uint32_t*)nonce)[1],
- ((uint32_t*)nonce)[2]
- };
-
- for (iters = 0; iters < inlen/(BPI*64); iters++)
- {
-#if GPR_TOO
- register unsigned x0, x1, x2, x3, x4, x5, x6, x7, x8,
- x9, x10, x11, x12, x13, x14, x15;
-#endif
-#if VBPI > 2
- vec v8,v9,v10,v11;
-#endif
-#if VBPI > 3
- vec v12,v13,v14,v15;
-#endif
-
- vec v0,v1,v2,v3,v4,v5,v6,v7;
- v4 = v0 = s0; v5 = v1 = s1; v6 = v2 = s2; v3 = s3;
- v7 = v3 + ONE;
-#if VBPI > 2
- v8 = v4; v9 = v5; v10 = v6;
- v11 = v7 + ONE;
-#endif
-#if VBPI > 3
- v12 = v8; v13 = v9; v14 = v10;
- v15 = v11 + ONE;
-#endif
-#if GPR_TOO
- x0 = chacha_const[0]; x1 = chacha_const[1];
- 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 = np[0];
- x14 = np[1]; x15 = np[2];
-#endif
- for (i = CHACHA_RNDS/2; i; i--)
- {
- DQROUND_VECTORS(v0,v1,v2,v3)
- DQROUND_VECTORS(v4,v5,v6,v7)
-#if VBPI > 2
- DQROUND_VECTORS(v8,v9,v10,v11)
-#endif
-#if VBPI > 3
- DQROUND_VECTORS(v12,v13,v14,v15)
-#endif
-#if GPR_TOO
- QROUND_WORDS( x0, x4, x8,x12)
- QROUND_WORDS( x1, x5, x9,x13)
- QROUND_WORDS( x2, x6,x10,x14)
- QROUND_WORDS( x3, x7,x11,x15)
- QROUND_WORDS( x0, x5,x10,x15)
- QROUND_WORDS( x1, x6,x11,x12)
- QROUND_WORDS( x2, x7, x8,x13)
- QROUND_WORDS( x3, x4, x9,x14)
-#endif
- }
-
- WRITE_XOR(ip, op, 0, v0+s0, v1+s1, v2+s2, v3+s3)
- s3 += ONE;
- WRITE_XOR(ip, op, 16, v4+s0, v5+s1, v6+s2, v7+s3)
- s3 += ONE;
-#if VBPI > 2
- WRITE_XOR(ip, op, 32, v8+s0, v9+s1, v10+s2, v11+s3)
- s3 += ONE;
-#endif
-#if VBPI > 3
- WRITE_XOR(ip, op, 48, v12+s0, v13+s1, v14+s2, v15+s3)
- s3 += ONE;
-#endif
- ip += VBPI*16;
- op += VBPI*16;
-#if GPR_TOO
- op[0] = REVW_BE(REVW_BE(ip[0]) ^ (x0 + chacha_const[0]));
- op[1] = REVW_BE(REVW_BE(ip[1]) ^ (x1 + chacha_const[1]));
- op[2] = REVW_BE(REVW_BE(ip[2]) ^ (x2 + chacha_const[2]));
- op[3] = REVW_BE(REVW_BE(ip[3]) ^ (x3 + chacha_const[3]));
- op[4] = REVW_BE(REVW_BE(ip[4]) ^ (x4 + kp[0]));
- op[5] = REVW_BE(REVW_BE(ip[5]) ^ (x5 + kp[1]));
- op[6] = REVW_BE(REVW_BE(ip[6]) ^ (x6 + kp[2]));
- op[7] = REVW_BE(REVW_BE(ip[7]) ^ (x7 + kp[3]));
- op[8] = REVW_BE(REVW_BE(ip[8]) ^ (x8 + kp[4]));
- op[9] = REVW_BE(REVW_BE(ip[9]) ^ (x9 + kp[5]));
- 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 + 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;
-#endif
- }
-
- for (iters = inlen%(BPI*64)/64; iters != 0; iters--)
- {
- vec v0 = s0, v1 = s1, v2 = s2, v3 = s3;
- for (i = CHACHA_RNDS/2; i; i--)
- {
- DQROUND_VECTORS(v0,v1,v2,v3);
- }
- WRITE_XOR(ip, op, 0, v0+s0, v1+s1, v2+s2, v3+s3)
- s3 += ONE;
- ip += 16;
- op += 16;
- }
-
- inlen = inlen % 64;
- if (inlen)
- {
- __attribute__ ((aligned (16))) vec buf[4];
- vec v0,v1,v2,v3;
- v0 = s0; v1 = s1; v2 = s2; v3 = s3;
- for (i = CHACHA_RNDS/2; i; i--)
- {
- DQROUND_VECTORS(v0,v1,v2,v3);
- }
-
- if (inlen >= 16)
- {
- STORE(op + 0, LOAD(ip + 0) ^ REVV_BE(v0 + s0));
- if (inlen >= 32)
- {
- STORE(op + 4, LOAD(ip + 4) ^ REVV_BE(v1 + s1));
- if (inlen >= 48)
- {
- STORE(op + 8, LOAD(ip + 8) ^
- REVV_BE(v2 + s2));
- buf[3] = REVV_BE(v3 + s3);
- }
- else
- buf[2] = REVV_BE(v2 + s2);
- }
- else
- buf[1] = REVV_BE(v1 + s1);
- }
- else
- buf[0] = REVV_BE(v0 + s0);
-
- for (i=inlen & ~15; i<inlen; i++)
- ((char *)op)[i] = ((char *)ip)[i] ^ ((char *)buf)[i];
- }
- }
-
-#endif /* ASM_GEN || !OPENSSL_WINDOWS && (OPENSSL_X86_64 || OPENSSL_X86) && SSE2 */
diff --git a/src/crypto/chacha/chacha_vec_arm.S b/src/crypto/chacha/chacha_vec_arm.S
deleted file mode 100644
index f18c867e..00000000
--- a/src/crypto/chacha/chacha_vec_arm.S
+++ /dev/null
@@ -1,1447 +0,0 @@
-# Copyright (c) 2014, Google Inc.
-#
-# Permission to use, copy, modify, and/or distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
-# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-# This file contains a pre-compiled version of chacha_vec.c for ARM. This is
-# needed to support switching on NEON code at runtime. If the whole of OpenSSL
-# were to be compiled with the needed flags to build chacha_vec.c, then it
-# wouldn't be possible to run on non-NEON systems.
-#
-# This file was generated by chacha_vec_arm_generate.go using the following
-# compiler command:
-#
-# /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
- .eabi_attribute 27, 3
-
-# EABI attribute 28 sets whether VFP register arguments were used to build this
-# file. If object files are inconsistent on this point, the linker will refuse
-# to link them. Thus we report whatever the compiler expects since we don't use
-# VFP arguments.
-
-#if defined(__ARM_PCS_VFP)
- .eabi_attribute 28, 1
-#else
- .eabi_attribute 28, 0
-#endif
-
- .fpu neon
- .eabi_attribute 20, 1
- .eabi_attribute 21, 1
- .eabi_attribute 23, 3
- .eabi_attribute 24, 1
- .eabi_attribute 25, 1
- .eabi_attribute 26, 2
- .eabi_attribute 30, 2
- .eabi_attribute 34, 1
- .eabi_attribute 18, 4
- .thumb
- .file "chacha_vec.c"
- .text
- .align 2
- .global CRYPTO_chacha_20_neon
- .hidden CRYPTO_chacha_20_neon
- .thumb
- .thumb_func
- .type CRYPTO_chacha_20_neon, %function
-CRYPTO_chacha_20_neon:
- @ args = 8, pretend = 0, frame = 160
- @ frame_needed = 1, uses_anonymous_args = 0
- push {r4, r5, r6, r7, r8, r9, r10, fp, lr}
- mov r9, r3
- vpush.64 {d8, d9, d10, d11, d12, d13, d14, d15}
- mov r10, r2
- ldr r4, .L91+16
- mov fp, r1
- mov r8, r9
-.LPIC16:
- add r4, pc
- sub sp, sp, #164
- add r7, sp, #0
- sub sp, sp, #112
- 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 r6, [r7, #264]
- str r4, [r7, #88]
- mov r5, r4
- adds r4, r4, #64
- add ip, r5, #80
- str r9, [r7, #56]
- stmia r4, {r0, r1, r2, r3}
- movw r4, #43691
- ldr r0, [r6] @ unaligned
- movt r4, 43690
- 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 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 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
- sub r3, r2, r3, lsl #6
- ldr r2, [r5, #68]
- ldr r6, [r6, #64]
- vldr d0, .L91
- vldr d1, .L91+8
- str r2, [r7, #48]
- ldr r2, [r5, #72]
- str r3, [r7, #4]
- str r6, [r7, #52]
- str r2, [r7, #44]
- 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 r3, [r7, #16]
-.L4:
- ldr r5, [r7, #56]
- add r8, r7, #40
- ldr r4, [r7, #68]
- vadd.i32 q3, q11, q0
- ldmia r8, {r8, r9, r10, fp}
- mov r1, r5
- ldr r2, [r5, #4]
- vmov q8, q14 @ v4si
- ldr r3, [r5]
- vmov q1, q13 @ v4si
- ldr r6, [r1, #28]
- vmov q9, q12 @ v4si
- mov r0, r2
- ldr r2, [r5, #8]
- str r4, [r7, #112]
- movs r1, #10
- ldr r4, [r7, #72]
- vmov q2, q11 @ v4si
- ldr lr, [r5, #20]
- vmov q15, q14 @ v4si
- str r3, [r7, #108]
- vmov q5, q13 @ v4si
- str r2, [r7, #116]
- vmov q10, q12 @ v4si
- ldr r2, [r5, #12]
- ldr ip, [r5, #16]
- ldr r3, [r7, #64]
- ldr r5, [r5, #24]
- str r6, [r7, #120]
- 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
- str lr, [r7, #104]
- mov r10, r9
- mov lr, r3
- mov r9, r5
- str r6, [r7, #124]
- b .L92
-.L93:
- .align 3
-.L91:
- .word 1
- .word 0
- .word 0
- .word 0
- .word .LANCHOR0-(.LPIC16+4)
-.L92:
-.L3:
- vadd.i32 q9, q9, q1
- add r3, r8, r0
- vadd.i32 q10, q10, q5
- add r5, fp, r4
- veor q3, q3, q9
- mov r6, r3
- veor q2, q2, q10
- ldr r3, [r7, #96]
- str r5, [r7, #116]
- add r10, r10, r1
- vrev32.16 q3, q3
- str r6, [r7, #108]
- vadd.i32 q8, q8, q3
- vrev32.16 q2, q2
- vadd.i32 q15, q15, q2
- mov fp, r3
- ldr r3, [r7, #100]
- veor q4, q8, q1
- veor q6, q15, q5
- add fp, fp, r2
- eors r3, r3, r5
- mov r5, r6
- ldr r6, [r7, #112]
- vshl.i32 q1, q4, #12
- vshl.i32 q5, q6, #12
- ror r3, r3, #16
- eors r6, r6, r5
- eor lr, lr, r10
- vsri.32 q1, q4, #20
- mov r5, r6
- ldr r6, [r7, #124]
- vsri.32 q5, q6, #20
- str r3, [r7, #124]
- eor r6, r6, fp
- ror r5, r5, #16
- vadd.i32 q9, q9, q1
- ror lr, lr, #16
- ror r3, r6, #16
- ldr r6, [r7, #124]
- vadd.i32 q10, q10, q5
- add r9, r9, lr
- veor q4, q9, q3
- add ip, ip, r6
- ldr r6, [r7, #104]
- veor q6, q10, q2
- eor r4, ip, r4
- 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, #100]
- eors r2, r2, r6
- ldr r6, [r7, #116]
- vsri.32 q2, q6, #24
- add r8, r8, r5
- ror r2, r2, #20
- adds r6, r4, r6
- vadd.i32 q4, q8, q3
- eor r0, r8, r0
- vadd.i32 q15, q15, q2
- mov r3, r6
- ldr r6, [r7, #108]
- veor q6, q4, q1
- ror r0, r0, #20
- str r3, [r7, #112]
- veor q5, q15, q5
- adds r6, r0, r6
- str r6, [r7, #120]
- mov r6, r3
- ldr r3, [r7, #124]
- vshl.i32 q8, q6, #7
- add fp, fp, r2
- eors r3, r3, r6
- ldr r6, [r7, #120]
- vshl.i32 q1, q5, #7
- ror r1, r1, #20
- eors r5, r5, r6
- vsri.32 q8, q6, #25
- ldr r6, [r7, #104]
- ror r3, r3, #24
- ror r5, r5, #24
- vsri.32 q1, q5, #25
- str r5, [r7, #116]
- eor r6, fp, r6
- ldr r5, [r7, #116]
- add r10, r10, r1
- add ip, r3, ip
- vext.32 q8, q8, q8, #1
- str ip, [r7, #124]
- add ip, r5, r8
- ldr r5, [r7, #100]
- eor lr, r10, lr
- ror r6, r6, #24
- vext.32 q1, q1, q1, #1
- add r8, r6, r5
- vadd.i32 q9, q9, q8
- ldr r5, [r7, #124]
- vext.32 q3, q3, q3, #3
- vadd.i32 q10, q10, q1
- ror lr, lr, #24
- eor r0, ip, r0
- vext.32 q2, q2, q2, #3
- add r9, r9, lr
- eors r4, r4, r5
- veor q3, q9, q3
- ldr r5, [r7, #112]
- eor r1, r9, r1
- ror r0, r0, #25
- veor q2, q10, q2
- adds r5, r0, r5
- vext.32 q4, q4, q4, #2
- str r5, [r7, #112]
- ldr r5, [r7, #120]
- ror r1, r1, #25
- vrev32.16 q3, q3
- eor r2, r8, r2
- vext.32 q15, q15, q15, #2
- adds r5, r1, r5
- vadd.i32 q4, q4, q3
- ror r4, r4, #25
- vrev32.16 q2, q2
- str r5, [r7, #100]
- vadd.i32 q15, q15, q2
- eors r3, r3, r5
- ldr r5, [r7, #112]
- add fp, fp, r4
- veor q8, q4, q8
- ror r2, r2, #25
- veor q1, q15, q1
- eor lr, fp, lr
- eors r6, r6, r5
- ror r3, r3, #16
- ldr r5, [r7, #116]
- add r10, r10, r2
- str r3, [r7, #120]
- ror lr, lr, #16
- ldr r3, [r7, #120]
- eor r5, r10, r5
- vshl.i32 q5, q8, #12
- add ip, lr, ip
- vshl.i32 q6, q1, #12
- str ip, [r7, #104]
- add ip, r3, r8
- str ip, [r7, #116]
- ldr r3, [r7, #124]
- ror r5, r5, #16
- vsri.32 q5, q8, #20
- ror r6, r6, #16
- add ip, r5, r3
- ldr r3, [r7, #104]
- vsri.32 q6, q1, #20
- add r9, r9, r6
- eor r2, ip, r2
- eors r4, r4, r3
- ldr r3, [r7, #116]
- eor r0, r9, r0
- vadd.i32 q9, q9, q5
- ror r4, r4, #20
- eors r1, r1, r3
- vadd.i32 q10, q10, q6
- ror r3, r2, #20
- str r3, [r7, #108]
- ldr r3, [r7, #112]
- veor q3, q9, q3
- ror r0, r0, #20
- add r8, r4, fp
- veor q2, q10, q2
- add fp, r0, r3
- ldr r3, [r7, #100]
- ror r1, r1, #20
- mov r2, r8
- vshl.i32 q8, q3, #8
- str r8, [r7, #96]
- add r8, r1, r3
- ldr r3, [r7, #108]
- vmov q1, q6 @ v4si
- vshl.i32 q6, q2, #8
- eor r6, fp, r6
- add r10, r10, r3
- ldr r3, [r7, #120]
- vsri.32 q8, q3, #24
- eor lr, r2, lr
- eor r3, r8, r3
- ror r2, r6, #24
- vsri.32 q6, q2, #24
- eor r5, r10, r5
- str r2, [r7, #124]
- ror r2, r3, #24
- ldr r3, [r7, #104]
- vmov q3, q8 @ v4si
- vadd.i32 q15, q15, q6
- ror lr, lr, #24
- vadd.i32 q8, q4, q8
- ror r6, r5, #24
- add r5, lr, r3
- ldr r3, [r7, #124]
- veor q4, q8, q5
- add ip, ip, r6
- vmov q2, q6 @ v4si
- add r9, r9, r3
- veor q6, q15, q1
- ldr r3, [r7, #116]
- vshl.i32 q1, q4, #7
- str r2, [r7, #100]
- add r3, r3, r2
- str r3, [r7, #120]
- vshl.i32 q5, q6, #7
- eors r1, r1, r3
- ldr r3, [r7, #108]
- vsri.32 q1, q4, #25
- eors r4, r4, r5
- eor r0, r9, r0
- eor r2, ip, r3
- vsri.32 q5, q6, #25
- ldr r3, [r7, #92]
- ror r4, r4, #25
- str r6, [r7, #112]
- ror r0, r0, #25
- subs r3, r3, #1
- str r5, [r7, #104]
- ror r1, r1, #25
- ror r2, r2, #25
- vext.32 q15, q15, q15, #2
- str r3, [r7, #92]
- vext.32 q2, q2, q2, #1
- vext.32 q8, q8, q8, #2
- vext.32 q3, q3, q3, #1
- vext.32 q5, q5, q5, #3
- vext.32 q1, q1, q1, #3
- bne .L3
- ldr r3, [r7, #84]
- vadd.i32 q4, q12, q10
- str r9, [r7, #92]
- mov r9, r10
- mov r10, r8
- ldr r8, [r7, #96]
- str lr, [r7, #96]
- mov lr, r5
- 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, #48]
- str r3, [r7, #104]
- vadd.i32 q7, q14, q8
- 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
- ldr r5, [r7, #104]
- vadd.i32 q1, q13, q1
- str r1, [r7, #116]
- vadd.i32 q11, q11, q0
- ldr r1, [r6, #4] @ unaligned
- str r2, [r7, #32]
- vadd.i32 q3, q11, q3
- ldr r2, [r6, #8] @ unaligned
- vadd.i32 q11, q11, q0
- str r4, [r7, #108]
- ldr r4, [r7, #100]
- vadd.i32 q11, q11, q0
- stmia r5!, {r0, r1, r2, r3}
- 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 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]
- 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, #60]
- str r4, [r7, #96]
- 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 r4, r8
- str r2, [r0, #8] @ unaligned
- 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 r6, [r7, #76]
- stmia r5!, {r0, r1, r2, r3}
- 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, r9
- str r0, [r8, #16] @ unaligned
- str r1, [r8, #20] @ unaligned
- str r2, [r8, #24] @ unaligned
- str r3, [r8, #28] @ unaligned
- mov r8, r5
- ldr r0, [r6, #32]! @ unaligned
- 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, r8
- ldr r1, [r7, #88]
- vldr d16, [r1, #80]
- vldr d17, [r1, #88]
- veor q15, q8, q15
- 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 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]
- 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]
- 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
- vstr d18, [r1, #80]
- vstr d19, [r1, #88]
- 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}
- mov r5, r8
- ldr r1, [r7, #88]
- vldr d18, [r1, #80]
- vldr d19, [r1, #88]
- veor q1, q9, q1
- vstr d2, [r1, #80]
- vstr d3, [r1, #88]
- 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 r6, [r7, #76]
- 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 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, r4
- stmia r6!, {r0, r1, r2, r3}
- 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 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, [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, [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 r3, [r6, #148]
- ldr r2, [r1, #4]
- ldr r6, [r7, #36]
- add r6, r6, r2
- eors r3, r3, r6
- 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, [r6, #20]
- ldr r3, [r4, #164]
- add lr, lr, r2
- 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
- ldr r6, [r7, #120]
- eors r3, r3, r2
- str r3, [r1, #168]
- ldr r5, [r5, #28]
- ldr r3, [r4, #172]
- add r6, r6, r5
- eors r3, r3, r6
- str r3, [r1, #172]
- ldr r4, [r4, #176]
- ldr r0, [r7, #28]
- ldr r5, [r7, #24]
- eors r4, r4, r0
- str r4, [r8, #176]
- ldr r0, [lr, #180]
- 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, [r8, #184]
- ldr r2, [lr, #188]
- add r1, lr, #192
- ldr r3, [r7, #72]
- eors r2, r2, r4
- str r2, [r8, #188]
- ldr r2, [r7, #16]
- 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]
- add r3, r3, r2
- str r3, [r7, #12]
-.L2:
- ldr r1, [r7, #8]
- movw r2, #43691
- movt r2, 43690
- umull r2, r3, r1, r2
- lsr fp, r3, #7
- lsl r3, fp, #8
- sub fp, r3, fp, lsl #6
- rsb fp, fp, r1
- lsrs fp, fp, #6
- beq .L6
- ldr r5, [r7, #12]
- ldr r4, [r7, #16]
- ldr r6, [r7, #88]
- ldr lr, [r7, #84]
- vldr d30, .L94
- vldr d31, .L94+8
- str fp, [r7, #120]
- str fp, [r7, #124]
-.L8:
- vmov q2, q11 @ v4si
- movs r3, #10
- vmov q8, q14 @ v4si
- vmov q9, q13 @ v4si
- vmov q10, q12 @ v4si
-.L7:
- vadd.i32 q10, q10, q9
- subs r3, r3, #1
- veor q3, q2, q10
- vrev32.16 q3, q3
- vadd.i32 q8, q8, q3
- veor q9, q8, q9
- vshl.i32 q2, q9, #12
- vsri.32 q2, q9, #20
- vadd.i32 q10, q10, q2
- veor q3, q10, q3
- vshl.i32 q9, q3, #8
- vsri.32 q9, q3, #24
- vadd.i32 q8, q8, q9
- vext.32 q9, q9, q9, #3
- veor q2, q8, q2
- vext.32 q8, q8, q8, #2
- vshl.i32 q3, q2, #7
- vsri.32 q3, q2, #25
- vext.32 q3, q3, q3, #1
- vadd.i32 q10, q10, q3
- veor q9, q10, q9
- vrev32.16 q9, q9
- vadd.i32 q8, q8, q9
- veor q3, q8, q3
- vshl.i32 q2, q3, #12
- vsri.32 q2, q3, #20
- vadd.i32 q10, q10, q2
- vmov q3, q2 @ v4si
- veor q9, q10, q9
- vshl.i32 q2, q9, #8
- vsri.32 q2, q9, #24
- vadd.i32 q8, q8, q2
- vext.32 q2, q2, q2, #1
- veor q3, q8, q3
- vext.32 q8, q8, q8, #2
- vshl.i32 q9, q3, #7
- vsri.32 q9, q3, #25
- vext.32 q9, q9, q9, #3
- bne .L7
- ldr r0, [r5] @ unaligned
- vadd.i32 q1, q12, q10
- ldr r1, [r5, #4] @ unaligned
- mov ip, lr
- ldr r2, [r5, #8] @ unaligned
- mov r9, lr
- ldr r3, [r5, #12] @ unaligned
- mov r10, r5
- vadd.i32 q9, q13, q9
- mov r8, lr
- vadd.i32 q8, q14, q8
- stmia ip!, {r0, r1, r2, r3}
- mov ip, lr
- vldr d20, [r6, #80]
- vldr d21, [r6, #88]
- vadd.i32 q3, q11, q2
- veor q10, q10, q1
- vadd.i32 q11, q11, q15
- vstr d20, [r6, #80]
- vstr d21, [r6, #88]
- ldmia r9!, {r0, r1, r2, r3}
- mov r9, r5
- str r0, [r4] @ unaligned
- str r1, [r4, #4] @ unaligned
- str r2, [r4, #8] @ unaligned
- str r3, [r4, #12] @ unaligned
- ldr r0, [r10, #16]! @ unaligned
- ldr r1, [r10, #4] @ unaligned
- ldr r2, [r10, #8] @ unaligned
- ldr r3, [r10, #12] @ unaligned
- add r10, r4, #48
- adds r4, r4, #64
- stmia r8!, {r0, r1, r2, r3}
- mov r8, lr
- vldr d20, [r6, #80]
- vldr d21, [r6, #88]
- veor q10, q10, q9
- vstr d20, [r6, #80]
- vstr d21, [r6, #88]
- ldmia ip!, {r0, r1, r2, r3}
- mov ip, lr
- str r0, [r4, #-48] @ unaligned
- str r1, [r4, #-44] @ unaligned
- str r2, [r4, #-40] @ unaligned
- str r3, [r4, #-36] @ unaligned
- ldr r0, [r9, #32]! @ unaligned
- ldr r1, [r9, #4] @ unaligned
- ldr r2, [r9, #8] @ unaligned
- ldr r3, [r9, #12] @ unaligned
- mov r9, r5
- adds r5, r5, #64
- stmia r8!, {r0, r1, r2, r3}
- mov r8, lr
- vldr d18, [r6, #80]
- vldr d19, [r6, #88]
- veor q9, q9, q8
- vstr d18, [r6, #80]
- vstr d19, [r6, #88]
- ldmia ip!, {r0, r1, r2, r3}
- mov ip, lr
- str r0, [r4, #-32] @ unaligned
- str r1, [r4, #-28] @ unaligned
- str r2, [r4, #-24] @ unaligned
- str r3, [r4, #-20] @ unaligned
- ldr r0, [r9, #48]! @ unaligned
- ldr r1, [r9, #4] @ unaligned
- ldr r2, [r9, #8] @ unaligned
- ldr r3, [r9, #12] @ unaligned
- stmia r8!, {r0, r1, r2, r3}
- vldr d16, [r6, #80]
- vldr d17, [r6, #88]
- veor q8, q8, q3
- vstr d16, [r6, #80]
- vstr d17, [r6, #88]
- ldmia ip!, {r0, r1, r2, r3}
- str r0, [r4, #-16] @ unaligned
- str r1, [r4, #-12] @ unaligned
- str r3, [r10, #12] @ unaligned
- ldr r3, [r7, #124]
- str r2, [r10, #8] @ unaligned
- cmp r3, #1
- beq .L87
- movs r3, #1
- str r3, [r7, #124]
- b .L8
-.L95:
- .align 3
-.L94:
- .word 1
- .word 0
- .word 0
- .word 0
-.L87:
- ldr fp, [r7, #120]
- ldr r3, [r7, #12]
- lsl fp, fp, #6
- add r3, r3, fp
- str r3, [r7, #12]
- ldr r3, [r7, #16]
- add r3, r3, fp
- str r3, [r7, #16]
-.L6:
- ldr r3, [r7, #8]
- ands r9, r3, #63
- beq .L1
- vmov q3, q11 @ v4si
- movs r3, #10
- vmov q8, q14 @ v4si
- mov r5, r9
- vmov q15, q13 @ v4si
- vmov q10, q12 @ v4si
-.L10:
- vadd.i32 q10, q10, q15
- subs r3, r3, #1
- veor q9, q3, q10
- vrev32.16 q9, q9
- vadd.i32 q8, q8, q9
- veor q15, q8, q15
- vshl.i32 q3, q15, #12
- vsri.32 q3, q15, #20
- vadd.i32 q10, q10, q3
- veor q15, q10, q9
- vshl.i32 q9, q15, #8
- vsri.32 q9, q15, #24
- vadd.i32 q8, q8, q9
- vext.32 q9, q9, q9, #3
- veor q3, q8, q3
- vext.32 q8, q8, q8, #2
- vshl.i32 q15, q3, #7
- vsri.32 q15, q3, #25
- vext.32 q15, q15, q15, #1
- vadd.i32 q10, q10, q15
- veor q9, q10, q9
- vrev32.16 q9, q9
- vadd.i32 q8, q8, q9
- veor q15, q8, q15
- vshl.i32 q3, q15, #12
- vsri.32 q3, q15, #20
- vadd.i32 q10, q10, q3
- vmov q15, q3 @ v4si
- veor q9, q10, q9
- vshl.i32 q3, q9, #8
- vsri.32 q3, q9, #24
- vadd.i32 q8, q8, q3
- vext.32 q3, q3, q3, #1
- veor q9, q8, q15
- vext.32 q8, q8, q8, #2
- vshl.i32 q15, q9, #7
- vsri.32 q15, q9, #25
- vext.32 q15, q15, q15, #3
- bne .L10
- cmp r5, #15
- mov r9, r5
- bhi .L88
- vadd.i32 q12, q12, q10
- ldr r3, [r7, #88]
- vst1.64 {d24-d25}, [r3:128]
-.L14:
- ldr r3, [r7, #8]
- and r2, r3, #48
- cmp r9, r2
- bls .L1
- ldr r6, [r7, #16]
- add r3, r2, #16
- ldr r1, [r7, #12]
- rsb ip, r2, r9
- adds r0, r1, r2
- mov r4, r6
- add r1, r1, r3
- add r4, r4, r2
- add r3, r3, r6
- cmp r0, r3
- it cc
- cmpcc r4, r1
- ite cs
- movcs r3, #1
- movcc r3, #0
- cmp ip, #18
- ite ls
- movls r3, #0
- andhi r3, r3, #1
- cmp r3, #0
- beq .L16
- and r1, r0, #7
- mov r3, r2
- negs r1, r1
- and r1, r1, #15
- cmp r1, ip
- it cs
- movcs r1, ip
- cmp r1, #0
- beq .L17
- ldr r5, [r7, #88]
- cmp r1, #1
- ldrb r0, [r0] @ zero_extendqisi2
- add r3, r2, #1
- ldrb lr, [r5, r2] @ zero_extendqisi2
- mov r6, r5
- eor r0, lr, r0
- strb r0, [r4]
- beq .L17
- ldr r0, [r7, #12]
- cmp r1, #2
- ldrb r4, [r5, r3] @ zero_extendqisi2
- ldr r5, [r7, #16]
- ldrb r0, [r0, r3] @ zero_extendqisi2
- eor r0, r0, r4
- strb r0, [r5, r3]
- add r3, r2, #2
- beq .L17
- ldr r0, [r7, #12]
- cmp r1, #3
- ldrb r4, [r6, r3] @ zero_extendqisi2
- ldrb r0, [r0, r3] @ zero_extendqisi2
- eor r0, r0, r4
- strb r0, [r5, r3]
- add r3, r2, #3
- beq .L17
- ldr r0, [r7, #12]
- cmp r1, #4
- ldrb r4, [r6, r3] @ zero_extendqisi2
- ldrb r0, [r0, r3] @ zero_extendqisi2
- eor r0, r0, r4
- strb r0, [r5, r3]
- add r3, r2, #4
- beq .L17
- ldr r0, [r7, #12]
- cmp r1, #5
- ldrb r4, [r6, r3] @ zero_extendqisi2
- ldrb r0, [r0, r3] @ zero_extendqisi2
- eor r0, r0, r4
- strb r0, [r5, r3]
- add r3, r2, #5
- beq .L17
- ldr r0, [r7, #12]
- cmp r1, #6
- ldrb r4, [r6, r3] @ zero_extendqisi2
- ldrb r0, [r0, r3] @ zero_extendqisi2
- eor r0, r0, r4
- strb r0, [r5, r3]
- add r3, r2, #6
- beq .L17
- ldr r0, [r7, #12]
- cmp r1, #7
- ldrb r4, [r6, r3] @ zero_extendqisi2
- ldrb r0, [r0, r3] @ zero_extendqisi2
- eor r0, r0, r4
- strb r0, [r5, r3]
- add r3, r2, #7
- beq .L17
- ldr r0, [r7, #12]
- cmp r1, #8
- ldrb r4, [r6, r3] @ zero_extendqisi2
- ldrb r0, [r0, r3] @ zero_extendqisi2
- eor r0, r0, r4
- strb r0, [r5, r3]
- add r3, r2, #8
- beq .L17
- ldr r0, [r7, #12]
- cmp r1, #9
- ldrb r4, [r6, r3] @ zero_extendqisi2
- ldrb r0, [r0, r3] @ zero_extendqisi2
- eor r0, r0, r4
- strb r0, [r5, r3]
- add r3, r2, #9
- beq .L17
- ldr r0, [r7, #12]
- cmp r1, #10
- ldrb r4, [r6, r3] @ zero_extendqisi2
- ldrb r0, [r0, r3] @ zero_extendqisi2
- eor r0, r0, r4
- strb r0, [r5, r3]
- add r3, r2, #10
- beq .L17
- ldr r0, [r7, #12]
- cmp r1, #11
- ldrb r4, [r6, r3] @ zero_extendqisi2
- ldrb r0, [r0, r3] @ zero_extendqisi2
- eor r0, r0, r4
- strb r0, [r5, r3]
- add r3, r2, #11
- beq .L17
- ldr r0, [r7, #12]
- cmp r1, #12
- ldrb r4, [r6, r3] @ zero_extendqisi2
- ldrb r0, [r0, r3] @ zero_extendqisi2
- eor r0, r0, r4
- strb r0, [r5, r3]
- add r3, r2, #12
- beq .L17
- ldr r0, [r7, #12]
- cmp r1, #13
- ldrb r4, [r6, r3] @ zero_extendqisi2
- ldrb r0, [r0, r3] @ zero_extendqisi2
- eor r0, r0, r4
- strb r0, [r5, r3]
- add r3, r2, #13
- beq .L17
- ldr r0, [r7, #12]
- cmp r1, #15
- ldrb r4, [r6, r3] @ zero_extendqisi2
- ldrb r0, [r0, r3] @ zero_extendqisi2
- eor r0, r0, r4
- strb r0, [r5, r3]
- add r3, r2, #14
- bne .L17
- ldr r0, [r7, #12]
- ldrb r4, [r6, r3] @ zero_extendqisi2
- ldrb r0, [r0, r3] @ zero_extendqisi2
- eors r0, r0, r4
- strb r0, [r5, r3]
- add r3, r2, #15
-.L17:
- rsb r4, r1, ip
- add r0, ip, #-1
- sub r6, r4, #16
- subs r0, r0, r1
- cmp r0, #14
- lsr r6, r6, #4
- add r6, r6, #1
- lsl lr, r6, #4
- bls .L19
- add r2, r2, r1
- ldr r1, [r7, #12]
- ldr r5, [r7, #16]
- cmp r6, #1
- add r0, r1, r2
- ldr r1, [r7, #88]
- add r1, r1, r2
- vld1.64 {d18-d19}, [r0:64]
- add r2, r2, r5
- vld1.8 {q8}, [r1]
- veor q8, q8, q9
- vst1.8 {q8}, [r2]
- beq .L20
- add r8, r1, #16
- add ip, r2, #16
- vldr d18, [r0, #16]
- vldr d19, [r0, #24]
- cmp r6, #2
- vld1.8 {q8}, [r8]
- veor q8, q8, q9
- vst1.8 {q8}, [ip]
- beq .L20
- add r8, r1, #32
- add ip, r2, #32
- vldr d18, [r0, #32]
- vldr d19, [r0, #40]
- cmp r6, #3
- vld1.8 {q8}, [r8]
- veor q8, q8, q9
- vst1.8 {q8}, [ip]
- beq .L20
- adds r1, r1, #48
- adds r2, r2, #48
- vldr d18, [r0, #48]
- vldr d19, [r0, #56]
- vld1.8 {q8}, [r1]
- veor q8, q8, q9
- vst1.8 {q8}, [r2]
-.L20:
- cmp lr, r4
- add r3, r3, lr
- beq .L1
-.L19:
- ldr r4, [r7, #88]
- adds r2, r3, #1
- ldr r1, [r7, #12]
- cmp r2, r9
- ldr r5, [r7, #16]
- ldrb r0, [r4, r3] @ zero_extendqisi2
- ldrb r1, [r1, r3] @ zero_extendqisi2
- eor r1, r1, r0
- strb r1, [r5, r3]
- bcs .L1
- ldr r0, [r7, #12]
- adds r1, r3, #2
- mov r6, r4
- cmp r9, r1
- ldrb r4, [r4, r2] @ zero_extendqisi2
- ldrb r0, [r0, r2] @ zero_extendqisi2
- eor r0, r0, r4
- strb r0, [r5, r2]
- bls .L1
- ldr r0, [r7, #12]
- adds r2, r3, #3
- ldrb r4, [r6, r1] @ zero_extendqisi2
- cmp r9, r2
- ldrb r0, [r0, r1] @ zero_extendqisi2
- eor r0, r0, r4
- strb r0, [r5, r1]
- bls .L1
- ldr r0, [r7, #12]
- adds r1, r3, #4
- ldrb r4, [r6, r2] @ zero_extendqisi2
- cmp r9, r1
- ldrb r0, [r0, r2] @ zero_extendqisi2
- eor r0, r0, r4
- strb r0, [r5, r2]
- bls .L1
- ldr r0, [r7, #12]
- adds r2, r3, #5
- ldrb r4, [r6, r1] @ zero_extendqisi2
- cmp r9, r2
- ldrb r0, [r0, r1] @ zero_extendqisi2
- eor r0, r0, r4
- strb r0, [r5, r1]
- bls .L1
- ldr r0, [r7, #12]
- adds r1, r3, #6
- ldrb r4, [r6, r2] @ zero_extendqisi2
- cmp r9, r1
- ldrb r0, [r0, r2] @ zero_extendqisi2
- eor r0, r0, r4
- strb r0, [r5, r2]
- bls .L1
- ldr r0, [r7, #12]
- adds r2, r3, #7
- ldrb r4, [r6, r1] @ zero_extendqisi2
- cmp r9, r2
- ldrb r0, [r0, r1] @ zero_extendqisi2
- eor r0, r0, r4
- strb r0, [r5, r1]
- bls .L1
- ldr r0, [r7, #12]
- add r1, r3, #8
- ldrb r4, [r6, r2] @ zero_extendqisi2
- cmp r9, r1
- ldrb r0, [r0, r2] @ zero_extendqisi2
- eor r0, r0, r4
- strb r0, [r5, r2]
- bls .L1
- ldr r0, [r7, #12]
- add r2, r3, #9
- ldrb r4, [r6, r1] @ zero_extendqisi2
- cmp r9, r2
- ldrb r0, [r0, r1] @ zero_extendqisi2
- eor r0, r0, r4
- strb r0, [r5, r1]
- bls .L1
- ldr r0, [r7, #12]
- add r1, r3, #10
- ldrb r4, [r6, r2] @ zero_extendqisi2
- cmp r9, r1
- ldrb r0, [r0, r2] @ zero_extendqisi2
- eor r0, r0, r4
- strb r0, [r5, r2]
- bls .L1
- ldr r0, [r7, #12]
- add r2, r3, #11
- ldrb r4, [r6, r1] @ zero_extendqisi2
- cmp r9, r2
- ldrb r0, [r0, r1] @ zero_extendqisi2
- eor r0, r0, r4
- strb r0, [r5, r1]
- bls .L1
- ldr r0, [r7, #12]
- add r1, r3, #12
- ldrb r4, [r6, r2] @ zero_extendqisi2
- cmp r9, r1
- ldrb r0, [r0, r2] @ zero_extendqisi2
- eor r0, r0, r4
- strb r0, [r5, r2]
- bls .L1
- ldr r0, [r7, #12]
- add r2, r3, #13
- ldrb r4, [r6, r1] @ zero_extendqisi2
- cmp r9, r2
- ldrb r0, [r0, r1] @ zero_extendqisi2
- eor r0, r0, r4
- strb r0, [r5, r1]
- bls .L1
- ldr r1, [r7, #12]
- adds r3, r3, #14
- ldrb r0, [r6, r2] @ zero_extendqisi2
- cmp r9, r3
- ldrb r1, [r1, r2] @ zero_extendqisi2
- eor r1, r1, r0
- strb r1, [r5, r2]
- bls .L1
- ldr r2, [r7, #88]
- ldrb r1, [r2, r3] @ zero_extendqisi2
- ldr r2, [r7, #12]
- ldrb r2, [r2, r3] @ zero_extendqisi2
- eors r2, r2, r1
- ldr r1, [r7, #16]
- strb r2, [r1, r3]
-.L1:
- adds r7, r7, #164
- mov sp, r7
- @ sp needed
- vldm sp!, {d8-d15}
- pop {r4, r5, r6, r7, r8, r9, r10, fp, pc}
-.L88:
- ldr r5, [r7, #12]
- vadd.i32 q12, q12, q10
- ldr r4, [r7, #84]
- cmp r9, #31
- ldr r0, [r5] @ unaligned
- ldr r1, [r5, #4] @ unaligned
- mov r6, r4
- ldr r2, [r5, #8] @ unaligned
- ldr r3, [r5, #12] @ unaligned
- stmia r6!, {r0, r1, r2, r3}
- ldr r2, [r7, #88]
- ldr r6, [r7, #16]
- vldr d18, [r2, #80]
- vldr d19, [r2, #88]
- veor q9, q9, q12
- vstr d18, [r2, #80]
- vstr d19, [r2, #88]
- ldmia r4!, {r0, r1, r2, r3}
- str r1, [r6, #4] @ unaligned
- mov r1, r6
- str r0, [r6] @ unaligned
- str r2, [r6, #8] @ unaligned
- str r3, [r6, #12] @ unaligned
- bhi .L89
- vadd.i32 q13, q13, q15
- ldr r3, [r7, #88]
- vstr d26, [r3, #16]
- vstr d27, [r3, #24]
- b .L14
-.L16:
- subs r3, r2, #1
- ldr r2, [r7, #12]
- add r2, r2, r9
- mov r5, r2
- ldr r2, [r7, #88]
- add r2, r2, r3
- mov r3, r2
-.L24:
- ldrb r1, [r0], #1 @ zero_extendqisi2
- ldrb r2, [r3, #1]! @ zero_extendqisi2
- cmp r0, r5
- eor r2, r2, r1
- strb r2, [r4], #1
- bne .L24
- adds r7, r7, #164
- mov sp, r7
- @ sp needed
- vldm sp!, {d8-d15}
- pop {r4, r5, r6, r7, r8, r9, r10, fp, pc}
-.L26:
- ldr r3, [r7, #80]
- str r3, [r7, #16]
- b .L2
-.L89:
- mov r3, r5
- ldr r4, [r7, #84]
- ldr r0, [r3, #16]! @ unaligned
- add lr, r1, #16
- mov r5, r1
- vadd.i32 q13, q13, q15
- mov r6, r4
- cmp r9, #47
- ldr r1, [r3, #4] @ unaligned
- ldr r2, [r3, #8] @ unaligned
- ldr r3, [r3, #12] @ unaligned
- stmia r6!, {r0, r1, r2, r3}
- ldr r2, [r7, #88]
- vldr d18, [r2, #80]
- vldr d19, [r2, #88]
- veor q13, q9, q13
- vstr d26, [r2, #80]
- vstr d27, [r2, #88]
- ldmia r4!, {r0, r1, r2, r3}
- str r0, [r5, #16] @ unaligned
- str r1, [lr, #4] @ unaligned
- str r2, [lr, #8] @ unaligned
- str r3, [lr, #12] @ unaligned
- bhi .L90
- vadd.i32 q8, q14, q8
- 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, #84]
- vadd.i32 q8, q14, q8
- ldr r5, [r7, #88]
- vadd.i32 q11, q11, q3
- ldr r0, [r3, #32]! @ unaligned
- mov r6, r4
- vstr d22, [r5, #48]
- vstr d23, [r5, #56]
- ldr r1, [r3, #4] @ unaligned
- ldr r2, [r3, #8] @ unaligned
- ldr r3, [r3, #12] @ unaligned
- stmia r4!, {r0, r1, r2, r3}
- vldr d18, [r5, #80]
- vldr d19, [r5, #88]
- veor q9, q9, q8
- ldr r4, [r7, #16]
- vstr d18, [r5, #80]
- vstr d19, [r5, #88]
- ldmia r6!, {r0, r1, r2, r3}
- str r0, [r4, #32] @ unaligned
- str r1, [lr, #4] @ unaligned
- str r2, [lr, #8] @ unaligned
- str r3, [lr, #12] @ unaligned
- b .L14
- .size CRYPTO_chacha_20_neon, .-CRYPTO_chacha_20_neon
- .section .rodata
- .align 2
-.LANCHOR0 = . + 0
-.LC0:
- .word 1634760805
- .word 857760878
- .word 2036477234
- .word 1797285236
- .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
deleted file mode 100644
index 82aa847f..00000000
--- a/src/crypto/chacha/chacha_vec_arm_generate.go
+++ /dev/null
@@ -1,153 +0,0 @@
-// Copyright (c) 2014, Google Inc.
-//
-// Permission to use, copy, modify, and/or distribute this software for any
-// purpose with or without fee is hereby granted, provided that the above
-// copyright notice and this permission notice appear in all copies.
-//
-// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
-// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-// This 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 (
- "bufio"
- "bytes"
- "os"
- "os/exec"
- "strings"
-)
-
-const defaultCompiler = "/opt/gcc-linaro-4.9-2014.11-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc"
-
-func main() {
- compiler := defaultCompiler
- if len(os.Args) > 1 {
- compiler = os.Args[1]
- }
-
- args := []string{
- "-O3",
- "-mcpu=cortex-a8",
- "-mfpu=neon",
- "-fpic",
- "-DASM_GEN",
- "-I", "../../include",
- "-S", "chacha_vec.c",
- "-o", "-",
- }
-
- output, err := os.OpenFile("chacha_vec_arm.S", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
- if err != nil {
- panic(err)
- }
- defer output.Close()
-
- output.WriteString(preamble)
- output.WriteString(compiler)
- output.WriteString(" ")
- output.WriteString(strings.Join(args, " "))
- 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
- asm, err := cmd.StdoutPipe()
- if err != nil {
- panic(err)
- }
- if err := cmd.Start(); err != nil {
- panic(err)
- }
-
- attr28 := []byte(".eabi_attribute 28,")
- globalDirective := []byte(".global\t")
- newLine := []byte("\n")
- attr28Handled := false
-
- scanner := bufio.NewScanner(asm)
- for scanner.Scan() {
- line := scanner.Bytes()
-
- if bytes.Contains(line, attr28) {
- output.WriteString(attr28Block)
- attr28Handled = true
- continue
- }
-
- output.Write(line)
- output.Write(newLine)
-
- if i := bytes.Index(line, globalDirective); i >= 0 {
- output.Write(line[:i])
- output.WriteString(".hidden\t")
- output.Write(line[i+len(globalDirective):])
- output.Write(newLine)
- }
- }
-
- if err := scanner.Err(); err != nil {
- panic(err)
- }
-
- if !attr28Handled {
- panic("EABI attribute 28 not seen in processing")
- }
-
- if err := cmd.Wait(); err != nil {
- panic(err)
- }
-
- output.WriteString(trailer)
-}
-
-const preamble = `# Copyright (c) 2014, Google Inc.
-#
-# Permission to use, copy, modify, and/or distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
-# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-# This file contains a pre-compiled version of chacha_vec.c for ARM. This is
-# needed to support switching on NEON code at runtime. If the whole of OpenSSL
-# were to be compiled with the needed flags to build chacha_vec.c, then it
-# wouldn't be possible to run on non-NEON systems.
-#
-# This file was generated by chacha_vec_arm_generate.go using the following
-# compiler command:
-#
-# `
-
-const attr28Block = `
-# EABI attribute 28 sets whether VFP register arguments were used to build this
-# file. If object files are inconsistent on this point, the linker will refuse
-# to link them. Thus we report whatever the compiler expects since we don't use
-# VFP arguments.
-
-#if defined(__ARM_PCS_VFP)
- .eabi_attribute 28, 1
-#else
- .eabi_attribute 28, 0
-#endif
-
-`
-
-const trailer = `
-#endif /* __arm__ */
-#endif /* !OPENSSL_NO_ASM */
-`
diff --git a/src/crypto/cipher/aead_test.cc b/src/crypto/cipher/aead_test.cc
index 79d7110d..f21291e7 100644
--- a/src/crypto/cipher/aead_test.cc
+++ b/src/crypto/cipher/aead_test.cc
@@ -192,37 +192,158 @@ static int TestCleanupAfterInitFailure(const EVP_AEAD *aead) {
return 1;
}
-struct AEADName {
+static bool TestWithAliasedBuffers(const EVP_AEAD *aead) {
+ const size_t key_len = EVP_AEAD_key_length(aead);
+ const size_t nonce_len = EVP_AEAD_nonce_length(aead);
+ const size_t max_overhead = EVP_AEAD_max_overhead(aead);
+
+ std::vector<uint8_t> key(key_len, 'a');
+ ScopedEVP_AEAD_CTX ctx;
+ if (!EVP_AEAD_CTX_init(ctx.get(), aead, key.data(), key_len,
+ EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr)) {
+ return false;
+ }
+
+ static const uint8_t kPlaintext[260] =
+ "testing123456testing123456testing123456testing123456testing123456testing"
+ "123456testing123456testing123456testing123456testing123456testing123456t"
+ "esting123456testing123456testing123456testing123456testing123456testing1"
+ "23456testing123456testing123456testing12345";
+ const std::vector<size_t> offsets = {
+ 0, 1, 2, 8, 15, 16, 17, 31, 32, 33, 63,
+ 64, 65, 95, 96, 97, 127, 128, 129, 255, 256, 257,
+ };
+
+ std::vector<uint8_t> nonce(nonce_len, 'b');
+ std::vector<uint8_t> valid_encryption(sizeof(kPlaintext) + max_overhead);
+ size_t valid_encryption_len;
+ if (!EVP_AEAD_CTX_seal(
+ ctx.get(), valid_encryption.data(), &valid_encryption_len,
+ sizeof(kPlaintext) + max_overhead, nonce.data(), nonce_len,
+ kPlaintext, sizeof(kPlaintext), nullptr, 0)) {
+ fprintf(stderr, "EVP_AEAD_CTX_seal failed with disjoint buffers.\n");
+ return false;
+ }
+
+ // First test with out > in, which we expect to fail.
+ for (auto offset : offsets) {
+ if (offset == 0) {
+ // Will be tested in the next loop.
+ continue;
+ }
+
+ std::vector<uint8_t> buffer(offset + valid_encryption_len);
+ memcpy(buffer.data(), kPlaintext, sizeof(kPlaintext));
+ uint8_t *out = buffer.data() + offset;
+
+ size_t out_len;
+ if (!EVP_AEAD_CTX_seal(ctx.get(), out, &out_len,
+ sizeof(kPlaintext) + max_overhead, nonce.data(),
+ nonce_len, buffer.data(), sizeof(kPlaintext),
+ nullptr, 0)) {
+ // We expect offsets where the output is greater than the input to fail.
+ ERR_clear_error();
+ } else {
+ fprintf(stderr,
+ "EVP_AEAD_CTX_seal unexpectedly succeeded for offset %u.\n",
+ static_cast<unsigned>(offset));
+ return false;
+ }
+
+ memcpy(buffer.data(), valid_encryption.data(), valid_encryption_len);
+ if (!EVP_AEAD_CTX_open(ctx.get(), out, &out_len, valid_encryption_len,
+ nonce.data(), nonce_len, buffer.data(),
+ valid_encryption_len, nullptr, 0)) {
+ // We expect offsets where the output is greater than the input to fail.
+ ERR_clear_error();
+ } else {
+ fprintf(stderr,
+ "EVP_AEAD_CTX_open unexpectedly succeeded for offset %u.\n",
+ static_cast<unsigned>(offset));
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+ }
+
+ // Test with out <= in, which we expect to work.
+ for (auto offset : offsets) {
+ std::vector<uint8_t> buffer(offset + valid_encryption_len);
+ uint8_t *const out = buffer.data();
+ uint8_t *const in = buffer.data() + offset;
+ memcpy(in, kPlaintext, sizeof(kPlaintext));
+
+ size_t out_len;
+ if (!EVP_AEAD_CTX_seal(ctx.get(), out, &out_len,
+ sizeof(kPlaintext) + max_overhead, nonce.data(),
+ nonce_len, in, sizeof(kPlaintext), nullptr, 0)) {
+ fprintf(stderr, "EVP_AEAD_CTX_seal failed for offset -%u.\n",
+ static_cast<unsigned>(offset));
+ return false;
+ }
+
+ if (out_len != valid_encryption_len ||
+ memcmp(out, valid_encryption.data(), out_len) != 0) {
+ fprintf(stderr, "EVP_AEAD_CTX_seal produced bad output for offset -%u.\n",
+ static_cast<unsigned>(offset));
+ return false;
+ }
+
+ memcpy(in, valid_encryption.data(), valid_encryption_len);
+ if (!EVP_AEAD_CTX_open(ctx.get(), out, &out_len,
+ offset + valid_encryption_len, nonce.data(),
+ nonce_len, in, valid_encryption_len, nullptr, 0)) {
+ fprintf(stderr, "EVP_AEAD_CTX_open failed for offset -%u.\n",
+ static_cast<unsigned>(offset));
+ return false;
+ }
+
+ if (out_len != sizeof(kPlaintext) ||
+ memcmp(out, kPlaintext, out_len) != 0) {
+ fprintf(stderr, "EVP_AEAD_CTX_open produced bad output for offset -%u.\n",
+ static_cast<unsigned>(offset));
+ return false;
+ }
+ }
+
+ return true;
+}
+
+struct KnownAEAD {
const char name[40];
const EVP_AEAD *(*func)(void);
+ // limited_implementation indicates that tests that assume a generic AEAD
+ // interface should not be performed. For example, the key-wrap AEADs only
+ // handle inputs that are a multiple of eight bytes in length and the
+ // SSLv3/TLS AEADs have the concept of “direction”.
+ bool limited_implementation;
};
-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 },
- { "aes-128-cbc-sha1-tls-implicit-iv", EVP_aead_aes_128_cbc_sha1_tls_implicit_iv },
- { "aes-128-cbc-sha256-tls", EVP_aead_aes_128_cbc_sha256_tls },
- { "aes-256-cbc-sha1-tls", EVP_aead_aes_256_cbc_sha1_tls },
- { "aes-256-cbc-sha1-tls-implicit-iv", EVP_aead_aes_256_cbc_sha1_tls_implicit_iv },
- { "aes-256-cbc-sha256-tls", EVP_aead_aes_256_cbc_sha256_tls },
- { "aes-256-cbc-sha384-tls", EVP_aead_aes_256_cbc_sha384_tls },
- { "des-ede3-cbc-sha1-tls", EVP_aead_des_ede3_cbc_sha1_tls },
- { "des-ede3-cbc-sha1-tls-implicit-iv", EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv },
- { "rc4-md5-ssl3", EVP_aead_rc4_md5_ssl3 },
- { "rc4-sha1-ssl3", EVP_aead_rc4_sha1_ssl3 },
- { "aes-128-cbc-sha1-ssl3", EVP_aead_aes_128_cbc_sha1_ssl3 },
- { "aes-256-cbc-sha1-ssl3", EVP_aead_aes_256_cbc_sha1_ssl3 },
- { "des-ede3-cbc-sha1-ssl3", EVP_aead_des_ede3_cbc_sha1_ssl3 },
- { "aes-128-key-wrap", EVP_aead_aes_128_key_wrap },
- { "aes-256-key-wrap", EVP_aead_aes_256_key_wrap },
- { "aes-128-ctr-hmac-sha256", EVP_aead_aes_128_ctr_hmac_sha256 },
- { "aes-256-ctr-hmac-sha256", EVP_aead_aes_256_ctr_hmac_sha256 },
- { "", NULL },
+static const struct KnownAEAD kAEADs[] = {
+ { "aes-128-gcm", EVP_aead_aes_128_gcm, false },
+ { "aes-256-gcm", EVP_aead_aes_256_gcm, false },
+ { "chacha20-poly1305", EVP_aead_chacha20_poly1305, false },
+ { "chacha20-poly1305-old", EVP_aead_chacha20_poly1305_old, false },
+ { "rc4-md5-tls", EVP_aead_rc4_md5_tls, true },
+ { "rc4-sha1-tls", EVP_aead_rc4_sha1_tls, true },
+ { "aes-128-cbc-sha1-tls", EVP_aead_aes_128_cbc_sha1_tls, true },
+ { "aes-128-cbc-sha1-tls-implicit-iv", EVP_aead_aes_128_cbc_sha1_tls_implicit_iv, true },
+ { "aes-128-cbc-sha256-tls", EVP_aead_aes_128_cbc_sha256_tls, true },
+ { "aes-256-cbc-sha1-tls", EVP_aead_aes_256_cbc_sha1_tls, true },
+ { "aes-256-cbc-sha1-tls-implicit-iv", EVP_aead_aes_256_cbc_sha1_tls_implicit_iv, true },
+ { "aes-256-cbc-sha256-tls", EVP_aead_aes_256_cbc_sha256_tls, true },
+ { "aes-256-cbc-sha384-tls", EVP_aead_aes_256_cbc_sha384_tls, true },
+ { "des-ede3-cbc-sha1-tls", EVP_aead_des_ede3_cbc_sha1_tls, true },
+ { "des-ede3-cbc-sha1-tls-implicit-iv", EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv, true },
+ { "rc4-md5-ssl3", EVP_aead_rc4_md5_ssl3, true },
+ { "rc4-sha1-ssl3", EVP_aead_rc4_sha1_ssl3, true },
+ { "aes-128-cbc-sha1-ssl3", EVP_aead_aes_128_cbc_sha1_ssl3, true },
+ { "aes-256-cbc-sha1-ssl3", EVP_aead_aes_256_cbc_sha1_ssl3, true },
+ { "des-ede3-cbc-sha1-ssl3", EVP_aead_des_ede3_cbc_sha1_ssl3, true },
+ { "aes-128-key-wrap", EVP_aead_aes_128_key_wrap, true },
+ { "aes-256-key-wrap", EVP_aead_aes_256_key_wrap, true },
+ { "aes-128-ctr-hmac-sha256", EVP_aead_aes_128_ctr_hmac_sha256, false },
+ { "aes-256-ctr-hmac-sha256", EVP_aead_aes_256_ctr_hmac_sha256, false },
+ { "", NULL, false },
};
int main(int argc, char **argv) {
@@ -233,22 +354,28 @@ int main(int argc, char **argv) {
return 1;
}
- const EVP_AEAD *aead;
+ const struct KnownAEAD *known_aead;
for (unsigned i = 0;; i++) {
- const struct AEADName &aead_name = kAEADs[i];
- if (aead_name.func == NULL) {
+ known_aead = &kAEADs[i];
+ if (known_aead->func == NULL) {
fprintf(stderr, "Unknown AEAD: %s\n", argv[1]);
return 2;
}
- if (strcmp(aead_name.name, argv[1]) == 0) {
- aead = aead_name.func();
+ if (strcmp(known_aead->name, argv[1]) == 0) {
break;
}
}
+ const EVP_AEAD *const aead = known_aead->func();
+
if (!TestCleanupAfterInitFailure(aead)) {
return 1;
}
+ if (!known_aead->limited_implementation && !TestWithAliasedBuffers(aead)) {
+ fprintf(stderr, "Aliased buffers test failed for %s.\n", known_aead->name);
+ return 1;
+ }
+
return FileTestMain(TestAEAD, const_cast<EVP_AEAD*>(aead), argv[2]);
}
diff --git a/src/crypto/cipher/cipher.c b/src/crypto/cipher/cipher.c
index 44018675..341516a7 100644
--- a/src/crypto/cipher/cipher.c
+++ b/src/crypto/cipher/cipher.c
@@ -61,7 +61,7 @@
#include <openssl/err.h>
#include <openssl/mem.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
#include "internal.h"
diff --git a/src/crypto/cipher/cipher_test.cc b/src/crypto/cipher/cipher_test.cc
index 1cbfae97..fa384c69 100644
--- a/src/crypto/cipher/cipher_test.cc
+++ b/src/crypto/cipher/cipher_test.cc
@@ -109,7 +109,7 @@ static const EVP_CIPHER *GetCipher(const std::string &name) {
static bool TestOperation(FileTest *t,
const EVP_CIPHER *cipher,
bool encrypt,
- bool streaming,
+ size_t chunk_size,
const std::vector<uint8_t> &key,
const std::vector<uint8_t> &iv,
const std::vector<uint8_t> &plaintext,
@@ -138,7 +138,7 @@ static bool TestOperation(FileTest *t,
iv.size(), 0)) {
return false;
}
- } else if (iv.size() != (size_t)EVP_CIPHER_CTX_iv_length(ctx.get())) {
+ } else if (iv.size() != EVP_CIPHER_CTX_iv_length(ctx.get())) {
t->PrintLine("Bad IV length.");
return false;
}
@@ -170,16 +170,21 @@ static bool TestOperation(FileTest *t,
t->PrintLine("Operation failed.");
return false;
}
- if (streaming) {
- for (size_t i = 0; i < in->size(); i++) {
- uint8_t c = (*in)[i];
+ if (chunk_size != 0) {
+ for (size_t i = 0; i < in->size();) {
+ size_t todo = chunk_size;
+ if (i + todo > in->size()) {
+ todo = in->size() - i;
+ }
+
int len;
- if (!EVP_CipherUpdate(ctx.get(), result.data() + result_len1, &len, &c,
- 1)) {
+ if (!EVP_CipherUpdate(ctx.get(), result.data() + result_len1, &len,
+ in->data() + i, todo)) {
t->PrintLine("Operation failed.");
return false;
}
result_len1 += len;
+ i += todo;
}
} else if (!in->empty() &&
!EVP_CipherUpdate(ctx.get(), result.data(), &result_len1,
@@ -258,20 +263,20 @@ static bool TestCipher(FileTest *t, void *arg) {
}
}
- // By default, both directions are run, unless overridden by the operation.
- 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)) {
+ const std::vector<size_t> chunk_sizes = {0, 1, 2, 5, 7, 8, 9, 15, 16,
+ 17, 31, 32, 33, 63, 64, 65, 512};
+
+ for (size_t chunk_size : chunk_sizes) {
+ // By default, both directions are run, unless overridden by the operation.
+ if (operation != kDecrypt &&
+ !TestOperation(t, cipher, true /* encrypt */, chunk_size, 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)) {
+
+ if (operation != kEncrypt &&
+ !TestOperation(t, cipher, false /* decrypt */, chunk_size, key, iv,
+ plaintext, ciphertext, aad, tag)) {
return false;
}
}
diff --git a/src/crypto/cipher/e_aes.c b/src/crypto/cipher/e_aes.c
index e5104b47..d61d0482 100644
--- a/src/crypto/cipher/e_aes.c
+++ b/src/crypto/cipher/e_aes.c
@@ -54,7 +54,7 @@
#include <openssl/cpu.h>
#include <openssl/err.h>
#include <openssl/mem.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
#include <openssl/rand.h>
#include <openssl/sha.h>
@@ -67,6 +67,10 @@
#endif
+#if defined(_MSC_VER)
+#pragma warning(disable: 4702) /* Unreachable code. */
+#endif
+
typedef struct {
union {
double align;
@@ -252,22 +256,6 @@ void aesni_ecb_encrypt(const uint8_t *in, uint8_t *out, size_t length,
void aesni_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
const AES_KEY *key, uint8_t *ivec, int enc);
-void aesni_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t blocks,
- const void *key, const uint8_t *ivec);
-
-#if defined(OPENSSL_X86_64)
-size_t aesni_gcm_encrypt(const uint8_t *in, uint8_t *out, size_t len,
- const void *key, uint8_t ivec[16], uint64_t *Xi);
-#define AES_gcm_encrypt aesni_gcm_encrypt
-size_t aesni_gcm_decrypt(const uint8_t *in, uint8_t *out, size_t len,
- const void *key, uint8_t ivec[16], uint64_t *Xi);
-#define AES_gcm_decrypt aesni_gcm_decrypt
-void gcm_ghash_avx(uint64_t Xi[2], const u128 Htable[16], const uint8_t *in,
- size_t len);
-#define AES_GCM_ASM(gctx) \
- (gctx->ctr == aesni_ctr32_encrypt_blocks && gctx->gcm.ghash == gcm_ghash_avx)
-#endif /* OPENSSL_X86_64 */
-
#else
/* On other platforms, aesni_capable() will always return false and so the
@@ -288,8 +276,7 @@ static void aesni_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out,
#endif
static int aes_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
- const uint8_t *iv, int enc)
- OPENSSL_SUPPRESS_UNREACHABLE_CODE_WARNINGS {
+ const uint8_t *iv, int enc) {
int ret, mode;
EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
@@ -384,17 +371,15 @@ static int aes_ecb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
static int aes_ctr_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
size_t len) {
- unsigned int num = ctx->num;
EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
if (dat->stream.ctr) {
- CRYPTO_ctr128_encrypt_ctr32(in, out, len, &dat->ks, ctx->iv, ctx->buf, &num,
- dat->stream.ctr);
+ CRYPTO_ctr128_encrypt_ctr32(in, out, len, &dat->ks, ctx->iv, ctx->buf,
+ &ctx->num, dat->stream.ctr);
} else {
- CRYPTO_ctr128_encrypt(in, out, len, &dat->ks, ctx->iv, ctx->buf, &num,
+ CRYPTO_ctr128_encrypt(in, out, len, &dat->ks, ctx->iv, ctx->buf, &ctx->num,
dat->block);
}
- ctx->num = (size_t)num;
return 1;
}
@@ -410,8 +395,7 @@ static char aesni_capable(void);
static ctr128_f aes_ctr_set_key(AES_KEY *aes_key, GCM128_CONTEXT *gcm_ctx,
block128_f *out_block, const uint8_t *key,
- size_t key_len)
- OPENSSL_SUPPRESS_UNREACHABLE_CODE_WARNINGS {
+ size_t key_len) {
if (aesni_capable()) {
aesni_set_encrypt_key(key, key_len * 8, aes_key);
if (gcm_ctx != NULL) {
@@ -651,57 +635,23 @@ static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
}
} else if (ctx->encrypt) {
if (gctx->ctr) {
- size_t bulk = 0;
-#if defined(AES_GCM_ASM)
- if (len >= 32 && AES_GCM_ASM(gctx)) {
- size_t res = (16 - gctx->gcm.mres) % 16;
-
- 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->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, &gctx->ks.ks, in + bulk,
- out + bulk, len - bulk, gctx->ctr)) {
+ if (!CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm, &gctx->ks.ks, in, out, len,
+ gctx->ctr)) {
return -1;
}
} else {
- size_t bulk = 0;
- if (!CRYPTO_gcm128_encrypt(&gctx->gcm, &gctx->ks.ks, in + bulk,
- out + bulk, len - bulk)) {
+ if (!CRYPTO_gcm128_encrypt(&gctx->gcm, &gctx->ks.ks, in, out, len)) {
return -1;
}
}
} else {
if (gctx->ctr) {
- size_t bulk = 0;
-#if defined(AES_GCM_ASM)
- if (len >= 16 && AES_GCM_ASM(gctx)) {
- size_t res = (16 - gctx->gcm.mres) % 16;
-
- 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->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, &gctx->ks.ks, in + bulk,
- out + bulk, len - bulk, gctx->ctr)) {
+ if (!CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm, &gctx->ks.ks, in, out, len,
+ gctx->ctr)) {
return -1;
}
} else {
- size_t bulk = 0;
- if (!CRYPTO_gcm128_decrypt(&gctx->gcm, &gctx->ks.ks, in + bulk,
- out + bulk, len - bulk)) {
+ if (!CRYPTO_gcm128_decrypt(&gctx->gcm, &gctx->ks.ks, in, out, len)) {
return -1;
}
}
diff --git a/src/crypto/cipher/e_chacha20poly1305.c b/src/crypto/cipher/e_chacha20poly1305.c
index f3849500..852b2c64 100644
--- a/src/crypto/cipher/e_chacha20poly1305.c
+++ b/src/crypto/cipher/e_chacha20poly1305.c
@@ -23,6 +23,7 @@
#include <openssl/poly1305.h>
#include "internal.h"
+#include "../internal.h"
#define POLY1305_TAG_LEN 16
@@ -79,12 +80,6 @@ static void poly1305_update_length(poly1305_state *poly1305, size_t data_len) {
CRYPTO_poly1305_update(poly1305, length_bytes, sizeof(length_bytes));
}
-#if defined(__arm__)
-#define ALIGNED __attribute__((aligned(16)))
-#else
-#define ALIGNED
-#endif
-
typedef void (*aead_poly1305_update)(poly1305_state *ctx, const uint8_t *ad,
size_t ad_len, const uint8_t *ciphertext,
size_t ciphertext_len);
@@ -98,7 +93,7 @@ static void aead_poly1305(aead_poly1305_update update,
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;
+ alignas(16) uint8_t poly1305_key[32];
memset(poly1305_key, 0, sizeof(poly1305_key));
CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key),
c20_ctx->key, nonce, 0);
@@ -122,7 +117,7 @@ static int seal_impl(aead_poly1305_update poly1305_update,
* 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) {
+ if (in_len_64 >= (UINT64_C(1) << 32) * 64 - 64) {
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
return 0;
}
@@ -139,7 +134,7 @@ static int seal_impl(aead_poly1305_update poly1305_update,
CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, nonce, 1);
- uint8_t tag[POLY1305_TAG_LEN] ALIGNED;
+ alignas(16) uint8_t tag[POLY1305_TAG_LEN];
aead_poly1305(poly1305_update, tag, c20_ctx, nonce, ad, ad_len, out, in_len);
memcpy(out + in_len, tag, c20_ctx->tag_len);
@@ -167,13 +162,13 @@ static int open_impl(aead_poly1305_update poly1305_update,
* 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) {
+ if (in_len_64 >= (UINT64_C(1) << 32) * 64 - 64) {
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
return 0;
}
plaintext_len = in_len - c20_ctx->tag_len;
- uint8_t tag[POLY1305_TAG_LEN] ALIGNED;
+ alignas(16) uint8_t tag[POLY1305_TAG_LEN];
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) {
@@ -249,10 +244,6 @@ 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) {
diff --git a/src/crypto/cipher/e_des.c b/src/crypto/cipher/e_des.c
index b1d312c3..2ba2bed3 100644
--- a/src/crypto/cipher/e_des.c
+++ b/src/crypto/cipher/e_des.c
@@ -56,7 +56,7 @@
#include <openssl/cipher.h>
#include <openssl/des.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
#include "internal.h"
diff --git a/src/crypto/cipher/e_null.c b/src/crypto/cipher/e_null.c
index cfe1d1b2..3d6a24c3 100644
--- a/src/crypto/cipher/e_null.c
+++ b/src/crypto/cipher/e_null.c
@@ -58,7 +58,7 @@
#include <string.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
#include "internal.h"
diff --git a/src/crypto/cipher/e_rc2.c b/src/crypto/cipher/e_rc2.c
index 8ca7bba6..67418d54 100644
--- a/src/crypto/cipher/e_rc2.c
+++ b/src/crypto/cipher/e_rc2.c
@@ -55,7 +55,7 @@
* [including the GNU Public Licence.] */
#include <openssl/cipher.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
#include "internal.h"
diff --git a/src/crypto/cipher/e_rc4.c b/src/crypto/cipher/e_rc4.c
index 3a2c166a..e7c2ccaf 100644
--- a/src/crypto/cipher/e_rc4.c
+++ b/src/crypto/cipher/e_rc4.c
@@ -58,7 +58,7 @@
#include <string.h>
#include <openssl/cipher.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
#include <openssl/rc4.h>
diff --git a/src/crypto/cipher/test/cipher_test.txt b/src/crypto/cipher/test/cipher_test.txt
index 21fffdb1..0a940f14 100644
--- a/src/crypto/cipher/test/cipher_test.txt
+++ b/src/crypto/cipher/test/cipher_test.txt
@@ -264,6 +264,14 @@ Ciphertext = 8ce24998625615b603a033aca13fb894be9112a5c3a211a8ba262a3cca7e2ca701e
AAD = feedfacedeadbeeffeedfacedeadbeefabaddad2
Tag = 619cc5aefffe0bfa462af43c1699d050
+Cipher = AES-128-GCM
+Key = 3de7b368783bd7287f2b9b731814c876
+IV = 90dedcfff100eb1f1db9d935
+Plaintext = 8d766795cadc0961c0f448c62df3827eef3a8664599b3adbaab0cfd63875bceb8f992b4f7447dca10ddd716aa0bc4fe925e1aa3e3fd1d5c430c650fe3546d6b9a24d576a857c5f04e8c0a3b149df277aa19cfa64ee235891d3b8ec0e840d268b1e70dd8a4bf97628a0c7aea38aa21eeb8fb1a8437f2abfee05e0d2c30659e312ec03d30da51b7c19073a2341c17df806e27e796d581143d39e4de8d3f8d46aa6d6fc1a98d94fa69b92dab751d930cc12de21fb1a7468af09e3c12ff6c3db3967d10cf140bc46f17a16e24b010b6cba5ebf777341c52042596ee53008389c48d9690ab9f5625795c3e588f72f7a1670b2b25a9f4eee1c8845ac90f1bf47ae4ea4b607a50aca88ed304cbb700d02d5486139b0bc81ec042e574abf986972fa008b83ef22dbfe720c2f2f6355c87c975932cec545ebed657e5e7570c503e9aa7f0b87d0b2648e421ed1d34749637c95d1e931af8925236387e50454f0ba2e22ed05f90450fad46f4eb7ddb08656511dd065c0f852a7e42f618a961a6c6bec42226c6b6043580b009ec9837cf99844cb74794a82c269ff648e0bae9ae50256a0ad98ad9f5a35057b3004ac96f469f9ee966dadc16dc47616586cf242706df96bb2f7ee43d3bd1c65d2eac7b82ef242e77ab509afb9639e5f3995380e926305729ca762c487f4411ec2a9c688b8347e5287216dbb38c3fe2281a89fcb47ee2ee7ddf79bfa3ab61cd56a00981019bbcea8aa0444eb75958e5fa56ea0036d2de4950a7db886f4a318b433bd41e00905ab158171e0ef13172293bdf70064b9dc7b243bf9dc927589bf9e99468d1cb330639dbff1850cc51929b8971b0b2ede9d06bc5f6ba39d4551b587f09bf6f8206e8f1524f55714612581d6aa45d8fb83425f84a736576deeecafdcbfbb8670d14cd2ab2a7f8b7f374c07881b7bac2605fd5ff7ff7cf43e30cf49910961a9079c0343b8601be8c3e9fe38f49fdab0b7e1a8c1536cf84e4d80d26ae5ec37570839b5cda02929221898d611525c3a88fc444167ffc532b256cdd0a8f31ff08097d75b629fab99c9e1062d1d9962b211e15ec8709934029c4934e64db8d7a2f32e23dc541be306e9a57a3419115994cbc3a8f8d5ea2a6f45b9ea9ac0e51ed0c6680fa029f4552a6c8665aab00ab77928342e7284c321e9500ad4774ef1fed0f596d5aea371fe1793271aef38cde55547f34701a525526e83a72673385a85f44db511bc87ce1f831fc6ccf8204ca4f4a20eac09897aae93684f14ede21bcaf40a09c08012b92600d6a839ebdf8bdca7b34192c6c50bad8796b3be3c375dbae6217815d2c75cc878d39b4e842d4eaa5f5df2242cf230e44a240e18e47827f089b18bf880fd41a2516eac8e6ba3fc2db64a4bc28789860d7b18d9edeae8b3059f4d945b15d0ee27b1f74842dd1df117fe83a8fdade23a47c93902eedc4d33f2dbfcd1996e6dc1458409fde2302830e8d44c58c5ae67486b9950dd938f14c38bc4c9484fdc4ded93a0f90875773453fc14d428cd6e7beb0c705d61229d2b3df09632ebb30b325fefe2aebbf2a7aa8e4ad46277ca4b8b078818b63d04e7652057f6cbbab7c43ac355537e0d3918b4a73c00dbe6b30a27ee7a6fa213d3347ae478e8edc323404b8322b9c7b0173ed61c38ed25f3576a675d527d22edd51d6dfa5767560d3a50a91226338e8c4e6436eedbcd3d2efe9dc1e686b15d2f57d553abcfda57dc316ca453a690f20148f0dfa20c1c4a58240aaf7195095fedfa56d839d0230d55ce9a8ca1b9d1acd6fe98d583148ba0f4a4e3413c76e6ec57ddb79428d3a90079f64d3321c791f60d501c3fd02c8403f0f5e6c6836bbc96430c1b48e83350c3a3cfd017f15bee3e4bb1295d821dc98b85ab3145555cce2c34a8142fe50f8db19918b514a165d12ff6301fb2296788760ac0b6d9e3a57770ad5111cde5d24b6321918cb0b0887a282b827a8749733171914b000e7d3c0edad1d42ca60da37f0698554bb2a1749f73b3120dbeaa32951f8217a781a200467d5b569d16f56fc9b7dff0ac524f03fee0617f4c692d94613b1e13b18075dc9f0d32811d4a8949a95f6b5fa46aeb83597adb409e68b2a0177c36dcc95dcb2e7dd4fb7337ff97c013364fe139e185014948fa698741d822044fa3f6978b16afd18138c845587c405ebf7a6cd1c28610ce67e992ed49e406658a0a202feed9709500d064b6f53eecfca57dd4b38363ce3aae9d59126d8ae7e140a373851188ae28c909181d0ac64770df70dd2475809350cb367825b59d521d5e457b4e36aea6dedd90a2266898b753b57fa359d43cd388e7d6c7ed90bc4c2af34ceafe88a3af6ac376fec35f1240f08af4f3eb30bc53dd68e5762e6d39e6b16f63003fbe0bee828d0d7adc58c41e857c2c44702215b202701fc696eae021af19c79e59c3e32627cd571f5db99b17f1772b5d746196befabb0b7446687827f3315b391d5dff069b1c39c00bb143218ef458e3b397e1c99640d57fc8db2e0083d3d22ed4111a8fc9e0e6f55fe6a56e946dbee43909bdd7d516fdf756ed8099ba80b1e17a5e279119345104379a36962ca9c8b2a53c414d79eb09fe79862ca749a9eabd9185ad1df57215945882f5894868a134bfc35c835e040e77ecf077d6a98a73ee022963d70b036be3fe5718280ae52c5d751211b22950c0597aaedd35af41f7dd5999e5f7ee34a37edcf97df54a46742b0252b196eaee454ff0c30685b15f8de087de208906be1d971f0fd89f7cdff2af0bdc96759d6889fba9ef092ad1c8deab0404562a7f3977d211c28dfd1573aebd5427a8773f03986101703fa19cd4ab96a381c76a747f63b63f7a9a3a08e251cdc593a024f63b443b76d17dd9e151809da3c582fbd334fa6dd0221b6d410c6a78ba95bb0154bb8999f619f2e084a6b9755ceee4ca3c7e0481a47776c8814f13054e627e37630d593bd09d5f10a049c66c9999f4b0b037e81ef70615d674c7c7975972994a053c069675fad3fae5ae3e779233b70254fb87f25d44c104afc3d5911b8b695173f9337130e39a02cf97356cb817f6cd23f55ef74dd06bd24ce5887a7001ef576262ffaa99f9bb5e3f55bda2aa0f199115909af48bb4d6b1a0a0847774515302cafebe75aad1f63362b1f38141e8721851c3ef1a247931b3b450581eb5d09027b9e3ba60ae9801d629b74991b7fd65520eac561d47115a85141d9a757bc75710bedff1630561ae05254ea541a7ff1846ed5e164834417556dd562c45543c88d8030bb56451fd5b3cbf10fb0164c5288789d2aac7e7a836e79bc3dd401a8e3e05aa6714ffb2dfddb3037c35fa1ebed62a073b2da42133f2620ae88de5e3f46cc69f2b9b3c9b88e39b8b108059ac6bd493be5f7a39f6b53ee825f4593b77ec9238f5ab804d533f48803e7d8187291ee25cfac4da5d8c9279517adfb09c422f6d704711726c73828a5082b4c7b3d85611b8f496d3e0f78c5c4f1dd1c722b1b11d55861f232beee6aaef8a00fd2eeeb45f182af191ca6de8eaa25ceda5451416fbf6d1abc0670b8c10e2815076f271044c690bdcb64856b91265bac202043a28f6bbeb807535aad4bd89e572a9427c826b170d3862f4cca70ddffb4769d6593a1cc6c42fd06cf68642835fe474a23e6f63df316f8361bab959b768d78e20c03c2a99913c162a9662bd9981eee55922f36792de0af68da04ab49dca72e3d9b0de79df828b433bcf6be073f851a36418c03a717d54d48c1014ccb793577c8393b7cb53cad6bc7060a54cc6363734f6ad388763519ca09b533078d3cfa61d7bdd4c4dd0ffe64d68d501b55903d3f4a1f310a3826ac2ca700de01d656188dcf577fd1b63e305614b8d13471f6f84a5d4b12c5e119870a63d1e3dbd39d3b5c26b09f9d80f8a59ce836b20bc933496923d278a022c00f3aac204d07d2e5075bbcef1e4820d633a3a2b35974f72a033484a91a1d6a9913239c93e5783b01833073c98f358e3465efd5087af37ad60b7285550e776d67ea7019e788776c5a456102358c32eb4e7c28096af88b9a20d8ce379ba3928a10ffd539c106f4927e7ac0f382c74017d6e4438fb128c660affd45e9bb68452de72b574eeffe3ce239d0718908c3800bc7e8ecd2fc7d9754171506017fd7868594c9373a96579fed475a28811649ce5dc8a3107bd0d8578748878ce4998684620931dc3981a2499568c2f61174c3b3fc46a7010468e8ff75c08cd43ac764d95e2ad1659f9db62e9554f811e0f43bb74779d923c8c243d12a5314d3c0c6ec84fe60e1d2b2e2b20d3e64054d62049ef9233ff55223a319c285e4e3f4c98dc95b2ca81230d7fed9bb99fd7d97430eb32c9c11647992bd85dcb47cfd58ea3e221d095bcf9374a6baa7c8333581f62b9e489282483023fdd18451f09bec764146b587209160b3d1d7a3d2e145fdb640c4bc382541e0d84255122d51a710887ebe1ccf29d41b4dd7fd7368d68ada250d3968d6f0971f0849c13c09abadb9db8b08960a18f84f0346ea0aa71227afa55b90cabc062d549b616400d36450b19adb67d7358e48c043fa1135abfca89374c906f8d1a6a845debf6b37f055d390b029c7f4524958bdf8d7e2755dde3b957f0926f9d3b8821ba96044d3cad2d637b973bfb657fcc06ff44c17965acf572ab7a0c87604c7dd1cfd136a0ad02b22e8ef320e101ea09772588e8c5b4d88f40fe1be18d27146a2b9559491949671700cebff9a709f297c2621ca9d5d1749623abc20a326ff5be55cb9435c03bf49b147b1e0a4a918bfdc3642df90b396a474f81d75c953d87b3f3b4e31fced630bd7c481c63acbb84dd31249101ac5277a36dcdfc80d8d9a2e928e9b2d65bb257bce97ccda83b187da8a7886dc96eab93d0864d88c358105f9cfe1ad0f0a8508b5b3985ff95de652e684da970b57669aa3fdfbe590a631522abe8246393639709a9a6cd549e78e3c2d1acf84643e9f554c5e076f75a5c1dce1be20a66722d0b896837b7036509ab8d473d5d2b7a8374d6a575f69d54afe3e7e18f4faf4e917be8a74e55c271b96d966e0c0b883f84b3ef2e4f278daeda2efd3ce770801d2c4bda5eb9b646deeab9fa55324e917e63e4eb6aeb4176cb4e43af3db61aea1546fbf16e76a12fcdbe726b565710e3f9866551023e5fbac0038678717e6ab4d3e92dcc53049e8cb65c00216d31a8869ff4d3539313fe2fd7ce0f53b255e3659e7dfc5f92b7627dd9ba42972f0ba72b888932d870ab97226040c4c0f4826be131fe1d2cdc21005ec2addd7796f0927501251ab26b0e5f3f9d2a1cb346a774e18bc233cc89aa69f5f70e3d5c17098eed350ec419c82837153b5c7f5813bf5918defc8df143063f3fe45125deded2b15892d5cebce589b60f2ada0f9d608983e8d107d8e6482b5f542c6650b014445e8c055aac142f16cfc59229fc9626f7aaa40cefacef777e494e13dfa93d27c201788ca9f60e572af8d65ffb513473dade5fe494cbf7377bd1ed03db2571d65af3be4b0bf27c1f069797bfb67ef0bd8a88c6286af6712c106df9c418d88054e3b46c88296a2e63894d6bee0dda8833c373d6a1b27637e1510fea3eb2fb34ae27354571369653a282a8d19f2c34f9e5ec34555b4ed24327dc5d246df13736bd41021697104f80c85bd0ae920e9aeb4e628fb8aec269d55858df149af298b06d61250b043c8a14a15f0646d0aaa18109d031c449e66dd7336044dbdec912b1bb615fae2a3df480bd64cbed74be65c8f1acac247e80bbaeb6f9dab38c6addf4f3b094d5934ef5c9749053b9159e280034e601731a12d6688ff27ee3581ae289de424d16676fb750d2ccd5b3f964dd77bdefc15bb204e2350632822384cc194cf9130f1ee81bfc3887d3366ec0b48cbbe0fe674281ae7445f03791887873659825680448f162452cef57d783821a73047078a8cf94c416850092ac772ef0b2e48517ef101ee0681b5259aa27fd56edf3c01e6dba6298ccc91b09bb304b637eccf8c673b816e74bd7f8ceffa6b17ab03df7ee9ca4098d24d044015a07df782a309cb6761528272632a6e1323c4e18284b463dfcabed708e4fc95cef133865cdbec8bfdde100621c65a92762cc3141ff37b66dea8fa6e3aad61dcbf3b512467c4773d36e58989e12a636389c1678c191137a5f7f59668c8a527dddcdd0c3fbb14cf48b8f3ea306850a5eda76c57aad06312d7bbfc18969d7b611f512358a7bdf959cc2f41de1c408133ef02b1fb2cdf8efe9973c27536434e56fc1bb4880db7fe901087b53ef3c0de18aafa47c25f1cd62c362f2e5da41c2dbff0e13adaba26c1e0829f027dc0320442e851eaed9507b70ac17180725349f6ea7b59bf39c095a9d10790e87221c7c2d24b8bca184ee95a3ef7449aad6c1d905f688498ae7a0cd1b01f76dabc342fb2be0295ca1484bece3c9b8a1b91e53de2d2587f3607a7f348f5cbefaa7a6dcf61bbbcae9444e2d25a77b016cbd1508c8cd319e9812b43b0bbca52df155d418dacb6ab1360a9e605fb53c6e20588a10bef42d884989e836b2ff16fbcdd2c1704f75dc8c1ac2cc6aeb92726f5d46e4784c70e1e249c102be6da506e5e3c2cef6a8bc4a60dac7adf3cacca8679f8f792ddc27613e44a70fd849b7617e042da46d65a3e6cf425f59b83cbae5b6e911142abd13a0a8cdf06d041435ee20e2ca417e905d2dc49c15b863ae5920ff7f9380a86bb0c86b69a000c157cd35245bf71f9dfdefbd1760af90ec3e554ebc511aebf650633221ca9157226f613f41406872765f8d7b916ff3877266f017b8d840dca0697ec3dffce7912ea9eafb62cc2f2d0a112c9bc0727444b47b62766bddf5b5f26d391f653b6894b069069979d0cf8cc7fc4143626a8420bc0a3866db3860096cc128d620ceff059d1614487004adbdf6b0c4428ac8897dcf16e6b11a692a6b465a92b40010f3480b444d4d2e24b0af8467666905c2a6233bdd6502521b621d3cdd4a5e1f268d65bf6a1879608ffd3abf635c5f0948f3cec7e087485c72b00258ba69783cfe7d611bc41c27814ef5674185791dbe626e1f276cf2c399a4eb264f19c77ee95d94252f546528f629188318e9ede65a927aafd2f2af56ff32c0ef39862d2f92268bc9400afa8ddeff591f3ef99681263a33b873bd9e01a59c8b281da30875245cbffee5268563c7f6f20b9e22d998934131dd219624d3cef6df2f3d2d6401833f72c619d6f763837141dbf93179d0f01375581ebe227185166aa7988eb9fd453d510ca6616cc013d551d23a33a4241e85aac3201284344977d496d768f5d920c5670b1d8bb608efc1b99abd261afb0a4ebe191605cc5c2e20523a13b3b94dd1fb24a27009d9a5b6329336f3516a327642386ba64c8769da1324a8a3d1f304cf0700df2b3e38215a954523e1d40ae96d0046e2929a815bf70785e94bc9b89246ab6aded60d65170eeb49b0ee0a57ee2e57db92409105c25f2d0c1a17b5556d06511bd0991a426258372c7f2b402dd533a75aa175524eb5d6b9575300b81fdb2258bd74429add8aa477bd1182db57107d411d16147defc3582861c68f5ce82e0a0316edd5d0f3cf36825a2c79a33e376cce2e63274b3b41bcbdd755845ad9ed2a3bdacb6fa3fa9484b7b60edeb1d9ef84772e78e39adca14c9fa0bb3ad1f1c17fb9449270e9b4c97b5b320839947fc73853fc58304ee9c9e86f3775f5469554d5006eb7ce9d02d5f900c771806c275ee7022e2b55d111338dd93ad51d14008df4c13d8c03fd9bb3689607e5cbdd499c3a372b487af74cb140f6300cd2dc2acda07277ea3dab57ecf09f1a8f2d6abf7c44fcdaa6dcb1f6e791164004b20b3b4c860f409c1483c7044b6fa445f7224606894e386ba08057a387b48920d4de203b1acc4dbe2b0b4cbdc3f7d7bbb097abbf81e01db09e120eab83def925a059cdb513efe6bc93f0579ebf75638df3c3d7f9eba3c36a169e9d88495c452888853640d93ee70f254f86e2d2d3fbb5e8883b36fbd2da105cf3a75cfe998068203186bb37f1d1ebead8ce1f9383b816f1da2fd0a9e01377b6ebfed4f05bec08b4ff9b90e385736fd13a3af7980c21b0dab58decea8e9545af5d0fb11bb51aeda2c8616960e8f6f84e6c2fc4f50d7e413afe030f75475509fbcf49cbe14445d267994fd3f38f41a1339f2895c0b2969a9bf9c59b85e629486c7bb5107c7a6b069793be7690f7a7c96c93b09a9d610594a156ab27a32d5557a5b1ec8920761cd2f559ad808dff3da64717ea5f10fba87b8ff2712ce322eb3c288939e0007f779a3920f45fdd533369f6f85a8cce21f91552fe03702ef81a926af0e402b418fbb25a6a3dad0ec18ec663126b3f48c341e2725abfeae865352d5ad275a9e3ca20393c64d118968023daac84bdc724a3c522d97a5878ed788cf8e44f80f8803d57584d8c8688cff24dd8c0e881b62d16ea30104d62007a4bec051da7fdc95d1df8556ebdf607383a0825ae503e24661ceb8ba773b793360c3f4ed3b761bd372570cb17e7c2030f07b0b45a7974e45ee6fcf5bd7ae9e9abde5421b42cff6af0c6eb7fc73f4deb67bb4e0b3dc9b4008da30c67071243cda649091a14b89bdacf2ae98dd230e932d9b277d6968c65e0006a8ff63f283f2cd9c21615dfd82e0b24af6ff559c97922a3d112ff0ef4af9d6583bec1f84d1aa8bbae705b9bcf458f5d93059b90fc2217ab27d0072a38aec3229d13266beb3015ac2389a06dec3120c6c04e540886091597919da293a4a8c0812d6cd336d5c5faeb64162ec0459e252d219bed78c4b6bb61c1213939bb3cca12a625ce5a45001d7408f6d40fa9466377caa43afe961b5c1602679220258fae72a8de2ac69c0dc97c90c270e306dbd8eb681ba9c092896b19a8d42665b94ff4d5b8b188f19f7c44abc8f88d4ad7b5df1cce3465de377072c70dd20dbd6779336f05ce328ad741d1e4606dce7065347df111c7d3282c8a3fa4a9458561c04d1056cd53ec5a8ddd6bd4434ac910c69cea0443fd09ee32d1256da44ab7896867a0c97fe4faa4a53b6db5cbfe3812a6667f04cd318f3da127a0dd46170cfbaadfcca863e0d4240ebec1cb2a5952881fe89804892d36dc5bd6484cc78db41bed868ed1b321a680a293bc29c420cffb5305d15fba05c76c2138b986f799b6a3d061658e498204c2b641f2f2ba73d633538eef6b5a01117951eedb7611742c120ff24261bea605e94d21e452ddb9ad27af08ed972b7d5e1eae010ec5d83e4505f6a2b7d9a0bb32a1fbba32a2a8c7823e736a69f516b781fb5354be4b0a67343c009a09b8f656c34ab895f9213531fdeee911d677d1cbc5e72c0fd1ad1f3b4b8bc735e14c3f75f1828ea28c90cda40e0cbdc40dec37031ff3d50305d5a8bba1d53d2f176895e53faa3067129a5c97505799967e55e4e9d87faf5920d71055009fd060ad06691b78583f63881b566d4a06b639c55796b23531ea79c6de24092c0e6fb4d3dc739f6d82ee3ee39f229de4c844aba36432d6119be0d2f02e5f72ef1d95fb2494522a7221e18e92cf22e00010ffd93b89fe60b6895a37fca91aa2fefa8debdae3147fe4f01a6adbfa0a59a5203516b2cc7de5faf821a2e72d43beafa30ac379791ad1e5da3286abecfc7a546b80191b7b892cdd01c25e95506471f5eb74568257439aea03300e80699909cc06db2fd607f3279651f7392f80bf4fc61d66f0dfed7b7db09744139d7374d3cdd18d153dede2a65f26130506acc51d5c721a7989485a145dac9565ef6d3cc938c5a51f31ccc88bb0739920ef8f0a01145f4ddccc74790a22a3099a4b57e31b3a01b4118c9e6c393c1304cc51ca1784db5633eb96ccdc88f8b732815b92c9072dbeb61a2cc1e6b2e7098d883e6174f5af7bd4f129389250926e041ba94d1ac543aab6525f151294060791fd26b668d09302c3482c78e5f3271c0150c437b4e78b1cff6f2b8660dc310965f2df14a1f2ad45cd2759433c4f3952402fefd79fff00dd309c3f09a58600223441c11693cdeeaf0a6100d38d612a759a8e01f753982803af30c7470f7bfd1ccf2c08aa0b187382d25868a9fdf729da10bb0aa0e1cd9c6e695eb2c80c6b6ce62737c3e655246edbce5b8f7ae21c473762db0969dc216a93d4db239f67dea74a1de21d50336793d1ae45e931d975bc706ea718a2ab10d66a59d9d23f76969d870ac279611246ed3aab0f79e11611b312624d78b88a9d1a49dc68d6968f7428c33f0a7a65675826422f7ac058101d2f85663de331345b3a25cf76b7c8fe0988a13278be9599b8e4708526b44a70bc31ac5c278ab739e3e6f0927b72507f34b0034e7fdf43364c466bb75b559e03d4d18c864714eb6061f83a6331b3f59dd62f39bfc2529d5cc68bb6ce63db1075105cbd7d7c4d4ab68c9e65a32092e34e76c3178382a965f49386bd4aae307128242a2ffe3022fd7dc1a824b330b9f032d55573c2f004a6905178a2479ba8a2d5b3140ed5f3e10d986265d8b4cf262295658f301b4d36281611d9c61624928da9abc51ff9a6eb481310511772fcb1c1786203d25295e4a319b9c6d65ccc966b4c5795e6e30b2b3ae8246c38b4a911d1904145de63dbd4470fac47f8ee3eeb3f58b5e665c26a316362382ccc6bf8db7699fa3334cb2ce61c746a7d3af24d8030df6759835f5890b7dd1de538cac1dfe843ad06eba2e887f08d9a49b39246fb26eff5cacc937d63c8d0136f7a8ed2af4cf473f3f0d9064f97fb4fe9938d631f7cea3c617c38771553eddd606ab80bf792f34b44111933796fe1fb8bb104223a4de9e16e17321ea7f8de3306e75a2bc79aa5e9c0ec8dde9b3dd1f2ae42a6a278410afa8fb62c16282f1e3dc1e2f8c28d4538a75b5da7645101253dd43aaa150b273f73e505d490490314606264c737bb344b616a80a4931825043a740ea4f75847e98cc99c6880d3085787903e54c63e90b60f03192234ab20cb41c70c6e82b00e0575a1bb0b0f435831c9ceb9dacd1fab8a7328eb3e28533d5bfbeace430e21758cac204631bf033752f947f78ac2bbd9423c2baf4dea22fcc65c96c332ece9abb20fed504643e82f3ba0fff213635910789a2fe1f2cedef68799fcf4a86d63ab0ccd395d6d4f393f7ee8905eb77df32d97592fb34ac86dcf20cbe5afbf9e9cff37bc34d75af046a09a1781cbf51ee2e0b0f40096d85413a30de974c4d1d16ec06c0fad00716c4e10f8dae46ef3cf27ccde74502b657d3dd26b5481d9787f5c6034083ff88807896da55fd2c951a28f15c8c9e6c86ab50c369e5ba4f6311de505c07c7b85573b5a539785820c672557cee4b58dcda948fb51c95674c23f1275b423ee5bf3a646df19bb5dfa22747857fb5c605669f334d116710bd9f1495e242bf47d6b607c1c9d9c706ee770808484ba552c978ef64daabb642a7caddf5a55facba474b8a63577ac817dc57e48ab072bc6a2cc5f5ae96edc45af41c896cecd8acfc36604db3b7fed9d2d17d429f94bd2542b194a3d3405f46c1021ecf6bb907fdfb4b53fe445d5adb18501aa772c9ba75619214384260306ab68a5ab59161b
+Ciphertext = 66c03198b3422cf3fd8291080f6fb3ebd9ad863e41cdff169becde726946a342ffa0ee547a27bae28cc782d95a90b0a618f717e3beb577354bd91e00a7a57485588265ad2dd0ab946926fea7c754c42751ec7247ee84c17262c0ed092186ec57d6044f0ac9deb21da6714ec7452e441e687e138ff144ea95636286263685419afd35f002830765d810b6f60e8dee0e6879995e9272c798b067d5f99f49e460b86d67c641f48240b61a16dc7cc27b048e8b8e8e80016470ecd2fc4225e29bb127ab48dfe7e7d5a65542176dd7ad40c07ac8b92891d595bbd7afb63fb6f9e1c2aa2fc659aa101f9b6a5c346625acec86fccf17f0d45809f3b9ee81572e5627f1afeed4ba96c6d3ed7e9232358dec01a1231ae7b94ad4675239f3b456adccec439b3cdd45504c5475bbc77dfd242e5e9671d103ba71a4601a7322e0e295357f335fa8d5651d528dda66575d106308338993e615b1c5bd7e95bf3f755ff726b4ac6dd5a43ef061ac9783f8f2804c68f66486f5844969103a36278ee0d10798bf8a802d3fee3a31294bf00ee74f087749ab3325c027d42b55b197469a5312bdc5c9b316b20093154e66605941d58f4db8d46a815c06f209c1dce2363771b5a794dd8d17e93a2fa7b194c6a0b79793c06f002638e5e3052365221232cc4b30adf161cc6e7865cf02911e2ac9b0a75f000e7ef3aa4f3c7438433513da7246d421f208b179763651f18e22a793961e5976a74744696912f22915244fcfbefdc472baee0be1e591d6503f2d9511ee1eededd9f5547c95eb94de134d0c2186109935207a23b2b8420a5858d831ed78202be855cc6b98d6663c1c52e1a0022ed7ebe0eea6b107da4cf50c1c7fced9744a914a66d4604a081587ce4b7e0f96ed408b8a9a2964314b1334a123d5184889958e6467a6d16e7615e5364e09aab75994e2758345511113321a3436db79351c63a282095ec6b99b6d775a5c09ea3f3225716e39e14df260bdefb2ecfe9a65c73ab4b3712ec842e43ccdfb535e3685fa39b4912719e67bbe195e5f0fe6c3aaada2d81b669c4565921f6c183d708b50c3f7172ba841815e9351fe5fbfe2fb1fabeb7cec9bd1dcf2d6332372f1b972b5144aa7ed6c5a985132f9a54469097e2e981b9e75a7df48fa79d0736c6f8a201c7c7d0ac8ac6512a7089514bf58442dbae0529135a7f2455e0ee5716c6610bd7600b3159197bcb20ca055695a36597bf7d3b18ecd08031b4ce3a643951e231c7ad15481e32ed7a3edd2b379c8e96d3288d5b93b562972a04f1b7e0abcc5090cb8655422cf5e9dac0b49678138faec81c78f113255eaa6110e95406a7e7417a6e221a8ec7fb9d55643bd589ace2da70fcb41722e66e0efce932cd7a34218375b6dfa3df1747953b24a41f94e50b84bad4d130d5dab4194665338e06f102f46badc5dad7aa06edb01f8a31244dceebe5e2006d6ab4a31582ff46731b19071c08ad1db79ba018687f3e6afbe703b1de26c11bc8b62fd6b2fa3219fa7190379504820abc97ff6c034f7850e2c7fd335462725db6748fe45920c213c539356b691f22eb490faca24e99f0a044a9f727d0786566ad00635983692ef324bbf1f80c42b269e9d5a8df3249873c51521c81400c729ed7a5e73995928abe94d189cddf2774f1735bc2060bb2240e558699c365dee45fa68801e6a1745e03736ced1b89fc2755565e3b36c2102594d43c451122d94f4a263664bd26b2fb5bc7700319f6b08796864f92d0fdb41710910bbc13aa9cc7baac3b48a24e4f3573f315448c317c149ddb433d9ddd2a2f0cfc81c22d3dab31f184975355b41e4b36fd8f22e8efa01d61a5cbb0e4fcdd273cdf68ac73fee745faff44d44d93c5a111aefe4a5ca8e8e7c075ffdb738cc5b6466dff78ddd837c72c54941707b04d60bc126a3a2fae9540ec2e4672ae13de0d927a7bd363f8abb5a56364d6d564df90a46df9fd59e2c54d5bcb8280415257a6976d8fb24c33330af32600cd1559e0eb05d55b34be456d434bca98252fa531486ce2a24c8bdea1d57d93a550ec586920903a39ca61cbfbce79b8f3a5b1653794872b2c614458177e748f8dfd43840e5bb0d608c26389347673fd0b005f60f52c56731ee5faec6c8d0617fb53d5f2415c2e7906ea0e6d0066354b213b3e94f4dfc311e4ec6afa7e8d1c69a63cccf8326741456a5e0bd0a359b7a37c117f7892969ad7b70cba9bea0a975ada7cf67e0d7255be8d2c6e7b8788b9ff14c5d1449d6173e07b5f9d94560d46f474ab2a67056fe9f4a9fd617a617d23143adb4e7ea35f2d5cc1398fb9ed43ddcd10f28debb27eb13533110005e6c78ca4a874db68c65081ecb8bff1b64eb1e2d7b76a1da3b375dce8a92d32a6277ed847879345717b9649f27e846a701549311c7e69a96d61df616157a114bdf1663ad93a26c28e1a62ee4a7c72bccb9785639eaf1e569decf777bb0548ad9ee36788cfa1150eee3ca3c96f09052ba2300cfb7526b9424b6f7418c27a1e9bc13e4d9868e5c330c051c3885e44714bddf7cb090fbd0f36b826aacbe191dc8c35c219e19fe736198c29dc4fa1a98b5fb1805dc29ecd02f74d4510a3928448b5ee61b5991e46644850a4885bb1ee272883faf27962430de1922d0883e7e80215cf5fe7e8f3fd0e2a49bd50727af793cb7e5b40860e80a1fbb9d5b5696bdf2f741909ab5a713de47716332df6c4f78288edcd6ea130d895fdb2f29f94635bbf2061de55f1801bd6a24294aa199d78021a1ba771c651de4bc08f032fe6ad7a5caf6a6afc6de649b901f783a0ee0fea9b803beeb0f431400d0707f159d7dc29c0c334a918fa08a653137a4a8bc86066c8800e1d171f1dbddf1fab8a3eff6b5023da96f002e7e217e826fa378b15dc8a376db30228f5d6b629f331a162d63e53e5b5bd7ff9ec098b4314285908281930ff0a8aa86a6d89411e6b5bc6b9c9e931623ccca6741fd6d36311e6a8e323a37ad40b7a2797b84694e736d9c135e52d149c760e727598726378cd674b0f4df1c361de0a12a2b8232e611d789bfbea699e8e77b99f3449609caff3d6ef7233df8cfc624376c905eea46c6f77c0b01d288868a19db77e227dbb5bfea5cc3f49d219c7477f7f2b3447b0b8efe08eab8f69579d727555e547c13ec7ae13b83386f2adf634140c311b6e2759cfb9c8aca1c32bb7c002d0f46ecc526916589a29e328ded9679c2163838f071b5b85b35e5e7d99c3c45d25bb9d37d7bafb8350ad4695a6e0cb7ea7d93868c30bb54e301e21147696b7dda156226a5ef8c62121e6b2cad0c4e192116192012468eaad46bea69a140aa3cb9056dec87c911636a1e55695b9e5a27c63cd8c03f31570d4b7507d13731ea31f082b33c6db8dd6e22282f9790be41350a96abfc4dc3de78e0a698930f540dbda3fee923a463a4c4a66bf00bb2cdd6d22b62a47af96b78b1f0f0a174e4ec5b785b3820f47d3c8cc1691d4751ce4e4ab78a4551956158a36717dc35488e890d0631241906db565603205e054815aaaaf17945c3372dfc7193369871e2e88fb84c15a2b9071101e1208177fc18397e6af17b5843e1fa75392d8d3ed214975d50f2b19c24e83f010f8c394ec1edbb1cb912e61627d2760b0e630b986bba2ae113b8f3b51ba00ddc495520274a85e6f6fa7573ac4ec6e2a86a1da9199ceb007aa6f132e5ab8ab8fdca7c829f452ff17524fec475b8f485b29fc6f0d972eea4ce98e242b5d58f6ddc1b3a71256de1c584c9914a3cf1e469f0033165d934fae68a7559011dac7a4e0c72e3b398fab8f8cc2fb67963b0f9220f410e5ba13026a27288a1d49edfaa51e8f220503fb5ec476147cbea975994fffde3ddc51bb189c470078978d238f5287fb2629d23989875d74b006a4122f6a342c996d4a244e8c5e4b804a44c301ac4d6054181a07964b279e0a44c158364395a2ead40053d2f3350ea0529a57552ed835513f533ee0c4b94ef674f31851616a4fa2d0302d13cd4aabf5f96ce28219c0b5bc0e5410fe0fa387ba1009a6f2280f9e7bbe20c33be5eb411a5f6327714b3443b4152cbc54c4012473237dd98b0490fc4228ded74afc81be2a58a22e03ca987faef5310e474f4f5a183f6b7ebede5a8df8a0f94a87a41852826b29466fd761f40b416ad0f263dd34e5497867766a361af1654c3fcd6ee7e6bb3f72d64cc980f04305b63bd574f116d1aa35b4bd642cab0cde6a29139aaa163805c6c40384313d4ec6027c891023083988c1b0d2edbdd9b1afe102fbda285a6f897efff72a0d7fc19a3cb6756cfaa2371e13be3cd167cddb90d525cba7da69608b9995cef92a6424a14df6b860ef0f09830fd7189497a432347680de0f463c0aff82df8098cc4f7753f7680c8c7374d01046b05c63be73f3a1623be778fdb0bdb90d4fb4b458af2890d15f108b0927304c91c8d62cb148c35cc93797db3ef9bba1014d89859a91da0c0a971f330600d71565d30e9c9ea8c07e7f629e1a6d578da04d37e597261cae8ab7d9a952bbf71573f1bf70e064f36c032cc624e3c980e5ea46d36232d61a57fa598347b7fb6b28401e34628b051d6ca3dea190d1d3c343fcc83175f70f77a8fc5e8791b9788989df1e37cc4881648f4fc673772003079adae55c83cf02a894b98561e4a6e4416bea3df18d6f702ad5c4f40faedec6b53cfdb5b3a52d7d43b97ee23ccfa2d30c7264ec555b15f1d9e7e19cd9890a7e8e01ff21d3b8b451e50932f189a420d18e7c7e2f103332c78c84600e5e8fdedd84f055a8b39be9a52782d47c6205c0de41644b09c0931f2da269a7e58e669f3b61ebda28ab8e3f9b83ff3d2bce37864af494860b2f01b000abeb737fbeaf8f9fa6378366606dcd0fc33031b94f9a7a0e562c08ea720a671ff92520047f69b138b4e032c3828874ec4c29e49aab302089956566372b20c0216b601c3958ed9691bbd89f1df45c6613d469e3b9758a70c860fddf768b10a6bf70237a454a2c0b70dd5d02da612a91fc5731513012a4a6fbc16d01550bdfdccaeca22bba104ccf6aeb19f21d4cdd3da231af8ec5bf2a726ee9cc7c85b8ed46d2f6fa4f1b010b2561fb69690d5a9df76d729450a6e139962bdaa2bec0254c5a252b97e7ce7eab1817f454c6121130952b8c40628065dc9b77b0f953552f5aa3ff983b6a51a51dd87c2b51a18e14adb8c80e002d0b47c61cb357babbbe3ed51d371941a8f111837ecf0e45020cb941de170c4a1b5e61bb928b1b11a8d902febd2ba016771f171b8a7ae825fcc4642d95649d53675d0027822e4ff79ffd302bfab1a0ff26f3648c7ab00c10f8d95f21e40ca2b40691bd4be79bb9ccc0bf760a05be4728bbc0a64e585207d1d09393a80d5f574442d6a933966777ab05f699c4e84aabbf753059287e7261d972745906a4fd8967bfc80ae9b6ec2ee1b22a81775f4f24999987365ae2dfb6739902ed51b9a4394fdf29f216c34567102d9db301661b09b728a79e377cf4bdfcf5c83b110a2e267abf6d40947e643ae2ff0c244af168c9f33e7685474ac30611ef95f218e0dd280899a92a41e7a759d03ce3709c2a140ebd35e199f1dbb96f7351cbe1f3de8da8c49758a49b9e724ebd3220ed6f51112944f70c0d1e9178f68a2c9476a913de00abbd1f5bcffa646f926da77a9e9fbdf81cdeaf7f9b13e843afefbca81c93614f8f1675325965b5836b8a77620a5ff162e25366718d8da7781e1a7e01fe2e9e56cf958c6273473abf5c2c8c7fb209307544e1c0726d5571e521621b18b6da3064b473423536b1b76ed75b21b4ee205d7ab5f081bada63062706bd155672dccf84614210d72660095437c6bc2213d9c904a4ba1bfda14d350fa3dce7141e817a50859b1a74aa64560b2ebc67add9f945b6e85577589817078c8ae54a9fc311593d2cbdb6692b089ee6264cebcc7719753f80e30dbe48b64fcfd1037fb9ddab69a5ff9e5898bd8aa947d9ad827c26df67c6786edcacb3478a20bded1ad8c48018ae0d439bb5afad5d39bb8fbaf22d72ffd759c4fa2e94a5a89f41358ebdc4c3aea5110f1965a049fdadff9cf703eabe9628e2680fa4e70320d304ecaed13f513f27220db1916ca1500f1c2e091671fb71329dec0bd6e310c83e67af61b8ab60ee1a8d559a508d174648b1bca451ef0ab0ee2ef74f4fcfaad1cc5ea6cadb8f1bffcb1f2c05122011ebbf6abc16838e452fc47653821589da4cb5bbac10deeea3ba0e0a6241338e64cc78d7a923d018e8b5b51c4442070e5b0e6f1e8c2b83791e930899c5897a602c401c1b85827962ff56d19c06f5af033059bc7fb1bd29b65f66aa5b4397834e846935e523b16438a42c1f990ebe4f83182163ca5fc60a4c6d77fc182e81fcda943a962e9e7f00f6399728b48bbe38d8178fae3582c8d9998e49df5f28e32d541636df3cdc8ac00df45db12da2e5e76f366c1ea8667ba5f3542d21f58ead7c55d06a4b35251b8f77dd34d3de262947379107a06d2f4891ffa0ad3a3e5bb2bbbb978af4953310d4cbe5525ab344ebb98ed24d003600de8f3af36ff3d0a7efeada963845d573685bec2221403b994f97b1e714fd7dccc300b62c2a516e9c6780983062eddde0178e93fcbb2ed4f06f60767356a11d22ca37078fda1ddb3cb907d1020f62ba85d09044574ba28aa3df36988eb8a41e4305e5b0687abe43a90e4f68f0374b6b05049aff5b065d7688cbbfb0e96ab03df38903bfa1c269f43a114085eb4596aec87ced88701b42f0b7426389727308bf10aee9d8f15ebdc411ce1e764a290a12faa2d7c1126dc7b5076f219b826ac8d380b69af7f95d69fc3929a97f5c7da1db6270e9ee1f2a5f7fa3a1b6bfcca00463655121f681d3a627d03efdf0b5fd045fb153bc4488a9a8b7264373c710ebfdb1c267fdca37723b21d5c3eaef48e784bd76e27c133cbc24d114f610c79f2a1f2c30d87ddba395887030b65097ca5566eb0361e70615b46d4b86c2759f1cc2efa3915b4cebdf51a745fb3c6cec69a1fda2ec5e884dce228e30af362815d2d8b59a14f89606bc77439042109369a9648db7d71024ed6df06c8ebd22e8623f48feea77f48b5e88827fafa84b0564151a5997b7f29c4d3d18068e34f2690a293d54003d0ea8f3bab9387ca72212cedb5f4602ad047dbffae2ab3a4cd2865bf896cd96f78b90e4017eb7e3c7092320c0a37f81dd65a5c4817a4e7053e6d2bcb23b11e09f681587f3a9361e974ad54b88c72c296629b1ab754d25be15e87c414cff975fafb3d7cb68167b21f1889685a48966705222b525fa47143b00041df94817c275d93c2550fdd82471cb3cc1b5644338060b767e807bca902c180b3e535c77be2651b3962287b6d1f6403033de4e0aa3a20615ab59d290f4b167325959c1524ef216dda2ffce86b50cb6b56b62a20a043d9d78c704479c22340151df5a1907670f8d4f8c90d93f7b5d94d04a4d383914867aa3c0e5ac85fc299a4d2801a3f80f4b0f046fb62c1c8c539a83b21c7549df0afe200537b52c80ebdbad8a438e430cf876cbbfee9ceb1bc5270577c27d53b40ac153cab377a565b1a9fbdee8bf8e94839c0fc04f7f664383bc90d56ccd1cc01b465c250b158b5e6f321c20db245602d10aab80c553d52f17282b095b5e2234c6c689a84b096112100359816cef7e92029fdfc048058f847cd2f2369ceec9fd171a0487bd7acfed6b0319832df6d59affbfd460ce8d12e4171da0f094e872a2888fe74925c5ef0621c4edad337f7006086748913b24d4d48ce36e662fefbe672b6d476456b1fbac6d80030ab93da93acb4a7e10f955547e7e20a0abcdbf909f05a2ee2e0b7485fa16be652b9d9fbfbf01f082488a81022bdb69af9e6fbe753e9eb92a1762afbb4df49f83ffc0cf03db563aa96fc5ba1af6d4d7eede6067749e8ecec79b63e09742e29e99e1c960dfb0688b0222c49ed919379ac66e3fa1c72645122d1664721e78fefdd1224c0b886f6e214e37d268ca9acab76ab3adc9f5549e5dcdbb3d31ac34ac472894d004eed71f88ca2377fcfa48d3ae43805dc612891dadd06c263ed8617194f890bcbb964f010d277ddce1f6682e661577ecd51a4d5421f00935a5b24fef0ea1809fa5c4fe9cf8c453046f61136ec8872915d2462157d73a205d56d77bb83cf16b88cadf6430c0e5397fae1f91a6a11b177bf04b065a2e55df81d5c086ec8dc8a0a660eed37d41fe4d8b3e3f22238e2a63b6e4feee1fe9a140ed37b2be4193f75c2d038aac7f6b7dad2a3b37e5b9b660615ec1db77a9b7ab416f43e66c872b71cb67c9245c757dc87723ab3b9544fdd8a16c9486e8ec3c4a44cefd98535d6e5683426c1cc8c888b8e0c2e7528bd7eb89b80d9e00969efd2f0a0fb09845426edf0d1d9a0809648e7e46ea0a8c9988bf9df475be12a72c7326c1f2bf01afafb190cf6f649133c7dc14ecf9b8c971135bd303c8894bac637e08257d45e1b68edf550d896c41682c002396e8f1eb7c1e2f4e0ed9b8b7010fc7847e6fb1c5907c17b2d2b7cd24c96f47406bd04cfcb2099d82dc2902d6f91e2f8f3a05bc62019af536309e7847fc06c10dbf7272a1509079fd16bb16a85ae2e078f97f9ce66bba66d6329c7ee70f9688f6d91aa38b25c7f4884658a72ad8cbf96d7d7a9652673273ee1b3d4d17780dfe9ca865416e318bdcbe9efd8e071fcb15ceb0743df5af4f7d598b31e38677e65af61c1109fdbb11fb11e3952e6c3ae8abc3f894ccdf205ae55dafce1dd05dca6b899877f57d712223dde4e7fdec7e0ed4f0a29ad359e318eb36ddb42fb205adca400f5b2615947c4f0ede95788093a1152d88acbbbb272750823151e245354e658452a95f21fef05bbfd98a10c1c975ad1a08c59fa3efa9fc73588407a83d0b26a53f1b4115f83780bc70ee2619d7374ca45b9e200055df1b93977e17aca89a009110a6e74caec7f86114f91975bc6e8bcdc7267ed2920cf12cd7137840628e1b8a0ea181dfef18dc5f74e752f842ea91bdce4b420ee709bca72c4514e92bcff55902e5529d77fd95f5837c8f4fffce80c813630550a0dde24092a25f65eba90790a06f4d4c3e739aaa8194a147fb32e81c71d3e8def79251c33637661b0a621a2a6b302dea00d34a9dbe9b621c1dabd0464e85241aa6712d90b4287cb23c17bf1e4d0e6dbed372e6b49c4a843305b3b0e5cab0b0964a93ad0bbc99ee711afa7f2d0a296a375fdb3176c65a957ddd9b88e9d57df736acdeb02a71b924cc2e972f51ba68a597215678573bede9ca5b3a0a2461b2d3b9ea57a5af8c91d40779bf917ded32f14a66d96e28e1415fea1e9306654c6b84d8a64243a5271c1f11590423c718961aecf5f659b49f67efa78e02ef2524d0966ebcc446d73d49ab7ec31f0c009069d14ccd63f926169291b83a3e37610054b0b964741e2ed8771d20bfa225eac0280b4d5af0c09d3218bd497a035536f5af0816884d606f1a872b8161a266466b56e0be8b80a7bde65ac706eea8cacf1749e5e71ff9fa3e69ce878427a0728d44e666eff977026abfe18cf3ad156a943b917e72ad65725a9a8d60b7b5740494fa63143a7f2a94fe6d8b319be55d6fe1a988244deb798f345f30dcafdb6af9e9cee9e35733274bdf3896750897371563ed2516c4ca6c3c3c994b48cc94b67e8129d234a0e19dabe39e500214c0ed5f0e5d61b2f58d7355d147102d93b2689bc5185dd4c0a18efd11a307b887d4d0fa84fd992731b3a80dbd027dd36cd6933766c537e8e9e27d35d5187e8276b0f59fbe7b6d629d3416b782e7981d85e1e890853c3aa94a93c1667a55044ae42badefab979fe7d525c6a180307c5ee3a9c3933038028c3e1d15d1e78fbf53b6ea61ac5e02db0161719398a31570c55f73cb47ddec8f99e3e14af5adb8d5cd179f4204d080331e75bd391b19d38eb81f148c36af3e8a3ebe76209bb75c9741a89b5d0708bb0fbb0945fc6fcd6ce142d19faf0947c338dbc8d976963281866b5216421c00cbd77c0907d1e16f5e925319cf6c62f8c6e8eff0c2f831c504e7a1c0df09a54e2af708ceef39ed7d0f63d83429e9b0920c03cf85c2244f2fbac3958847113bed577dbde8992cd91be5833c75faedd5e2005d4f7b66fab8fa9305927406f863d1795dfe04028940b765bd79de6972dc7094fe1c2503a73d7b50208835216c23aab3e47094587549fdd74bb50ae21cd1354daab632fd0907e63f4c2b2d39d7fdc4fc216bfa742b4608238623cb7fa01bd851c1e7ad5ef5215173a71f363fbb7dae8092486f4a1549e32ae53b14c1343ff7fb5e2b1487d9c594a1b56e22625d275e41535534d225b7b2c9deeb0d30dba7188cf75d680d4545ed05044a0661c690a37fa14a73ba8c68357e2c948e290b5d9a4b51822824614ef2938d19ea4b650041f59f3b548f0a305b86f55e69760f37f09dfdad62651aa5fd84eef28a4431136b34a49c9bf1f2891364f86b0aae70b0414e821e3db1533b0f1db5fd232308bf118f858aab5ae974c10583f61b283a3870eb82aaa8ea3c4e2ee3c3a3d7169aa8e975ddee7f620f6c5bcf3eaaef0101b62cd54495cb8809052c9e3151690cff7c1efcc4f63b22472111a7c5d9d7d2a2be951510f60dec8c426f14700c8630f8a14dfd359addf5d9b7ae031a745ecb4e17321b385799c90f924c4780287ac187530a40b064064b9036cc46e3f87c4d23aeeed1bc22a5411c7c503594d5d1261eb9fc4da242493beee9f671485a978a32e965faf9b0e2c13f78e31e1630b72d35b4be691e90b3798e18223c1b514b39a8e1eeb7897c22fdee1e33fc76e2b2f9298ad4fd89f44163aaab23d754d98c7890e58708b81b3832aee31aeca85e76416133710aeba0e5d9f17695e607d09ae3f94be191553bc39c6df03cefb4ee05516fc02d66c9866e4eb0d89a662e309379a347159db2e070abceee226f2b8b62847ef7c51d69c5f12eb567fa13af4b4f90b3f3d9d4b6a3f68bc4dd77075081e2e99833c18b154d0d6ac360141de2a25af61d551f10a34e03e1419a37409b4c177c51a8d248157b411868eb607c34d2daaa453a0954fade5eac45d5f21f50efba8bbc9c87ff0435c70f064b42cb2d158384fe0a4d9c90030ace7723af0a6c8faecd8f97f9850e2a489a94ebcc655301e2e14711de9eb08726638a9ddb57160c5545c152a26860a17dd18172bfac138a300f60431fc49eff18c93f71400e887f878f4dd637cf5df8c1e2b12c0f87e31ba2754ac1748479eda0c4184b528554106128320dcce349939e5e6cd3434f86dc7adfee28c008a21ddf9d0dbc87ceb14cc3afbef1e06fb3f9908a4b14f5e6c43b23ba783b75a6cbfa2ebac6533661b8c1143a34e8e2a9723389c4b7087dc07701c53b169894551084aedbb423bcce2f470881fdc7240c26b3b76fd6cfeebf8eb2828b4741e5e8698b19fa0a44703cb4e4c8ed6a7e4d6063f5fab724e08a159f4f04a2f351dcfb6335ae6697dbeca25c76b55e6ec9045eaaa8706902df492b8c8cfbf68c4cc1be5d1e5a173262e38bde051656ea85ffe35d97f1b25f6a47381bc327a946f7cbf6210adfd957b2921
+AAD = 85ddde4720659e80e25168585a354eb1e021c0b5d2ee289f2314dd5aae52bdf1fd44755bb56a6e659111a1d4b4da73315bde01c7d2c15a4f7114aefd68c141049fac27acfdca24e65c51fb1c27d307cd948e13af2963166bbc9411401d124f1ddf20f890db5611385257f52aa05c09b467e3ae886decf5744ec3749e5879f2a60017f601bbee11a66604d5f3d521d2c48cea1794f77366f29c7bd12a8aa51d34a4f3fb52809561b527016bc6badf9d136156c330e1d69d1aab98c7caa9cb46e782a898b4c66e4ee3e2445fbfacaadf9a8f73c4cbcb2a1ceb604ba5637b51337fcbe0fc366da98e805ceeb29feaf05420113b16e1005079c0e88af33f5970b3d7a8b51d0d9f5120a0795063db508171b75ed07705ac6d6bfe4ecc59243091d48865536515e036860affa880bfc91aae2fd1700de15994792aefc4a176e5d49d0f9135c7d670f3cb8798bfbe83fe73de7427e0f3e6a2df561cfa15ffe6ae80d5016096c8875b0beac8cee8fb530fb421b9a8ada4d551a528d0a0b521086f5a2db371a3bf12a2ef861f831fcb44cb2baede907a9306d3e5a3af796e0a50ba2c8dd61fb03727df5f0654d837dabee2fd90eecb7b2e8f303b0d57f97dc6a52d8281574d8457c89c6a9f5d80e0bd86c90ed39b1db4253affee614e8cf1ff05166c66e7d2a2aa2fe8a81c4741339683debe189c126e7f553a5f2dc16fc16672f74aebf94c7e3041c758fbc6d0c7f71c192cfd0fb2ec52d0a0705b05815d567f3d19f9b5d553a2adce9a79159b0e38980851bf64e97f896c028a6df8363cf1f13f4654265a7b0c0b24198efcf4418c32772bafd3980dbc689fab12e85b3ef4a491e2e5ffaa2fadaaf3deb392105a42380797d3b41ef61303a6016b269ec9a9f6e3f26070ff33cb467435ecb325dc7e18728a5c2e882e720c8f876fef10f5bffd5a925cdc9689d934272019e90e3a3bbf63a295f207faa5c014e1517c7d5c18c3ed70e92304d51944dcd3604c999d4aa8d8dbf2a4c69cbbc08635c968a20dcb80f438d43c57851c4cafec0b9568dd6c19932fd3f1294afd16f019f20e40ec87f6f5dffc7717470614b2de6e9000969e6b7e561cf91c06dd379a09c6c25c7841330dc78fc5be1d9b86581a81f55c0289531128638441fc98a1ad9472d74e2be2f874aff2fcf9c941502f59f716185a4c39289ca368c6dbf5257b5dc5e57a420792c26e602e4ecbc4f17c8787004eb88ea091d6b6ddc3c85dc110b5d1f46f6e1d872723176f4c73664ecb4219258fedce19ae22360354fa4894fe51d69434c2e58e1ec665b5cc33bb295053c591b474b6ae178c8834667bef971604279440170ebf3e739a4ff19704e5886767f81edce95a3dd93d1147995e7eb6c794b7be136658ed23cec7c374705ec0d8479dfb44cc7213076668e5fbe6a508537a9157815c6e5187b89f
+Tag = 469e3ef168a64945f76d7a2013f27b68
+
Cipher = AES-256-GCM
Key = 0000000000000000000000000000000000000000000000000000000000000000
IV = 000000000000000000000000
@@ -384,6 +392,14 @@ Ciphertext = cec189d0e8419b90fb16d555
Tag = 32893832a8d609224d77c2e56a922282
AAD =
+Cipher = AES-256-GCM
+Key = 53a6f0d9b8a81818f2fd7525acd65acbaac82684cda4fd357b1ceb6146b31ee4
+IV = 05d8a92b5a510c3a3dacbbc0
+Plaintext = ac0ae17d3d0ee5935e18675c36d9e43967f6da38dddec14c7ec574ff8473e11ae5019e638232323c175b7672a7462df6709f5014bbe12a1370a1ffb570177927106f995dc8f35bd6e6228de7c16acb71e583c87477dcc7b17a908ce01543496c2cab8a14a21c43b18fab52d8a882dd1d999b4275db34c7f32bcba624d128580d7566a2da4bcfcc4136d58816c437d21e90456fc86381b946b8955f0448e83564165a629cb2edb978e5941010ee9153b054ee429b315058334ad7899aacedbc0bf423de69f57c633b56033c6531dde29258694045c46a797987471ae6af8fee8ad0c1be4149605064aaebafd1c5592e61beca9b5c7771410a276c3ae517490735ddd6af499ff705b9fa68d50650e60c19f5ae2c88dbb6d612afc7be28a5f55556a2163b6f66609f7d9ba7e97c074ea39a618727421fbfbb6453ffeefa643decf11404764515d28fce8ba66b8c85d077c47a54125a38bcb6b0adf6d248ba0a9ea129c887c66ef537c45e9fd3c17ce352e3936cf139e13a5946a7dc9dcb6423ca6a051bf560cfc572ef366940e71c81aa302cb9701f9a5206e9eacfe9835bdacb6425d058022a27fe73e5edeeba98c7a3edb761578ab2ad5a442c2dc1cb3c143c6f18dbe525fedd2a9cee0ada3b2c116465c5cca9a7e5d4374b29aa4ad8adaff8d6b0d1ac3990685240ce022faaa07241f9ff445566b9e0463350792cadcafd5fdf5c37706c0025b3c627185b356d39dcb2244b15566e6e3f8942f730fd6d855daa1456fe294f9156c4b5131e5bde7f2d938ceb6c7f5deb0f847a98b7fd11a3f5d0163eef9bbeb83cfc96dd8eedd447901ff4d3a35c0ea1f691b01385eb39fd265f756bbd77bb61b1741db0502947b4b985382a08a5916da809a8afd3fb1d78d9e16f8e37f51aba100d031d9da8613e9cd2cc621025b47150b3e76775ab23412d74334bcd79746cf601407481310a923047ac68a4e6a7f7b96bcd85bb6f24e38f03c80ad41a0a581b4246ea4715ee561cdc5384a51a6fc9ed8569ba6b12bcd95e6202ecf834dd9062ec539cc8cc4ed64ab9ff85998da0e63161e7391b14de47dfde41523b6c614618bf2fd1edd68a5de1c03c4181569b6c361d955c637abbf4efdb5dbf2f0dd2544329c44b77081a48f53231fa9d4cf6f2186427e469d0cfbcd698f7e7cf773240dd2b807a2fe699f0ceb4a2339e9cde01114b2aa5c3591a82a3a27b308e1e7f092af8ad97bbe7b28d78ecd80c0c0a28372193d66bdbadc0b58e4d5408acace53bd5e12101fcb25754f8c545340fbbd1328287044a29d18f40a24b4084febebe228b67cefd970df6d44ffdc033a50534e5977bda660c589c6e3c3a28b4c500b29ff4a1c3eaefb068784a29914ecab7868a43999833b0b37ae79afe58875a0425262e0ec7e10ee8a6bc1c97d332bc2a6195de239a166486a3c1ad8de3a026e5b1757f9a778a511024a260c9809ae3b22d78f18ac483281a796b1ccbfe7a9b9f357d12d340e20bdf2037e8bb91ef858cdf2eb9d7161a756d8c244c55524f8f5be2e4f18641bc4c2409c14816846c4655be716276d8356e516640da49e8412fcfc7ac0e084a079129b23e54952d8030e1f8ceaafcd322dfb4bd189bb5d940ac83231de0585783387d0642a245183f7a251779bdb12c63e9edbf3d0c94281140598fea9e73e951ce650c984cfb1398f8813abf8f8827af5eb64a65dfd1305bccc45086438ac439a9265790fb225c509ce3c9d39e25d2276d7f3c06d7cc28d33b2c21bb38b50dca5b10afc09da83ba12ee878e0f6054e8d3e78d731671de4f9d5a7b97298b01f37c7e78e5fcf5188554bcf5d42559d3b15153bb3cd5a0d1cc4a96d02ae8b1b115d1ff617b6ad894ce0585f46a2a5f4cc1b83065c1d7b5d2f25f3f4bf9966b4c7d7156931861d5edd199c126f1ee4ff6345023419d0a4c87f3388fcfbecbb6c1e2f4745922b88085d21d4551e4c127eb423db87a51c9f9a140f8a7415dbd70c4b0173e687a40f895404f2203e14ccd61e0e5b0d5aa3fbd1c8affb5807d787d840916ece24c56c50d3d9ed9f19d73f2c80c461b5b3c07dedcdb41402c3826a958d74be48382dc741dcf3e0eb8955397da33941fc47288147736d778914a57effbafccd4cf293e6ed1c7d19b55433bc0363e41546b3638a4c630eb35dc6a074f90185cb9daaa6eab54825a4daf76f49ad918e90e5777a826d6d5d52f32f7ceaf818f87251ab4d1b5406ae94e41cc97fe022b144f26335829d9c81725b3daead621a0df71313d18214ff8dc687a7ab86b8eec3070ee1ca9f62005a0cc15ca6e2f4fd893de8fd91f6210f6c96a576024678535c962a2dab06f56be377dfa74bca089adb7327abd05c3ad7646b5e9e6fc2f29916b34c8642f3c0caedb53b8f30c2a77d1757103b7ed156cdc703911366b02cde87ce7343886987f7a8c028921a7b87c5c0aca7ada34970a6d0d32eb1b177ed8e64c1fc6839b9d08acec19560bf4a815ca6187635f0cabb8bf062e8216d3b09b7abd99e956734129e16a7c4f3beb850fe2b1548729355f9015c9bba336d3e26a27b3d75d75722f7a8170d15ebf77f325c97778a5a9d7c76d3e101eeae354e54e6fa60b58cbdd900751854ede326b58fa5caca073c630f3719d6f52afe675f10d464e8b58e5fde75a4f225063ca48d76efd1b645e4bc89d98215beae765601f635a3bc8cfc08d74722f3d95ccb4cb4e3ea977d0c534a4abb866fb9a31771222cfd998231c30bd16b6844ef71038b67d72c910cca40db7260dff0b74162449a9e2cf15d7dfbfb3a685080e6c83ff4341c95819c0317502ed49af7ae688b52c9866518f74d69b4144500ab9d5a0829b9287d5fb67b78801119ddae7a76e80be8c4dbcec7866ffa7d081406e51cf617be061530b539cca7e1ef9118cc06e8eb2a01425b45947a1d2332e360acd0654bba8f1fa43ece68467690d36f6802a32f03f9ea056e57fd548dd4a3225ad5006c6c931aef1990639498dc88a23895ff1f75520a8009dbde4debc20ecc546e378eb7ed5ea3740d2244036588471d96e4751390b6b76b39816d853944cb5677b493b36de9736ba0fa404ad4b3a7d7c54d0c15072c040064b871401b25b88559d059a9519c7e2446b0d110a4aba9c12555e5f620680d1fea2359bc85cd15b5c0bfd6b3715d647514118cd60483dbc9c83e285192108f4ea6bcbee1f0935044610c68d052ccaba23258d09465d5521e2664d59358621ebbb8f28a4627362c8397f0a9852e5d8daf53a961d4ee66299e2b54d8adf5134ceedef57011f810aea76262422236c3e1a478a759584c7880fb3f32389c4bd4b637caad7b2bd6fd295aefb150754799434e99e0fd45c1cc4698ab14d1f63eeb06e53797cbdddd45e7f87e85b45a3dd0df6335c3b1addee87ba953bde29ed98042d745c1465a967ef922993798966e1c8b96ad6f68404136be0caa2264e24d8d93aa1b99da9316c7780904753d4e0b45cf282b43a0c91bc9ff83cb25cacea2ea72563b2e759b69cabbb6a50d6a0a5ba545622e5ce576cc301ba35afadbfd1e26668782e1d741feed8aae894b564a425141442fb8470b325cf7c8e1552973463bf4e67a2ad58d15417e418bb91d2df4b1310a0a70ac744bbb4245efd2ae642609079a44cbf6be19809a5ff7ad6847432368c9749cfb336ddcc0e6f52a699b910cd24671f38af5dc39268a3c87771f07d53bf220b7c2d5058cc7b0bcd492abfedf9bb295ec304107130f0e98dacaac6dab998b511f176d48daeb81db53643ad194690b6e28c5ed2927e09a1e959c494b90db401681f67bf1e23fe9ef4c903f666ef39332a91a25c63efe9bc518e9aff61842007dda72dcc0264aa47543c0a8b1f0d25749ddfbed487282241140d4c64def1831c4d75ca975fdb03258ddd013445e08bfb479a516b011fe3a12e4bfca439407c0022889e46914cd41a4d92a25eaa57a55bc7337e5fbbd11584dca34adb5643105c8171e53cf04b1412c3107e72330ebf1b52f524b4e72570cfdc0ab179991f3782d05091ea57b1a233048bf062e88939cfeefb61e8beaa90395faf61c4d974b23723a4a5cd39d70f92620f8f4f27bc99ca67bed7fb6e594913991ca3025480ad791bc94a0def36fca491a206440ec31e32bb85850c3606c875708309be63c2b4f5c477521aa08e1d059cedaafe4fbef5523b79f88b57d0c81bbdd09202095f10f13e2609e833ff41b862b2214c22e8f2b04a363b38d26bf95c07b184b9f909ad3a92122e158d3566d2204b22d4f2f3ce11a65544ccecb01a4a5ef62bc969fddcb648224a5c7bd94f8da9a7d4df393d880f537a377888874c19dad357a0564d303a5c1485c1451ea55d68779dc0c11c7c38025660684ba3f70cbbab00d15b34c0f2342207ad548eacb32ebad95292e85211a8669b586d05b0d0b9f278a35ea4d78e97fd5dafca6b72d8e1fbf3e704a60a8ec60befe2e3e4d3d37f9d33a0feb88add59f0171ddeba0b79a52feb9a1f4a7a6ee7c6927bd10968fba788a807409346a0fccd4f7daac3c8591fc689aed881829d479e8d360cdb5819d5eac718a6f860f2d9ef6a0d36ef6e10efbb37819bb7b03ab7649173447b2cd47f3433a2422b1611dff91cee0b10c6d060d4e84a9e3f4dc194514cb67f1e3985be05c845fc92b41955d0f61aeba6268789998bbf341a8b37af48f07b13a676a11d27330529cabcd52365842be559857cbc2a63a4ea1c77fa8619040e79705c5b51f473e13b73fc09c28598e070dbbb63ce884c2843ec365d4c5bebbf815ee3314dde0bab6b0a71a398e2d9ee8ba2f832863fae7eb0c18adcdd17f1dee0df29a8409acabf516c8e6dfea5a264c1c6657f774c86a14cf96eecac18a41b1650a9e652c6c9264b03aa2fd30e333a9f24cd6b0313358e3c00943a1de63ca970b7da2cb8a0fd1109cefbf12176f5dfb59457480428b194e88449bffd8b8d87d05d30f9ffe9ac3a7442b0df3418acf9165b14242489a54b6b47ea543fed5de74a00f61ab2af553b60d8d21c76c42052c72e4841bd94cf88185c39287c04d05f6336ae581cf7528a59b2874795caca79f5600ac64ad5820a91c711ae5a1c3762028242c5c8a9aae89177ec4db5785cd07402d45805a2e2e970059e4e6483074df1bcc01f57470fb66f45ab475ebb5343b727168e355a6c25d42384e39802d7b4a8c54ac94d82de12f8de13630ec8c19f008f98c505dbbfb21b363472e23d0147d1ac555f0981e2bfd07c62d097acf930094dcf239a40699421b207ac2575b7edf9b1d772ab066362820c182c2c5097a47d1dd25ca9e0dd9c3ae94e9a8f0dece74cdeeec3a17803d5e11f037820ea20364234079286a7c291f3424292b0eec3e956513cc6b078a76a3b8ab42c5fb5efdcea1d438f7ae08507275b48f9588a15be763ad094885269efa7330f6fc9d4746997c98d9f5feeb6dff2734d75afc6a11196b35bb9fd0c0af428cacef0df2c5ad4e5fb4559f0f93af2fafad6fb77f453238f409ec71a912350d7b62952e4858927f620d31569242615345265ff1cbbd7fdfaff35a45732628da663bfff3d3af3d7b537337754554458a2d1af0e16aa8ad9436096f42e243109cad32fac1adc58d714cd3d0d8483c783006991f3da263ef5ae1ff2ea06584e45849d64a07170675c29f0b2abcf1eedbb63b6f5d9dba600996c7d5edce9ac69448d05c0704fb9f84e831b60c376b8a5d33ea22030e2dd3dd421d8e0a810a77c085a3861fcba214a8baf592d624d673fb34f906581d923d80b06186db8ce5fbef2bb750166f7556adfe93d4951a825d55b0bf92c9f25776df784f6aec808ae221cc98d05ce988fe6a13ff96083dba15500e149409b54345274e3633fa8f6685d6fed40c20a5c5705f8b37099a5949846ca15def5a6a427eb4eec72747f116366adcb9b74d3de0b125bdee23ca98ee6312f41fa3d9bba43a8d343552c969c41f766ab4341a42ec4cd6f4d1d4c4b1f16979e5389fea36a150580418d95520506fe0cb1a1d861e09d21c57d88c46e10a3c5ad1aedc8f2743f5c06f10d6da9b2bb3ec783c6f5788ce9400795022cdcec197f9dd3ee4cd26531e7f057b6d9418a0c52ecdb35a24a2a079b3d396017feca8b31aa55e3d5ef79c9ea9ccc7e3d0b47f28f273276666fa1763b3a452672fedc94557d984c3353344a8bc9fc833dee685e33d63540d0801d8068cf66cc48ddcb0d42cec881eae36fc2614f96ad67fceb5c98ec33fbade0e3049178d503c13c2d5d71f32f4582d1cb0f47a2ace578b903796768a906998bed2995798251d7eb92faacc19255bf12c0024a94971c185841113faa288beb7e58d4a98289630fb3d230f936eb1b9d9c7b94b5ac9d3a211c0b454a26e29bdffb522548a65e8dde3730918fdf0575245e71ba013ce08f6e698342a61a81b1355d2483e97c06462cae1cdc7787f4bcee4396a08dac9c14981f2a8f4614a31b019c83782d5d8370acf9db467d9d95e8efbe44274fefde5860c2333cf81593a2ada9f5bb6c2362ba97fd7c3e5bc836c327c66b57c0f023efc0c0ff6feae0e625df2f4e21057060170c844c86412700d7d337b1f7835a0dafee5206cbd76104c5a36623c7783213f8dd457b5e69a86b74030a27b3c30074242b1d97e65a233885a681ec5a8532bce9dca1998dc32c6b40dd997b99a6ed6288e0b9b09447e356bc5345b2133571e65d47db2c736a391970879103d4137cab6c0724b8e67064167cd5521f32135fb6ca43c1e118adcded8227c9dbfdc18cdce154108eba5d8c60e5362e8fffc5c9ae6ac2572188617e4ce0f432e2476c74a4227af64b58e0ebafaf0b1ce01723ecd36a2a4167b7991e28b6a9e81992fcaf7b4b906d0361add02104db83914f28baea26b50561faa46293ba5247e8263ac0347509c36405747866d2fa2beef44f366108f6a4047e282a477c28654511075ddfaad9b9844e18e67320a831e647d923b2720d65ddd9ece165c222231d3c3e7f0001d15e3c690e9831ceb369a8edf183133814bfd20dd25d50973bda58ad03c4cbda8008556fc653ef401ff76ee858c1f79a0b09b4232768e72dd06e42078923d5647cb310bb644feb24d6b7e9d1167c3676cd96f79965a066aca314089db60bdc40c2be4b69c569ec76b3bb74a43fe731bc869c9222ab5404304a513d4f7d2ec5af278f7c3d664fcde579bba7bd472bdc00a1eb4c46ff69fb7e45e5712919e8656a8887afa28cadd66461fc57f53d574c92105818a89f210d7e8aee6de2e78228b2cb03b850a6e77627f70f51bb919bddf61837a978dd4cec2db138c657214ac07b67134bd53b071e2bffa3608a0b0bac88b0ddcfc1ba4dea17191c9ad76ab8de72118893256a7e13e15a3bf98bb5757a78c58328cc4b380f3786f22c6be81884d213ec3cc2784583a47a4003a59ebea08bd06e290a892c937448e664dac672942b068b839593c442f6e1d22875e01859cd24c17d108696a3196ea4794ddfdf25721d3dd3e754d1ea884e5086479819452991403a39014297fcc734e56f8daae4d49d5c47016fc3ead550783df895542229ff3b034b5b722ae2a2b04ba70e42c174e9ddb89ffa60024aa16f297ac9383b2ccad53de4bbe4ea2fa3fe3d059d16b4b4fe9959ba3c4e58922e7fa2673f50be5b636ee7c79b445471ddf5b851ec3ac505980bb184c8fe44c7776ae9aab4e66ce31fe1bc00efced390a82f96b4866e31ba3ff832a25b1e1d00ec44bf525ae523b7102ba60c1d3a2e2bed004524afc90a064b325a258eb36315b1496c748f5407e922914787acb8b47bdc495e521518e0637eac4b1b4fe1adede145181ec7ef038d48c473d6f296b349d7cf874d329c71f272883eb7e77ff303957e159fd417d5055d82687448950dd149e1074a1785518ebaf7ac167e07f1f559893a20d133b59aa294efebdae1e19a30ec9a3e257203eb9a854096395825ef4d1e4ecf1f8daeadfa049ea6c435c50d67fd21c6f6b11a8be46502f0dda1715f5349df5330454316498660b7996432e679c73f1af33e529ac669496bde538890cc093122842e3e2e4bff937708dd4b1b1d3fc066a63824266461e4af9245032d690aac0ea5636c29606473820ee57b112e2bd68c0ce1936b7e76a7873cad678b26b560d7bb10a7dcad3f69bbf226faf2f572c105741a121fa1c55ff30b2d0b7339ed9aa4c9a3671e6e4b572800afcbc8764b16f0a61c4c1ff24c3b64992cd84f39d1a4d5532a7dbd9f7bc847258a33c509a945e53236cbc46b61fc6fad662c523eef0c1eaa4bc0a49610c8d09659e7bdfa858d2494dc3da0a54fcce229951d366fd17f4120f27ac77e5e6b777693641a853eacec09cc4dc08ff6ba22295acec61c5e6215eaf2a3a012461eaade8faa9cba630c5ce2bee6f1a4676d54b4a38b7b5cfb6c98106a4882ed88153a4f0bad3e0f3d04dc1ae5318e3b8f4ab1d122a548eed47f70edad1a164a9c5c3eb10fdecb24b0b68005b2e958980481834c4f673478d3f47d07836d3c1c513dd920042381f70f1a68671acee2fdd453a7552eba497af27127999a13a33104f0086390e01635d1a0b79d92dd43211c74047804e82d9ab26f97ee88e664871dab52a2a79443e39f06a6e8ac9d5e986252529b389d9ed0b2f55fb16ca65f6e90cc9a149065f499630f973996c1e2b6c53f2ab391b7d78cc6926b1684d066a3a74b86b3b633baaf3730acd28deaf18fb926e1ec9c1f8a2345103cc4cbec05345db57c5adcf062412f289607f5fa41194f69bc2f426a30c7a6f8d1027ee8dc96c9957e90fbd9b16475b82dfd8698195159bd7b4860004beb1fa85e6843eca1acbbb0b8c7ec0b865ed108e297a2d5f915304167e18d01e51497e6e3ea76ae99bcb849f7595fa74c2a6263e2bef65f1063bce05483980ed51eac5289307117f17e99d761337e9b1fb625a1b900e6179f3b02de57a0b5f52352298c8a2d2c816182ec169d2b9c0490097ad98e2edc99c6df683a4b5b6eb73ccee0aaf07e8cf8f2f632381ac407c5c578bc1c5a8d0915dc231b01b92dbd25c2bfd412995780582793736572f1e23ef690bfe6872c2572285cd737a4be91f4dcafef09232de77b315d73f5beb23d03625e031d2438081222b063c343f52565ae314ac47a4fe518b45d0c12f2ceabc5e05c20f607b97035afbe0e29249e47961d9cf9b385c065966b0c7ea91cfa9ed1b55a58b9aaa9de080ca05c6405fdf15bcef74177226eb225a47d532bcbc82a5ffed7fd86c2609b146d86f566d0b84f638d46d6eb696bfbbc62c4fc981a94c1d6ccb9f3f7ed7976ea7e8ff1d2a2d79986fb27f1401f25d5a83f64844fa9e839fc8855007b417b261d325b6e7cb124b27ede8ad18d2b6da8bfc4d4f50c3960d5a1c82e4557b16d05471602d2a31462e4bac9535c9a57389ae0613a674815c2ec10c19f529c9274896dfe49ab06889da517d482145ed8f57ba4b7c0434ce24090ef2459682a4f6342ecc382b4cd3409c3415bcb7f1bbaadfb7ec308eea8b6cb2912469b707c99a55c1754db0650616754735b85a41433a30b28e3946754f90caeb03c7579fc9982e6ec5501d6f23e0f2b6392acc435907d79ea11eb6955723a81c4f02bfc78e2eeb1d0408f8f06b4d2f6d20d90f7698c4e58bcfa993884424f8fcb602ef35d23737fb6aff220927e28c19043ae708fd9755256a8a1660d9c5827bab1b836a10aa23aea9c92fa3b25428b3791c5d25f3f1b63befd5480ac4192c966350edceea8938ecc608e0f063d16d427049ad62625f5177470e7a0d811e8d4273aea8f7377d51db07fc34d9f18497a0c2b5c0bc5e8778e06bf7460f0487eed54d661d74346eeada9090957159b86f8b68183e33d0c3fc134d87e068badd8789d4c7adb829fe08e4558bada5ef3f526afb2c7b6184244af0d07aa5cb525c519ed32298bb6241d900ead0532b0b1fc77a6577963e7a44627ed326741af254ab957ca0298a74323d2ee4f1bca70e20ff796491424e108e03c20f2eed7374c0aa2474a91f3ced6f46165c886a510734d606ceaa08822bfced69def33cea3662512fb42ecefee341d1b499b826ad882542374b032e907a7e6a4dddc4620a5d1002b5aee25711fd2dd6e9d4e90ee350f2889d6c1f4328e4b711fc919ef3c655311637b83b4eff39c157e0510807ec61714b843bc9eb22a0f4dac7e5cc07b8e9ed587b701d9aca2a239e76ac9a16338b74d50578956e06b1ac35ee3b822ca779922d89de7d915afd7d80831e8534b8f8a2eaed252fd862abc99aadde62d4520d9a7c3c3da86081fc36927de60e3479096a2b5025b9a789da01da969cfb0ab2f252c82db9e6663dce3888146b365080f649cf94f991312817147d8f0d1774d8d44ba4afd846060df2de1d1043659c3b94b1eff51fff84e5a81a0c635aedcf677285e0d722e3335449fd0f49a41264fb963ea5bba31dae469c789047812071d8853291fd8003cc31a8968ce7acb68a6e0172ba6ee0e9dedbebeb62143047336c5a91c77085afb01fc075938b306d7e36383ecdfda55b9b5dfdab53aa34000289c398f617a146c4a06404737600484d8d4ea960061ec2cb575dc485f65f275540d0ce7550da08417632b6f0f7d044f6f719ff839aa3e5c9db94d45225a1cf0bdb0c5bffa781572ad605ad37aa988240858c9493dee9f00ed281e93532d89aba5e9e59ec430cdd5edfdfc2ef65e094eeab71cc40b59c997943a0e0dbbc80f1e11834bf3b53153ba1c1f0ccf63b3c802439b2ef1430be6994300d9b2efe4b84e25bd3bf8a566d4851e7fff57cada544d722438e8980a31563ef0558fdd8db9bdd6f1a3e34f06104b680f63c1f80a08ec6ed74bca69bb1023fe63d24c7e7a14ce85db6e21173f2ddf14f233f3787a37e4b347e4d64907fc0a23c3da017c81c27df9fafd4695886d0ddec8c47982912eceef886ab5680a130bfacbf3c67bb4f0cc118274bdfed43bbc2ba56f048d6a390e48932469b30ac84fdfc2e812f32d00a85349bb22f2d8091e64282fca1b40811db756059de5d03861d6a22cfc6289097d23c26c5e3f000f9b34a0e1b28a1269d8673d09107b29ccaa1adc8939bdca312c69ae4a238f45410d8f1b27392d594ceea2a6b42899ee5c5857965b29bea1bc413da618899b1894f2adff3b3a7b05a626e50e42379f5d0e0a148ded33d815f59d1401b197a85656466eaf88ed30d1ad4a87985570291efbb3a2c6f22c0b111e65c843ca3c6179e94335f0f91d4696e1a31107948a042f55f264c32a35e719668483957c9c8e13fd01e5f751870a509f5f06ba41ad63cbd5f706f25b1e598f6c9709ee6bab627211bc38494962e930779ed4ea2a8471d309c4c4f0603238959cb13476b673489696c87ad9da5fef0d6467145a77ae0b1089c8626988278a85be3292680d9d7e4c6866f19b78595d611f15f9a5e37b3d145d5aff4a5b58a3286bd25a862904817afe8e9b9105584af15f54554ca5e7dceaa0fbd1111aae126d74f68bb6f0ce98094dc9a59a31d9526729efa171beda9ac5b7db9118aa94b9b5ad58dc20ae1c328e31269244d636139
+Ciphertext = d248b9e47c303f735b0d29f6111a742d93509ae051466688d56b587104a74fab1b259da64475fc0d2c3e28d87ca4edfeaa5715c23dc0e5281eb0c0c14e22182bb02f9f7d3c24555cd6a3ff766c774e67730a920db5f85d47dc23bbbee460f0922cd7ddba81ccbe727b4b489e79a19db2d012dad2a732273dafabc0fbded3c47dbe5b6b585570c39eb62850dc47f4aa0c29bf5fadf334041fdd4658fa6cc29a81192a53dcf47c03ddca9d03b33b06e5b3808be77925b7e7d8cf51fa939e023161d969f92430917d73f3aa10b83d5b7402410280561a27c376ce0b5151a51be2ef4eb9057eed25a0715436233615dcad1559fdbd81042544441857cdf46d72f5f50ee552cfd3bf166c530e57fd97f34e2e71bff8a90b30b4c4cc3e843b0f06e4eb2ff82675e428f5303aa9141dbeb615cf6aca5540fd7cb756fe5f9b08a4abdc6eb90b2eaef51c21eb9ae79a0e44b0755b3ed48f5e6e57f3148ce02501528dd3dd2b0bbec2650710a183e38510990002ce6498dc5ce7bf33d699dd18b66c0f8031d958b11d678674c355a635f4b5e8d863785f5dc2f99eba9ce74595493c017697344b651dcc2a0b1d5386b73abd8bb2dc77a2d92173d3688d0d704da9e44a6385af9fb3a81db68822b1eac9ab284f0155c20f6bc34af85d8518d0dfd32fdaece1379abca339a00e1326b624b3e4050be5db8dced5e6c4b88b82b6ee2a48c373d236ea3565ecc072e953ffe01b624c6ecbf534678aad9c3f8a07d7dd7232134b6b397d0c96ab5f795f9e3af65b96e7a765283d8081dab9f953113abe06e8d150bf9a8416d8932fac17b032dc346be43736dbf066ed239328803510f6f62bc8abc92f6df9a82c02cbf85de91739bc8d7805d392341be99798079419540dc952fa0d3ceca4b806ab1db3b717f0d720038343465a8bc0da8e8964e58634e8a2d6c99230af2ac7c89acd3f86a22075dc40818028f3c632b36a39c0e064e3ca2a078c617a3e73aaea56ef11114f9efaac90a3ec8f8d9b18921a80d74b09ada83efee127f41179dc6c19c7965f3e7f43e22f636534b123e9246172f9920f253d2a2652a5e8c337ff93b2d479bef5e96e972a9b9cd8af057c750bd711010d59ce065ad50fdd487b5dde616301d0ae6373b6f9efae99d8972f242dd7a6bc61caee70201869be202fd384a992478dfc133b84171f013244c5d17585934aed3b43b818926246227d255bf832ff481f5f8d074ab159a11d6d17ed0ac50f727b870db966e0373bd3b1eecbf9ed66aa66caf33ac57cffe4ac6df3cf7b0e54ac54be4f3d50f61b33557c2990c908a710c85000ef6fa62716960daf918ae3d81ee60b3813e65673bd911ce468510bd230b9c2d215afe86ec12e49e0ae87e4235baf3df237188f5e0af2e61c22a4bf77190dd5dc804b4cc330b360c3dc093ef208c37d299ea0cd2ba906084011e16ac5f4fc9646538d5b538a99546d34a4599c8529c1524fc4b394d6a9cd762855905233ed92e72c8b538372ffe2f0df7085eb074616c7e695d7de40779e384d5fdb49fe02385424ea991dc05c6ae813f76c673eb45d6105bcdcfdbf04dcdd20caa6e30efcf3537bcf72947e1ac37d1e8c600ba9238569a4b3afa590d61acceb2572da85885146a142c8f8c60afe4d53ee4d61f33c47e5a99da9a346bcfbd013754ef39a4d7f16c4c5fbfa53d7f180c16e2b64f97dcfd65349939b5fc167c7a78926f638f1893fe9a81e897beea3258a4175d14f41dc123ddd846e45a87f35154db8a5ac27c7a0fc95d3b3113cfa9e7c828f83a1f0d91ab7789c33be5f55ecbb8eb0c81bcc0fccc880011b21000e2f10773388b198ce79c5d694472d3ef6b2e55c342b29c70e4f33fe59e2e0bd3f9ef617733dd3329a0e426338d9c007bcdd382522cb96e59b223825a39b01b52809f5e8518f64b81c99022d8215b5c435d87cc1a57bd440b31a19b197b277b2072968595ccd64c135ae1b218046e27a7f2685d013ce3173efd07586dc72a28ac4792e804d44f9efd785ef005213df928560a20daa4c24ab07f081479270a0dcee3c26331c48a164e4b9d79a7c30c77ab06b00e9b72c190d35fb873bc095d5e6231a89b52a0737a99532079bcc72ee221b48f0d0d9ba9105f981beb4225f6efc1230d6da10fd2b58a65112a98e4bbbe1accd6e8589eb6d9c771bb911cccf42aa6cbc68d1976f0da7eff1e70277e8c5f83734ec1efb2b00708fef08e986bd6519a0fa4b5772e585ac8e37fd2a2af07aa382579498b3b75863fe792461492b8e71c4a1a2f4421705696a96601317cfff1632784b5d75fc2036ed3fa650354620781b9fcfd53f1927223fa045edf4abe7b2144512f3e3aee99f7ac3e46028bc2427aeb18e9cb40db57b696ea884658abc9b7bae0d8117f93074a3ef903528f8b55c7687cf9f0119a1f246cc9e993219c6384359e7e5e639bb294b264048060224ae168d7b9f1f795c07eaafcddb10b61ac2be3ab3e1fddf75c1f47559f38d24f0c773d0e8bc5fa85d7d33e3aa8d0f15583b8c1e7aab6f5d0e085b7175678bf11cfee8eb069b78220377819e3f4d28eb833d3d21efff543d5c6357fffb4a8fdd6ce399fca42e2d71c53c50f6b20bcbaa1650b57ff483837c39a37d5e978393c332b43021508b8ef27773164d69d0af3c0dfdc125cf30a7c49a7d8e5320d68a35e80cdfd62a0b7ce6a412f08c8062e35265fad5d1f226d590e9b068d09e48772711d7dbd786a38c0325b3d5665c2ff45ad0a20c174dc5739896ac727b34f11c7af299d36d30c69bbdc35770138cf891cfdd8123489fdef2dfaffa9c2548ebd60b0f0bcedff44691979b4e92b364753120364dc2e3b895095da828e8659575a85cca587ba05ca625480f977a6fe10181ab6ce005defbcd8894f8c71811909cd6b56eb7ffe327f46793a9e98bd7fe8951400276bb9c7607f8ba1e633034b73d7f0d040197c3f346394eba68c8accccefe05f59cb7ea9ab1ae2e172d8f466ee21c6531cec2c9dfeebc477a6d98195c28bccc1d5e23ae50e3a1ddd7de189e36ffe0e387df7be43427b194b16e18b42eacd517bba78edc9f56a2c7e89e6f13513718869da7c8c529bc337217a69e14e35cf97ff7db2c23700347f0a33ad25a299fc52b35f63949735ad864aa127053797541864b07168f89ffb7ba5c9a8bfbcb4248383a95f45461a7aee9c658c5679205f47144ba4a06175e746037b8cb6556f06405e0d537d0f2bcd898dd5fb987d96dbce33001a50abff5b9cb0161dbfe30f5df5a161ddd8a750b0cb33898c110415881fc81239f2e25440bca41a5bc46fbd3787e6c8fe8a463415cd9a82be368a02566da740dca8e40e686e1213d9c15de2d3556a1e1180b298ba3074b4ab93e469dd9a39ac0c8a173b04a5ad913e72e4d7b5ff520f108e1a1747c11b6b2fcfaa89b3ef7e669f8ad9620364b4f4f0f9ab274e76bdd631df033357a24723653e427324d907a9eceb3c375c43ee36cdeb046a6374be19ab04922da93d4dc07c5914df06fee97dd813f5fd501ca75e3c5ad53574837f2e51ba6a257134e8ee0f4127c59840ba8b1bb13592dcbe47aea50e453c7837e91bb12ad1c74fd0f149479bc0334c511a822145690a3a408caa32671ed05c2dd219ea360c67727c1fe6a6cd842301761e94bedc73f93de7091b8b6d2783a788313b2fa12595904bf5d1167a5ddc4ee151b1522de60b7293b72a62c4d08b396ed682b6a6262a212ddc8c70dbec1a972cedc09f593e21d843279561884f9759a593da7b17a147db7559f19d5d6f43ea98012872f974306037dc0d344c55403b35a5903f766359341bee5bccb696fc0fd1c7aa8803e4c2f9e6e23d386d3a202027c5792e355592efab9330af330392a7c91e3cacc4e645359edafd78b77829374cd4b644817322b7650696fa763a0cc7143f9ec7e2f6ab3c9ec2443b0c0b0a31e9eeafb7bb8c375232357f08256959a10a6d4bc98d6cd9314a2ce7feaa8c0eb1eeb15047f715d6ae9ebd64238d648ed6bc50617a360d8ff9a01aa0ce0e29338d34bb9612751445372ac6d74837c7d2d67729760216ee33476cce1a154086ec31d986cc5a14e86561c6929554fb280646164bb03e8e52588a1b947960a77d61c2d2499212a742e1a5b78805b5b64fed141d3c4834301b8a8bef31ce65edb539fd9469b590a6980d0d1bd29e34a09f87438059a09b1ea234d1bb29882e67599fc1e417db9d86332077cfb05fe440ad1243e26a67a0ea30e63cdee8850a543d76e810140547412fb1400ac87a10e3bc77d3918750a5cc3e7a0efbd736c7ed4139cd5855ddba47143362bf40b91fcbf27222017c1552360466483e67ed125745724cc713c713dcf7ef6ea3081d65d8d78b903382717848bee7410431e1040ec92373f75a1bf229816f55dcfffb6e6da33ed8e1e8b05f9348cdcd6938f053eb9f93e0de639e922627bf61a6688f9649bb9cdfce6236a176db8b9b53ce4b5f9eb9c0680c92128bd327aa7f04a745025faaf117a18d5664027ab0e3f5898b834e1a75cd4b4087637733416f8bac1ccd67cb4457005945676d03f76fd0453fdb9968643fec98d28da7c8cd7070a803b14a2459f073ea075fd023a896d3306fdabc54416e95907103cd2fb642e301c71cc48e8eabedaae356582761a14e0b3b0ef1de06002c2acf594c85820ae3a094e5b4680566b592221543c1dc5192d6b208e86b5aca91d4e3454564eedb3b8208169ce97e1632b864f1d9d4c4c4c0fd4bcc5206e8f6d64c7cdf212d718cb5b7c7ee21593ada3f33f5952e12bba4f46cb99044978fe75349c6ca735db35891351d7e5f02a93354bc45a9ec756453f053cb87430b3e9211807f81ad99b6fceb8ef1b2d655910e1f5fd22f2ee90e42abab230f8f39a8345eed6ad294a0d32416a253f829093ecae209bc1dbfadae04a373080f9ea8394a28ddfe1134309bb53ae571d2019ff2bd4be94f8176d90987fcebad323f0b2921b85b2610852973f383a2ff4a5fa82a77b13cfd50a33f29164a9ff409422cc4cbd772132856cbd08470b220ace957a6b8e02c8003d750539a38a8df19a5b662907b72e3098d77c2fc3ece0693b47ff19ce911a93b6adce75653d48ace6af10b8f1141437f9206658707b16794e349db3f1a02606ea167d0213ce3644f64ced64de3799b1729210fc31ba1811b0c226306f2466b230ae35e6d8fa11c8f932e27da8cb1bd311919bf9178ef08bb7a2b4ca2d2e6e9585ee9f916991cfcd4862f5de9fbbc63bee6edbdcfcec9173a252eb59fc6d6e58258ca8b2a4475acfc1e09a0c9566d23d92e9ada97de51895bfb0867c42025c8d089c65bba67f4dd84d7c5155a930329345cdf3b1d6e910e730df273e183190beb900344bbce8c3bdb13a7e4ecbe967a61d47921aa55bac2bbb24e3e03d386ddbfafb3b32235b5ed922ed6ac2c89ded1316b69079b826507d708a6cca14ce2244a67be90fb91ddcb0c97432703729bceb432bc856f5eb9d2f169800a04283b080f0e053670a21468df9414fda9f4153eaf1669a19ede7925f832280800f0063ceee34b9d3b0f8da2012525fa7927e76bda71954714d5f51405b920391eca2ad71160acef4091878b907974573b4cf1b377baca0340ab0e4ec546fcaa6130603ad633c3ef980e88d8f44ec5de743cdc6cd9e0e4cbdb97a5c076be9ada8f26bc54d711facec16a2401292cc167bb98cdd320ec9321414bd97498f6d9b54dbb45ffe4b3e3f88260657ee23e19de48a93595c8e3a289a02d76a27ceead05d591633464709aca117c26aa49b64667f2a3b6371984f813d7098fae7a6ba1841775b52314a06c80b4c994ef8100e233ab3115ba2c39b97f2d5082a145720ad0b12b8a7cb275ba848b3fae14fc0c82bf0353195c056b302e508982f73a8519cca722892482b9d9e6a58bfb4d862fa393eabe6aedeae1be5ed772ea3c94a0df1d9684a131c35246c68b32e46aaf89f3649e58b2e99bd6bb3923d3ab43cbf73b6b3d19fe3b62bef178f46c79ba85e23ee4b25bc561e8fa97f51605bc0b210b02aa28242e81dae9489076d259f17d25b93b0e8a2010584d907314e3bd55482f0fa43d37ae9535629d28d6f837360bb35ec869d2a959789dc49b9c8c515942a1e03650566b736551a5180a60279bdb0ff9c387beebeb9e59ed930b3746464a010a6f7ef1de3c7d76fc6899b1e5ed98213813ffb333d969ad72fd8537ef4e12ca7b78d35c24f44ac82da4a7116492ca2efd86ee6a4474014e72a5cfeee7f729b77cfdd1a5d10a03f3cf28f1d314fca36d31ef2ecb3cfccecbcdfd22367b0a0e04435654286ae3d4fee13f56bb7cdab40b4e1dd01f9ef857f94a67c1e237e24819949935ff3bd73b0461ee9020fd0a2db2cc6312ace97e4a8a33c295271453a12822db8d1438f22ed0d466150990dcb39ed042424eef7a1210c83224c856923e3251484a81a15cddb4d7ada8bb7968dcc8f85e39ca99ece8ce2ed7753fcee6900cc9b7b5691f2d67ef9be13f70d195bbd0047908025df01b4f4d581fd59239836578627d9d585ebe9b053d807e9d3ba25405029a148938a746636decdade02b1afb5ccbf2f0e14a27c98a1e130d9208bbf7da4bb4e572927eb348568921d4a3309a2c24f367c935c2a8e1524c3024ff350ac7da8d2849586817bc9d46a08a21aef035a6151e608ed93b1556a484e455819f9ac2fb155020738962e7255a82a0854b31fe20cdd351c10a33eb693c9be1a51a932e04d0364ced41ee1bf800d0c12ab5eb37fe52563666e52827720e856d4f24eb06e0aba446910aabbe36513f2274362fedba4c19398433029495284ccb499bb559a9cdbc94a0d1b733136969a743945a04e1d2d4e77fed21550af35f22651c7de802eab7a3942d7ec55a3a5002bde8d5cccc1d4ac4bb7f4926615fcece543fe5d9092d2c4f50d94fd9868775a072f4a5bcf2e5fd10795f7f172a3341ce33505ba68e7ebedc9c1e9165864244ed31bbe5c308dceff858cc42010ad8c281a24689cf2dee8a549b1abab9981d70a912174944b403ce664d8608b2f723150f5c12164e4caf28676e7a25c3928ca2a4dbe96355ef8f282e57888d40715df07bd8b5895549ad957e758abf868def1c1f5e260d26498616e2ac962bcaa33b879874569f198a91ce4e50fc50da77fea1df9f9ea900c834dcdd462d338efcf8e612aedebf254fac596507d175d30a90543627cfcef6852c7cda8b430e255c4d6d417de31eb5dba123e3ce9e2269867d9a94fdcd8ccac40a9451953085109f5ae0c3e04daadb4a2a47b0e176917660eb3c9f1aae0ec6b00635fa387e056623947c0621f0a12e86fac1881ed1dc1b9f523388d6b6596a152b3e732c561972879dcd3f0232ef0773a4fb195a90c3186c4688ea58967ce7f18386b80bd38e90cfd4cb899337ab27cba8db6523e979b4c449645bb2f320ccd28578bc7ec38f47225273fa61a2e5df97c4d76c556fbe2b0fd30e615f5fc82c3de7194caed9f5946c151c22b7a0c48f4a7cf78aa153414f2913c5eb95e3dbcea7ca544272cd13a1c52fa87759aeb430aab144fab418c835344605df3a044825965ca15de6ba0e59b2080f5844b2d110d71587e19acf14264cec2de5b8c77d18893215d1c1da0a940e7c2ee429a99e2633c216aecb7675a2314a09044951ca5a8eac798f8878fb5ea65f4ddccac53ee0c786e597169079fb6e8ceb37a71580b0904a97450909ca454a690821e249aebb75449e582fe1b30f1fa9f6464bdef654daa5ede6d4f223f4589ea25a25f4672cfbe974d51008bce296628556f55d26646e40b59f40e3149273760b40806ace3b5171e0b79865c6adb53513da2f24c4115de243150cec76107b48ca8da19117f00b5870e67eb8357e43c1b7b593c9875795d46ede26a109e05406b69fda988947e49ab195f22454c3c743c2ec51b91370b4df8d38653b353e51bb83215d122bcfa591009c007bbb6124bc590fed3f9c5699180b3b1424ad02f7c90a149b77d22dea5c996aba675c2a1a20e206d9c25d9446247d495a26486c0d0bfb09d0b5a1a177a09fa749dc36cee73af0116a6b779c2b827512a04ff0f60b483edbcdb33d2a18339463c498ae67ffa9da0aa3f3beb6bc99212f9e6961afde89045520b1f3f2e2761666a333d76030f443f53322f099035584a60978ef8b49f46d7d4d8c5c758ea52a04b59c1a3a1c2f9df3f3b6f5c45cf4b3547043b18c1d615a2c965c3918d090cc72946e8fd0b938e60e03464f4bc71fb719a1d173b0931930e58bf7f6d4403971d36b40f83be6b57244a7029e1d41dc908764d57a5442557218b509faeda4e9fcf31debbc54ae671ef636871233f29e0013c0e33933543f4b59df1978ec89b109c3977b0cf938b7f6166d6c93be5e87684a703c8b7b5fe1a8bfe153a179b55575ff05e599b39e32ed10d958699a1ffe07136081f0719b18c69dc74f66f211103e9c544f3c81a88ba9f66a9bc7017d9ca9e2cd97634052694a598476b99daf1cdfb6122869375ca5873d32d5c1e07d9b5b380b4f09dbe04478cfb1a13853eafacfed70c8abcd444ed095f78d07c0e8b4093be95c3aa24b2e5b6bfe3a06e9d2d9fedfcfeac4cea2490627e6da6a5cca383351952f654ce2b0ad359c0f7f4ad3f8d1d4a030a947d4a2e417bb79102729115cc8b6558c3362b1d805fb48ce4858deff97677e60375ed13e150a12ee7dcc8ccc64d9710c7f516555c1f7a1a08f0d7c6fd21f864fcf28c8f748c40494e01fc32006f977a5100577f86a484d11b82c90cfe6b4d6b1902fef486cc6f3e033904e150e67283e49a5382961dabd244412ca9657b48796e476a82443167e277d5a65c0c563a6abca77d316e5d3ab639a1ecfb1110af2d29f146508bd9874486dbb56328d6f59479e2766692821660462aa60b6bc8a710707ceeb0ea6429e5113e03c9f41ce0d69c7589deb547527673e8a9f9a9a74e9e4bbcabf2e306b35504c1da99730ae86e94cd047b2e6ea5e97e63a492430d37ec446434fb3b066adde08b17d7d903ad194a4a863d6cfe181a45c8c97b5062bf7c4e44d69c0d1a7e1f5029b805b7c21d1b5e56e697999a32557870ebaae8d87dcb5ca5eea2c5547a16b3f30ef9df8df821028c106f86e091050ff8b6ea4171e59dc2592d405073bea53f8ea62edf112dfbc7ca69809db8005783d63557d3d90d123a944be395c1dc3b5e1476dff188346327769fea65f3cf9363e88ed67335870ec8ef13eb9d9ff5317c4e24dfce9d11699e5f47b4233cc8f9d1b915e716a5730a5898ee65d30b1628b484a5e82eda95a590964a8d8bc89dd3c5cf6c4f9137b8c6ee9d6a692e0c0d1d858dd5b3c12de48badade4d01bff312c56ce3ddb34b0fdde3b0c2706fc292b9fac7e1a0dcd0b6534c968117f7de15eba84d2754e4bcb8093a5440297605598659f686075e2b1b464b6b3ec68abb13cde263b1c607545c45746338b9b207b5c381da690f653b35e363e1249551ad938b9fd7b0a944151cda07127bf9ba76958e926472f4aa1de8512ce834cfcae5414b226f23acdb1fe5cf685d2201b78167ad35fc1da282744c2a43cc49d49242f968f7e06de14455e7ef5adedc5b33184346018114e2d1fc7a5349e378da9b2af5b328c213888652aca9f1145363809eca7c1fd8e64a5cc3255418736e048a731f3053db77971f67014e6121a8e464833e5dbd02ea6caf385e43e9f378bfba657986bf852b32adb55e35a2675bfc8d70d43a902032a61f59f57dad2dd7d7963322136233200cb9a90c952074e9ba0fc0654f1b6fd6f7f0eb77c0fa6d8143213ce6e8b0c178f73e17a7c64839f9bebca2fc955ea8ae406a13b80a9045fa8d129fd859faa46fd27c48bde7b890f98ee938c0d78889f84181ae2f5711304fe554d4251bbc6437ced59d577a2a1f26da736193c3674adb13cef9f4cb4aa6585c4d6874b0309ecde300493b1642c595746f09e03977c8902f3a4a877db1153b248f295a0ca2f1e437d15fcab8fd77c5f967304efb5c4920b990674ae61b954af40be17a8559dc377c591b68067fdcaf2d27bd9a22041b981a84be3de50d5962b58f8c4a22fa05192c5ac99a0a9423284fe62a3a59f085136cec72cda2a53af106a2eb5bda28b6e02c299118cd91714c2e7d045346c78d9ed1b41c73231a21e42c298949f70122277f4134ed5c56639edbf3c3e717310e3d1f03dc5a94e64c4ce148bc5c6bde64eb80b17d5979892786a31225eb89bf9f5a582bcf65b83ff7aa361ccd9238d144f6a22a3f77dd8a01382df4ee90a2057dd310a6b0c4b81dfc92a2cc0c606d3be8b18fbe64ddfdf2004eeabea892be2f914edd1edd8e8829dc7704d71bbaaf08c41824dd0f4b34c9eedead9e10e53bfc6fc0bd37417de0c5c71cff0754d672f29c262d8e27b524427e12bc4e4705ab311d3bedcb1ddd09a3ca0c268c05c64951b7d724a9dafe4d249aaabda91d68633aaab845bf78f9a22d467c7e0c5fc70fc9a318b01d7492efea7fffd329d70692e76647ae665c62b280da0d62f870a52e4dc4cd92c9150c96aab16f8c23475e3152d4debb41b6756f000c3d8aceef18b49e295be7a71da1eeadf4eb96509d45d7cc42af4b7013d8bb445f577e8d4cff92770b8ba0e451f3e24c6d981efdb68c7f2dfafee40b8a425955796e369f0d4da3e998c1626ae0fa583334475f1fdde68ca211c3f2e9afb003f553191702e11f8b731c89ea26059ea4466f2bd0a1a5601025ca9417006bca5c9a57dfdba44c603ef9ad38922623b40feda036d84425c47fa42973e348a180a7570e1215044c375313ab08d6f521052dda415707ebb74d6c4774e039bb04cadc2799224bde1802e2ee2a018032e3a341700c0fa2aa28bf93cc479231efe7da0e9f68e572415348c08cf648117e9b6d1267fef6617f5927252c86cc087775db3e30180feb5ce7e1ac9c3761161e07a4853aa6d97e525aa88302954cf9390fde81f8e11d97a11c79e3bad261364c18890dd1f8fc71127edefe3571518a42be611a46a0426a33221aa25a0ae6514daaf96038cb59aaba898de49e3b215a4464e0af614e638c2d9b6e676ec427fc906bc516331a18121f306a5246d179e2d3d0f38ab8393f7ea5a2d24585e7cca649637b9983924a15483c167e8780f8dd7aa1154cbf731745a8d8d54a8c4f8d854371bb8172303f9ba3c8c7cfe8c378ee56bc35c6376aafe907d3294ee9a8786281b7deff78ff125761f1a31d0e8fffe04a52a7574eeb8679670ca3bfb740167a559488d4337819613d32752d8a89013622f6a8d70f3c64b84a4215f4b7bb282a2d17c36a326167e3270757b8f1d9a0137bfc5ec278e8ca35a69e49779cfc25b95a89cc18732b5b9d1986b18878c57e118506909207207ad0b4edf32fb2b35b6e70546f45d0849bd139ffff9d8ae547787e7b51403b54f110e2ac65468cd0910d80a4e321deafd46e9af19609bee1efa41b762b8ace989dd681503539e7d9948664cf7a73ffac9ce2a34b514253c4f21bbccd38057a6d68732930dcdfc9a32219b53339d100db0037a8bbd101e71f5054f3
+AAD = 7b3b9c07148fcd897f657ecfcc87e530191536b8e77f9309e8d7323888b3b21477f2ab7c885c105d9c29ac96aed23b366f9fde4177401b7038c6770c7bd2ee8b4335105cc0eab9e367f0cea90d6f1ae3fa76cd21ceb9f3500ce7fb4b2a3f9e90f900a231ec693aeced7afb6821391d1f5b1b957895777aa7a2b71d9571c00336f26d54d756392cdb74bfb67d5a621d517db20441f74d0940180baf613b09452f64224f8af7bbc864ab4a8434ff624d0c0646ee07132fd376506951899bde975df8c836ab4ed9cc084f1f6d500ad56345d2f250a0d6991b9e458c62b6023191f341c8659e8a38c878cfac12b032674503df9c9bb01c4340c709eb6dd7c74907d769a317f4dd7317843c47bdb4c5e1f07f2380d464b0c47269389cc8a43a09adba86f6aa8f44c8fe514e73b5fe8d344769c1aa20a4538ecfbf47562ca79fa497b0f02f103f75522db9ead50d56dbe86997d6085f1b5aa7a4cab9e51a1247ce4f724a14983b6bafd17369fac973c6be268e20d800de870928e100990ebb0d3bedfceda36c64be3a729b603bce677a49e8caf282c9159b6e3e1e775129bd30dc3f5c9849535d86a27474be03bb5749b4c0115e2614f8feaa7405cc69b1de479b3b57e551f876a9c8c57ab9879cc68bb2ea110b2e77e59dd6a65eaa67cc4d4b2f4d6e646b2a298d3c80fb43969275d4414734e74726145dab06124c040656c39a94846e8fd58d326f4f9eafe5b95d85254765a21993f55070fcb9e85db5d42ab6b9464ce66de3f236dd2a0a26c4e5535dbdcd6eb350209a65aee785c6647ad4103d092a8ac932470880eb314f7c98cdff34fdf35ee2d36f09bd443b5defad7a5acb9df55965421fd043def6f4771e1bb27385b30ba22c0d8972aead6b654085a7dd3b60c4004a0dae22e25100e54e0badd0cadf909799329ddff699de8066dd6c3822d80c73c52d87e6fcbdb2dbbf852e37804b1256e23e76dbe43f30be4a577bc23c7941a3d708d1e1f579e9c6eebc219c74768168f6790a41f883790e08cd1e88ad09a544eb97b3d1d5af67eea666b9c027e5c7c976921189b955a9e605f6cc9c012c1c2e197c5b02504cb9ffbcb0f3ed778d540d5194fdf5d38dba6340c93da7c5501a082689616f337d8b59c2a92c25e777515726e1d7f6cc9552693cc7c30f1294b37f97d49814250d6c1e3eb335c5d214ef3641739d508b87106eaaf367902433a148ca962ec694409acb82d7749e1c88938ad382d0ca6e6cbe8255746832fe737c3e71dae8397f260c98d4a292a126ec21935c24096d2f91ae114194af659455d8a4206197495a28474dd2809debf5f550d77ffac2b0db521559910c352f23472d7aa9f4dbbdb158f40aa36912cbd918ae4c642e76d78d57ade1075c4fe1086ddee3d554353b4693bbcef1cfa87e49890838c36156af0edf384b0413d6d7aa
+Tag = 51cbcf4a2fd82f221de1bfebf86a8c24
+
# OFB tests from OpenSSL upstream.
# OFB-AES128.Encrypt
diff --git a/src/crypto/cipher/tls_cbc.c b/src/crypto/cipher/tls_cbc.c
index c541db37..510b4c73 100644
--- a/src/crypto/cipher/tls_cbc.c
+++ b/src/crypto/cipher/tls_cbc.c
@@ -54,10 +54,11 @@
#include <string.h>
#include <openssl/digest.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
#include <openssl/sha.h>
#include "../internal.h"
+#include "internal.h"
/* TODO(davidben): unsigned should be size_t. The various constant_time
@@ -146,7 +147,6 @@ void EVP_tls_cbc_copy_mac(uint8_t *out, unsigned md_size,
* the MAC's position can only vary by 255 bytes. */
unsigned scan_start = 0;
unsigned i, j;
- unsigned div_spoiler;
unsigned rotate_offset;
assert(orig_len >= in_len);
@@ -161,16 +161,46 @@ void EVP_tls_cbc_copy_mac(uint8_t *out, unsigned md_size,
if (orig_len > md_size + 255 + 1) {
scan_start = orig_len - (md_size + 255 + 1);
}
- /* div_spoiler contains a multiple of md_size that is used to cause the
- * modulo operation to be constant time. Without this, the time varies
- * based on the amount of padding when running on Intel chips at least.
+
+ /* Ideally the next statement would be:
+ *
+ * rotate_offset = (mac_start - scan_start) % md_size;
*
- * The aim of right-shifting md_size is so that the compiler doesn't
- * figure out that it can remove div_spoiler as that would require it
- * to prove that md_size is always even, which I hope is beyond it. */
- div_spoiler = md_size >> 1;
- div_spoiler <<= (sizeof(div_spoiler) - 1) * 8;
- rotate_offset = (div_spoiler + mac_start - scan_start) % md_size;
+ * However, division is not a constant-time operation (at least on Intel
+ * chips). Thus we enumerate the possible values of md_size and handle each
+ * separately. The value of |md_size| is public information (it's determined
+ * by the cipher suite in the ServerHello) so our timing can vary based on
+ * its value. */
+
+ rotate_offset = mac_start - scan_start;
+ /* rotate_offset can be, at most, 255 (bytes of padding) + 1 (padding length)
+ * + md_size = 256 + 48 (since SHA-384 is the largest hash) = 304. */
+ assert(rotate_offset <= 304);
+
+ if (md_size == 16) {
+ rotate_offset &= 15;
+ } else if (md_size == 20) {
+ /* 1/20 is approximated as 25/512 and then Barrett reduction is used.
+ * Analytically, this is correct for 0 <= rotate_offset <= 853. */
+ unsigned q = (rotate_offset * 25) >> 9;
+ rotate_offset -= q * 20;
+ rotate_offset -=
+ constant_time_select(constant_time_ge(rotate_offset, 20), 20, 0);
+ } else if (md_size == 32) {
+ rotate_offset &= 31;
+ } else if (md_size == 48) {
+ /* 1/48 is approximated as 10/512 and then Barrett reduction is used.
+ * Analytically, this is correct for 0 <= rotate_offset <= 768. */
+ unsigned q = (rotate_offset * 10) >> 9;
+ rotate_offset -= q * 48;
+ rotate_offset -=
+ constant_time_select(constant_time_ge(rotate_offset, 48), 48, 0);
+ } else {
+ /* This should be impossible therefore this path doesn't run in constant
+ * time. */
+ assert(0);
+ rotate_offset = rotate_offset % md_size;
+ }
memset(rotated_mac, 0, md_size);
for (i = scan_start, j = 0; i < orig_len; i++) {
diff --git a/src/crypto/cmac/cmac_test.cc b/src/crypto/cmac/cmac_test.cc
index 53f45d15..2496f2a9 100644
--- a/src/crypto/cmac/cmac_test.cc
+++ b/src/crypto/cmac/cmac_test.cc
@@ -44,7 +44,7 @@ static int test(const char *name, const uint8_t *key, size_t key_len,
}
ScopedCMAC_CTX ctx(CMAC_CTX_new());
- if (!CMAC_Init(ctx.get(), key, key_len, EVP_aes_128_cbc(), NULL)) {
+ if (!ctx || !CMAC_Init(ctx.get(), key, key_len, EVP_aes_128_cbc(), NULL)) {
fprintf(stderr, "%s: CMAC_Init failed.\n", name);
return 0;
}
diff --git a/src/crypto/conf/conf.c b/src/crypto/conf/conf.c
index e098a2ce..e4fc428b 100644
--- a/src/crypto/conf/conf.c
+++ b/src/crypto/conf/conf.c
@@ -65,6 +65,7 @@
#include <openssl/mem.h>
#include "conf_def.h"
+#include "internal.h"
static uint32_t conf_value_hash(const CONF_VALUE *v) {
@@ -152,7 +153,7 @@ void NCONF_free(CONF *conf) {
OPENSSL_free(conf);
}
-CONF_VALUE *NCONF_new_section(const CONF *conf, const char *section) {
+static CONF_VALUE *NCONF_new_section(const CONF *conf, const char *section) {
STACK_OF(CONF_VALUE) *sk = NULL;
int ok = 0;
CONF_VALUE *v = NULL, *old_value;
@@ -776,3 +777,12 @@ int CONF_parse_list(const char *list, char sep, int remove_whitespace,
lstart = p + 1;
}
}
+
+int CONF_modules_load_file(CONF_MUST_BE_NULL *filename, const char *appname,
+ unsigned long flags) {
+ return 1;
+}
+
+void CONF_modules_free(void) {}
+
+void OPENSSL_config(CONF_MUST_BE_NULL *config_name) {}
diff --git a/src/crypto/cpu-aarch64-linux.c b/src/crypto/cpu-aarch64-linux.c
new file mode 100644
index 00000000..1b0f3955
--- /dev/null
+++ b/src/crypto/cpu-aarch64-linux.c
@@ -0,0 +1,61 @@
+/* Copyright (c) 2016, 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/cpu.h>
+
+#if defined(OPENSSL_AARCH64) && !defined(OPENSSL_STATIC_ARMCAP)
+
+#include <sys/auxv.h>
+
+#include <openssl/arm_arch.h>
+
+#include "internal.h"
+
+
+extern uint32_t OPENSSL_armcap_P;
+
+void OPENSSL_cpuid_setup(void) {
+ unsigned long hwcap = getauxval(AT_HWCAP);
+
+ /* See /usr/include/asm/hwcap.h on an aarch64 installation for the source of
+ * these values. */
+ static const unsigned long kNEON = 1 << 1;
+ static const unsigned long kAES = 1 << 3;
+ static const unsigned long kPMULL = 1 << 4;
+ static const unsigned long kSHA1 = 1 << 5;
+ static const unsigned long kSHA256 = 1 << 6;
+
+ if ((hwcap & kNEON) == 0) {
+ /* Matching OpenSSL, if NEON is missing, don't report other features
+ * either. */
+ return;
+ }
+
+ OPENSSL_armcap_P |= ARMV7_NEON;
+
+ if (hwcap & kAES) {
+ OPENSSL_armcap_P |= ARMV8_AES;
+ }
+ if (hwcap & kPMULL) {
+ OPENSSL_armcap_P |= ARMV8_PMULL;
+ }
+ if (hwcap & kSHA1) {
+ OPENSSL_armcap_P |= ARMV8_SHA1;
+ }
+ if (hwcap & kSHA256) {
+ OPENSSL_armcap_P |= ARMV8_SHA256;
+ }
+}
+
+#endif /* OPENSSL_AARCH64 && !OPENSSL_STATIC_ARMCAP */
diff --git a/src/crypto/cpu-arm-asm.S b/src/crypto/cpu-arm-asm.S
deleted file mode 100644
index faf3ad89..00000000
--- a/src/crypto/cpu-arm-asm.S
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright (c) 2014, Google Inc.
-#
-# Permission to use, copy, modify, and/or distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
-# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-#if !defined(OPENSSL_NO_ASM) && defined(__arm__)
-
-.syntax unified
-.cpu cortex-a8
-.fpu neon
-.text
-.thumb
-.align 2
-.global CRYPTO_arm_neon_probe
-.hidden CRYPTO_arm_neon_probe
-.type CRYPTO_arm_neon_probe, %function
-.thumb_func
-CRYPTO_arm_neon_probe:
- vorr q1, q1, q1
- bx lr
-.section .note.GNU-stack,"",%progbits
-
-#endif /* !OPENSSL_NO_ASM && __arm__ */
diff --git a/src/crypto/cpu-arm-linux.c b/src/crypto/cpu-arm-linux.c
new file mode 100644
index 00000000..73c38ecc
--- /dev/null
+++ b/src/crypto/cpu-arm-linux.c
@@ -0,0 +1,360 @@
+/* Copyright (c) 2016, 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/cpu.h>
+
+#if defined(OPENSSL_ARM) && !defined(OPENSSL_STATIC_ARMCAP)
+
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <openssl/arm_arch.h>
+#include <openssl/buf.h>
+#include <openssl/mem.h>
+
+#include "internal.h"
+
+
+#define AT_HWCAP 16
+#define AT_HWCAP2 26
+
+#define HWCAP_NEON (1 << 12)
+
+/* See /usr/include/asm/hwcap.h on an ARM installation for the source of
+ * these values. */
+#define HWCAP2_AES (1 << 0)
+#define HWCAP2_PMULL (1 << 1)
+#define HWCAP2_SHA1 (1 << 2)
+#define HWCAP2_SHA2 (1 << 3)
+
+/* |getauxval| is not available on Android until API level 20. Link it as a weak
+ * symbol and use other methods as fallback. */
+unsigned long getauxval(unsigned long type) __attribute__((weak));
+
+static int open_eintr(const char *path, int flags) {
+ int ret;
+ do {
+ ret = open(path, flags);
+ } while (ret < 0 && errno == EINTR);
+ return ret;
+}
+
+static ssize_t read_eintr(int fd, void *out, size_t len) {
+ ssize_t ret;
+ do {
+ ret = read(fd, out, len);
+ } while (ret < 0 && errno == EINTR);
+ return ret;
+}
+
+/* read_full reads exactly |len| bytes from |fd| to |out|. On error or end of
+ * file, it returns zero. */
+static int read_full(int fd, void *out, size_t len) {
+ char *outp = out;
+ while (len > 0) {
+ ssize_t ret = read_eintr(fd, outp, len);
+ if (ret <= 0) {
+ return 0;
+ }
+ outp += ret;
+ len -= ret;
+ }
+ return 1;
+}
+
+/* read_file opens |path| and reads until end-of-file. On success, it returns
+ * one and sets |*out_ptr| and |*out_len| to a newly-allocated buffer with the
+ * contents. Otherwise, it returns zero. */
+static int read_file(char **out_ptr, size_t *out_len, const char *path) {
+ int fd = open_eintr(path, O_RDONLY);
+ if (fd < 0) {
+ return 0;
+ }
+
+ static const size_t kReadSize = 1024;
+ int ret = 0;
+ size_t cap = kReadSize, len = 0;
+ char *buf = OPENSSL_malloc(cap);
+ if (buf == NULL) {
+ goto err;
+ }
+
+ for (;;) {
+ if (cap - len < kReadSize) {
+ size_t new_cap = cap * 2;
+ if (new_cap < cap) {
+ goto err;
+ }
+ char *new_buf = OPENSSL_realloc(buf, new_cap);
+ if (new_buf == NULL) {
+ goto err;
+ }
+ buf = new_buf;
+ cap = new_cap;
+ }
+
+ ssize_t bytes_read = read_eintr(fd, buf + len, kReadSize);
+ if (bytes_read < 0) {
+ goto err;
+ }
+ if (bytes_read == 0) {
+ break;
+ }
+ len += bytes_read;
+ }
+
+ *out_ptr = buf;
+ *out_len = len;
+ ret = 1;
+ buf = NULL;
+
+err:
+ OPENSSL_free(buf);
+ close(fd);
+ return ret;
+}
+
+/* getauxval_proc behaves like |getauxval| but reads from /proc/self/auxv. */
+static unsigned long getauxval_proc(unsigned long type) {
+ int fd = open_eintr("/proc/self/auxv", O_RDONLY);
+ if (fd < 0) {
+ return 0;
+ }
+
+ struct {
+ unsigned long tag;
+ unsigned long value;
+ } entry;
+
+ for (;;) {
+ if (!read_full(fd, &entry, sizeof(entry)) ||
+ (entry.tag == 0 && entry.value == 0)) {
+ break;
+ }
+ if (entry.tag == type) {
+ close(fd);
+ return entry.value;
+ }
+ }
+ close(fd);
+ return 0;
+}
+
+typedef struct {
+ const char *data;
+ size_t len;
+} STRING_PIECE;
+
+static int STRING_PIECE_equals(const STRING_PIECE *a, const char *b) {
+ size_t b_len = strlen(b);
+ return a->len == b_len && memcmp(a->data, b, b_len) == 0;
+}
+
+/* STRING_PIECE_split finds the first occurence of |sep| in |in| and, if found,
+ * sets |*out_left| and |*out_right| to |in| split before and after it. It
+ * returns one if |sep| was found and zero otherwise. */
+static int STRING_PIECE_split(STRING_PIECE *out_left, STRING_PIECE *out_right,
+ const STRING_PIECE *in, char sep) {
+ const char *p = memchr(in->data, sep, in->len);
+ if (p == NULL) {
+ return 0;
+ }
+ /* |out_left| or |out_right| may alias |in|, so make a copy. */
+ STRING_PIECE in_copy = *in;
+ out_left->data = in_copy.data;
+ out_left->len = p - in_copy.data;
+ out_right->data = in_copy.data + out_left->len + 1;
+ out_right->len = in_copy.len - out_left->len - 1;
+ return 1;
+}
+
+/* STRING_PIECE_trim removes leading and trailing whitespace from |s|. */
+static void STRING_PIECE_trim(STRING_PIECE *s) {
+ while (s->len != 0 && (s->data[0] == ' ' || s->data[0] == '\t')) {
+ s->data++;
+ s->len--;
+ }
+ while (s->len != 0 &&
+ (s->data[s->len - 1] == ' ' || s->data[s->len - 1] == '\t')) {
+ s->len--;
+ }
+}
+
+/* extract_cpuinfo_field extracts a /proc/cpuinfo field named |field| from
+ * |in|. If found, it sets |*out| to the value and returns one. Otherwise, it
+ * returns zero. */
+static int extract_cpuinfo_field(STRING_PIECE *out, const STRING_PIECE *in,
+ const char *field) {
+ /* Process |in| one line at a time. */
+ STRING_PIECE remaining = *in, line;
+ while (STRING_PIECE_split(&line, &remaining, &remaining, '\n')) {
+ STRING_PIECE key, value;
+ if (!STRING_PIECE_split(&key, &value, &line, ':')) {
+ continue;
+ }
+ STRING_PIECE_trim(&key);
+ if (STRING_PIECE_equals(&key, field)) {
+ STRING_PIECE_trim(&value);
+ *out = value;
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static int cpuinfo_field_equals(const STRING_PIECE *cpuinfo, const char *field,
+ const char *value) {
+ STRING_PIECE extracted;
+ return extract_cpuinfo_field(&extracted, cpuinfo, field) &&
+ STRING_PIECE_equals(&extracted, value);
+}
+
+/* has_list_item treats |list| as a space-separated list of items and returns
+ * one if |item| is contained in |list| and zero otherwise. */
+static int has_list_item(const STRING_PIECE *list, const char *item) {
+ STRING_PIECE remaining = *list, feature;
+ while (STRING_PIECE_split(&feature, &remaining, &remaining, ' ')) {
+ if (STRING_PIECE_equals(&feature, item)) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static unsigned long get_hwcap_cpuinfo(const STRING_PIECE *cpuinfo) {
+ if (cpuinfo_field_equals(cpuinfo, "CPU architecture", "8")) {
+ /* This is a 32-bit ARM binary running on a 64-bit kernel. NEON is always
+ * available on ARMv8. Linux omits required features, so reading the
+ * "Features" line does not work. (For simplicity, use strict equality. We
+ * assume everything running on future ARM architectures will have a
+ * working |getauxval|.) */
+ return HWCAP_NEON;
+ }
+
+ STRING_PIECE features;
+ if (extract_cpuinfo_field(&features, cpuinfo, "Features") &&
+ has_list_item(&features, "neon")) {
+ return HWCAP_NEON;
+ }
+ return 0;
+}
+
+static unsigned long get_hwcap2_cpuinfo(const STRING_PIECE *cpuinfo) {
+ STRING_PIECE features;
+ if (!extract_cpuinfo_field(&features, cpuinfo, "Features")) {
+ return 0;
+ }
+
+ unsigned long ret = 0;
+ if (has_list_item(&features, "aes")) {
+ ret |= HWCAP2_AES;
+ }
+ if (has_list_item(&features, "pmull")) {
+ ret |= HWCAP2_PMULL;
+ }
+ if (has_list_item(&features, "sha1")) {
+ ret |= HWCAP2_SHA1;
+ }
+ if (has_list_item(&features, "sha2")) {
+ ret |= HWCAP2_SHA2;
+ }
+ return ret;
+}
+
+/* has_broken_neon returns one if |in| matches a CPU known to have a broken
+ * NEON unit. See https://crbug.com/341598. */
+static int has_broken_neon(const STRING_PIECE *cpuinfo) {
+ return cpuinfo_field_equals(cpuinfo, "CPU implementer", "0x51") &&
+ cpuinfo_field_equals(cpuinfo, "CPU architecture", "7") &&
+ cpuinfo_field_equals(cpuinfo, "CPU variant", "0x1") &&
+ cpuinfo_field_equals(cpuinfo, "CPU part", "0x04d") &&
+ cpuinfo_field_equals(cpuinfo, "CPU revision", "0");
+}
+
+extern uint32_t OPENSSL_armcap_P;
+
+static int g_has_broken_neon;
+
+void OPENSSL_cpuid_setup(void) {
+ char *cpuinfo_data;
+ size_t cpuinfo_len;
+ if (!read_file(&cpuinfo_data, &cpuinfo_len, "/proc/cpuinfo")) {
+ return;
+ }
+ STRING_PIECE cpuinfo;
+ cpuinfo.data = cpuinfo_data;
+ cpuinfo.len = cpuinfo_len;
+
+ /* |getauxval| is not available on Android until API level 20. If it is
+ * unavailable, read from /proc/self/auxv as a fallback. This is unreadable
+ * on some versions of Android, so further fall back to /proc/cpuinfo.
+ *
+ * See
+ * https://android.googlesource.com/platform/ndk/+/882ac8f3392858991a0e1af33b4b7387ec856bd2
+ * and b/13679666 (Google-internal) for details. */
+ unsigned long hwcap = 0;
+ if (getauxval != NULL) {
+ hwcap = getauxval(AT_HWCAP);
+ }
+ if (hwcap == 0) {
+ hwcap = getauxval_proc(AT_HWCAP);
+ }
+ if (hwcap == 0) {
+ hwcap = get_hwcap_cpuinfo(&cpuinfo);
+ }
+
+ /* Clear NEON support if known broken. */
+ g_has_broken_neon = has_broken_neon(&cpuinfo);
+ if (g_has_broken_neon) {
+ hwcap &= ~HWCAP_NEON;
+ }
+
+ /* Matching OpenSSL, only report other features if NEON is present. */
+ if (hwcap & HWCAP_NEON) {
+ OPENSSL_armcap_P |= ARMV7_NEON;
+
+ /* Some ARMv8 Android devices don't expose AT_HWCAP2. Fall back to
+ * /proc/cpuinfo. See https://crbug.com/596156. */
+ unsigned long hwcap2 = 0;
+ if (getauxval != NULL) {
+ hwcap2 = getauxval(AT_HWCAP2);
+ }
+ if (hwcap2 == 0) {
+ hwcap2 = get_hwcap2_cpuinfo(&cpuinfo);
+ }
+
+ if (hwcap2 & HWCAP2_AES) {
+ OPENSSL_armcap_P |= ARMV8_AES;
+ }
+ if (hwcap2 & HWCAP2_PMULL) {
+ OPENSSL_armcap_P |= ARMV8_PMULL;
+ }
+ if (hwcap2 & HWCAP2_SHA1) {
+ OPENSSL_armcap_P |= ARMV8_SHA1;
+ }
+ if (hwcap2 & HWCAP2_SHA2) {
+ OPENSSL_armcap_P |= ARMV8_SHA256;
+ }
+ }
+
+ OPENSSL_free(cpuinfo_data);
+}
+
+int CRYPTO_has_broken_NEON(void) { return g_has_broken_neon; }
+
+#endif /* OPENSSL_ARM && !OPENSSL_STATIC_ARMCAP */
diff --git a/src/crypto/cpu-arm.c b/src/crypto/cpu-arm.c
index 675d174e..ef395eae 100644
--- a/src/crypto/cpu-arm.c
+++ b/src/crypto/cpu-arm.c
@@ -17,52 +17,15 @@
#if (defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) && \
!defined(OPENSSL_STATIC_ARMCAP)
-#include <inttypes.h>
-#include <string.h>
-
-#include <setjmp.h>
-#include <signal.h>
-
#include <openssl/arm_arch.h>
-/* We can't include <sys/auxv.h> because the Android SDK version against which
- * Chromium builds is too old to have it. Instead we define all the constants
- * that we need and have a weak pointer to getauxval. */
-
-unsigned long getauxval(unsigned long type) __attribute__((weak));
-
extern uint32_t OPENSSL_armcap_P;
char CRYPTO_is_NEON_capable_at_runtime(void) {
return (OPENSSL_armcap_P & ARMV7_NEON) != 0;
}
-static char g_set_neon_called = 0;
-
-void CRYPTO_set_NEON_capable(char neon_capable) {
- g_set_neon_called = 1;
-
- if (neon_capable) {
- OPENSSL_armcap_P |= ARMV7_NEON;
- } else {
- OPENSSL_armcap_P &= ~ARMV7_NEON;
- }
-}
-
-char CRYPTO_is_NEON_functional(void) {
- static const uint32_t kWantFlags = ARMV7_NEON | ARMV7_NEON_FUNCTIONAL;
- return (OPENSSL_armcap_P & kWantFlags) == kWantFlags;
-}
-
-void CRYPTO_set_NEON_functional(char neon_functional) {
- if (neon_functional) {
- OPENSSL_armcap_P |= ARMV7_NEON_FUNCTIONAL;
- } else {
- OPENSSL_armcap_P &= ~ARMV7_NEON_FUNCTIONAL;
- }
-}
-
int CRYPTO_is_ARMv8_AES_capable(void) {
return (OPENSSL_armcap_P & ARMV8_AES) != 0;
}
@@ -71,129 +34,5 @@ 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;
-
-static void sigill_handler(int signal) {
- siglongjmp(sigill_jmp, signal);
-}
-
-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(void) {
- int supported = 0;
-
- sigset_t sigmask;
- sigfillset(&sigmask);
- sigdelset(&sigmask, SIGILL);
- sigdelset(&sigmask, SIGTRAP);
- sigdelset(&sigmask, SIGFPE);
- sigdelset(&sigmask, SIGBUS);
- sigdelset(&sigmask, SIGSEGV);
-
- struct sigaction sigill_original_action, sigill_action;
- memset(&sigill_action, 0, sizeof(sigill_action));
- sigill_action.sa_handler = sigill_handler;
- sigill_action.sa_mask = sigmask;
-
- sigset_t original_sigmask;
- sigprocmask(SIG_SETMASK, &sigmask, &original_sigmask);
-
- if (sigsetjmp(sigill_jmp, 1 /* save signals */) == 0) {
- sigaction(SIGILL, &sigill_action, &sigill_original_action);
-
- // This function cannot be inline asm because GCC will refuse to compile
- // inline NEON instructions unless building with -mfpu=neon, which would
- // defeat the point of probing for support at runtime.
- CRYPTO_arm_neon_probe();
- supported = 1;
- }
- // Note that Android up to and including Lollipop doesn't restore the signal
- // mask correctly after returning from a sigsetjmp. So that would need to be
- // set again here if more probes were added.
- // See https://android-review.googlesource.com/#/c/127624/
-
- sigaction(SIGILL, &sigill_original_action, NULL);
- sigprocmask(SIG_SETMASK, &original_sigmask, NULL);
-
- return supported;
-}
-
-#else
-
-static int probe_for_NEON(void) {
- return 0;
-}
-
-#endif /* !OPENSSL_NO_ASM && OPENSSL_ARM */
-
-void OPENSSL_cpuid_setup(void) {
- if (getauxval == NULL) {
- // On ARM, but not AArch64, try a NEON instruction and see whether it works
- // in order to probe for NEON support.
- //
- // Note that |CRYPTO_is_NEON_capable| can be true even if
- // |CRYPTO_set_NEON_capable| has never been called if the code was compiled
- // with NEON support enabled (e.g. -mfpu=neon).
- if (!g_set_neon_called && !CRYPTO_is_NEON_capable() && probe_for_NEON()) {
- OPENSSL_armcap_P |= ARMV7_NEON;
- }
- return;
- }
-
- static const unsigned long AT_HWCAP = 16;
- unsigned long hwcap = getauxval(AT_HWCAP);
-
-#if defined(OPENSSL_ARM)
- static const unsigned long kNEON = 1 << 12;
- if ((hwcap & kNEON) == 0) {
- return;
- }
-
- /* In 32-bit mode, the ARMv8 feature bits are in a different aux vector
- * value. */
- static const unsigned long AT_HWCAP2 = 26;
- hwcap = getauxval(AT_HWCAP2);
-
- /* See /usr/include/asm/hwcap.h on an ARM installation for the source of
- * these values. */
- static const unsigned long kAES = 1 << 0;
- static const unsigned long kPMULL = 1 << 1;
- static const unsigned long kSHA1 = 1 << 2;
- static const unsigned long kSHA256 = 1 << 3;
-#elif defined(OPENSSL_AARCH64)
- /* See /usr/include/asm/hwcap.h on an aarch64 installation for the source of
- * these values. */
- static const unsigned long kNEON = 1 << 1;
- static const unsigned long kAES = 1 << 3;
- static const unsigned long kPMULL = 1 << 4;
- static const unsigned long kSHA1 = 1 << 5;
- static const unsigned long kSHA256 = 1 << 6;
-
- if ((hwcap & kNEON) == 0) {
- return;
- }
-#endif
-
- OPENSSL_armcap_P |= ARMV7_NEON;
-
- if (hwcap & kAES) {
- OPENSSL_armcap_P |= ARMV8_AES;
- }
- if (hwcap & kPMULL) {
- OPENSSL_armcap_P |= ARMV8_PMULL;
- }
- if (hwcap & kSHA1) {
- OPENSSL_armcap_P |= ARMV8_SHA1;
- }
- if (hwcap & kSHA256) {
- OPENSSL_armcap_P |= ARMV8_SHA256;
- }
-}
-
#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 924bab04..431e1e15 100644
--- a/src/crypto/cpu-intel.c
+++ b/src/crypto/cpu-intel.c
@@ -64,8 +64,8 @@
#if !defined(OPENSSL_NO_ASM) && (defined(OPENSSL_X86) || defined(OPENSSL_X86_64))
#include <inttypes.h>
-#include <stdlib.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#if defined(OPENSSL_WINDOWS)
@@ -75,6 +75,8 @@
#pragma warning(pop)
#endif
+#include "internal.h"
+
/* 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
@@ -127,7 +129,7 @@ static void handle_cpu_env(uint32_t *out, const char *in) {
const int invert = in[0] == '~';
uint64_t v;
- if (!sscanf(in + invert, "%" PRIi64, &v)) {
+ if (!sscanf(in + invert, "%" PRIu64, &v)) {
return;
}
diff --git a/src/crypto/crypto.c b/src/crypto/crypto.c
index ace1c82e..89b0bd14 100644
--- a/src/crypto/crypto.c
+++ b/src/crypto/crypto.c
@@ -63,7 +63,7 @@ uint32_t OPENSSL_ia32cap_P[4] = {0};
uint32_t OPENSSL_armcap_P =
#if defined(OPENSSL_STATIC_ARMCAP_NEON) || defined(__ARM_NEON__)
- ARMV7_NEON | ARMV7_NEON_FUNCTIONAL |
+ ARMV7_NEON |
#endif
#if defined(OPENSSL_STATIC_ARMCAP_AES)
ARMV8_AES |
@@ -79,10 +79,8 @@ uint32_t OPENSSL_armcap_P =
#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;
+uint32_t OPENSSL_armcap_P = 0;
#endif
#endif
@@ -138,3 +136,7 @@ int CRYPTO_malloc_init(void) {
}
void ENGINE_load_builtin_engines(void) {}
+
+void OPENSSL_load_builtin_modules(void) {}
+
+int FIPS_mode(void) { return 0; }
diff --git a/src/crypto/curve25519/CMakeLists.txt b/src/crypto/curve25519/CMakeLists.txt
index a2ef3bb2..195b1e6a 100644
--- a/src/crypto/curve25519/CMakeLists.txt
+++ b/src/crypto/curve25519/CMakeLists.txt
@@ -22,6 +22,7 @@ add_library(
OBJECT
curve25519.c
+ spake25519.c
x25519-x86_64.c
${CURVE25519_ARCH_SOURCES}
@@ -45,3 +46,12 @@ add_executable(
target_link_libraries(x25519_test crypto)
add_dependencies(all_tests x25519_test)
+
+add_executable(
+ spake25519_test
+
+ spake25519_test.cc
+)
+
+target_link_libraries(spake25519_test crypto)
+add_dependencies(all_tests spake25519_test)
diff --git a/src/crypto/curve25519/asm/x25519-asm-arm.S b/src/crypto/curve25519/asm/x25519-asm-arm.S
index 60d08dd5..3af1dba9 100644
--- a/src/crypto/curve25519/asm/x25519-asm-arm.S
+++ b/src/crypto/curve25519/asm/x25519-asm-arm.S
@@ -17,6 +17,9 @@
* domain licensed but the standard ISC license is included above to keep
* licensing simple. */
+#if !defined(OPENSSL_NO_ASM)
+#if defined(__arm__)
+
.fpu neon
.text
.align 4
@@ -2116,3 +2119,6 @@ ldr r0,=0
mov sp,r12
vpop {q4,q5,q6,q7}
bx lr
+
+#endif /* __arm__ */
+#endif /* !OPENSSL_NO_ASM */
diff --git a/src/crypto/curve25519/asm/x25519-asm-x86_64.S b/src/crypto/curve25519/asm/x25519-asm-x86_64.S
index 7e86a231..531ac163 100644
--- a/src/crypto/curve25519/asm/x25519-asm-x86_64.S
+++ b/src/crypto/curve25519/asm/x25519-asm-x86_64.S
@@ -17,6 +17,9 @@
* domain licensed but the standard ISC license is included above to keep
* licensing simple. */
+#if !defined(OPENSSL_NO_ASM)
+#if defined(__x86_64__)
+
.data
.p2align 4
@@ -1929,3 +1932,6 @@ add %r11,%rsp
mov %rdi,%rax
mov %rsi,%rdx
ret
+
+#endif /* __x86_64__ */
+#endif /* !OPENSSL_NO_ASM */
diff --git a/src/crypto/curve25519/curve25519.c b/src/crypto/curve25519/curve25519.c
index 272db6c1..1dd1b3ed 100644
--- a/src/crypto/curve25519/curve25519.c
+++ b/src/crypto/curve25519/curve25519.c
@@ -31,11 +31,10 @@
#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 const int64_t kBottom25Bits = INT64_C(0x1ffffff);
+static const int64_t kBottom26Bits = INT64_C(0x3ffffff);
+static const int64_t kTop39Bits = INT64_C(0xfffffffffe000000);
+static const int64_t kTop38Bits = INT64_C(0xfffffffffc000000);
static uint64_t load_3(const uint8_t *in) {
uint64_t result;
@@ -77,17 +76,17 @@ static void fe_frombytes(fe h, const uint8_t *s) {
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;
+ carry9 = h9 + (1 << 24); h0 += (carry9 >> 25) * 19; h9 -= carry9 & kTop39Bits;
+ carry1 = h1 + (1 << 24); h2 += carry1 >> 25; h1 -= carry1 & kTop39Bits;
+ carry3 = h3 + (1 << 24); h4 += carry3 >> 25; h3 -= carry3 & kTop39Bits;
+ carry5 = h5 + (1 << 24); h6 += carry5 >> 25; h5 -= carry5 & kTop39Bits;
+ carry7 = h7 + (1 << 24); h8 += carry7 >> 25; h7 -= carry7 & kTop39Bits;
- 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;
+ carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
+ carry2 = h2 + (1 << 25); h3 += carry2 >> 26; h2 -= carry2 & kTop38Bits;
+ carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
+ carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & kTop38Bits;
+ carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & kTop38Bits;
h[0] = h0;
h[1] = h1;
@@ -135,16 +134,6 @@ static void fe_tobytes(uint8_t *s, const fe h) {
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;
@@ -162,16 +151,16 @@ static void fe_tobytes(uint8_t *s, const fe h) {
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;
+ h1 += h0 >> 26; h0 &= kBottom26Bits;
+ h2 += h1 >> 25; h1 &= kBottom25Bits;
+ h3 += h2 >> 26; h2 &= kBottom26Bits;
+ h4 += h3 >> 25; h3 &= kBottom25Bits;
+ h5 += h4 >> 26; h4 &= kBottom26Bits;
+ h6 += h5 >> 25; h5 &= kBottom25Bits;
+ h7 += h6 >> 26; h6 &= kBottom26Bits;
+ h8 += h7 >> 25; h7 &= kBottom25Bits;
+ h9 += h8 >> 26; h8 &= kBottom26Bits;
+ h9 &= kBottom25Bits;
/* h10 = carry9 */
/* Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20.
@@ -182,32 +171,32 @@ static void fe_tobytes(uint8_t *s, const fe h) {
s[0] = h0 >> 0;
s[1] = h0 >> 8;
s[2] = h0 >> 16;
- s[3] = (h0 >> 24) | (h1 << 2);
+ s[3] = (h0 >> 24) | ((uint32_t)(h1) << 2);
s[4] = h1 >> 6;
s[5] = h1 >> 14;
- s[6] = (h1 >> 22) | (h2 << 3);
+ s[6] = (h1 >> 22) | ((uint32_t)(h2) << 3);
s[7] = h2 >> 5;
s[8] = h2 >> 13;
- s[9] = (h2 >> 21) | (h3 << 5);
+ s[9] = (h2 >> 21) | ((uint32_t)(h3) << 5);
s[10] = h3 >> 3;
s[11] = h3 >> 11;
- s[12] = (h3 >> 19) | (h4 << 6);
+ s[12] = (h3 >> 19) | ((uint32_t)(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[19] = (h5 >> 24) | ((uint32_t)(h6) << 1);
s[20] = h6 >> 7;
s[21] = h6 >> 15;
- s[22] = (h6 >> 23) | (h7 << 3);
+ s[22] = (h6 >> 23) | ((uint32_t)(h7) << 3);
s[23] = h7 >> 5;
s[24] = h7 >> 13;
- s[25] = (h7 >> 21) | (h8 << 4);
+ s[25] = (h7 >> 21) | ((uint32_t)(h8) << 4);
s[26] = h8 >> 4;
s[27] = h8 >> 12;
- s[28] = (h8 >> 20) | (h9 << 6);
+ s[28] = (h8 >> 20) | ((uint32_t)(h9) << 6);
s[29] = h9 >> 2;
s[30] = h9 >> 10;
s[31] = h9 >> 18;
@@ -447,46 +436,46 @@ static void fe_mul(fe h, const fe f, const fe g) {
* |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;
+ carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
+ carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
/* |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;
+ carry1 = h1 + (1 << 24); h2 += carry1 >> 25; h1 -= carry1 & kTop39Bits;
+ carry5 = h5 + (1 << 24); h6 += carry5 >> 25; h5 -= carry5 & kTop39Bits;
/* |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;
+ carry2 = h2 + (1 << 25); h3 += carry2 >> 26; h2 -= carry2 & kTop38Bits;
+ carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & kTop38Bits;
/* |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;
+ carry3 = h3 + (1 << 24); h4 += carry3 >> 25; h3 -= carry3 & kTop39Bits;
+ carry7 = h7 + (1 << 24); h8 += carry7 >> 25; h7 -= carry7 & kTop39Bits;
/* |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;
+ carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
+ carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & kTop38Bits;
/* |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;
+ carry9 = h9 + (1 << 24); h0 += (carry9 >> 25) * 19; h9 -= carry9 & kTop39Bits;
/* |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;
+ carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
/* |h0| <= 2^25; from now on fits into int32 unchanged */
/* |h1| <= 1.01*2^24 */
@@ -612,24 +601,24 @@ static void fe_sq(fe h, const fe f) {
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;
+ carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
+ carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
- carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
- carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
+ carry1 = h1 + (1 << 24); h2 += carry1 >> 25; h1 -= carry1 & kTop39Bits;
+ carry5 = h5 + (1 << 24); h6 += carry5 >> 25; h5 -= carry5 & kTop39Bits;
- carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
- carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
+ carry2 = h2 + (1 << 25); h3 += carry2 >> 26; h2 -= carry2 & kTop38Bits;
+ carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & kTop38Bits;
- carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
- carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
+ carry3 = h3 + (1 << 24); h4 += carry3 >> 25; h3 -= carry3 & kTop39Bits;
+ carry7 = h7 + (1 << 24); h8 += carry7 >> 25; h7 -= carry7 & kTop39Bits;
- carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
- carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
+ carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
+ carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & kTop38Bits;
- carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
+ carry9 = h9 + (1 << 24); h0 += (carry9 >> 25) * 19; h9 -= carry9 & kTop39Bits;
- carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
+ carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
h[0] = h0;
h[1] = h1;
@@ -880,24 +869,24 @@ static void fe_sq2(fe h, const fe f) {
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;
+ carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
+ carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
- carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
- carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
+ carry1 = h1 + (1 << 24); h2 += carry1 >> 25; h1 -= carry1 & kTop39Bits;
+ carry5 = h5 + (1 << 24); h6 += carry5 >> 25; h5 -= carry5 & kTop39Bits;
- carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
- carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
+ carry2 = h2 + (1 << 25); h3 += carry2 >> 26; h2 -= carry2 & kTop38Bits;
+ carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & kTop38Bits;
- carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
- carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
+ carry3 = h3 + (1 << 24); h4 += carry3 >> 25; h3 -= carry3 & kTop39Bits;
+ carry7 = h7 + (1 << 24); h8 += carry7 >> 25; h7 -= carry7 & kTop39Bits;
- carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
- carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
+ carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
+ carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & kTop38Bits;
- carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
+ carry9 = h9 + (1 << 24); h0 += (carry9 >> 25) * 19; h9 -= carry9 & kTop39Bits;
- carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
+ carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
h[0] = h0;
h[1] = h1;
@@ -974,52 +963,7 @@ static void fe_pow22523(fe out, const fe z) {
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) {
+void x25519_ge_tobytes(uint8_t *s, const ge_p2 *h) {
fe recip;
fe x;
fe y;
@@ -1049,7 +993,7 @@ static const fe d = {-10913610, 13857413, -15372611, 6949391, 114729,
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) {
+int x25519_ge_frombytes_vartime(ge_p3 *h, const uint8_t *s) {
fe u;
fe v;
fe v3;
@@ -1084,7 +1028,7 @@ static int ge_frombytes_negate_vartime(ge_p3 *h, const uint8_t *s) {
fe_mul(h->X, h->X, sqrtm1);
}
- if (fe_isnegative(h->X) == (s[31] >> 7)) {
+ if (fe_isnegative(h->X) != (s[31] >> 7)) {
fe_neg(h->X, h->X);
}
@@ -1105,6 +1049,13 @@ static void ge_p3_0(ge_p3 *h) {
fe_0(h->T);
}
+static void ge_cached_0(ge_cached *h) {
+ fe_1(h->YplusX);
+ fe_1(h->YminusX);
+ fe_1(h->Z);
+ fe_0(h->T2d);
+}
+
static void ge_precomp_0(ge_precomp *h) {
fe_1(h->yplusx);
fe_1(h->yminusx);
@@ -1122,7 +1073,7 @@ 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) {
+void x25519_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);
@@ -1130,20 +1081,27 @@ static void ge_p3_to_cached(ge_cached *r, const ge_p3 *p) {
}
/* r = p */
-static void ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p) {
+void x25519_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) {
+void x25519_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 = p */
+static void ge_p1p1_to_cached(ge_cached *r, const ge_p1p1 *p) {
+ ge_p3 t;
+ x25519_ge_p1p1_to_p3(&t, p);
+ x25519_ge_p3_to_cached(r, &t);
+}
+
/* r = 2 * p */
static void ge_p2_dbl(ge_p1p1 *r, const ge_p2 *p) {
fe t0;
@@ -1199,7 +1157,7 @@ static void ge_msub(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) {
}
/* r = p + q */
-static void ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) {
+void x25519_ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) {
fe t0;
fe_add(r->X, p->Y, p->X);
@@ -1216,7 +1174,7 @@ static void ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) {
}
/* r = p - q */
-static void ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) {
+void x25519_ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) {
fe t0;
fe_add(r->X, p->Y, p->X);
@@ -1242,12 +1200,64 @@ static uint8_t equal(signed char b, signed char c) {
return y;
}
-static void cmov(ge_precomp *t, ge_precomp *u, uint8_t b) {
+static void cmov(ge_precomp *t, const 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);
}
+void x25519_ge_scalarmult_small_precomp(
+ ge_p3 *h, const uint8_t a[32], const uint8_t precomp_table[15 * 2 * 32]) {
+ /* precomp_table is first expanded into matching |ge_precomp|
+ * elements. */
+ ge_precomp multiples[15];
+
+ unsigned i;
+ for (i = 0; i < 15; i++) {
+ const uint8_t *bytes = &precomp_table[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 |k25519SmallPrecomp| 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;
+ x25519_ge_p3_to_cached(&cached, h);
+ x25519_ge_add(&r, h, &cached);
+ x25519_ge_p1p1_to_p3(h, &r);
+
+ ge_madd(&r, h, &e);
+ x25519_ge_p1p1_to_p3(h, &r);
+ }
+}
+
#if defined(OPENSSL_SMALL)
/* This block of code replaces the standard base-point table with a much smaller
@@ -1258,7 +1268,7 @@ static void cmov(ge_precomp *t, ge_precomp *u, uint8_t b) {
* 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] = {
+static const uint8_t k25519SmallPrecomp[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,
@@ -1341,60 +1351,14 @@ static const uint8_t kSmallPrecomp[15 * 2 * 32] = {
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);
- }
+void x25519_ge_scalarmult_base(ge_p3 *h, const uint8_t a[32]) {
+ x25519_ge_scalarmult_small_precomp(h, a, k25519SmallPrecomp);
}
#else
-/* base[i][j] = (j+1)*256^i*B */
-static ge_precomp base[32][8] = {
+/* k25519Precomp[i][j] = (j+1)*256^i*B */
+static const ge_precomp k25519Precomp[32][8] = {
{
{
{25967493, -14356035, 29566456, 3660896, -12694345, 4014787,
@@ -3518,17 +3482,17 @@ static uint8_t negative(signed char b) {
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);
+ uint8_t babs = b - ((uint8_t)((-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));
+ cmov(t, &k25519Precomp[pos][0], equal(babs, 1));
+ cmov(t, &k25519Precomp[pos][1], equal(babs, 2));
+ cmov(t, &k25519Precomp[pos][2], equal(babs, 3));
+ cmov(t, &k25519Precomp[pos][3], equal(babs, 4));
+ cmov(t, &k25519Precomp[pos][4], equal(babs, 5));
+ cmov(t, &k25519Precomp[pos][5], equal(babs, 6));
+ cmov(t, &k25519Precomp[pos][6], equal(babs, 7));
+ cmov(t, &k25519Precomp[pos][7], equal(babs, 8));
fe_copy(minust.yplusx, t->yminusx);
fe_copy(minust.yminusx, t->yplusx);
fe_neg(minust.xy2d, t->xy2d);
@@ -3541,7 +3505,7 @@ static void table_select(ge_precomp *t, int pos, signed char b) {
*
* Preconditions:
* a[31] <= 127 */
-static void ge_scalarmult_base(ge_p3 *h, const uint8_t *a) {
+void x25519_ge_scalarmult_base(ge_p3 *h, const uint8_t *a) {
signed char e[64];
signed char carry;
ge_p1p1 r;
@@ -3570,27 +3534,88 @@ static void ge_scalarmult_base(ge_p3 *h, const uint8_t *a) {
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);
+ x25519_ge_p1p1_to_p3(h, &r);
}
ge_p3_dbl(&r, h);
- ge_p1p1_to_p2(&s, &r);
+ x25519_ge_p1p1_to_p2(&s, &r);
ge_p2_dbl(&r, &s);
- ge_p1p1_to_p2(&s, &r);
+ x25519_ge_p1p1_to_p2(&s, &r);
ge_p2_dbl(&r, &s);
- ge_p1p1_to_p2(&s, &r);
+ x25519_ge_p1p1_to_p2(&s, &r);
ge_p2_dbl(&r, &s);
- ge_p1p1_to_p3(h, &r);
+ x25519_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);
+ x25519_ge_p1p1_to_p3(h, &r);
}
}
#endif
+static void cmov_cached(ge_cached *t, ge_cached *u, uint8_t b) {
+ fe_cmov(t->YplusX, u->YplusX, b);
+ fe_cmov(t->YminusX, u->YminusX, b);
+ fe_cmov(t->Z, u->Z, b);
+ fe_cmov(t->T2d, u->T2d, b);
+}
+
+/* r = scalar * A.
+ * where a = a[0]+256*a[1]+...+256^31 a[31]. */
+void x25519_ge_scalarmult(ge_p2 *r, const uint8_t *scalar, const ge_p3 *A) {
+ ge_p2 Ai_p2[8];
+ ge_cached Ai[16];
+ ge_p1p1 t;
+
+ ge_cached_0(&Ai[0]);
+ x25519_ge_p3_to_cached(&Ai[1], A);
+ ge_p3_to_p2(&Ai_p2[1], A);
+
+ unsigned i;
+ for (i = 2; i < 16; i += 2) {
+ ge_p2_dbl(&t, &Ai_p2[i / 2]);
+ ge_p1p1_to_cached(&Ai[i], &t);
+ if (i < 8) {
+ x25519_ge_p1p1_to_p2(&Ai_p2[i], &t);
+ }
+ x25519_ge_add(&t, A, &Ai[i]);
+ ge_p1p1_to_cached(&Ai[i + 1], &t);
+ if (i < 7) {
+ x25519_ge_p1p1_to_p2(&Ai_p2[i + 1], &t);
+ }
+ }
+
+ ge_p2_0(r);
+ ge_p3 u;
+
+ for (i = 0; i < 256; i += 4) {
+ ge_p2_dbl(&t, r);
+ x25519_ge_p1p1_to_p2(r, &t);
+ ge_p2_dbl(&t, r);
+ x25519_ge_p1p1_to_p2(r, &t);
+ ge_p2_dbl(&t, r);
+ x25519_ge_p1p1_to_p2(r, &t);
+ ge_p2_dbl(&t, r);
+ x25519_ge_p1p1_to_p3(&u, &t);
+
+ uint8_t index = scalar[31 - i/8];
+ index >>= 4 - (i & 4);
+ index &= 0xf;
+
+ unsigned j;
+ ge_cached selected;
+ ge_cached_0(&selected);
+ for (j = 0; j < 16; j++) {
+ cmov_cached(&selected, &Ai[j], equal(j, index));
+ }
+
+ x25519_ge_add(&t, &u, &selected);
+ x25519_ge_p1p1_to_p2(r, &t);
+ }
+}
+
static void slide(signed char *r, const uint8_t *a) {
int i;
int b;
@@ -3625,7 +3650,7 @@ static void slide(signed char *r, const uint8_t *a) {
}
}
-static ge_precomp Bi[8] = {
+static const ge_precomp Bi[8] = {
{
{25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626,
-11754271, -6079156, 2047605},
@@ -3696,8 +3721,8 @@ static ge_precomp Bi[8] = {
* 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) {
+static 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 */
@@ -3709,30 +3734,30 @@ void ge_double_scalarmult_vartime(ge_p2 *r, const uint8_t *a,
slide(aslide, a);
slide(bslide, b);
- ge_p3_to_cached(&Ai[0], A);
+ x25519_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);
+ x25519_ge_p1p1_to_p3(&A2, &t);
+ x25519_ge_add(&t, &A2, &Ai[0]);
+ x25519_ge_p1p1_to_p3(&u, &t);
+ x25519_ge_p3_to_cached(&Ai[1], &u);
+ x25519_ge_add(&t, &A2, &Ai[1]);
+ x25519_ge_p1p1_to_p3(&u, &t);
+ x25519_ge_p3_to_cached(&Ai[2], &u);
+ x25519_ge_add(&t, &A2, &Ai[2]);
+ x25519_ge_p1p1_to_p3(&u, &t);
+ x25519_ge_p3_to_cached(&Ai[3], &u);
+ x25519_ge_add(&t, &A2, &Ai[3]);
+ x25519_ge_p1p1_to_p3(&u, &t);
+ x25519_ge_p3_to_cached(&Ai[4], &u);
+ x25519_ge_add(&t, &A2, &Ai[4]);
+ x25519_ge_p1p1_to_p3(&u, &t);
+ x25519_ge_p3_to_cached(&Ai[5], &u);
+ x25519_ge_add(&t, &A2, &Ai[5]);
+ x25519_ge_p1p1_to_p3(&u, &t);
+ x25519_ge_p3_to_cached(&Ai[6], &u);
+ x25519_ge_add(&t, &A2, &Ai[6]);
+ x25519_ge_p1p1_to_p3(&u, &t);
+ x25519_ge_p3_to_cached(&Ai[7], &u);
ge_p2_0(r);
@@ -3746,22 +3771,22 @@ void ge_double_scalarmult_vartime(ge_p2 *r, const uint8_t *a,
ge_p2_dbl(&t, r);
if (aslide[i] > 0) {
- ge_p1p1_to_p3(&u, &t);
- ge_add(&t, &u, &Ai[aslide[i] / 2]);
+ x25519_ge_p1p1_to_p3(&u, &t);
+ x25519_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]);
+ x25519_ge_p1p1_to_p3(&u, &t);
+ x25519_ge_sub(&t, &u, &Ai[(-aslide[i]) / 2]);
}
if (bslide[i] > 0) {
- ge_p1p1_to_p3(&u, &t);
+ x25519_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);
+ x25519_ge_p1p1_to_p3(&u, &t);
ge_msub(&t, &u, &Bi[(-bslide[i]) / 2]);
}
- ge_p1p1_to_p2(r, &t);
+ x25519_ge_p1p1_to_p2(r, &t);
}
}
@@ -3775,7 +3800,7 @@ void ge_double_scalarmult_vartime(ge_p2 *r, const uint8_t *a,
* 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) {
+void x25519_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);
@@ -4609,7 +4634,7 @@ void ED25519_keypair(uint8_t out_public_key[32], uint8_t out_private_key[64]) {
az[31] |= 64;
ge_p3 A;
- ge_scalarmult_base(&A, az);
+ x25519_ge_scalarmult_base(&A, az);
ge_p3_tobytes(out_public_key, &A);
memcpy(out_private_key, seed, 32);
@@ -4632,9 +4657,9 @@ int ED25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len,
uint8_t nonce[SHA512_DIGEST_LENGTH];
SHA512_Final(nonce, &hash_ctx);
- sc_reduce(nonce);
+ x25519_sc_reduce(nonce);
ge_p3 R;
- ge_scalarmult_base(&R, nonce);
+ x25519_ge_scalarmult_base(&R, nonce);
ge_p3_tobytes(out_sig, &R);
SHA512_Init(&hash_ctx);
@@ -4644,7 +4669,7 @@ int ED25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len,
uint8_t hram[SHA512_DIGEST_LENGTH];
SHA512_Final(hram, &hash_ctx);
- sc_reduce(hram);
+ x25519_sc_reduce(hram);
sc_muladd(out_sig + 32, hram, az, nonce);
return 1;
@@ -4654,10 +4679,13 @@ 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) {
+ x25519_ge_frombytes_vartime(&A, public_key) != 0) {
return 0;
}
+ fe_neg(A.X, A.X);
+ fe_neg(A.T, A.T);
+
uint8_t pkcopy[32];
memcpy(pkcopy, public_key, 32);
uint8_t rcopy[32];
@@ -4673,13 +4701,13 @@ int ED25519_verify(const uint8_t *message, size_t message_len,
uint8_t h[SHA512_DIGEST_LENGTH];
SHA512_Final(h, &hash_ctx);
- sc_reduce(h);
+ x25519_sc_reduce(h);
ge_p2 R;
ge_double_scalarmult_vartime(&R, h, &A, scopy);
uint8_t rcheck[32];
- ge_tobytes(rcheck, &R);
+ x25519_ge_tobytes(rcheck, &R);
return CRYPTO_memcmp(rcheck, rcopy, sizeof(rcheck)) == 0;
}
@@ -4749,17 +4777,17 @@ static void fe_mul121666(fe h, fe f) {
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;
+ carry9 = h9 + (1 << 24); h0 += (carry9 >> 25) * 19; h9 -= carry9 & kTop39Bits;
+ carry1 = h1 + (1 << 24); h2 += carry1 >> 25; h1 -= carry1 & kTop39Bits;
+ carry3 = h3 + (1 << 24); h4 += carry3 >> 25; h3 -= carry3 & kTop39Bits;
+ carry5 = h5 + (1 << 24); h6 += carry5 >> 25; h5 -= carry5 & kTop39Bits;
+ carry7 = h7 + (1 << 24); h8 += carry7 >> 25; h7 -= carry7 & kTop39Bits;
- 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;
+ carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
+ carry2 = h2 + (1 << 25); h3 += carry2 >> 26; h2 -= carry2 & kTop38Bits;
+ carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
+ carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & kTop38Bits;
+ carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & kTop38Bits;
h[0] = h0;
h[1] = h1;
@@ -4883,7 +4911,7 @@ void X25519_public_from_private(uint8_t out_public_value[32],
e[31] |= 64;
ge_p3 A;
- ge_scalarmult_base(&A, e);
+ x25519_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). */
diff --git a/src/crypto/curve25519/internal.h b/src/crypto/curve25519/internal.h
index 27994b7b..ea206a3e 100644
--- a/src/crypto/curve25519/internal.h
+++ b/src/crypto/curve25519/internal.h
@@ -37,6 +37,70 @@ void x25519_NEON(uint8_t out[32], const uint8_t scalar[32],
const uint8_t point[32]);
#endif
+/* 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];
+
+/* 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;
+
+void x25519_ge_tobytes(uint8_t *s, const ge_p2 *h);
+int x25519_ge_frombytes_vartime(ge_p3 *h, const uint8_t *s);
+void x25519_ge_p3_to_cached(ge_cached *r, const ge_p3 *p);
+void x25519_ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p);
+void x25519_ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *p);
+void x25519_ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q);
+void x25519_ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q);
+void x25519_ge_scalarmult_small_precomp(
+ ge_p3 *h, const uint8_t a[32], const uint8_t precomp_table[15 * 2 * 32]);
+void x25519_ge_scalarmult_base(ge_p3 *h, const uint8_t a[32]);
+void x25519_ge_scalarmult(ge_p2 *r, const uint8_t *scalar, const ge_p3 *A);
+void x25519_sc_reduce(uint8_t *s);
+
#if defined(__cplusplus)
} /* extern C */
diff --git a/src/crypto/curve25519/spake25519.c b/src/crypto/curve25519/spake25519.c
new file mode 100644
index 00000000..617418cf
--- /dev/null
+++ b/src/crypto/curve25519/spake25519.c
@@ -0,0 +1,464 @@
+/* Copyright (c) 2016, 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 <string.h>
+
+#include <openssl/bytestring.h>
+#include <openssl/mem.h>
+#include <openssl/rand.h>
+#include <openssl/sha.h>
+
+#include "internal.h"
+
+
+/* The following precomputation tables are for the following
+ * points used in the SPAKE2 protocol.
+ *
+ * N:
+ * x: 49918732221787544735331783592030787422991506689877079631459872391322455579424
+ * y: 54629554431565467720832445949441049581317094546788069926228343916274969994000
+ * encoded: 10e3df0ae37d8e7a99b5fe74b44672103dbddcbd06af680d71329a11693bc778
+ *
+ * M:
+ * x: 31406539342727633121250288103050113562375374900226415211311216773867585644232
+ * y: 21177308356423958466833845032658859666296341766942662650232962324899758529114
+ * encoded: 5ada7e4bf6ddd9adb6626d32131c6b5c51a1e347a3478f53cfcf441b88eed12e
+ *
+ * These points and their precomputation tables are generated with the
+ * following Python code. For a description of the precomputation table,
+ * see curve25519.c in this directory.
+ *
+ * Exact copies of the source code are kept in bug 27296743.
+ *
+ * import hashlib
+ * import ed25519 as E # http://ed25519.cr.yp.to/python/ed25519.py
+ *
+ * SEED_N = 'edwards25519 point generation seed (N)'
+ * SEED_M = 'edwards25519 point generation seed (M)'
+ *
+ * def genpoint(seed):
+ * v = hashlib.sha256(seed).digest()
+ * it = 1
+ * while True:
+ * try:
+ * x,y = E.decodepoint(v)
+ * except Exception, e:
+ * print e
+ * it += 1
+ * v = hashlib.sha256(v).digest()
+ * continue
+ * print "Found in %d iterations:" % it
+ * print " x = %d" % x
+ * print " y = %d" % y
+ * print " Encoded (hex)"
+ * print E.encodepoint((x,y)).encode('hex')
+ * return (x,y)
+ *
+ * def gentable(P):
+ * t = []
+ * for i in range(1,16):
+ * k = (i >> 3 & 1) * (1 << 192) + \
+ * (i >> 2 & 1) * (1 << 128) + \
+ * (i >> 1 & 1) * (1 << 64) + \
+ * (i & 1)
+ * t.append(E.scalarmult(P, k))
+ * return ''.join(E.encodeint(x) + E.encodeint(y) for (x,y) in t)
+ *
+ * def printtable(table, name):
+ * print "static const uint8_t %s[15 * 2 * 32] = {" % name,
+ * for i in range(15 * 2 * 32):
+ * if i % 12 == 0:
+ * print "\n ",
+ * print " 0x%02x," % ord(table[i]),
+ * print "\n};"
+ *
+ * if __name__ == "__main__":
+ * print "Searching for N"
+ * N = genpoint(SEED_N)
+ * print "Generating precomputation table for N"
+ * Ntable = gentable(N)
+ * printtable(Ntable, "kSpakeNSmallPrecomp")
+ *
+ * print "Searching for M"
+ * M = genpoint(SEED_M)
+ * print "Generating precomputation table for M"
+ * Mtable = gentable(M)
+ * printtable(Mtable, "kSpakeMSmallPrecomp")
+ */
+static const uint8_t kSpakeNSmallPrecomp[15 * 2 * 32] = {
+ 0x20, 0x1b, 0xc5, 0xb3, 0x43, 0x17, 0x71, 0x10, 0x44, 0x1e, 0x73, 0xb3,
+ 0xae, 0x3f, 0xbf, 0x9f, 0xf5, 0x44, 0xc8, 0x13, 0x8f, 0xd1, 0x01, 0xc2,
+ 0x8a, 0x1a, 0x6d, 0xea, 0x4d, 0x00, 0x5d, 0x6e, 0x10, 0xe3, 0xdf, 0x0a,
+ 0xe3, 0x7d, 0x8e, 0x7a, 0x99, 0xb5, 0xfe, 0x74, 0xb4, 0x46, 0x72, 0x10,
+ 0x3d, 0xbd, 0xdc, 0xbd, 0x06, 0xaf, 0x68, 0x0d, 0x71, 0x32, 0x9a, 0x11,
+ 0x69, 0x3b, 0xc7, 0x78, 0x93, 0xf1, 0x57, 0x97, 0x6e, 0xf0, 0x6e, 0x45,
+ 0x37, 0x4a, 0xf4, 0x0b, 0x18, 0x51, 0xf5, 0x4f, 0x67, 0x3c, 0xdc, 0xec,
+ 0x84, 0xed, 0xd0, 0xeb, 0xca, 0xfb, 0xdb, 0xff, 0x7f, 0xeb, 0xa8, 0x23,
+ 0x68, 0x87, 0x13, 0x64, 0x6a, 0x10, 0xf7, 0x45, 0xe0, 0x0f, 0x32, 0x21,
+ 0x59, 0x7c, 0x0e, 0x50, 0xad, 0x56, 0xd7, 0x12, 0x69, 0x7b, 0x58, 0xf8,
+ 0xb9, 0x3b, 0xa5, 0xbb, 0x4d, 0x1b, 0x87, 0x1c, 0x46, 0xa7, 0x17, 0x9d,
+ 0x6d, 0x84, 0x45, 0xbe, 0x7f, 0x95, 0xd2, 0x34, 0xcd, 0x89, 0x95, 0xc0,
+ 0xf0, 0xd3, 0xdf, 0x6e, 0x10, 0x4a, 0xe3, 0x7b, 0xce, 0x7f, 0x40, 0x27,
+ 0xc7, 0x2b, 0xab, 0x66, 0x03, 0x59, 0xb4, 0x7b, 0xc7, 0xc7, 0xf0, 0x39,
+ 0x9a, 0x33, 0x35, 0xbf, 0xcc, 0x2f, 0xf3, 0x2e, 0x68, 0x9d, 0x53, 0x5c,
+ 0x88, 0x52, 0xe3, 0x77, 0x90, 0xa1, 0x27, 0x85, 0xc5, 0x74, 0x7f, 0x23,
+ 0x0e, 0x93, 0x01, 0x3e, 0xe7, 0x2e, 0x2e, 0x95, 0xf3, 0x0d, 0xc2, 0x25,
+ 0x25, 0x39, 0x39, 0x3d, 0x6e, 0x8e, 0x89, 0xbd, 0xe8, 0xbb, 0x67, 0x5e,
+ 0x8c, 0x66, 0x8b, 0x63, 0x28, 0x1e, 0x4e, 0x74, 0x85, 0xa8, 0xaf, 0x0f,
+ 0x12, 0x5d, 0xb6, 0x8a, 0x83, 0x1a, 0x77, 0x76, 0x5e, 0x62, 0x8a, 0xa7,
+ 0x3c, 0xb8, 0x05, 0x57, 0x2b, 0xaf, 0x36, 0x2e, 0x10, 0x90, 0xb2, 0x39,
+ 0xb4, 0x3e, 0x75, 0x6d, 0x3a, 0xa8, 0x31, 0x35, 0xc2, 0x1e, 0x8f, 0xc2,
+ 0x79, 0x89, 0x35, 0x16, 0x26, 0xd1, 0xc7, 0x0b, 0x04, 0x1f, 0x1d, 0xf9,
+ 0x9c, 0x05, 0xa6, 0x6b, 0xb5, 0x19, 0x5a, 0x24, 0x6d, 0x91, 0xc5, 0x31,
+ 0xfd, 0xc5, 0xfa, 0xe7, 0xa6, 0xcb, 0x0e, 0x4b, 0x18, 0x0d, 0x94, 0xc7,
+ 0xee, 0x1d, 0x46, 0x1f, 0x92, 0xb1, 0xb2, 0x4a, 0x2b, 0x43, 0x37, 0xfe,
+ 0xc2, 0x15, 0x11, 0x89, 0xef, 0x59, 0x73, 0x3c, 0x06, 0x76, 0x78, 0xcb,
+ 0xa6, 0x0d, 0x79, 0x5f, 0x28, 0x0b, 0x5b, 0x8c, 0x9e, 0xe4, 0xaa, 0x51,
+ 0x9a, 0x42, 0x6f, 0x11, 0x50, 0x3d, 0x01, 0xd6, 0x21, 0xc0, 0x99, 0x5e,
+ 0x1a, 0xe8, 0x81, 0x25, 0x80, 0xeb, 0xed, 0x5d, 0x37, 0x47, 0x30, 0x70,
+ 0xa0, 0x4e, 0x0b, 0x43, 0x17, 0xbe, 0xb6, 0x47, 0xe7, 0x2a, 0x62, 0x9d,
+ 0x5d, 0xa6, 0xc5, 0x33, 0x62, 0x9d, 0x56, 0x24, 0x9d, 0x1d, 0xb2, 0x13,
+ 0xbc, 0x17, 0x66, 0x43, 0xd1, 0x68, 0xd5, 0x3b, 0x17, 0x69, 0x17, 0xa6,
+ 0x06, 0x9e, 0x12, 0xb8, 0x7c, 0xd5, 0xaf, 0x3e, 0x21, 0x1b, 0x31, 0xeb,
+ 0x0b, 0xa4, 0x98, 0x1c, 0xf2, 0x6a, 0x5e, 0x7c, 0x9b, 0x45, 0x8f, 0xb2,
+ 0x12, 0x06, 0xd5, 0x8c, 0x1d, 0xb2, 0xa7, 0x57, 0x5f, 0x2f, 0x4f, 0xdb,
+ 0x52, 0x99, 0x7c, 0x58, 0x01, 0x5f, 0xf2, 0xa5, 0xf6, 0x51, 0x86, 0x21,
+ 0x2f, 0x5b, 0x8d, 0x6a, 0xae, 0x83, 0x34, 0x6d, 0x58, 0x4b, 0xef, 0xfe,
+ 0xbf, 0x73, 0x5d, 0xdb, 0xc4, 0x97, 0x2a, 0x85, 0xf3, 0x6c, 0x46, 0x42,
+ 0xb3, 0x90, 0xc1, 0x57, 0x97, 0x50, 0x35, 0xb1, 0x9d, 0xb7, 0xc7, 0x3c,
+ 0x85, 0x6d, 0x6c, 0xfd, 0xce, 0xb0, 0xc9, 0xa2, 0x77, 0xee, 0xc3, 0x6b,
+ 0x0c, 0x37, 0xfa, 0x30, 0x91, 0xd1, 0x2c, 0xb8, 0x5e, 0x7f, 0x81, 0x5f,
+ 0x87, 0xfd, 0x18, 0x02, 0x5a, 0x30, 0x4e, 0x62, 0xbc, 0x65, 0xc6, 0xce,
+ 0x1a, 0xcf, 0x2b, 0xaa, 0x56, 0x3e, 0x4d, 0xcf, 0xba, 0x62, 0x5f, 0x9a,
+ 0xd0, 0x72, 0xff, 0xef, 0x28, 0xbd, 0xbe, 0xd8, 0x57, 0x3d, 0xf5, 0x57,
+ 0x7d, 0xe9, 0x71, 0x31, 0xec, 0x98, 0x90, 0x94, 0xd9, 0x54, 0xbf, 0x84,
+ 0x0b, 0xe3, 0x06, 0x47, 0x19, 0x9a, 0x13, 0x1d, 0xef, 0x9d, 0x13, 0xf3,
+ 0xdb, 0xc3, 0x5c, 0x72, 0x9e, 0xed, 0x24, 0xaa, 0x64, 0xed, 0xe7, 0x0d,
+ 0xa0, 0x7c, 0x73, 0xba, 0x9b, 0x86, 0xa7, 0x3b, 0x55, 0xab, 0x58, 0x30,
+ 0xf1, 0x15, 0x81, 0x83, 0x2f, 0xf9, 0x62, 0x84, 0x98, 0x66, 0xf6, 0x55,
+ 0x21, 0xd8, 0xf2, 0x25, 0x64, 0x71, 0x4b, 0x12, 0x76, 0x59, 0xc5, 0xaa,
+ 0x93, 0x67, 0xc3, 0x86, 0x25, 0xab, 0x4e, 0x4b, 0xf6, 0xd8, 0x3f, 0x44,
+ 0x2e, 0x11, 0xe0, 0xbd, 0x6a, 0xf2, 0x5d, 0xf5, 0xf9, 0x53, 0xea, 0xa4,
+ 0xc8, 0xd9, 0x50, 0x33, 0x81, 0xd9, 0xa8, 0x2d, 0x91, 0x7d, 0x13, 0x2a,
+ 0x11, 0xcf, 0xde, 0x3f, 0x0a, 0xd2, 0xbc, 0x33, 0xb2, 0x62, 0x53, 0xea,
+ 0x77, 0x88, 0x43, 0x66, 0x27, 0x43, 0x85, 0xe9, 0x5f, 0x55, 0xf5, 0x2a,
+ 0x8a, 0xac, 0xdf, 0xff, 0x9b, 0x4c, 0x96, 0x9c, 0xa5, 0x7a, 0xce, 0xd5,
+ 0x79, 0x18, 0xf1, 0x0b, 0x58, 0x95, 0x7a, 0xe7, 0xd3, 0x74, 0x65, 0x0b,
+ 0xa4, 0x64, 0x30, 0xe8, 0x5c, 0xfc, 0x55, 0x56, 0xee, 0x14, 0x14, 0xd3,
+ 0x45, 0x3b, 0xf8, 0xde, 0x05, 0x3e, 0xb9, 0x3c, 0xd7, 0x6a, 0x52, 0x72,
+ 0x5b, 0x39, 0x09, 0xbe, 0x82, 0x23, 0x10, 0x4a, 0xb7, 0xc3, 0xdc, 0x4c,
+ 0x5d, 0xc9, 0xf1, 0x14, 0x83, 0xf9, 0x0b, 0x9b, 0xe9, 0x23, 0x84, 0x6a,
+ 0xc4, 0x08, 0x3d, 0xda, 0x3d, 0x12, 0x95, 0x87, 0x18, 0xa4, 0x7d, 0x3f,
+ 0x23, 0xde, 0xd4, 0x1e, 0xa8, 0x47, 0xc3, 0x71, 0xdb, 0xf5, 0x03, 0x6c,
+ 0x57, 0xe7, 0xa4, 0x43, 0x82, 0x33, 0x7b, 0x62, 0x46, 0x7d, 0xf7, 0x10,
+ 0x69, 0x18, 0x38, 0x27, 0x9a, 0x6f, 0x38, 0xac, 0xfa, 0x92, 0xc5, 0xae,
+ 0x66, 0xa6, 0x73, 0x95, 0x15, 0x0e, 0x4c, 0x04, 0xb6, 0xfc, 0xf5, 0xc7,
+ 0x21, 0x3a, 0x99, 0xdb, 0x0e, 0x36, 0xf0, 0x56, 0xbc, 0x75, 0xf9, 0x87,
+ 0x9b, 0x11, 0x18, 0x92, 0x64, 0x1a, 0xe7, 0xc7, 0xab, 0x5a, 0xc7, 0x26,
+ 0x7f, 0x13, 0x98, 0x42, 0x52, 0x43, 0xdb, 0xc8, 0x6d, 0x0b, 0xb7, 0x31,
+ 0x93, 0x24, 0xd6, 0xe8, 0x24, 0x1f, 0x6f, 0x21, 0xa7, 0x8c, 0xeb, 0xdb,
+ 0x83, 0xb8, 0x89, 0xe3, 0xc1, 0xd7, 0x69, 0x3b, 0x02, 0x6b, 0x54, 0x0f,
+ 0x84, 0x2f, 0xb5, 0x5c, 0x17, 0x77, 0xbe, 0xe5, 0x61, 0x0d, 0xc5, 0xdf,
+ 0x3b, 0xcf, 0x3e, 0x93, 0x4f, 0xf5, 0x89, 0xb9, 0x5a, 0xc5, 0x29, 0x31,
+ 0xc0, 0xc2, 0xff, 0xe5, 0x3f, 0xa6, 0xac, 0x03, 0xca, 0xf5, 0xff, 0xe0,
+ 0x36, 0xce, 0xf3, 0xe2, 0xb7, 0x9c, 0x02, 0xe9, 0x9e, 0xd2, 0xbc, 0x87,
+ 0x2f, 0x3d, 0x9a, 0x1d, 0x8f, 0xc5, 0x72, 0xb8, 0xa2, 0x01, 0xd4, 0x68,
+ 0xb1, 0x84, 0x16, 0x10, 0xf6, 0xf3, 0x52, 0x25, 0xd9, 0xdc, 0x4c, 0xdd,
+ 0x0f, 0xd6, 0x4a, 0xcf, 0x60, 0x96, 0x7e, 0xcc, 0x42, 0x0f, 0x64, 0x9d,
+ 0x72, 0x46, 0x04, 0x07, 0xf2, 0x5b, 0xf4, 0x07, 0xd1, 0xf4, 0x59, 0x71,
+};
+
+static const uint8_t kSpakeMSmallPrecomp[15 * 2 * 32] = {
+ 0xc8, 0xa6, 0x63, 0xc5, 0x97, 0xf1, 0xee, 0x40, 0xab, 0x62, 0x42, 0xee,
+ 0x25, 0x6f, 0x32, 0x6c, 0x75, 0x2c, 0xa7, 0xd3, 0xbd, 0x32, 0x3b, 0x1e,
+ 0x11, 0x9c, 0xbd, 0x04, 0xa9, 0x78, 0x6f, 0x45, 0x5a, 0xda, 0x7e, 0x4b,
+ 0xf6, 0xdd, 0xd9, 0xad, 0xb6, 0x62, 0x6d, 0x32, 0x13, 0x1c, 0x6b, 0x5c,
+ 0x51, 0xa1, 0xe3, 0x47, 0xa3, 0x47, 0x8f, 0x53, 0xcf, 0xcf, 0x44, 0x1b,
+ 0x88, 0xee, 0xd1, 0x2e, 0x03, 0x89, 0xaf, 0xc0, 0x61, 0x2d, 0x9e, 0x35,
+ 0xeb, 0x0e, 0x03, 0xe0, 0xb7, 0xfb, 0xa5, 0xbc, 0x44, 0xbe, 0x0c, 0x89,
+ 0x0a, 0x0f, 0xd6, 0x59, 0x47, 0x9e, 0xe6, 0x3d, 0x36, 0x9d, 0xff, 0x44,
+ 0x5e, 0xac, 0xab, 0xe5, 0x3a, 0xd5, 0xb0, 0x35, 0x9f, 0x6d, 0x7f, 0xba,
+ 0xc0, 0x85, 0x0e, 0xf4, 0x70, 0x3f, 0x13, 0x90, 0x4c, 0x50, 0x1a, 0xee,
+ 0xc5, 0xeb, 0x69, 0xfe, 0x98, 0x42, 0x87, 0x1d, 0xce, 0x6c, 0x29, 0xaa,
+ 0x2b, 0x31, 0xc2, 0x38, 0x7b, 0x6b, 0xee, 0x88, 0x0b, 0xba, 0xce, 0xa8,
+ 0xca, 0x19, 0x60, 0x1b, 0x16, 0xf1, 0x25, 0x1e, 0xcf, 0x63, 0x66, 0x1e,
+ 0xbb, 0x63, 0xeb, 0x7d, 0xca, 0xd2, 0xb4, 0x23, 0x5a, 0x01, 0x6f, 0x05,
+ 0xd1, 0xdc, 0x41, 0x73, 0x75, 0xc0, 0xfd, 0x30, 0x91, 0x52, 0x68, 0x96,
+ 0x45, 0xb3, 0x66, 0x01, 0x3b, 0x53, 0x89, 0x3c, 0x69, 0xbc, 0x6c, 0x69,
+ 0xe3, 0x51, 0x8f, 0xe3, 0xd2, 0x84, 0xd5, 0x28, 0x66, 0xb5, 0xe6, 0x06,
+ 0x09, 0xfe, 0x6d, 0xb0, 0x72, 0x16, 0xe0, 0x8a, 0xce, 0x61, 0x65, 0xa9,
+ 0x21, 0x32, 0x48, 0xdc, 0x7a, 0x1d, 0xe1, 0x38, 0x7f, 0x8c, 0x75, 0x88,
+ 0x3d, 0x08, 0xa9, 0x4a, 0x6f, 0x3d, 0x9f, 0x7f, 0x3f, 0xbd, 0x57, 0x6b,
+ 0x19, 0xce, 0x3f, 0x4a, 0xc9, 0xd3, 0xf9, 0x6e, 0x72, 0x7b, 0x5b, 0x74,
+ 0xea, 0xbe, 0x9c, 0x7a, 0x6d, 0x9c, 0x40, 0x49, 0xe6, 0xfb, 0x2a, 0x1a,
+ 0x75, 0x70, 0xe5, 0x4e, 0xed, 0x74, 0xe0, 0x75, 0xac, 0xc0, 0xb1, 0x11,
+ 0x3e, 0xf2, 0xaf, 0x88, 0x4d, 0x66, 0xb6, 0xf6, 0x15, 0x4f, 0x3c, 0x6c,
+ 0x77, 0xae, 0x47, 0x51, 0x63, 0x9a, 0xfe, 0xe1, 0xb4, 0x1a, 0x12, 0xdf,
+ 0xe9, 0x54, 0x8d, 0x3b, 0x30, 0x2a, 0x75, 0xe3, 0xe5, 0x29, 0xb1, 0x4c,
+ 0xb0, 0x7c, 0x6d, 0xb5, 0xae, 0x85, 0xdb, 0x1e, 0x38, 0x55, 0x96, 0xa5,
+ 0x5b, 0x9f, 0x15, 0x23, 0x28, 0x36, 0xb8, 0xa2, 0x41, 0xb4, 0xd7, 0x19,
+ 0x91, 0x8d, 0x26, 0x3e, 0xca, 0x9c, 0x05, 0x7a, 0x2b, 0x60, 0x45, 0x86,
+ 0x8b, 0xee, 0x64, 0x6f, 0x5c, 0x09, 0x4d, 0x4b, 0x5a, 0x7f, 0xb0, 0xc3,
+ 0x26, 0x9d, 0x8b, 0xb8, 0x83, 0x69, 0xcf, 0x16, 0x72, 0x62, 0x3e, 0x5e,
+ 0x53, 0x4f, 0x9c, 0x73, 0x76, 0xfc, 0x19, 0xef, 0xa0, 0x74, 0x3a, 0x11,
+ 0x1e, 0xd0, 0x4d, 0xb7, 0x87, 0xa1, 0xd6, 0x87, 0x6c, 0x0e, 0x6c, 0x8c,
+ 0xe9, 0xa0, 0x44, 0xc4, 0x72, 0x3e, 0x73, 0x17, 0x13, 0xd1, 0x4e, 0x3d,
+ 0x8e, 0x1d, 0x5a, 0x8b, 0x75, 0xcb, 0x59, 0x2c, 0x47, 0x87, 0x15, 0x41,
+ 0xfe, 0x08, 0xe9, 0xa6, 0x97, 0x17, 0x08, 0x26, 0x6a, 0xb5, 0xbb, 0x73,
+ 0xaa, 0xb8, 0x5b, 0x65, 0x65, 0x5b, 0x30, 0x9e, 0x62, 0x59, 0x02, 0xf8,
+ 0xb8, 0x0f, 0x32, 0x10, 0xc1, 0x36, 0x08, 0x52, 0x98, 0x4a, 0x1e, 0xf0,
+ 0xab, 0x21, 0x5e, 0xde, 0x16, 0x0c, 0xda, 0x09, 0x99, 0x6b, 0x9e, 0xc0,
+ 0x90, 0xa5, 0x5a, 0xcc, 0xb0, 0xb7, 0xbb, 0xd2, 0x8b, 0x5f, 0xd3, 0x3b,
+ 0x3e, 0x8c, 0xa5, 0x71, 0x66, 0x06, 0xe3, 0x28, 0xd4, 0xf8, 0x3f, 0xe5,
+ 0x27, 0xdf, 0xfe, 0x0f, 0x09, 0xb2, 0x8a, 0x09, 0x5a, 0x23, 0x61, 0x0d,
+ 0x2d, 0xf5, 0x44, 0xf1, 0x5c, 0xf8, 0x82, 0x4e, 0xdc, 0x78, 0x7a, 0xab,
+ 0xc3, 0x57, 0x91, 0xaf, 0x65, 0x6e, 0x71, 0xf1, 0x44, 0xbf, 0xed, 0x43,
+ 0x50, 0xb4, 0x67, 0x48, 0xef, 0x5a, 0x10, 0x46, 0x81, 0xb4, 0x0c, 0xc8,
+ 0x48, 0xed, 0x99, 0x7a, 0x45, 0xa5, 0x92, 0xc3, 0x69, 0xd6, 0xd7, 0x8a,
+ 0x20, 0x1b, 0xeb, 0x8f, 0xb2, 0xff, 0xec, 0x6d, 0x76, 0x04, 0xf8, 0xc2,
+ 0x58, 0x9b, 0xf2, 0x20, 0x53, 0xc4, 0x74, 0x91, 0x19, 0xdd, 0x2d, 0x12,
+ 0x53, 0xc7, 0x6e, 0xd0, 0x02, 0x51, 0x3c, 0xa6, 0x7d, 0x80, 0x75, 0x6b,
+ 0x1d, 0xdf, 0xf8, 0x6a, 0x52, 0xbb, 0x81, 0xf8, 0x30, 0x45, 0xef, 0x51,
+ 0x85, 0x36, 0xbe, 0x8e, 0xcf, 0x0b, 0x9a, 0x46, 0xe8, 0x3f, 0x99, 0xfd,
+ 0xf7, 0xd9, 0x3e, 0x84, 0xe5, 0xe3, 0x37, 0xcf, 0x98, 0x7f, 0xeb, 0x5e,
+ 0x5a, 0x53, 0x77, 0x1c, 0x20, 0xdc, 0xf1, 0x20, 0x99, 0xec, 0x60, 0x40,
+ 0x93, 0xef, 0x5c, 0x1c, 0x81, 0xe2, 0xa5, 0xad, 0x2a, 0xc2, 0xdb, 0x6b,
+ 0xc1, 0x7e, 0x8f, 0xa9, 0x23, 0x5b, 0xd9, 0x0d, 0xfe, 0xa0, 0xac, 0x11,
+ 0x28, 0xba, 0x8e, 0x92, 0x07, 0x2d, 0x07, 0x40, 0x83, 0x14, 0x4c, 0x35,
+ 0x8d, 0xd0, 0x11, 0xff, 0x98, 0xdb, 0x00, 0x30, 0x6f, 0x65, 0xb6, 0xa0,
+ 0x7f, 0x9c, 0x08, 0xb8, 0xce, 0xb3, 0xa8, 0x42, 0xd3, 0x84, 0x45, 0xe1,
+ 0xe3, 0x8f, 0xa6, 0x89, 0x21, 0xd7, 0x74, 0x02, 0x4d, 0x64, 0xdf, 0x54,
+ 0x15, 0x9e, 0xba, 0x12, 0x49, 0x09, 0x41, 0xf6, 0x10, 0x24, 0xa1, 0x84,
+ 0x15, 0xfd, 0x68, 0x6a, 0x57, 0x66, 0xb3, 0x6d, 0x4c, 0xea, 0xbf, 0xbc,
+ 0x60, 0x3f, 0x52, 0x1c, 0x44, 0x1b, 0xc0, 0x4a, 0x25, 0xe3, 0xd9, 0x4c,
+ 0x9a, 0x74, 0xad, 0xfc, 0x9e, 0x8d, 0x0b, 0x18, 0x66, 0x24, 0xd1, 0x06,
+ 0xac, 0x68, 0xc1, 0xae, 0x14, 0xce, 0xb1, 0xf3, 0x86, 0x9f, 0x87, 0x11,
+ 0xd7, 0x9f, 0x30, 0x92, 0xdb, 0xec, 0x0b, 0x4a, 0xe8, 0xf6, 0x53, 0x36,
+ 0x68, 0x12, 0x11, 0x5e, 0xe0, 0x34, 0xa4, 0xff, 0x00, 0x0a, 0x26, 0xb8,
+ 0x62, 0x79, 0x9c, 0x0c, 0xd5, 0xe5, 0xf5, 0x1c, 0x1a, 0x16, 0x84, 0x4d,
+ 0x8e, 0x5d, 0x31, 0x7e, 0xf7, 0xe2, 0xd3, 0xa1, 0x41, 0x90, 0x61, 0x5d,
+ 0x04, 0xb2, 0x9a, 0x18, 0x9e, 0x54, 0xfb, 0xd1, 0x61, 0x95, 0x1b, 0x08,
+ 0xca, 0x7c, 0x49, 0x44, 0x74, 0x1d, 0x2f, 0xca, 0xc4, 0x7a, 0xe1, 0x8b,
+ 0x2f, 0xbb, 0x96, 0xee, 0x19, 0x8a, 0x5d, 0xfb, 0x3e, 0x82, 0xe7, 0x15,
+ 0xdb, 0x29, 0x14, 0xee, 0xc9, 0x4d, 0x9a, 0xfb, 0x9f, 0x8a, 0xbb, 0x17,
+ 0x37, 0x1b, 0x6e, 0x28, 0x6c, 0xf9, 0xff, 0xb5, 0xb5, 0x8b, 0x9d, 0x88,
+ 0x20, 0x08, 0x10, 0xd7, 0xca, 0x58, 0xf6, 0xe1, 0x32, 0x91, 0x6f, 0x36,
+ 0xc0, 0xad, 0xc1, 0x57, 0x5d, 0x76, 0x31, 0x43, 0xf3, 0xdd, 0xec, 0xf1,
+ 0xa9, 0x79, 0xe9, 0xe9, 0x85, 0xd7, 0x91, 0xc7, 0x31, 0x62, 0x3c, 0xd2,
+ 0x90, 0x2c, 0x9c, 0xa4, 0x56, 0x37, 0x7b, 0xbe, 0x40, 0x58, 0xc0, 0x81,
+ 0x83, 0x22, 0xe8, 0x13, 0x79, 0x18, 0xdb, 0x3a, 0x1b, 0x31, 0x0d, 0x00,
+ 0x6c, 0x22, 0x62, 0x75, 0x70, 0xd8, 0x96, 0x59, 0x99, 0x44, 0x79, 0x71,
+ 0xa6, 0x76, 0x81, 0x28, 0xb2, 0x65, 0xe8, 0x47, 0x14, 0xc6, 0x39, 0x06,
+};
+
+enum spake2_state_t {
+ spake2_state_init = 0,
+ spake2_state_msg_generated,
+ spake2_state_key_generated,
+};
+
+struct spake2_ctx_st {
+ uint8_t private_key[32];
+ uint8_t my_msg[32];
+ uint8_t password_scalar[32];
+ uint8_t password_hash[SHA512_DIGEST_LENGTH];
+ uint8_t *my_name;
+ size_t my_name_len;
+ uint8_t *their_name;
+ size_t their_name_len;
+ enum spake2_role_t my_role;
+ enum spake2_state_t state;
+};
+
+SPAKE2_CTX *SPAKE2_CTX_new(enum spake2_role_t my_role,
+ const uint8_t *my_name, size_t my_name_len,
+ const uint8_t *their_name, size_t their_name_len) {
+ SPAKE2_CTX *ctx = OPENSSL_malloc(sizeof(SPAKE2_CTX));
+ if (ctx == NULL) {
+ return NULL;
+ }
+
+ memset(ctx, 0, sizeof(SPAKE2_CTX));
+ ctx->my_role = my_role;
+
+ CBS my_name_cbs, their_name_cbs;
+ CBS_init(&my_name_cbs, my_name, my_name_len);
+ CBS_init(&their_name_cbs, their_name, their_name_len);
+ if (!CBS_stow(&my_name_cbs, &ctx->my_name, &ctx->my_name_len) ||
+ !CBS_stow(&their_name_cbs, &ctx->their_name, &ctx->their_name_len)) {
+ SPAKE2_CTX_free(ctx);
+ return NULL;
+ }
+
+ return ctx;
+}
+
+void SPAKE2_CTX_free(SPAKE2_CTX *ctx) {
+ if (ctx == NULL) {
+ return;
+ }
+
+ OPENSSL_free(ctx->my_name);
+ OPENSSL_free(ctx->their_name);
+ OPENSSL_free(ctx);
+}
+
+/* left_shift_3 sets |n| to |n|*8, where |n| is represented in little-endian
+ * order. */
+static void left_shift_3(uint8_t n[32]) {
+ uint8_t carry = 0;
+ unsigned i;
+
+ for (i = 0; i < 32; i++) {
+ const uint8_t next_carry = n[i] >> 5;
+ n[i] = (n[i] << 3) | carry;
+ carry = next_carry;
+ }
+}
+
+int SPAKE2_generate_msg(SPAKE2_CTX *ctx, uint8_t *out, size_t *out_len,
+ size_t max_out_len, const uint8_t *password,
+ size_t password_len) {
+ if (ctx->state != spake2_state_init) {
+ return 0;
+ }
+
+ if (max_out_len < sizeof(ctx->my_msg)) {
+ return 0;
+ }
+
+ uint8_t private_tmp[64];
+ RAND_bytes(private_tmp, sizeof(private_tmp));
+ x25519_sc_reduce(private_tmp);
+ /* Multiply by the cofactor (eight) so that we'll clear it when operating on
+ * the peer's point later in the protocol. */
+ left_shift_3(private_tmp);
+ memcpy(ctx->private_key, private_tmp, sizeof(ctx->private_key));
+
+ ge_p3 P;
+ x25519_ge_scalarmult_base(&P, ctx->private_key);
+
+ /* mask = h(password) * <N or M>. */
+ uint8_t password_tmp[SHA512_DIGEST_LENGTH];
+ SHA512(password, password_len, password_tmp);
+ memcpy(ctx->password_hash, password_tmp, sizeof(ctx->password_hash));
+ x25519_sc_reduce(password_tmp);
+ memcpy(ctx->password_scalar, password_tmp, sizeof(ctx->password_scalar));
+
+ ge_p3 mask;
+ x25519_ge_scalarmult_small_precomp(&mask, ctx->password_scalar,
+ ctx->my_role == spake2_role_alice
+ ? kSpakeMSmallPrecomp
+ : kSpakeNSmallPrecomp);
+
+ /* P* = P + mask. */
+ ge_cached mask_cached;
+ x25519_ge_p3_to_cached(&mask_cached, &mask);
+ ge_p1p1 Pstar;
+ x25519_ge_add(&Pstar, &P, &mask_cached);
+
+ /* Encode P* */
+ ge_p2 Pstar_proj;
+ x25519_ge_p1p1_to_p2(&Pstar_proj, &Pstar);
+ x25519_ge_tobytes(ctx->my_msg, &Pstar_proj);
+
+ memcpy(out, ctx->my_msg, sizeof(ctx->my_msg));
+ *out_len = sizeof(ctx->my_msg);
+ ctx->state = spake2_state_msg_generated;
+
+ return 1;
+}
+
+static void update_with_length_prefix(SHA512_CTX *sha, const uint8_t *data,
+ const size_t len) {
+ uint8_t len_le[8];
+ size_t l = len;
+ unsigned i;
+
+ for (i = 0; i < 8; i++) {
+ len_le[i] = l & 0xff;
+ l >>= 8;
+ }
+
+ SHA512_Update(sha, len_le, sizeof(len_le));
+ SHA512_Update(sha, data, len);
+}
+
+int SPAKE2_process_msg(SPAKE2_CTX *ctx, uint8_t *out_key, size_t *out_key_len,
+ size_t max_out_key_len, const uint8_t *their_msg,
+ size_t their_msg_len) {
+ if (ctx->state != spake2_state_msg_generated ||
+ their_msg_len != 32) {
+ return 0;
+ }
+
+ ge_p3 Qstar;
+ if (0 != x25519_ge_frombytes_vartime(&Qstar, their_msg)) {
+ /* Point received from peer was not on the curve. */
+ return 0;
+ }
+
+ /* Unmask peer's value. */
+ ge_p3 peers_mask;
+ x25519_ge_scalarmult_small_precomp(&peers_mask, ctx->password_scalar,
+ ctx->my_role == spake2_role_alice
+ ? kSpakeNSmallPrecomp
+ : kSpakeMSmallPrecomp);
+
+ ge_cached peers_mask_cached;
+ x25519_ge_p3_to_cached(&peers_mask_cached, &peers_mask);
+
+ ge_p1p1 Q_compl;
+ ge_p3 Q_ext;
+ x25519_ge_sub(&Q_compl, &Qstar, &peers_mask_cached);
+ x25519_ge_p1p1_to_p3(&Q_ext, &Q_compl);
+
+ ge_p2 dh_shared;
+ x25519_ge_scalarmult(&dh_shared, ctx->private_key, &Q_ext);
+
+ uint8_t dh_shared_encoded[32];
+ x25519_ge_tobytes(dh_shared_encoded, &dh_shared);
+
+ SHA512_CTX sha;
+ SHA512_Init(&sha);
+ if (ctx->my_role == spake2_role_alice) {
+ update_with_length_prefix(&sha, ctx->my_name, ctx->my_name_len);
+ update_with_length_prefix(&sha, ctx->their_name, ctx->their_name_len);
+ update_with_length_prefix(&sha, ctx->my_msg, sizeof(ctx->my_msg));
+ update_with_length_prefix(&sha, their_msg, 32);
+ } else {
+ update_with_length_prefix(&sha, ctx->their_name, ctx->their_name_len);
+ update_with_length_prefix(&sha, ctx->my_name, ctx->my_name_len);
+ update_with_length_prefix(&sha, their_msg, 32);
+ update_with_length_prefix(&sha, ctx->my_msg, sizeof(ctx->my_msg));
+ }
+ update_with_length_prefix(&sha, dh_shared_encoded, sizeof(dh_shared_encoded));
+ update_with_length_prefix(&sha, ctx->password_hash,
+ sizeof(ctx->password_hash));
+
+ uint8_t key[SHA512_DIGEST_LENGTH];
+ SHA512_Final(key, &sha);
+
+ size_t to_copy = max_out_key_len;
+ if (to_copy > sizeof(key)) {
+ to_copy = sizeof(key);
+ }
+ memcpy(out_key, key, to_copy);
+ *out_key_len = to_copy;
+ ctx->state = spake2_state_key_generated;
+
+ return 1;
+}
diff --git a/src/crypto/curve25519/spake25519_test.cc b/src/crypto/curve25519/spake25519_test.cc
new file mode 100644
index 00000000..d97a8602
--- /dev/null
+++ b/src/crypto/curve25519/spake25519_test.cc
@@ -0,0 +1,169 @@
+/* Copyright (c) 2016, 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 <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <openssl/curve25519.h>
+#include "../test/scoped_types.h"
+
+
+struct SPAKE2Run {
+ bool Run() {
+ ScopedSPAKE2_CTX alice(SPAKE2_CTX_new(
+ spake2_role_alice,
+ reinterpret_cast<const uint8_t *>(alice_names.first.data()),
+ alice_names.first.size(),
+ reinterpret_cast<const uint8_t *>(alice_names.second.data()),
+ alice_names.second.size()));
+ ScopedSPAKE2_CTX bob(SPAKE2_CTX_new(
+ spake2_role_bob,
+ reinterpret_cast<const uint8_t *>(bob_names.first.data()),
+ bob_names.first.size(),
+ reinterpret_cast<const uint8_t *>(bob_names.second.data()),
+ bob_names.second.size()));
+
+ if (!alice || !bob) {
+ return false;
+ }
+
+ uint8_t alice_msg[SPAKE2_MAX_MSG_SIZE];
+ uint8_t bob_msg[SPAKE2_MAX_MSG_SIZE];
+ size_t alice_msg_len, bob_msg_len;
+
+ if (!SPAKE2_generate_msg(
+ alice.get(), alice_msg, &alice_msg_len, sizeof(alice_msg),
+ reinterpret_cast<const uint8_t *>(alice_password.data()),
+ alice_password.size()) ||
+ !SPAKE2_generate_msg(
+ bob.get(), bob_msg, &bob_msg_len, sizeof(bob_msg),
+ reinterpret_cast<const uint8_t *>(bob_password.data()),
+ bob_password.size())) {
+ return false;
+ }
+
+ if (alice_corrupt_msg_bit >= 0 &&
+ static_cast<size_t>(alice_corrupt_msg_bit) < 8 * alice_msg_len) {
+ alice_msg[alice_corrupt_msg_bit/8] ^= 1 << (alice_corrupt_msg_bit & 7);
+ }
+
+ uint8_t alice_key[64], bob_key[64];
+ size_t alice_key_len, bob_key_len;
+
+ if (!SPAKE2_process_msg(alice.get(), alice_key, &alice_key_len,
+ sizeof(alice_key), bob_msg, bob_msg_len) ||
+ !SPAKE2_process_msg(bob.get(), bob_key, &bob_key_len, sizeof(bob_key),
+ alice_msg, alice_msg_len)) {
+ return false;
+ }
+
+ key_matches_ = (alice_key_len == bob_key_len &&
+ memcmp(alice_key, bob_key, alice_key_len) == 0);
+
+ return true;
+ }
+
+ bool key_matches() const {
+ return key_matches_;
+ }
+
+ std::string alice_password = "password";
+ std::string bob_password = "password";
+ std::pair<std::string, std::string> alice_names = {"alice", "bob"};
+ std::pair<std::string, std::string> bob_names = {"bob", "alice"};
+ int alice_corrupt_msg_bit = -1;
+
+ private:
+ bool key_matches_ = false;
+};
+
+static bool TestSPAKE2() {
+ for (unsigned i = 0; i < 20; i++) {
+ SPAKE2Run spake2;
+ if (!spake2.Run()) {
+ fprintf(stderr, "TestSPAKE2: SPAKE2 failed.\n");
+ return false;
+ }
+
+ if (!spake2.key_matches()) {
+ fprintf(stderr, "Key didn't match for equal passwords.\n");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static bool TestWrongPassword() {
+ SPAKE2Run spake2;
+ spake2.bob_password = "wrong password";
+ if (!spake2.Run()) {
+ fprintf(stderr, "TestSPAKE2: SPAKE2 failed.\n");
+ return false;
+ }
+
+ if (spake2.key_matches()) {
+ fprintf(stderr, "Key matched for unequal passwords.\n");
+ return false;
+ }
+
+ return true;
+}
+
+static bool TestWrongNames() {
+ SPAKE2Run spake2;
+ spake2.alice_names.second = "charlie";
+ spake2.bob_names.second = "charlie";
+ if (!spake2.Run()) {
+ fprintf(stderr, "TestSPAKE2: SPAKE2 failed.\n");
+ return false;
+ }
+
+ if (spake2.key_matches()) {
+ fprintf(stderr, "Key matched for unequal names.\n");
+ return false;
+ }
+
+ return true;
+}
+
+static bool TestCorruptMessages() {
+ for (int i = 0; i < 8 * SPAKE2_MAX_MSG_SIZE; i++) {
+ SPAKE2Run spake2;
+ spake2.alice_corrupt_msg_bit = i;
+ if (spake2.Run() && spake2.key_matches()) {
+ fprintf(stderr, "Passed after corrupting Alice's message, bit %d\n", i);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/* TODO(agl): add tests with fixed vectors once SPAKE2 is nailed down. */
+
+int main(int argc, char **argv) {
+ if (!TestSPAKE2() ||
+ !TestWrongPassword() ||
+ !TestWrongNames() ||
+ !TestCorruptMessages()) {
+ return 1;
+ }
+
+ printf("PASS\n");
+ return 0;
+}
diff --git a/src/crypto/curve25519/x25519_test.cc b/src/crypto/curve25519/x25519_test.cc
index 85ee4a2d..24dfa650 100644
--- a/src/crypto/curve25519/x25519_test.cc
+++ b/src/crypto/curve25519/x25519_test.cc
@@ -20,8 +20,7 @@
static bool TestX25519() {
- /* Taken from
- * https://tools.ietf.org/html/draft-irtf-cfrg-curves-11#section-5.2 */
+ /* Taken from https://tools.ietf.org/html/rfc7748#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,
@@ -91,8 +90,7 @@ static bool TestX25519SmallOrder() {
}
static bool TestX25519Iterated() {
- /* Taken from
- * https://tools.ietf.org/html/draft-irtf-cfrg-curves-11#section-5.2 */
+ /* Taken from https://tools.ietf.org/html/rfc7748#section-5.2 */
uint8_t scalar[32] = {9}, point[32] = {9}, out[32];
unsigned i;
diff --git a/src/crypto/dh/check.c b/src/crypto/dh/check.c
index 06af6f25..d27fdf15 100644
--- a/src/crypto/dh/check.c
+++ b/src/crypto/dh/check.c
@@ -62,30 +62,52 @@
int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret) {
+ *ret = 0;
+
+ BN_CTX *ctx = BN_CTX_new();
+ if (ctx == NULL) {
+ return 0;
+ }
+ BN_CTX_start(ctx);
+
int ok = 0;
- BIGNUM q;
- *ret = 0;
- BN_init(&q);
- if (!BN_set_word(&q, 1)) {
+ /* Check |pub_key| is greater than 1. */
+ BIGNUM *tmp = BN_CTX_get(ctx);
+ if (tmp == NULL ||
+ !BN_set_word(tmp, 1)) {
goto err;
}
-
- if (BN_cmp(pub_key, &q) <= 0) {
+ if (BN_cmp(pub_key, tmp) <= 0) {
*ret |= DH_CHECK_PUBKEY_TOO_SMALL;
}
- if (!BN_copy(&q, dh->p) ||
- !BN_sub_word(&q, 1)) {
+
+ /* Check |pub_key| is less than |dh->p| - 1. */
+ if (!BN_copy(tmp, dh->p) ||
+ !BN_sub_word(tmp, 1)) {
goto err;
}
- if (BN_cmp(pub_key, &q) >= 0) {
+ if (BN_cmp(pub_key, tmp) >= 0) {
*ret |= DH_CHECK_PUBKEY_TOO_LARGE;
}
+ if (dh->q != NULL) {
+ /* Check |pub_key|^|dh->q| is 1 mod |dh->p|. This is necessary for RFC 5114
+ * groups which are not safe primes but pick a generator on a prime-order
+ * subgroup of size |dh->q|. */
+ if (!BN_mod_exp(tmp, pub_key, dh->q, dh->p, ctx)) {
+ goto err;
+ }
+ if (!BN_is_one(tmp)) {
+ *ret |= DH_CHECK_PUBKEY_INVALID;
+ }
+ }
+
ok = 1;
err:
- BN_free(&q);
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
return ok;
}
diff --git a/src/crypto/dh/dh.c b/src/crypto/dh/dh.c
index bf6196ce..a5cf94d9 100644
--- a/src/crypto/dh/dh.c
+++ b/src/crypto/dh/dh.c
@@ -74,7 +74,7 @@
static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT;
DH *DH_new(void) {
- DH *dh = (DH *)OPENSSL_malloc(sizeof(DH));
+ DH *dh = OPENSSL_malloc(sizeof(DH));
if (dh == NULL) {
OPENSSL_PUT_ERROR(DH, ERR_R_MALLOC_FAILURE);
return NULL;
@@ -236,7 +236,6 @@ int DH_generate_key(DH *dh) {
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;
@@ -269,9 +268,8 @@ int DH_generate_key(DH *dh) {
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) {
+ if (!BN_MONT_CTX_set_locked(&dh->method_mont_p, &dh->method_mont_p_lock,
+ dh->p, ctx)) {
goto err;
}
@@ -293,7 +291,8 @@ int DH_generate_key(DH *dh) {
}
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)) {
+ if (!BN_mod_exp_mont(pub_key, dh->g, &local_priv, dh->p, ctx,
+ dh->method_mont_p)) {
goto err;
}
@@ -318,7 +317,6 @@ err:
int DH_compute_key(unsigned char *out, const BIGNUM *peers_key, DH *dh) {
BN_CTX *ctx = NULL;
- BN_MONT_CTX *mont = NULL;
BIGNUM *shared_key;
int ret = -1;
int check_result;
@@ -344,9 +342,8 @@ int DH_compute_key(unsigned char *out, const BIGNUM *peers_key, DH *dh) {
goto err;
}
- mont = BN_MONT_CTX_set_locked(&dh->method_mont_p, &dh->method_mont_p_lock,
- dh->p, ctx);
- if (!mont) {
+ if (!BN_MONT_CTX_set_locked(&dh->method_mont_p, &dh->method_mont_p_lock,
+ dh->p, ctx)) {
goto err;
}
@@ -357,7 +354,7 @@ int DH_compute_key(unsigned char *out, const BIGNUM *peers_key, DH *dh) {
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)) {
+ dh->method_mont_p)) {
OPENSSL_PUT_ERROR(DH, ERR_R_BN_LIB);
goto err;
}
diff --git a/src/crypto/dh/dh_test.cc b/src/crypto/dh/dh_test.cc
index c117bd49..885bd32b 100644
--- a/src/crypto/dh/dh_test.cc
+++ b/src/crypto/dh/dh_test.cc
@@ -72,12 +72,14 @@
static bool RunBasicTests();
static bool RunRFC5114Tests();
+static bool TestBadY();
int main(int argc, char *argv[]) {
CRYPTO_library_init();
if (!RunBasicTests() ||
- !RunRFC5114Tests()) {
+ !RunRFC5114Tests() ||
+ !TestBadY()) {
ERR_print_errors_fp(stderr);
return 1;
}
@@ -477,3 +479,57 @@ static bool RunRFC5114Tests() {
return 1;
}
+
+// kRFC5114_2048_224BadY is a bad y-coordinate for RFC 5114's 2048-bit MODP
+// Group with 224-bit Prime Order Subgroup (section 2.2).
+static const uint8_t kRFC5114_2048_224BadY[] = {
+ 0x45, 0x32, 0x5f, 0x51, 0x07, 0xe5, 0xdf, 0x1c, 0xd6, 0x02, 0x82, 0xb3,
+ 0x32, 0x8f, 0xa4, 0x0f, 0x87, 0xb8, 0x41, 0xfe, 0xb9, 0x35, 0xde, 0xad,
+ 0xc6, 0x26, 0x85, 0xb4, 0xff, 0x94, 0x8c, 0x12, 0x4c, 0xbf, 0x5b, 0x20,
+ 0xc4, 0x46, 0xa3, 0x26, 0xeb, 0xa4, 0x25, 0xb7, 0x68, 0x8e, 0xcc, 0x67,
+ 0xba, 0xea, 0x58, 0xd0, 0xf2, 0xe9, 0xd2, 0x24, 0x72, 0x60, 0xda, 0x88,
+ 0x18, 0x9c, 0xe0, 0x31, 0x6a, 0xad, 0x50, 0x6d, 0x94, 0x35, 0x8b, 0x83,
+ 0x4a, 0x6e, 0xfa, 0x48, 0x73, 0x0f, 0x83, 0x87, 0xff, 0x6b, 0x66, 0x1f,
+ 0xa8, 0x82, 0xc6, 0x01, 0xe5, 0x80, 0xb5, 0xb0, 0x52, 0xd0, 0xe9, 0xd8,
+ 0x72, 0xf9, 0x7d, 0x5b, 0x8b, 0xa5, 0x4c, 0xa5, 0x25, 0x95, 0x74, 0xe2,
+ 0x7a, 0x61, 0x4e, 0xa7, 0x8f, 0x12, 0xe2, 0xd2, 0x9d, 0x8c, 0x02, 0x70,
+ 0x34, 0x44, 0x32, 0xc7, 0xb2, 0xf3, 0xb9, 0xfe, 0x17, 0x2b, 0xd6, 0x1f,
+ 0x8b, 0x7e, 0x4a, 0xfa, 0xa3, 0xb5, 0x3e, 0x7a, 0x81, 0x9a, 0x33, 0x66,
+ 0x62, 0xa4, 0x50, 0x18, 0x3e, 0xa2, 0x5f, 0x00, 0x07, 0xd8, 0x9b, 0x22,
+ 0xe4, 0xec, 0x84, 0xd5, 0xeb, 0x5a, 0xf3, 0x2a, 0x31, 0x23, 0xd8, 0x44,
+ 0x22, 0x2a, 0x8b, 0x37, 0x44, 0xcc, 0xc6, 0x87, 0x4b, 0xbe, 0x50, 0x9d,
+ 0x4a, 0xc4, 0x8e, 0x45, 0xcf, 0x72, 0x4d, 0xc0, 0x89, 0xb3, 0x72, 0xed,
+ 0x33, 0x2c, 0xbc, 0x7f, 0x16, 0x39, 0x3b, 0xeb, 0xd2, 0xdd, 0xa8, 0x01,
+ 0x73, 0x84, 0x62, 0xb9, 0x29, 0xd2, 0xc9, 0x51, 0x32, 0x9e, 0x7a, 0x6a,
+ 0xcf, 0xc1, 0x0a, 0xdb, 0x0e, 0xe0, 0x62, 0x77, 0x6f, 0x59, 0x62, 0x72,
+ 0x5a, 0x69, 0xa6, 0x5b, 0x70, 0xca, 0x65, 0xc4, 0x95, 0x6f, 0x9a, 0xc2,
+ 0xdf, 0x72, 0x6d, 0xb1, 0x1e, 0x54, 0x7b, 0x51, 0xb4, 0xef, 0x7f, 0x89,
+ 0x93, 0x74, 0x89, 0x59,
+};
+
+static bool TestBadY() {
+ ScopedDH dh(DH_get_2048_224(nullptr));
+ ScopedBIGNUM pub_key(
+ BN_bin2bn(kRFC5114_2048_224BadY, sizeof(kRFC5114_2048_224BadY), nullptr));
+ if (!dh || !pub_key || !DH_generate_key(dh.get())) {
+ return false;
+ }
+
+ int flags;
+ if (!DH_check_pub_key(dh.get(), pub_key.get(), &flags)) {
+ return false;
+ }
+ if (!(flags & DH_CHECK_PUBKEY_INVALID)) {
+ fprintf(stderr, "DH_check_pub_key did not reject the key.\n");
+ return false;
+ }
+
+ std::vector<uint8_t> result(DH_size(dh.get()));
+ if (DH_compute_key(result.data(), pub_key.get(), dh.get()) >= 0) {
+ fprintf(stderr, "DH_compute_key unexpectedly succeeded.\n");
+ return false;
+ }
+ ERR_clear_error();
+
+ return true;
+}
diff --git a/src/crypto/digest/digest.c b/src/crypto/digest/digest.c
index eb71b073..fdd9fe55 100644
--- a/src/crypto/digest/digest.c
+++ b/src/crypto/digest/digest.c
@@ -60,7 +60,6 @@
#include <string.h>
#include <openssl/err.h>
-#include <openssl/obj.h>
#include <openssl/mem.h>
#include "internal.h"
@@ -166,6 +165,7 @@ 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 > 0) {
OPENSSL_free(ctx->md_data);
+ ctx->md_data = NULL;
}
ctx->digest = type;
if (type->ctx_size > 0) {
@@ -231,11 +231,11 @@ const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx) {
return ctx->digest;
}
-unsigned EVP_MD_CTX_size(const EVP_MD_CTX *ctx) {
+size_t EVP_MD_CTX_size(const EVP_MD_CTX *ctx) {
return EVP_MD_size(EVP_MD_CTX_md(ctx));
}
-unsigned EVP_MD_CTX_block_size(const EVP_MD_CTX *ctx) {
+size_t EVP_MD_CTX_block_size(const EVP_MD_CTX *ctx) {
return EVP_MD_block_size(EVP_MD_CTX_md(ctx));
}
diff --git a/src/crypto/digest/digest_test.cc b/src/crypto/digest/digest_test.cc
index 6a6113d5..39ceaffc 100644
--- a/src/crypto/digest/digest_test.cc
+++ b/src/crypto/digest/digest_test.cc
@@ -245,7 +245,6 @@ static int TestGetters() {
int main(void) {
CRYPTO_library_init();
- ERR_load_crypto_strings();
for (size_t i = 0; i < sizeof(kTestVectors) / sizeof(kTestVectors[0]); i++) {
if (!TestDigest(&kTestVectors[i])) {
diff --git a/src/crypto/digest/md32_common.h b/src/crypto/digest/md32_common.h
index 9db8c54a..4cf050ca 100644
--- a/src/crypto/digest/md32_common.h
+++ b/src/crypto/digest/md32_common.h
@@ -140,89 +140,29 @@ extern "C" {
#if defined(DATA_ORDER_IS_BIG_ENDIAN)
-#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)++)))))
-#endif
-#ifndef HOST_l2c
#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) (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) \
(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
#endif /* DATA_ORDER */
diff --git a/src/crypto/directory.h b/src/crypto/directory.h
deleted file mode 100644
index 29123ea9..00000000
--- a/src/crypto/directory.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* Copied from Richard Levitte's (richard@levitte.org) LP library. All
- * symbol names have been changed, with permission from the author. */
-
-/* $LP: LPlib/source/LPdir.h,v 1.1 2004/06/14 08:56:04 _cvs_levitte Exp $ */
-/*
- * Copyright (c) 2004, Richard Levitte <richard@levitte.org>
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS 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.
- */
-
-#ifndef OPENSSL_HEADER_DIRECTORY_H
-#define OPENSSL_HEADER_DIRECTORY_H
-
-#include <openssl/base.h>
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-
-/* Directory functions abstract the O/S specific operations for opening and
- * reading directories in the filesystem. */
-
-
-/* OPENSSL_dir_context_st is an opaque structure that represents an open
- * directory and a position in that directory. */
-typedef struct OPENSSL_dir_context_st OPENSSL_DIR_CTX;
-
-/* OPENSSL_DIR_read reads a single filename from |ctx|. On the first call,
- * |directory| must be given and |*ctx| must be NULL. Subsequent calls with the
- * same |*ctx| will return subsequent file names until it returns NULL to
- * indicate EOF. The strings returned reference a buffer internal to the
- * |OPENSSL_DIR_CTX| and will be overridden by subsequent calls. */
-OPENSSL_EXPORT const char *OPENSSL_DIR_read(OPENSSL_DIR_CTX **ctx,
- const char *directory);
-
-/* OPENSSL_DIR_end closes |*ctx|. It returns one on success and zero on
- * error. */
-OPENSSL_EXPORT int OPENSSL_DIR_end(OPENSSL_DIR_CTX **ctx);
-
-
-#if defined(__cplusplus)
-} /* extern C */
-#endif
-
-#endif /* OPENSSL_HEADER_DIRECTORY_H */
diff --git a/src/crypto/directory_posix.c b/src/crypto/directory_posix.c
deleted file mode 100644
index b944b692..00000000
--- a/src/crypto/directory_posix.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/* $LP: LPlib/source/LPdir_unix.c,v 1.11 2004/09/23 22:07:22 _cvs_levitte Exp $ */
-/*
- * Copyright (c) 2004, Richard Levitte <richard@levitte.org>
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * ``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 COPYRIGHT
- * OWNER 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. */
-
-#if !defined(_POSIX_C_SOURCE)
-#define _POSIX_C_SOURCE 201409 /* for readdir_r */
-#endif
-
-#include "directory.h"
-
-
-#if !defined(OPENSSL_WINDOWS)
-
-#include <dirent.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-
-#if defined(OPENSSL_PNACL)
-/* pnacl doesn't include readdir_r! So we do the best we can. */
-int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) {
- errno = 0;
- *result = readdir(dirp);
- if (*result != NULL) {
- return 0;
- }
- if (errno) {
- return 1;
- }
- return 0;
-}
-#endif
-
-struct OPENSSL_dir_context_st {
- DIR *dir;
- struct dirent dirent;
-};
-
-const char *OPENSSL_DIR_read(OPENSSL_DIR_CTX **ctx, const char *directory) {
- struct dirent *dirent;
-
- if (ctx == NULL || directory == NULL) {
- errno = EINVAL;
- return NULL;
- }
-
- errno = 0;
- if (*ctx == NULL) {
- *ctx = malloc(sizeof(OPENSSL_DIR_CTX));
- if (*ctx == NULL) {
- errno = ENOMEM;
- return 0;
- }
- memset(*ctx, 0, sizeof(OPENSSL_DIR_CTX));
-
- (*ctx)->dir = opendir(directory);
- if ((*ctx)->dir == NULL) {
- int save_errno = errno; /* Probably not needed, but I'm paranoid */
- free(*ctx);
- *ctx = NULL;
- errno = save_errno;
- return 0;
- }
- }
-
- if (readdir_r((*ctx)->dir, &(*ctx)->dirent, &dirent) != 0 ||
- dirent == NULL) {
- return 0;
- }
-
- return (*ctx)->dirent.d_name;
-}
-
-int OPENSSL_DIR_end(OPENSSL_DIR_CTX **ctx) {
- if (ctx != NULL && *ctx != NULL) {
- int r = closedir((*ctx)->dir);
- free(*ctx);
- *ctx = NULL;
- return r == 0;
- }
-
- errno = EINVAL;
- return 0;
-}
-
-#endif /* !OPENSSL_WINDOWS */
diff --git a/src/crypto/directory_win.c b/src/crypto/directory_win.c
deleted file mode 100644
index 4ebacf21..00000000
--- a/src/crypto/directory_win.c
+++ /dev/null
@@ -1,144 +0,0 @@
-/* $LP: LPlib/source/LPdir_win.c,v 1.10 2004/08/26 13:36:05 _cvs_levitte Exp $ */
-/*
- * Copyright (c) 2004, Richard Levitte <richard@levitte.org>
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * ``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 COPYRIGHT
- * OWNER 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.
- */
-
-#include "directory.h"
-
-
-#if defined(OPENSSL_WINDOWS)
-
-#pragma warning(push, 3)
-#include <windows.h>
-#pragma warning(pop)
-#include <errno.h>
-#include <string.h>
-#include <tchar.h>
-
-#ifndef NAME_MAX
-#define NAME_MAX 255
-#endif
-
-#include <openssl/mem.h>
-
-
-struct OPENSSL_dir_context_st {
- WIN32_FIND_DATA ctx;
- HANDLE handle;
- char entry_name[NAME_MAX + 1];
-};
-
-const char *OPENSSL_DIR_read(OPENSSL_DIR_CTX **ctx, const char *directory) {
- if (ctx == NULL || directory == NULL) {
- errno = EINVAL;
- return 0;
- }
-
- errno = 0;
- if (*ctx == NULL) {
- *ctx = malloc(sizeof(OPENSSL_DIR_CTX));
- if (*ctx == NULL) {
- errno = ENOMEM;
- return 0;
- }
- memset(*ctx, 0, sizeof(OPENSSL_DIR_CTX));
-
- if (sizeof(TCHAR) != sizeof(char)) {
- TCHAR *wdir = NULL;
- /* len_0 denotes string length *with* trailing 0 */
- size_t index = 0, len_0 = strlen(directory) + 1;
-
- wdir = (TCHAR *)malloc(len_0 * sizeof(TCHAR));
- if (wdir == NULL) {
- free(*ctx);
- *ctx = NULL;
- errno = ENOMEM;
- return 0;
- }
-
- if (!MultiByteToWideChar(CP_ACP, 0, directory, len_0, (WCHAR *)wdir,
- len_0)) {
- for (index = 0; index < len_0; index++) {
- wdir[index] = (TCHAR)directory[index];
- }
- }
-
- (*ctx)->handle = FindFirstFile(wdir, &(*ctx)->ctx);
-
- free(wdir);
- } else {
- (*ctx)->handle = FindFirstFile((TCHAR *)directory, &(*ctx)->ctx);
- }
-
- if ((*ctx)->handle == INVALID_HANDLE_VALUE) {
- free(*ctx);
- *ctx = NULL;
- errno = EINVAL;
- return 0;
- }
- } else {
- if (FindNextFile((*ctx)->handle, &(*ctx)->ctx) == FALSE) {
- return 0;
- }
- }
-
- if (sizeof(TCHAR) != sizeof(char)) {
- TCHAR *wdir = (*ctx)->ctx.cFileName;
- size_t index, len_0 = 0;
-
- while (wdir[len_0] && len_0 < (sizeof((*ctx)->entry_name) - 1)) {
- len_0++;
- }
- len_0++;
-
- if (!WideCharToMultiByte(CP_ACP, 0, (WCHAR *)wdir, len_0,
- (*ctx)->entry_name, sizeof((*ctx)->entry_name),
- NULL, 0)) {
- for (index = 0; index < len_0; index++) {
- (*ctx)->entry_name[index] = (char)wdir[index];
- }
- }
- } else {
- strncpy((*ctx)->entry_name, (const char *)(*ctx)->ctx.cFileName,
- sizeof((*ctx)->entry_name) - 1);
- }
-
- (*ctx)->entry_name[sizeof((*ctx)->entry_name) - 1] = '\0';
-
- return (*ctx)->entry_name;
-}
-
-int OPENSSL_DIR_end(OPENSSL_DIR_CTX **ctx) {
- if (ctx != NULL && *ctx != NULL) {
- FindClose((*ctx)->handle);
- free(*ctx);
- *ctx = NULL;
- return 1;
- }
- errno = EINVAL;
- return 0;
-}
-
-#endif /* OPENSSL_WINDOWS */
diff --git a/src/crypto/dsa/dsa.c b/src/crypto/dsa/dsa.c
index ebe55e84..fe29aa0e 100644
--- a/src/crypto/dsa/dsa.c
+++ b/src/crypto/dsa/dsa.c
@@ -61,7 +61,6 @@
#include <string.h>
-#include <openssl/asn1.h>
#include <openssl/bn.h>
#include <openssl/dh.h>
#include <openssl/digest.h>
@@ -73,7 +72,6 @@
#include <openssl/sha.h>
#include <openssl/thread.h>
-#include "internal.h"
#include "../internal.h"
@@ -86,7 +84,7 @@
static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT;
DSA *DSA_new(void) {
- DSA *dsa = (DSA *)OPENSSL_malloc(sizeof(DSA));
+ DSA *dsa = OPENSSL_malloc(sizeof(DSA));
if (dsa == NULL) {
OPENSSL_PUT_ERROR(DSA, ERR_R_MALLOC_FAILURE);
return NULL;
@@ -94,7 +92,6 @@ DSA *DSA_new(void) {
memset(dsa, 0, sizeof(DSA));
- dsa->write_params = 1;
dsa->references = 1;
CRYPTO_MUTEX_init(&dsa->method_mont_p_lock);
@@ -393,6 +390,21 @@ err:
return ok;
}
+DSA *DSAparams_dup(const DSA *dsa) {
+ DSA *ret = DSA_new();
+ if (ret == NULL) {
+ return NULL;
+ }
+ ret->p = BN_dup(dsa->p);
+ ret->q = BN_dup(dsa->q);
+ ret->g = BN_dup(dsa->g);
+ if (ret->p == NULL || ret->q == NULL || ret->g == NULL) {
+ DSA_free(ret);
+ return NULL;
+ }
+ return ret;
+}
+
int DSA_generate_key(DSA *dsa) {
int ok = 0;
BN_CTX *ctx = NULL;
@@ -579,7 +591,6 @@ int DSA_do_check_signature(int *out_valid, const uint8_t *digest,
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;
@@ -650,15 +661,14 @@ int DSA_do_check_signature(int *out_valid, const uint8_t *digest,
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) {
+ if (!BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_p,
+ (CRYPTO_MUTEX *)&dsa->method_mont_p_lock, dsa->p,
+ ctx)) {
goto err;
}
if (!BN_mod_exp2_mont(&t1, dsa->g, &u1, dsa->pub_key, &u2, dsa->p, ctx,
- mont)) {
+ dsa->method_mont_p)) {
goto err;
}
@@ -740,24 +750,38 @@ err:
return ret;
}
-int DSA_size(const DSA *dsa) {
- int ret, i;
- ASN1_INTEGER bs;
- unsigned char buf[4]; /* 4 bytes looks really small.
- However, i2d_ASN1_INTEGER() will not look
- beyond the first byte, as long as the second
- parameter is NULL. */
+/* 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;
+}
- i = BN_num_bits(dsa->q);
- bs.length = (i + 7) / 8;
- bs.data = buf;
- bs.type = V_ASN1_INTEGER;
- /* If the top bit is set the asn1 encoding is 1 larger. */
- buf[0] = 0xff;
-
- i = i2d_ASN1_INTEGER(&bs, NULL);
- i += i; /* r and s */
- ret = ASN1_object_size(1, i, V_ASN1_SEQUENCE);
+int DSA_size(const DSA *dsa) {
+ size_t order_len = BN_num_bytes(dsa->q);
+ /* 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;
+ }
+ /* A DSA 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;
}
@@ -797,9 +821,9 @@ int DSA_sign_setup(const DSA *dsa, BN_CTX *ctx_in, BIGNUM **out_kinv,
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) {
+ if (!BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_p,
+ (CRYPTO_MUTEX *)&dsa->method_mont_p_lock, dsa->p,
+ ctx)) {
goto err;
}
diff --git a/src/crypto/dsa/dsa_asn1.c b/src/crypto/dsa/dsa_asn1.c
index b6b3fa4d..ff5ee003 100644
--- a/src/crypto/dsa/dsa_asn1.c
+++ b/src/crypto/dsa/dsa_asn1.c
@@ -54,97 +54,286 @@
#include <openssl/dsa.h>
-#include <string.h>
+#include <assert.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"
+#include "../bytestring/internal.h"
-static int dsa_sig_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
- void *exarg) {
- if (operation != ASN1_OP_NEW_PRE) {
- return 1;
+static int parse_integer(CBS *cbs, BIGNUM **out) {
+ assert(*out == NULL);
+ *out = BN_new();
+ if (*out == NULL) {
+ return 0;
}
+ return BN_parse_asn1_unsigned(cbs, *out);
+}
- DSA_SIG *sig;
- sig = OPENSSL_malloc(sizeof(DSA_SIG));
- if (!sig) {
- OPENSSL_PUT_ERROR(DSA, ERR_R_MALLOC_FAILURE);
+static int marshal_integer(CBB *cbb, BIGNUM *bn) {
+ if (bn == NULL) {
+ /* A DSA object may be missing some components. */
+ OPENSSL_PUT_ERROR(DSA, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
-
- memset(sig, 0, sizeof(DSA_SIG));
- *pval = (ASN1_VALUE *)sig;
- return 2;
+ return BN_marshal_asn1(cbb, bn);
}
-ASN1_SEQUENCE_cb(DSA_SIG, dsa_sig_cb) = {
- ASN1_SIMPLE(DSA_SIG, r, CBIGNUM),
- ASN1_SIMPLE(DSA_SIG, s, CBIGNUM)} ASN1_SEQUENCE_END_cb(DSA_SIG, DSA_SIG);
+DSA_SIG *DSA_SIG_parse(CBS *cbs) {
+ DSA_SIG *ret = DSA_SIG_new();
+ if (ret == NULL) {
+ return NULL;
+ }
+ CBS child;
+ if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) ||
+ !parse_integer(&child, &ret->r) ||
+ !parse_integer(&child, &ret->s) ||
+ CBS_len(&child) != 0) {
+ OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR);
+ DSA_SIG_free(ret);
+ return NULL;
+ }
+ return ret;
+}
-IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA_SIG, DSA_SIG, DSA_SIG);
+int DSA_SIG_marshal(CBB *cbb, const DSA_SIG *sig) {
+ CBB child;
+ if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) ||
+ !marshal_integer(&child, sig->r) ||
+ !marshal_integer(&child, sig->s) ||
+ !CBB_flush(cbb)) {
+ OPENSSL_PUT_ERROR(DSA, DSA_R_ENCODE_ERROR);
+ return 0;
+ }
+ return 1;
+}
+DSA *DSA_parse_public_key(CBS *cbs) {
+ DSA *ret = DSA_new();
+ if (ret == NULL) {
+ return NULL;
+ }
+ CBS child;
+ if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) ||
+ !parse_integer(&child, &ret->pub_key) ||
+ !parse_integer(&child, &ret->p) ||
+ !parse_integer(&child, &ret->q) ||
+ !parse_integer(&child, &ret->g) ||
+ CBS_len(&child) != 0) {
+ OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR);
+ DSA_free(ret);
+ return NULL;
+ }
+ return ret;
+}
-static int dsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
- void *exarg) {
- switch (operation) {
- case ASN1_OP_NEW_PRE:
- *pval = (ASN1_VALUE *)DSA_new();
- if (*pval) {
- return 2;
- }
- return 0;
+int DSA_marshal_public_key(CBB *cbb, const DSA *dsa) {
+ CBB child;
+ if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) ||
+ !marshal_integer(&child, dsa->pub_key) ||
+ !marshal_integer(&child, dsa->p) ||
+ !marshal_integer(&child, dsa->q) ||
+ !marshal_integer(&child, dsa->g) ||
+ !CBB_flush(cbb)) {
+ OPENSSL_PUT_ERROR(DSA, DSA_R_ENCODE_ERROR);
+ return 0;
+ }
+ return 1;
+}
- case ASN1_OP_FREE_PRE:
- DSA_free((DSA *)*pval);
- *pval = NULL;
- return 2;
+DSA *DSA_parse_parameters(CBS *cbs) {
+ DSA *ret = DSA_new();
+ if (ret == NULL) {
+ return NULL;
+ }
+ CBS child;
+ if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) ||
+ !parse_integer(&child, &ret->p) ||
+ !parse_integer(&child, &ret->q) ||
+ !parse_integer(&child, &ret->g) ||
+ CBS_len(&child) != 0) {
+ OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR);
+ DSA_free(ret);
+ return NULL;
+ }
+ return ret;
+}
- default:
- return 1;
+int DSA_marshal_parameters(CBB *cbb, const DSA *dsa) {
+ CBB child;
+ if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) ||
+ !marshal_integer(&child, dsa->p) ||
+ !marshal_integer(&child, dsa->q) ||
+ !marshal_integer(&child, dsa->g) ||
+ !CBB_flush(cbb)) {
+ OPENSSL_PUT_ERROR(DSA, DSA_R_ENCODE_ERROR);
+ return 0;
}
+ return 1;
}
-ASN1_SEQUENCE_cb(DSAPrivateKey, dsa_cb) = {
- ASN1_SIMPLE(DSA, version, LONG),
- ASN1_SIMPLE(DSA, p, BIGNUM),
- ASN1_SIMPLE(DSA, q, BIGNUM),
- ASN1_SIMPLE(DSA, g, BIGNUM),
- ASN1_SIMPLE(DSA, pub_key, BIGNUM),
- ASN1_SIMPLE(DSA, priv_key, BIGNUM)} ASN1_SEQUENCE_END_cb(DSA,
- DSAPrivateKey);
+DSA *DSA_parse_private_key(CBS *cbs) {
+ DSA *ret = DSA_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(DSA, DSA_R_DECODE_ERROR);
+ goto err;
+ }
+
+ if (version != 0) {
+ OPENSSL_PUT_ERROR(DSA, DSA_R_BAD_VERSION);
+ goto err;
+ }
+
+ if (!parse_integer(&child, &ret->p) ||
+ !parse_integer(&child, &ret->q) ||
+ !parse_integer(&child, &ret->g) ||
+ !parse_integer(&child, &ret->pub_key) ||
+ !parse_integer(&child, &ret->priv_key) ||
+ CBS_len(&child) != 0) {
+ OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR);
+ goto err;
+ }
+ return ret;
+
+err:
+ DSA_free(ret);
+ return NULL;
+}
-IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAPrivateKey, DSAPrivateKey);
+int DSA_marshal_private_key(CBB *cbb, const DSA *dsa) {
+ CBB child;
+ if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) ||
+ !CBB_add_asn1_uint64(&child, 0 /* version */) ||
+ !marshal_integer(&child, dsa->p) ||
+ !marshal_integer(&child, dsa->q) ||
+ !marshal_integer(&child, dsa->g) ||
+ !marshal_integer(&child, dsa->pub_key) ||
+ !marshal_integer(&child, dsa->priv_key) ||
+ !CBB_flush(cbb)) {
+ OPENSSL_PUT_ERROR(DSA, DSA_R_ENCODE_ERROR);
+ return 0;
+ }
+ return 1;
+}
-ASN1_SEQUENCE_cb(DSAparams, dsa_cb) = {
- ASN1_SIMPLE(DSA, p, BIGNUM), ASN1_SIMPLE(DSA, q, BIGNUM),
- ASN1_SIMPLE(DSA, g, BIGNUM), } ASN1_SEQUENCE_END_cb(DSA, DSAparams);
+DSA_SIG *d2i_DSA_SIG(DSA_SIG **out_sig, const uint8_t **inp, long len) {
+ if (len < 0) {
+ return NULL;
+ }
+ CBS cbs;
+ CBS_init(&cbs, *inp, (size_t)len);
+ DSA_SIG *ret = DSA_SIG_parse(&cbs);
+ if (ret == NULL) {
+ return NULL;
+ }
+ if (out_sig != NULL) {
+ DSA_SIG_free(*out_sig);
+ *out_sig = ret;
+ }
+ *inp = CBS_data(&cbs);
+ return ret;
+}
-IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAparams, DSAparams);
+int i2d_DSA_SIG(const DSA_SIG *in, uint8_t **outp) {
+ CBB cbb;
+ if (!CBB_init(&cbb, 0) ||
+ !DSA_SIG_marshal(&cbb, in)) {
+ CBB_cleanup(&cbb);
+ return -1;
+ }
+ return CBB_finish_i2d(&cbb, outp);
+}
+DSA *d2i_DSAPublicKey(DSA **out, const uint8_t **inp, long len) {
+ if (len < 0) {
+ return NULL;
+ }
+ CBS cbs;
+ CBS_init(&cbs, *inp, (size_t)len);
+ DSA *ret = DSA_parse_public_key(&cbs);
+ if (ret == NULL) {
+ return NULL;
+ }
+ if (out != NULL) {
+ DSA_free(*out);
+ *out = ret;
+ }
+ *inp = CBS_data(&cbs);
+ return ret;
+}
-/* DSA public key is a bit trickier... its effectively a CHOICE type decided by
- * a field called write_params which can either write out just the public key
- * as an INTEGER or the parameters and public key in a SEQUENCE. */
+int i2d_DSAPublicKey(const DSA *in, uint8_t **outp) {
+ CBB cbb;
+ if (!CBB_init(&cbb, 0) ||
+ !DSA_marshal_public_key(&cbb, in)) {
+ CBB_cleanup(&cbb);
+ return -1;
+ }
+ return CBB_finish_i2d(&cbb, outp);
+}
-ASN1_SEQUENCE(dsa_pub_internal) = {
- ASN1_SIMPLE(DSA, pub_key, BIGNUM),
- ASN1_SIMPLE(DSA, p, BIGNUM),
- ASN1_SIMPLE(DSA, q, BIGNUM),
- ASN1_SIMPLE(DSA, g, BIGNUM)
-} ASN1_SEQUENCE_END_name(DSA, dsa_pub_internal);
+DSA *d2i_DSAPrivateKey(DSA **out, const uint8_t **inp, long len) {
+ if (len < 0) {
+ return NULL;
+ }
+ CBS cbs;
+ CBS_init(&cbs, *inp, (size_t)len);
+ DSA *ret = DSA_parse_private_key(&cbs);
+ if (ret == NULL) {
+ return NULL;
+ }
+ if (out != NULL) {
+ DSA_free(*out);
+ *out = ret;
+ }
+ *inp = CBS_data(&cbs);
+ return ret;
+}
-ASN1_CHOICE_cb(DSAPublicKey, dsa_cb) = {
- ASN1_SIMPLE(DSA, pub_key, BIGNUM),
- ASN1_EX_COMBINE(0, 0, dsa_pub_internal)
-} ASN1_CHOICE_END_cb(DSA, DSAPublicKey, write_params);
+int i2d_DSAPrivateKey(const DSA *in, uint8_t **outp) {
+ CBB cbb;
+ if (!CBB_init(&cbb, 0) ||
+ !DSA_marshal_private_key(&cbb, in)) {
+ CBB_cleanup(&cbb);
+ return -1;
+ }
+ return CBB_finish_i2d(&cbb, outp);
+}
-IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAPublicKey, DSAPublicKey);
+DSA *d2i_DSAparams(DSA **out, const uint8_t **inp, long len) {
+ if (len < 0) {
+ return NULL;
+ }
+ CBS cbs;
+ CBS_init(&cbs, *inp, (size_t)len);
+ DSA *ret = DSA_parse_parameters(&cbs);
+ if (ret == NULL) {
+ return NULL;
+ }
+ if (out != NULL) {
+ DSA_free(*out);
+ *out = ret;
+ }
+ *inp = CBS_data(&cbs);
+ return ret;
+}
-DSA *DSAparams_dup(const DSA *dsa) {
- return ASN1_item_dup(ASN1_ITEM_rptr(DSAparams), (DSA*) dsa);
+int i2d_DSAparams(const DSA *in, uint8_t **outp) {
+ CBB cbb;
+ if (!CBB_init(&cbb, 0) ||
+ !DSA_marshal_parameters(&cbb, in)) {
+ CBB_cleanup(&cbb);
+ return -1;
+ }
+ return CBB_finish_i2d(&cbb, outp);
}
diff --git a/src/crypto/dsa/dsa_test.c b/src/crypto/dsa/dsa_test.c
index 8bdaaf44..6296c8f0 100644
--- a/src/crypto/dsa/dsa_test.c
+++ b/src/crypto/dsa/dsa_test.c
@@ -65,8 +65,6 @@
#include <openssl/crypto.h>
#include <openssl/err.h>
-#include "internal.h"
-
static int dsa_cb(int p, int n, BN_GENCB *arg);
diff --git a/src/crypto/ec/asm/p256-x86_64-asm.pl b/src/crypto/ec/asm/p256-x86_64-asm.pl
index 361a84b2..50a5fe6e 100644..100755
--- a/src/crypto/ec/asm/p256-x86_64-asm.pl
+++ b/src/crypto/ec/asm/p256-x86_64-asm.pl
@@ -1729,6 +1729,7 @@ $code.=<<___;
push %r15
sub \$32*5+8, %rsp
+.Lpoint_double_shortcut$x:
movdqu 0x00($a_ptr), %xmm0 # copy *(P256_POINT *)$a_ptr.x
mov $a_ptr, $b_ptr # backup copy
movdqu 0x10($a_ptr), %xmm1
@@ -2019,6 +2020,7 @@ $code.=<<___;
mov 0x40+8*1($b_ptr), $acc6
mov 0x40+8*2($b_ptr), $acc7
mov 0x40+8*3($b_ptr), $acc0
+ movq $b_ptr, %xmm1
lea 0x40-$bias($b_ptr), $a_ptr
lea $Z1sqr(%rsp), $r_ptr # Z1^2
@@ -2074,7 +2076,7 @@ $code.=<<___;
test $acc0, $acc0
jnz .Ladd_proceed$x # (in1infty || in2infty)?
test $acc1, $acc1
- jz .Ladd_proceed$x # is_equal(S1,S2)?
+ jz .Ladd_double$x # is_equal(S1,S2)?
movq %xmm0, $r_ptr # restore $r_ptr
pxor %xmm0, %xmm0
@@ -2087,6 +2089,13 @@ $code.=<<___;
jmp .Ladd_done$x
.align 32
+.Ladd_double$x:
+ movq %xmm1, $a_ptr # restore $a_ptr
+ movq %xmm0, $r_ptr # restore $r_ptr
+ add \$`32*(18-5)`, %rsp # difference in frame sizes
+ jmp .Lpoint_double_shortcut$x
+
+.align 32
.Ladd_proceed$x:
`&load_for_sqr("$R(%rsp)", "$src0")`
lea $Rsqr(%rsp), $r_ptr # R^2
diff --git a/src/crypto/ec/ec.c b/src/crypto/ec/ec.c
index 827cc570..8f3fa6e1 100644
--- a/src/crypto/ec/ec.c
+++ b/src/crypto/ec/ec.c
@@ -73,7 +73,7 @@
#include <openssl/bn.h>
#include <openssl/err.h>
#include <openssl/mem.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
#include "internal.h"
#include "../internal.h"
@@ -228,10 +228,25 @@ static const struct curve_data P521 = {
#endif
const struct built_in_curve OPENSSL_built_in_curves[] = {
- {NID_secp521r1, &P521, 0},
- {NID_secp384r1, &P384, 0},
{
- NID_X9_62_prime256v1, &P256,
+ NID_secp521r1,
+ /* 1.3.132.0.35 */
+ {0x2b, 0x81, 0x04, 0x00, 0x23}, 5,
+ &P521,
+ NULL,
+ },
+ {
+ NID_secp384r1,
+ /* 1.3.132.0.34 */
+ {0x2b, 0x81, 0x04, 0x00, 0x22}, 5,
+ &P384,
+ NULL,
+ },
+ {
+ NID_X9_62_prime256v1,
+ /* 1.2.840.10045.3.1.7 */
+ {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07}, 8,
+ &P256,
#if defined(BORINGSSL_USE_INT128_CODE)
#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \
!defined(OPENSSL_SMALL)
@@ -240,18 +255,21 @@ const struct built_in_curve OPENSSL_built_in_curves[] = {
EC_GFp_nistp256_method,
#endif
#else
- 0,
+ NULL,
#endif
},
{
- NID_secp224r1, &P224,
+ NID_secp224r1,
+ /* 1.3.132.0.33 */
+ {0x2b, 0x81, 0x04, 0x00, 0x21}, 5,
+ &P224,
#if defined(BORINGSSL_USE_INT128_CODE) && !defined(OPENSSL_SMALL)
EC_GFp_nistp224_method,
#else
- 0,
+ NULL,
#endif
},
- {NID_undef, 0, 0},
+ {NID_undef, {0}, 0, NULL, NULL},
};
/* built_in_curve_scalar_field_monts contains Montgomery contexts for
@@ -373,40 +391,50 @@ EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
const BIGNUM *order, const BIGNUM *cofactor) {
- if (group->curve_name != NID_undef) {
- /* |EC_GROUP_set_generator| should only be used with |EC_GROUP|s returned
- * by |EC_GROUP_new_curve_GFp|. */
+ if (group->curve_name != NID_undef || group->generator != NULL) {
+ /* |EC_GROUP_set_generator| may only be used with |EC_GROUP|s returned by
+ * |EC_GROUP_new_curve_GFp| and may only used once on each group. */
return 0;
}
- if (group->generator == NULL) {
- group->generator = EC_POINT_new(group);
- if (group->generator == NULL) {
- return 0;
- }
- }
+ group->generator = EC_POINT_new(group);
+ return group->generator != NULL &&
+ EC_POINT_copy(group->generator, generator) &&
+ BN_copy(&group->order, order) &&
+ BN_copy(&group->cofactor, cofactor);
+}
- if (!EC_POINT_copy(group->generator, generator)) {
- return 0;
+EC_GROUP *EC_GROUP_new_arbitrary(const BIGNUM *p, const BIGNUM *a,
+ const BIGNUM *b, const BIGNUM *gx,
+ const BIGNUM *gy, const BIGNUM *order,
+ const BIGNUM *cofactor) {
+ BN_CTX *ctx = BN_CTX_new();
+ if (ctx == NULL) {
+ return NULL;
}
- if (order != NULL) {
- if (!BN_copy(&group->order, order)) {
- return 0;
- }
- } else {
- BN_zero(&group->order);
+ EC_POINT *generator = NULL;
+ EC_GROUP *ret = EC_GROUP_new_curve_GFp(p, a, b, ctx);
+ if (ret == NULL) {
+ goto err;
}
- if (cofactor != NULL) {
- if (!BN_copy(&group->cofactor, cofactor)) {
- return 0;
- }
- } else {
- BN_zero(&group->cofactor);
+ generator = EC_POINT_new(ret);
+ if (generator == NULL ||
+ !EC_POINT_set_affine_coordinates_GFp(ret, generator, gx, gy, ctx) ||
+ !EC_GROUP_set_generator(ret, generator, order, cofactor)) {
+ goto err;
}
- return 1;
+ EC_POINT_free(generator);
+ BN_CTX_free(ctx);
+ return ret;
+
+err:
+ EC_POINT_free(generator);
+ EC_GROUP_free(ret);
+ BN_CTX_free(ctx);
+ return NULL;
}
static EC_GROUP *ec_group_new_from_data(unsigned built_in_index) {
@@ -887,3 +915,21 @@ void EC_GROUP_set_point_conversion_form(EC_GROUP *group,
abort();
}
}
+
+size_t EC_get_builtin_curves(EC_builtin_curve *out_curves,
+ size_t max_num_curves) {
+ 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;
+ }
+ }
+
+ unsigned i;
+ for (i = 0; i < max_num_curves && i < num_built_in_curves; i++) {
+ out_curves[i].comment = OPENSSL_built_in_curves[i].data->comment;
+ out_curves[i].nid = OPENSSL_built_in_curves[i].nid;
+ }
+
+ return num_built_in_curves;
+}
diff --git a/src/crypto/ec/ec_asn1.c b/src/crypto/ec/ec_asn1.c
index a085be53..f31e1587 100644
--- a/src/crypto/ec/ec_asn1.c
+++ b/src/crypto/ec/ec_asn1.c
@@ -53,490 +53,453 @@
#include <openssl/ec.h>
+#include <limits.h>
#include <string.h>
-#include <openssl/asn1.h>
-#include <openssl/asn1t.h>
+#include <openssl/bytestring.h>
#include <openssl/bn.h>
#include <openssl/err.h>
#include <openssl/mem.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
#include "internal.h"
+#include "../bytestring/internal.h"
+
+
+static const uint8_t kParametersTag =
+ CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0;
+static const uint8_t kPublicKeyTag =
+ CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 1;
+
+EC_KEY *EC_KEY_parse_private_key(CBS *cbs, const EC_GROUP *group) {
+ CBS ec_private_key, private_key;
+ uint64_t version;
+ if (!CBS_get_asn1(cbs, &ec_private_key, CBS_ASN1_SEQUENCE) ||
+ !CBS_get_asn1_uint64(&ec_private_key, &version) ||
+ version != 1 ||
+ !CBS_get_asn1(&ec_private_key, &private_key, CBS_ASN1_OCTETSTRING)) {
+ OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
+ return NULL;
+ }
-
-typedef struct x9_62_fieldid_st {
- ASN1_OBJECT *fieldType;
- union {
- char *ptr;
- /* NID_X9_62_prime_field */
- ASN1_INTEGER *prime;
- /* anything else */
- ASN1_TYPE *other;
- } p;
-} X9_62_FIELDID;
-
-ASN1_ADB_TEMPLATE(fieldID_def) = ASN1_SIMPLE(X9_62_FIELDID, p.other, ASN1_ANY);
-
-ASN1_ADB(X9_62_FIELDID) = {
- ADB_ENTRY(NID_X9_62_prime_field, ASN1_SIMPLE(X9_62_FIELDID, p.prime, ASN1_INTEGER)),
-} ASN1_ADB_END(X9_62_FIELDID, 0, fieldType, 0, &fieldID_def_tt, NULL);
-
-ASN1_SEQUENCE(X9_62_FIELDID) = {
- ASN1_SIMPLE(X9_62_FIELDID, fieldType, ASN1_OBJECT),
- ASN1_ADB_OBJECT(X9_62_FIELDID)
-} ASN1_SEQUENCE_END(X9_62_FIELDID);
-
-typedef struct x9_62_curve_st {
- ASN1_OCTET_STRING *a;
- ASN1_OCTET_STRING *b;
- ASN1_BIT_STRING *seed;
-} X9_62_CURVE;
-
-ASN1_SEQUENCE(X9_62_CURVE) = {
- ASN1_SIMPLE(X9_62_CURVE, a, ASN1_OCTET_STRING),
- ASN1_SIMPLE(X9_62_CURVE, b, ASN1_OCTET_STRING),
- ASN1_OPT(X9_62_CURVE, seed, ASN1_BIT_STRING)
-} ASN1_SEQUENCE_END(X9_62_CURVE);
-
-typedef struct ec_parameters_st {
- long version;
- X9_62_FIELDID *fieldID;
- X9_62_CURVE *curve;
- ASN1_OCTET_STRING *base;
- ASN1_INTEGER *order;
- ASN1_INTEGER *cofactor;
-} ECPARAMETERS;
-
-DECLARE_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS);
-
-ASN1_SEQUENCE(ECPARAMETERS) = {
- ASN1_SIMPLE(ECPARAMETERS, version, LONG),
- ASN1_SIMPLE(ECPARAMETERS, fieldID, X9_62_FIELDID),
- ASN1_SIMPLE(ECPARAMETERS, curve, X9_62_CURVE),
- ASN1_SIMPLE(ECPARAMETERS, base, ASN1_OCTET_STRING),
- ASN1_SIMPLE(ECPARAMETERS, order, ASN1_INTEGER),
- ASN1_OPT(ECPARAMETERS, cofactor, ASN1_INTEGER)
-} ASN1_SEQUENCE_END(ECPARAMETERS);
-
-IMPLEMENT_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS);
-
-typedef struct ecpk_parameters_st {
- int type;
- union {
- ASN1_OBJECT *named_curve;
- ECPARAMETERS *parameters;
- } value;
-} ECPKPARAMETERS;
-
-/* SEC1 ECPrivateKey */
-typedef struct ec_privatekey_st {
- long version;
- ASN1_OCTET_STRING *privateKey;
- ECPKPARAMETERS *parameters;
- ASN1_BIT_STRING *publicKey;
-} EC_PRIVATEKEY;
-
-DECLARE_ASN1_FUNCTIONS_const(ECPKPARAMETERS);
-DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECPKPARAMETERS, ECPKPARAMETERS);
-
-ASN1_CHOICE(ECPKPARAMETERS) = {
- ASN1_SIMPLE(ECPKPARAMETERS, value.named_curve, ASN1_OBJECT),
- ASN1_SIMPLE(ECPKPARAMETERS, value.parameters, ECPARAMETERS),
-} ASN1_CHOICE_END(ECPKPARAMETERS);
-
-IMPLEMENT_ASN1_FUNCTIONS_const(ECPKPARAMETERS);
-
-DECLARE_ASN1_FUNCTIONS_const(EC_PRIVATEKEY);
-DECLARE_ASN1_ENCODE_FUNCTIONS_const(EC_PRIVATEKEY, EC_PRIVATEKEY);
-
-ASN1_SEQUENCE(EC_PRIVATEKEY) = {
- ASN1_SIMPLE(EC_PRIVATEKEY, version, LONG),
- ASN1_SIMPLE(EC_PRIVATEKEY, privateKey, ASN1_OCTET_STRING),
- ASN1_EXP_OPT(EC_PRIVATEKEY, parameters, ECPKPARAMETERS, 0),
- ASN1_EXP_OPT(EC_PRIVATEKEY, publicKey, ASN1_BIT_STRING, 1),
-} ASN1_SEQUENCE_END(EC_PRIVATEKEY);
-
-IMPLEMENT_ASN1_FUNCTIONS_const(EC_PRIVATEKEY);
-
-
-ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *group,
- ECPKPARAMETERS *params) {
- int ok = 0, nid;
- ECPKPARAMETERS *ret = params;
-
- if (ret == NULL) {
- ret = ECPKPARAMETERS_new();
- if (ret == NULL) {
- OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
- return NULL;
+ /* Parse the optional parameters field. */
+ EC_GROUP *inner_group = NULL;
+ EC_KEY *ret = NULL;
+ if (CBS_peek_asn1_tag(&ec_private_key, kParametersTag)) {
+ /* Per SEC 1, as an alternative to omitting it, one is allowed to specify
+ * this field and put in a NULL to mean inheriting this value. This was
+ * omitted in a previous version of this logic without problems, so leave it
+ * unimplemented. */
+ CBS child;
+ if (!CBS_get_asn1(&ec_private_key, &child, kParametersTag)) {
+ OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
+ goto err;
+ }
+ inner_group = EC_KEY_parse_parameters(&child);
+ if (inner_group == NULL) {
+ goto err;
+ }
+ if (group == NULL) {
+ group = inner_group;
+ } else if (EC_GROUP_cmp(group, inner_group, NULL) != 0) {
+ /* If a group was supplied externally, it must match. */
+ OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH);
+ goto err;
+ }
+ if (CBS_len(&child) != 0) {
+ OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
+ goto err;
}
- } else {
- ASN1_OBJECT_free(ret->value.named_curve);
}
- /* use the ASN.1 OID to describe the the elliptic curve parameters. */
- nid = EC_GROUP_get_curve_name(group);
- if (nid) {
- ret->type = 0;
- ret->value.named_curve = (ASN1_OBJECT*) OBJ_nid2obj(nid);
- ok = ret->value.named_curve != NULL;
+ if (group == NULL) {
+ OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PARAMETERS);
+ goto err;
}
- if (!ok) {
- ECPKPARAMETERS_free(ret);
- return NULL;
+ ret = EC_KEY_new();
+ if (ret == NULL || !EC_KEY_set_group(ret, group)) {
+ goto err;
}
- return ret;
-}
-
-EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *params) {
- EC_GROUP *ret = NULL;
- int nid = NID_undef;
+ /* Although RFC 5915 specifies the length of the key, OpenSSL historically
+ * got this wrong, so accept any length. See upstream's
+ * 30cd4ff294252c4b6a4b69cbef6a5b4117705d22. */
+ ret->priv_key =
+ BN_bin2bn(CBS_data(&private_key), CBS_len(&private_key), NULL);
+ ret->pub_key = EC_POINT_new(group);
+ if (ret->priv_key == NULL || ret->pub_key == NULL) {
+ goto err;
+ }
- if (params == NULL) {
- OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PARAMETERS);
- return NULL;
+ if (BN_cmp(ret->priv_key, EC_GROUP_get0_order(group)) >= 0) {
+ OPENSSL_PUT_ERROR(EC, EC_R_WRONG_ORDER);
+ goto err;
}
- if (params->type == 0) {
- nid = OBJ_obj2nid(params->value.named_curve);
- } else if (params->type == 1) {
- /* We don't support arbitary curves so we attempt to recognise it from the
- * group order. */
- const ECPARAMETERS *ecparams = params->value.parameters;
- unsigned i;
- const struct built_in_curve *curve;
-
- 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 ((unsigned) ecparams->order->length == param_len &&
- memcmp(ecparams->order->data, &curve->data->data[param_len * 5],
- param_len) == 0) {
- nid = curve->nid;
- break;
- }
+ if (CBS_peek_asn1_tag(&ec_private_key, kPublicKeyTag)) {
+ CBS child, public_key;
+ uint8_t padding;
+ if (!CBS_get_asn1(&ec_private_key, &child, kPublicKeyTag) ||
+ !CBS_get_asn1(&child, &public_key, CBS_ASN1_BITSTRING) ||
+ /* As in a SubjectPublicKeyInfo, the byte-encoded public key is then
+ * encoded as a BIT STRING with bits ordered as in the DER encoding. */
+ !CBS_get_u8(&public_key, &padding) ||
+ padding != 0 ||
+ /* Explicitly check |public_key| is non-empty to save the conversion
+ * form later. */
+ CBS_len(&public_key) == 0 ||
+ !EC_POINT_oct2point(group, ret->pub_key, CBS_data(&public_key),
+ CBS_len(&public_key), NULL) ||
+ CBS_len(&child) != 0) {
+ OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
+ goto err;
}
+
+ /* Save the point conversion form.
+ * TODO(davidben): Consider removing this. */
+ ret->conv_form = (point_conversion_form_t)(CBS_data(&public_key)[0] & ~0x01);
+ } else {
+ /* Compute the public key instead. */
+ if (!EC_POINT_mul(group, ret->pub_key, ret->priv_key, NULL, NULL, NULL)) {
+ goto err;
+ }
+ /* Remember the original private-key-only encoding.
+ * TODO(davidben): Consider removing this. */
+ ret->enc_flag |= EC_PKEY_NO_PUBKEY;
}
- if (nid == NID_undef) {
- OPENSSL_PUT_ERROR(EC, EC_R_NON_NAMED_CURVE);
- return NULL;
+ if (CBS_len(&ec_private_key) != 0) {
+ OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
+ goto err;
}
- ret = EC_GROUP_new_by_curve_name(nid);
- if (ret == NULL) {
- OPENSSL_PUT_ERROR(EC, EC_R_EC_GROUP_NEW_BY_NAME_FAILURE);
- return NULL;
+ /* Ensure the resulting key is valid. */
+ if (!EC_KEY_check_key(ret)) {
+ goto err;
}
+ EC_GROUP_free(inner_group);
return ret;
+
+err:
+ EC_KEY_free(ret);
+ EC_GROUP_free(inner_group);
+ return NULL;
}
-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;
+int EC_KEY_marshal_private_key(CBB *cbb, const EC_KEY *key,
+ unsigned enc_flags) {
+ if (key == NULL || key->group == NULL || key->priv_key == NULL) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
- params = d2i_ECPKPARAMETERS(NULL, &in, len);
- if (params == NULL) {
- OPENSSL_PUT_ERROR(EC, EC_R_D2I_ECPKPARAMETERS_FAILURE);
- ECPKPARAMETERS_free(params);
- return NULL;
+ CBB ec_private_key, private_key;
+ if (!CBB_add_asn1(cbb, &ec_private_key, CBS_ASN1_SEQUENCE) ||
+ !CBB_add_asn1_uint64(&ec_private_key, 1 /* version */) ||
+ !CBB_add_asn1(&ec_private_key, &private_key, CBS_ASN1_OCTETSTRING) ||
+ !BN_bn2cbb_padded(&private_key,
+ BN_num_bytes(EC_GROUP_get0_order(key->group)),
+ key->priv_key)) {
+ OPENSSL_PUT_ERROR(EC, EC_R_ENCODE_ERROR);
+ return 0;
}
- group = ec_asn1_pkparameters2group(params);
- if (group == NULL) {
- OPENSSL_PUT_ERROR(EC, EC_R_PKPARAMETERS2GROUP_FAILURE);
- ECPKPARAMETERS_free(params);
- return NULL;
+ if (!(enc_flags & EC_PKEY_NO_PARAMETERS)) {
+ CBB child;
+ if (!CBB_add_asn1(&ec_private_key, &child, kParametersTag) ||
+ !EC_KEY_marshal_curve_name(&child, key->group) ||
+ !CBB_flush(&ec_private_key)) {
+ OPENSSL_PUT_ERROR(EC, EC_R_ENCODE_ERROR);
+ return 0;
+ }
}
- if (groupp) {
- EC_GROUP_free(*groupp);
- *groupp = group;
+ /* TODO(fork): replace this flexibility with sensible default? */
+ if (!(enc_flags & EC_PKEY_NO_PUBKEY) && key->pub_key != NULL) {
+ CBB child, public_key;
+ if (!CBB_add_asn1(&ec_private_key, &child, kPublicKeyTag) ||
+ !CBB_add_asn1(&child, &public_key, CBS_ASN1_BITSTRING) ||
+ /* As in a SubjectPublicKeyInfo, the byte-encoded public key is then
+ * encoded as a BIT STRING with bits ordered as in the DER encoding. */
+ !CBB_add_u8(&public_key, 0 /* padding */) ||
+ !EC_POINT_point2cbb(&public_key, key->group, key->pub_key,
+ key->conv_form, NULL) ||
+ !CBB_flush(&ec_private_key)) {
+ OPENSSL_PUT_ERROR(EC, EC_R_ENCODE_ERROR);
+ return 0;
+ }
+ }
+
+ if (!CBB_flush(cbb)) {
+ OPENSSL_PUT_ERROR(EC, EC_R_ENCODE_ERROR);
+ return 0;
}
- ECPKPARAMETERS_free(params);
- *inp = in;
- return group;
+ return 1;
}
-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, EC_R_GROUP2PKPARAMETERS_FAILURE);
+/* is_unsigned_integer returns one if |cbs| is a valid unsigned DER INTEGER and
+ * zero otherwise. */
+static int is_unsigned_integer(const CBS *cbs) {
+ if (CBS_len(cbs) == 0) {
return 0;
}
- ret = i2d_ECPKPARAMETERS(tmp, outp);
- if (ret == 0) {
- OPENSSL_PUT_ERROR(EC, EC_R_I2D_ECPKPARAMETERS_FAILURE);
- ECPKPARAMETERS_free(tmp);
+ uint8_t byte = CBS_data(cbs)[0];
+ if ((byte & 0x80) ||
+ (byte == 0 && CBS_len(cbs) > 1 && (CBS_data(cbs)[1] & 0x80) == 0)) {
+ /* Negative or not minimally-encoded. */
return 0;
}
- ECPKPARAMETERS_free(tmp);
- return ret;
+ return 1;
}
-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;
-
- const uint8_t *in = *inp;
- priv_key = d2i_EC_PRIVATEKEY(NULL, &in, len);
- if (priv_key == NULL) {
- OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
- return NULL;
+/* kPrimeFieldOID is the encoding of 1.2.840.10045.1.1. */
+static const uint8_t kPrimeField[] = {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01, 0x01};
+
+static int parse_explicit_prime_curve(CBS *in, CBS *out_prime, CBS *out_a,
+ CBS *out_b, CBS *out_base_x,
+ CBS *out_base_y, CBS *out_order) {
+ /* See RFC 3279, section 2.3.5. Note that RFC 3279 calls this structure an
+ * ECParameters while RFC 5480 calls it a SpecifiedECDomain. */
+ CBS params, field_id, field_type, curve, base;
+ uint64_t version;
+ if (!CBS_get_asn1(in, &params, CBS_ASN1_SEQUENCE) ||
+ !CBS_get_asn1_uint64(&params, &version) ||
+ version != 1 ||
+ !CBS_get_asn1(&params, &field_id, CBS_ASN1_SEQUENCE) ||
+ !CBS_get_asn1(&field_id, &field_type, CBS_ASN1_OBJECT) ||
+ CBS_len(&field_type) != sizeof(kPrimeField) ||
+ memcmp(CBS_data(&field_type), kPrimeField, sizeof(kPrimeField)) != 0 ||
+ !CBS_get_asn1(&field_id, out_prime, CBS_ASN1_INTEGER) ||
+ !is_unsigned_integer(out_prime) ||
+ CBS_len(&field_id) != 0 ||
+ !CBS_get_asn1(&params, &curve, CBS_ASN1_SEQUENCE) ||
+ !CBS_get_asn1(&curve, out_a, CBS_ASN1_OCTETSTRING) ||
+ !CBS_get_asn1(&curve, out_b, CBS_ASN1_OCTETSTRING) ||
+ /* |curve| has an optional BIT STRING seed which we ignore. */
+ !CBS_get_asn1(&params, &base, CBS_ASN1_OCTETSTRING) ||
+ !CBS_get_asn1(&params, out_order, CBS_ASN1_INTEGER) ||
+ !is_unsigned_integer(out_order)) {
+ OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
+ return 0;
}
- if (a == NULL || *a == NULL) {
- ret = EC_KEY_new();
- if (ret == NULL) {
- OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- } else {
- ret = *a;
- }
+ /* |params| has an optional cofactor which we ignore. With the optional seed
+ * in |curve|, a group already has arbitrarily many encodings. Parse enough to
+ * uniquely determine the curve. */
- if (priv_key->parameters) {
- EC_GROUP_free(ret->group);
- ret->group = ec_asn1_pkparameters2group(priv_key->parameters);
+ /* Require that the base point use uncompressed form. */
+ uint8_t form;
+ if (!CBS_get_u8(&base, &form) || form != POINT_CONVERSION_UNCOMPRESSED) {
+ OPENSSL_PUT_ERROR(EC, EC_R_INVALID_FORM);
+ return 0;
}
- if (ret->group == NULL) {
- OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
- goto err;
+ if (CBS_len(&base) % 2 != 0) {
+ OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
+ return 0;
}
+ size_t field_len = CBS_len(&base) / 2;
+ CBS_init(out_base_x, CBS_data(&base), field_len);
+ CBS_init(out_base_y, CBS_data(&base) + field_len, field_len);
- ret->version = priv_key->version;
+ return 1;
+}
- if (priv_key->privateKey) {
- ret->priv_key =
- 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, ERR_R_BN_LIB);
- goto err;
- }
- } else {
- OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PRIVATE_KEY);
- goto err;
+/* integers_equal returns one if |a| and |b| are equal, up to leading zeros, and
+ * zero otherwise. */
+static int integers_equal(const CBS *a, const uint8_t *b, size_t b_len) {
+ /* Remove leading zeros from |a| and |b|. */
+ CBS a_copy = *a;
+ while (CBS_len(&a_copy) > 0 && CBS_data(&a_copy)[0] == 0) {
+ CBS_skip(&a_copy, 1);
}
-
- if (BN_cmp(ret->priv_key, EC_GROUP_get0_order(ret->group)) >= 0) {
- OPENSSL_PUT_ERROR(EC, EC_R_WRONG_ORDER);
- goto err;
+ while (b_len > 0 && b[0] == 0) {
+ b++;
+ b_len--;
}
+ return CBS_mem_equal(&a_copy, b, b_len);
+}
- EC_POINT_free(ret->pub_key);
- ret->pub_key = EC_POINT_new(ret->group);
- if (ret->pub_key == NULL) {
- OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
- goto err;
+EC_GROUP *EC_KEY_parse_curve_name(CBS *cbs) {
+ CBS named_curve;
+ if (!CBS_get_asn1(cbs, &named_curve, CBS_ASN1_OBJECT)) {
+ OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
+ return NULL;
}
- if (priv_key->publicKey) {
- const uint8_t *pub_oct;
- int pub_oct_len;
-
- pub_oct = M_ASN1_STRING_data(priv_key->publicKey);
- 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, 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, ERR_R_EC_LIB);
- goto err;
+ /* Look for a matching curve. */
+ unsigned i;
+ for (i = 0; OPENSSL_built_in_curves[i].nid != NID_undef; i++) {
+ const struct built_in_curve *curve = &OPENSSL_built_in_curves[i];
+ if (CBS_len(&named_curve) == curve->oid_len &&
+ memcmp(CBS_data(&named_curve), curve->oid, curve->oid_len) == 0) {
+ return EC_GROUP_new_by_curve_name(curve->nid);
}
- } else {
- if (!EC_POINT_mul(ret->group, ret->pub_key, ret->priv_key, NULL, NULL,
- NULL)) {
- OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
- goto err;
- }
- /* Remember the original private-key-only encoding. */
- ret->enc_flag |= EC_PKEY_NO_PUBKEY;
}
- if (a) {
- *a = ret;
+ OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP);
+ return NULL;
+}
+
+int EC_KEY_marshal_curve_name(CBB *cbb, const EC_GROUP *group) {
+ int nid = EC_GROUP_get_curve_name(group);
+ if (nid == NID_undef) {
+ OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP);
+ return 0;
}
- *inp = in;
- ok = 1;
-err:
- if (!ok) {
- if (a == NULL || *a != ret) {
- EC_KEY_free(ret);
+ unsigned i;
+ for (i = 0; OPENSSL_built_in_curves[i].nid != NID_undef; i++) {
+ const struct built_in_curve *curve = &OPENSSL_built_in_curves[i];
+ if (curve->nid == nid) {
+ CBB child;
+ return CBB_add_asn1(cbb, &child, CBS_ASN1_OBJECT) &&
+ CBB_add_bytes(&child, curve->oid, curve->oid_len) &&
+ CBB_flush(cbb);
}
- ret = NULL;
}
- EC_PRIVATEKEY_free(priv_key);
-
- return ret;
+ OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP);
+ return 0;
}
-int i2d_ECPrivateKey(const EC_KEY *key, uint8_t **outp) {
- int ret = 0, ok = 0;
- uint8_t *buffer = NULL;
- size_t buf_len = 0, tmp_len;
- EC_PRIVATEKEY *priv_key = NULL;
-
- if (key == NULL || key->group == NULL || key->priv_key == NULL) {
- OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
- goto err;
+EC_GROUP *EC_KEY_parse_parameters(CBS *cbs) {
+ if (!CBS_peek_asn1_tag(cbs, CBS_ASN1_SEQUENCE)) {
+ return EC_KEY_parse_curve_name(cbs);
}
- priv_key = EC_PRIVATEKEY_new();
- if (priv_key == NULL) {
- OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
- goto err;
+ /* OpenSSL sometimes produces ECPrivateKeys with explicitly-encoded versions
+ * of named curves.
+ *
+ * TODO(davidben): Remove support for this. */
+ CBS prime, a, b, base_x, base_y, order;
+ if (!parse_explicit_prime_curve(cbs, &prime, &a, &b, &base_x, &base_y,
+ &order)) {
+ return NULL;
}
- priv_key->version = key->version;
-
- buf_len = BN_num_bytes(&key->group->order);
- buffer = OPENSSL_malloc(buf_len);
- if (buffer == NULL) {
- OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
- goto err;
+ /* Look for a matching prime curve. */
+ unsigned i;
+ for (i = 0; OPENSSL_built_in_curves[i].nid != NID_undef; i++) {
+ const struct built_in_curve *curve = &OPENSSL_built_in_curves[i];
+ const unsigned param_len = curve->data->param_len;
+ /* |curve->data->data| is ordered p, a, b, x, y, order, each component
+ * zero-padded up to the field length. Although SEC 1 states that the
+ * Field-Element-to-Octet-String conversion also pads, OpenSSL mis-encodes
+ * |a| and |b|, so this comparison must allow omitting leading zeros. (This
+ * is relevant for P-521 whose |b| has a leading 0.) */
+ if (integers_equal(&prime, curve->data->data, param_len) &&
+ integers_equal(&a, curve->data->data + param_len, param_len) &&
+ integers_equal(&b, curve->data->data + param_len * 2, param_len) &&
+ integers_equal(&base_x, curve->data->data + param_len * 3, param_len) &&
+ integers_equal(&base_y, curve->data->data + param_len * 4, param_len) &&
+ integers_equal(&order, curve->data->data + param_len * 5, param_len)) {
+ return EC_GROUP_new_by_curve_name(curve->nid);
+ }
}
- if (!BN_bn2bin_padded(buffer, buf_len, key->priv_key)) {
- OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
- goto err;
- }
+ OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP);
+ return NULL;
+}
- if (!M_ASN1_OCTET_STRING_set(priv_key->privateKey, buffer, buf_len)) {
- OPENSSL_PUT_ERROR(EC, ERR_R_ASN1_LIB);
- goto err;
+EC_KEY *d2i_ECPrivateKey(EC_KEY **out, const uint8_t **inp, long len) {
+ /* This function treats its |out| parameter differently from other |d2i|
+ * functions. If supplied, take the group from |*out|. */
+ const EC_GROUP *group = NULL;
+ if (out != NULL && *out != NULL) {
+ group = EC_KEY_get0_group(*out);
}
- /* TODO(fork): replace this flexibility with key sensible default? */
- 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, ERR_R_EC_LIB);
- goto err;
- }
+ if (len < 0) {
+ OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
+ return NULL;
}
-
- /* TODO(fork): replace this flexibility with key sensible default? */
- 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, ERR_R_MALLOC_FAILURE);
- goto err;
- }
-
- tmp_len = EC_POINT_point2oct(key->group, key->pub_key, key->conv_form, NULL,
- 0, NULL);
-
- if (tmp_len > buf_len) {
- uint8_t *tmp_buffer = OPENSSL_realloc(buffer, tmp_len);
- if (!tmp_buffer) {
- OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- buffer = tmp_buffer;
- buf_len = tmp_len;
- }
-
- if (!EC_POINT_point2oct(key->group, key->pub_key, key->conv_form, buffer,
- buf_len, NULL)) {
- 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, ERR_R_ASN1_LIB);
- goto err;
- }
+ CBS cbs;
+ CBS_init(&cbs, *inp, (size_t)len);
+ EC_KEY *ret = EC_KEY_parse_private_key(&cbs, group);
+ if (ret == NULL) {
+ return NULL;
}
-
- ret = i2d_EC_PRIVATEKEY(priv_key, outp);
- if (ret == 0) {
- OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
- goto err;
+ if (out != NULL) {
+ EC_KEY_free(*out);
+ *out = ret;
}
- ok = 1;
-
-err:
- OPENSSL_free(buffer);
- EC_PRIVATEKEY_free(priv_key);
- return (ok ? ret : 0);
+ *inp = CBS_data(&cbs);
+ return ret;
}
-int i2d_ECParameters(const EC_KEY *key, uint8_t **outp) {
- if (key == NULL) {
- OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
- return 0;
+int i2d_ECPrivateKey(const EC_KEY *key, uint8_t **outp) {
+ CBB cbb;
+ if (!CBB_init(&cbb, 0) ||
+ !EC_KEY_marshal_private_key(&cbb, key, EC_KEY_get_enc_flags(key))) {
+ CBB_cleanup(&cbb);
+ return -1;
}
- return i2d_ECPKParameters(key->group, outp);
+ return CBB_finish_i2d(&cbb, outp);
}
-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, ERR_R_PASSED_NULL_PARAMETER);
+EC_KEY *d2i_ECParameters(EC_KEY **out_key, const uint8_t **inp, long len) {
+ if (len < 0) {
return NULL;
}
- if (key == NULL || *key == NULL) {
- ret = EC_KEY_new();
- if (ret == NULL) {
- OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
- } else {
- ret = *key;
+ CBS cbs;
+ CBS_init(&cbs, *inp, (size_t)len);
+ EC_GROUP *group = EC_KEY_parse_parameters(&cbs);
+ if (group == NULL) {
+ return NULL;
}
- if (!d2i_ECPKParameters(&ret->group, inp, len)) {
- OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
- if (key == NULL || *key == NULL) {
- EC_KEY_free(ret);
- }
+ EC_KEY *ret = EC_KEY_new();
+ if (ret == NULL || !EC_KEY_set_group(ret, group)) {
+ EC_GROUP_free(group);
+ EC_KEY_free(ret);
return NULL;
}
+ EC_GROUP_free(group);
- if (key) {
- *key = ret;
+ if (out_key != NULL) {
+ EC_KEY_free(*out_key);
+ *out_key = ret;
}
+ *inp = CBS_data(&cbs);
return ret;
}
+int i2d_ECParameters(const EC_KEY *key, uint8_t **outp) {
+ if (key == NULL || key->group == NULL) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
+ return -1;
+ }
+
+ CBB cbb;
+ if (!CBB_init(&cbb, 0) ||
+ !EC_KEY_marshal_curve_name(&cbb, key->group)) {
+ CBB_cleanup(&cbb);
+ return -1;
+ }
+ return CBB_finish_i2d(&cbb, outp);
+}
+
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, ERR_R_PASSED_NULL_PARAMETER);
- return 0;
+ return NULL;
}
ret = *keyp;
if (ret->pub_key == NULL &&
(ret->pub_key = EC_POINT_new(ret->group)) == NULL) {
OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
- return 0;
+ return NULL;
}
if (!EC_POINT_oct2point(ret->group, ret->pub_key, *inp, len, NULL)) {
OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
- return 0;
+ return NULL;
}
/* save the point conversion form */
ret->conv_form = (point_conversion_form_t)(*inp[0] & ~0x01);
diff --git a/src/crypto/ec/ec_key.c b/src/crypto/ec/ec_key.c
index d3bf4c61..fee71fed 100644
--- a/src/crypto/ec/ec_key.c
+++ b/src/crypto/ec/ec_key.c
@@ -85,7 +85,7 @@ static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT;
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));
+ EC_KEY *ret = OPENSSL_malloc(sizeof(EC_KEY));
if (ret == NULL) {
OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
return NULL;
@@ -100,7 +100,6 @@ EC_KEY *EC_KEY_new_method(const ENGINE *engine) {
METHOD_ref(ret->ecdsa_meth);
}
- ret->version = 1;
ret->conv_form = POINT_CONVERSION_UNCOMPRESSED;
ret->references = 1;
@@ -209,8 +208,6 @@ EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src) {
/* copy the rest */
dest->enc_flag = src->enc_flag;
dest->conv_form = src->conv_form;
- dest->version = src->version;
- dest->flags = src->flags;
return dest;
}
@@ -368,15 +365,24 @@ int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x,
return 0;
}
ctx = BN_CTX_new();
+
+ if (ctx == NULL) {
+ return 0;
+ }
+
+ BN_CTX_start(ctx);
point = EC_POINT_new(key->group);
- if (ctx == NULL ||
- point == NULL) {
+ if (point == NULL) {
goto err;
}
tx = BN_CTX_get(ctx);
ty = BN_CTX_get(ctx);
+ if (tx == NULL ||
+ ty == NULL) {
+ goto err;
+ }
if (!EC_POINT_set_affine_coordinates_GFp(key->group, point, x, y, ctx) ||
!EC_POINT_get_affine_coordinates_GFp(key->group, point, tx, ty, ctx)) {
@@ -401,6 +407,7 @@ int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x,
ok = 1;
err:
+ BN_CTX_end(ctx);
BN_CTX_free(ctx);
EC_POINT_free(point);
return ok;
diff --git a/src/crypto/ec/ec_montgomery.c b/src/crypto/ec/ec_montgomery.c
index 1d4113db..35df3651 100644
--- a/src/crypto/ec/ec_montgomery.c
+++ b/src/crypto/ec/ec_montgomery.c
@@ -79,31 +79,18 @@ int ec_GFp_mont_group_init(EC_GROUP *group) {
ok = ec_GFp_simple_group_init(group);
group->mont = NULL;
- group->one = NULL;
return ok;
}
void ec_GFp_mont_group_finish(EC_GROUP *group) {
BN_MONT_CTX_free(group->mont);
group->mont = NULL;
- BN_free(group->one);
- group->one = NULL;
ec_GFp_simple_group_finish(group);
}
-void ec_GFp_mont_group_clear_finish(EC_GROUP *group) {
- BN_MONT_CTX_free(group->mont);
- group->mont = NULL;
- BN_clear_free(group->one);
- group->one = NULL;
- ec_GFp_simple_group_clear_finish(group);
-}
-
int ec_GFp_mont_group_copy(EC_GROUP *dest, const EC_GROUP *src) {
BN_MONT_CTX_free(dest->mont);
dest->mont = NULL;
- BN_clear_free(dest->one);
- dest->one = NULL;
if (!ec_GFp_simple_group_copy(dest, src)) {
return 0;
@@ -118,12 +105,6 @@ int ec_GFp_mont_group_copy(EC_GROUP *dest, const EC_GROUP *src) {
goto err;
}
}
- if (src->one != NULL) {
- dest->one = BN_dup(src->one);
- if (dest->one == NULL) {
- goto err;
- }
- }
return 1;
@@ -137,13 +118,10 @@ int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p,
const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) {
BN_CTX *new_ctx = NULL;
BN_MONT_CTX *mont = NULL;
- BIGNUM *one = NULL;
int ret = 0;
BN_MONT_CTX_free(group->mont);
group->mont = NULL;
- BN_free(group->one);
- group->one = NULL;
if (ctx == NULL) {
ctx = new_ctx = BN_CTX_new();
@@ -160,29 +138,20 @@ int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p,
OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
goto err;
}
- one = BN_new();
- if (one == NULL || !BN_to_montgomery(one, BN_value_one(), mont, ctx)) {
- goto err;
- }
group->mont = mont;
mont = NULL;
- group->one = one;
- one = NULL;
ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
if (!ret) {
BN_MONT_CTX_free(group->mont);
group->mont = NULL;
- BN_free(group->one);
- group->one = NULL;
}
err:
BN_CTX_free(new_ctx);
BN_MONT_CTX_free(mont);
- BN_free(one);
return ret;
}
@@ -226,19 +195,6 @@ int ec_GFp_mont_field_decode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
return BN_from_montgomery(r, a, group->mont, ctx);
}
-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_R_NOT_INITIALIZED);
- return 0;
- }
-
- if (!BN_copy(r, group->one)) {
- return 0;
- }
- return 1;
-}
-
static int ec_GFp_mont_check_pub_key_order(const EC_GROUP *group,
const EC_POINT* pub_key,
BN_CTX *ctx) {
@@ -259,21 +215,108 @@ err:
return ret;
}
+static int ec_GFp_mont_point_get_affine_coordinates(const EC_GROUP *group,
+ const EC_POINT *point,
+ BIGNUM *x, BIGNUM *y,
+ BN_CTX *ctx) {
+ if (EC_POINT_is_at_infinity(group, point)) {
+ OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY);
+ return 0;
+ }
+
+ BN_CTX *new_ctx = NULL;
+ if (ctx == NULL) {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL) {
+ return 0;
+ }
+ }
+
+ int ret = 0;
+
+ BN_CTX_start(ctx);
+
+ if (BN_cmp(&point->Z, &group->one) == 0) {
+ /* |point| is already affine. */
+ if (x != NULL && !BN_from_montgomery(x, &point->X, group->mont, ctx)) {
+ goto err;
+ }
+ if (y != NULL && !BN_from_montgomery(y, &point->Y, group->mont, ctx)) {
+ goto err;
+ }
+ } else {
+ /* transform (X, Y, Z) into (x, y) := (X/Z^2, Y/Z^3) */
+
+ BIGNUM *Z_1 = BN_CTX_get(ctx);
+ BIGNUM *Z_2 = BN_CTX_get(ctx);
+ BIGNUM *Z_3 = BN_CTX_get(ctx);
+ if (Z_1 == NULL ||
+ Z_2 == NULL ||
+ Z_3 == NULL) {
+ goto err;
+ }
+
+ /* The straightforward way to calculate the inverse of a Montgomery-encoded
+ * value where the result is Montgomery-encoded is:
+ *
+ * |BN_from_montgomery| + |BN_mod_inverse| + |BN_to_montgomery|.
+ *
+ * This is equivalent, but more efficient, because |BN_from_montgomery|
+ * is more efficient (at least in theory) than |BN_to_montgomery|, since it
+ * doesn't have to do the multiplication before the reduction. */
+ if (!BN_from_montgomery(Z_1, &point->Z, group->mont, ctx) ||
+ !BN_from_montgomery(Z_1, Z_1, group->mont, ctx) ||
+ !BN_mod_inverse(Z_1, Z_1, &group->field, ctx)) {
+ goto err;
+ }
+
+ if (!BN_mod_mul_montgomery(Z_2, Z_1, Z_1, group->mont, ctx)) {
+ goto err;
+ }
+
+ /* Instead of using |BN_from_montgomery| to convert the |x| coordinate
+ * and then calling |BN_from_montgomery| again to convert the |y|
+ * coordinate below, convert the common factor |Z_2| once now, saving one
+ * reduction. */
+ if (!BN_from_montgomery(Z_2, Z_2, group->mont, ctx)) {
+ goto err;
+ }
+
+ if (x != NULL) {
+ if (!BN_mod_mul_montgomery(x, &point->X, Z_2, group->mont, ctx)) {
+ goto err;
+ }
+ }
+
+ if (y != NULL) {
+ if (!BN_mod_mul_montgomery(Z_3, Z_2, Z_1, group->mont, ctx) ||
+ !BN_mod_mul_montgomery(y, &point->Y, Z_3, group->mont, ctx)) {
+ goto err;
+ }
+ }
+ }
+
+ ret = 1;
+
+err:
+ BN_CTX_end(ctx);
+ BN_CTX_free(new_ctx);
+ 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_GFp_mont_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 2088e72b..ce9d99f3 100644
--- a/src/crypto/ec/ec_test.cc
+++ b/src/crypto/ec/ec_test.cc
@@ -17,6 +17,7 @@
#include <vector>
+#include <openssl/bytestring.h>
#include <openssl/crypto.h>
#include <openssl/ec_key.h>
#include <openssl/err.h>
@@ -34,6 +35,36 @@ static const uint8_t kECKeyWithoutPublic[] = {
0xa0, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07,
};
+// kECKeySpecifiedCurve is the above key with P-256's parameters explicitly
+// spelled out rather than using a named curve.
+static const uint8_t kECKeySpecifiedCurve[] = {
+ 0x30, 0x82, 0x01, 0x22, 0x02, 0x01, 0x01, 0x04, 0x20, 0xc6, 0xc1, 0xaa,
+ 0xda, 0x15, 0xb0, 0x76, 0x61, 0xf8, 0x14, 0x2c, 0x6c, 0xaf, 0x0f, 0xdb,
+ 0x24, 0x1a, 0xff, 0x2e, 0xfe, 0x46, 0xc0, 0x93, 0x8b, 0x74, 0xf2, 0xbc,
+ 0xc5, 0x30, 0x52, 0xb0, 0x77, 0xa0, 0x81, 0xfa, 0x30, 0x81, 0xf7, 0x02,
+ 0x01, 0x01, 0x30, 0x2c, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01,
+ 0x01, 0x02, 0x21, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x30, 0x5b, 0x04, 0x20, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
+ 0x04, 0x20, 0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7, 0xb3, 0xeb,
+ 0xbd, 0x55, 0x76, 0x98, 0x86, 0xbc, 0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53,
+ 0xb0, 0xf6, 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b, 0x03, 0x15,
+ 0x00, 0xc4, 0x9d, 0x36, 0x08, 0x86, 0xe7, 0x04, 0x93, 0x6a, 0x66, 0x78,
+ 0xe1, 0x13, 0x9d, 0x26, 0xb7, 0x81, 0x9f, 0x7e, 0x90, 0x04, 0x41, 0x04,
+ 0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc, 0xe6, 0xe5,
+ 0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0,
+ 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96, 0x4f, 0xe3, 0x42, 0xe2,
+ 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16,
+ 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68,
+ 0x37, 0xbf, 0x51, 0xf5, 0x02, 0x21, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbc,
+ 0xe6, 0xfa, 0xad, 0xa7, 0x17, 0x9e, 0x84, 0xf3, 0xb9, 0xca, 0xc2, 0xfc,
+ 0x63, 0x25, 0x51, 0x02, 0x01, 0x01,
+};
+
// kECKeyMissingZeros is an ECPrivateKey containing a degenerate P-256 key where
// the private key is one. The private key is incorrectly encoded without zero
// padding.
@@ -66,9 +97,10 @@ static const uint8_t kECKeyWithZeros[] = {
// DecodeECPrivateKey decodes |in| as an ECPrivateKey structure and returns the
// result or nullptr on error.
static ScopedEC_KEY DecodeECPrivateKey(const uint8_t *in, size_t in_len) {
- const uint8_t *inp = in;
- ScopedEC_KEY ret(d2i_ECPrivateKey(NULL, &inp, in_len));
- if (!ret || inp != in + in_len) {
+ CBS cbs;
+ CBS_init(&cbs, in, in_len);
+ ScopedEC_KEY ret(EC_KEY_parse_private_key(&cbs, NULL));
+ if (!ret || CBS_len(&cbs) != 0) {
return nullptr;
}
return ret;
@@ -76,14 +108,21 @@ static ScopedEC_KEY DecodeECPrivateKey(const uint8_t *in, size_t in_len) {
// EncodeECPrivateKey encodes |key| as an ECPrivateKey structure into |*out|. It
// returns true on success or false on error.
-static bool EncodeECPrivateKey(std::vector<uint8_t> *out, EC_KEY *key) {
- int len = i2d_ECPrivateKey(key, NULL);
- out->resize(len);
- uint8_t *outp = out->data();
- return i2d_ECPrivateKey(key, &outp) == len;
+static bool EncodeECPrivateKey(std::vector<uint8_t> *out, const EC_KEY *key) {
+ ScopedCBB cbb;
+ uint8_t *der;
+ size_t der_len;
+ if (!CBB_init(cbb.get(), 0) ||
+ !EC_KEY_marshal_private_key(cbb.get(), key, EC_KEY_get_enc_flags(key)) ||
+ !CBB_finish(cbb.get(), &der, &der_len)) {
+ return false;
+ }
+ out->assign(der, der + der_len);
+ OPENSSL_free(der);
+ return true;
}
-bool Testd2i_ECPrivateKey() {
+static bool Testd2i_ECPrivateKey() {
ScopedEC_KEY key = DecodeECPrivateKey(kECKeyWithoutPublic,
sizeof(kECKeyWithoutPublic));
if (!key) {
@@ -172,7 +211,39 @@ static bool TestZeroPadding() {
return true;
}
-bool TestSetAffine(const int nid) {
+static bool TestSpecifiedCurve() {
+ // Test keys with specified curves may be decoded.
+ ScopedEC_KEY key =
+ DecodeECPrivateKey(kECKeySpecifiedCurve, sizeof(kECKeySpecifiedCurve));
+ if (!key) {
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ // The group should have been interpreted as P-256.
+ if (EC_GROUP_get_curve_name(EC_KEY_get0_group(key.get())) !=
+ NID_X9_62_prime256v1) {
+ fprintf(stderr, "Curve name incorrect.\n");
+ return false;
+ }
+
+ // Encoding the key should still use named form.
+ std::vector<uint8_t> out;
+ if (!EncodeECPrivateKey(&out, key.get())) {
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+ if (std::vector<uint8_t>(kECKeyWithoutPublic,
+ kECKeyWithoutPublic + sizeof(kECKeyWithoutPublic)) !=
+ out) {
+ fprintf(stderr, "Serialisation of key was incorrect.\n");
+ return false;
+ }
+
+ return true;
+}
+
+static bool TestSetAffine(const int nid) {
ScopedEC_KEY key(EC_KEY_new_by_curve_name(nid));
if (!key) {
return false;
@@ -240,16 +311,206 @@ bool TestSetAffine(const int nid) {
return true;
}
+static bool TestArbitraryCurve() {
+ // Make a P-256 key and extract the affine coordinates.
+ ScopedEC_KEY key(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
+ if (!key || !EC_KEY_generate_key(key.get())) {
+ return false;
+ }
+
+ // Make an arbitrary curve which is identical to P-256.
+ static const uint8_t kP[] = {
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ };
+ static const uint8_t kA[] = {
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
+ };
+ static const uint8_t kB[] = {
+ 0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7, 0xb3, 0xeb, 0xbd,
+ 0x55, 0x76, 0x98, 0x86, 0xbc, 0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53,
+ 0xb0, 0xf6, 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b,
+ };
+ static const uint8_t kX[] = {
+ 0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc, 0xe6,
+ 0xe5, 0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb,
+ 0x33, 0xa0, 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96,
+ };
+ static const uint8_t kY[] = {
+ 0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb,
+ 0x4a, 0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31,
+ 0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5,
+ };
+ static const uint8_t kOrder[] = {
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xbc, 0xe6, 0xfa, 0xad, 0xa7, 0x17,
+ 0x9e, 0x84, 0xf3, 0xb9, 0xca, 0xc2, 0xfc, 0x63, 0x25, 0x51,
+ };
+ ScopedBN_CTX ctx(BN_CTX_new());
+ ScopedBIGNUM p(BN_bin2bn(kP, sizeof(kP), nullptr));
+ ScopedBIGNUM a(BN_bin2bn(kA, sizeof(kA), nullptr));
+ ScopedBIGNUM b(BN_bin2bn(kB, sizeof(kB), nullptr));
+ ScopedBIGNUM gx(BN_bin2bn(kX, sizeof(kX), nullptr));
+ ScopedBIGNUM gy(BN_bin2bn(kY, sizeof(kY), nullptr));
+ ScopedBIGNUM order(BN_bin2bn(kOrder, sizeof(kOrder), nullptr));
+ ScopedBIGNUM cofactor(BN_new());
+ if (!ctx || !p || !a || !b || !gx || !gy || !order || !cofactor ||
+ !BN_set_word(cofactor.get(), 1)) {
+ return false;
+ }
+
+ ScopedEC_GROUP group(
+ EC_GROUP_new_curve_GFp(p.get(), a.get(), b.get(), ctx.get()));
+ if (!group) {
+ return false;
+ }
+ ScopedEC_POINT generator(EC_POINT_new(group.get()));
+ if (!generator ||
+ !EC_POINT_set_affine_coordinates_GFp(group.get(), generator.get(),
+ gx.get(), gy.get(), ctx.get()) ||
+ !EC_GROUP_set_generator(group.get(), generator.get(), order.get(),
+ cofactor.get())) {
+ return false;
+ }
+
+ // |group| should not have a curve name.
+ if (EC_GROUP_get_curve_name(group.get()) != NID_undef) {
+ return false;
+ }
+
+ // Copy |key| to |key2| using |group|.
+ ScopedEC_KEY key2(EC_KEY_new());
+ ScopedEC_POINT point(EC_POINT_new(group.get()));
+ ScopedBIGNUM x(BN_new()), y(BN_new());
+ if (!key2 || !point || !x || !y ||
+ !EC_KEY_set_group(key2.get(), group.get()) ||
+ !EC_KEY_set_private_key(key2.get(), EC_KEY_get0_private_key(key.get())) ||
+ !EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(key.get()),
+ EC_KEY_get0_public_key(key.get()),
+ x.get(), y.get(), nullptr) ||
+ !EC_POINT_set_affine_coordinates_GFp(group.get(), point.get(), x.get(),
+ y.get(), nullptr) ||
+ !EC_KEY_set_public_key(key2.get(), point.get())) {
+ fprintf(stderr, "Could not copy key.\n");
+ return false;
+ }
+
+ // The key must be valid according to the new group too.
+ if (!EC_KEY_check_key(key2.get())) {
+ fprintf(stderr, "Copied key is not valid.\n");
+ return false;
+ }
+
+ // Repeat the process for |EC_GROUP_new_arbitrary|.
+ group.reset(EC_GROUP_new_arbitrary(p.get(), a.get(), b.get(), gx.get(),
+ gy.get(), order.get(), cofactor.get()));
+ if (!group) {
+ return false;
+ }
+
+ // |group| should not have a curve name.
+ if (EC_GROUP_get_curve_name(group.get()) != NID_undef) {
+ return false;
+ }
+
+ // Copy |key| to |key2| using |group|.
+ key2.reset(EC_KEY_new());
+ point.reset(EC_POINT_new(group.get()));
+ if (!key2 || !point ||
+ !EC_KEY_set_group(key2.get(), group.get()) ||
+ !EC_KEY_set_private_key(key2.get(), EC_KEY_get0_private_key(key.get())) ||
+ !EC_POINT_set_affine_coordinates_GFp(group.get(), point.get(), x.get(),
+ y.get(), nullptr) ||
+ !EC_KEY_set_public_key(key2.get(), point.get())) {
+ fprintf(stderr, "Could not copy key.\n");
+ return false;
+ }
+
+ // The key must be valid according to the new group too.
+ if (!EC_KEY_check_key(key2.get())) {
+ fprintf(stderr, "Copied key is not valid.\n");
+ return false;
+ }
+
+ return true;
+}
+
+static bool TestAddingEqualPoints(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;
+ }
+
+ ScopedEC_POINT p1(EC_POINT_new(group));
+ ScopedEC_POINT p2(EC_POINT_new(group));
+ ScopedEC_POINT double_p1(EC_POINT_new(group));
+ ScopedEC_POINT p1_plus_p2(EC_POINT_new(group));
+ if (!p1 || !p2 || !double_p1 || !p1_plus_p2) {
+ return false;
+ }
+
+ if (!EC_POINT_copy(p1.get(), EC_KEY_get0_public_key(key.get())) ||
+ !EC_POINT_copy(p2.get(), EC_KEY_get0_public_key(key.get()))) {
+ fprintf(stderr, "EC_POINT_COPY failed with nid %d\n", nid);
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ ScopedBN_CTX ctx(BN_CTX_new());
+ if (!ctx) {
+ return false;
+ }
+
+ if (!EC_POINT_dbl(group, double_p1.get(), p1.get(), ctx.get()) ||
+ !EC_POINT_add(group, p1_plus_p2.get(), p1.get(), p2.get(), ctx.get())) {
+ fprintf(stderr, "Point operation failed with nid %d\n", nid);
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ if (EC_POINT_cmp(group, double_p1.get(), p1_plus_p2.get(), ctx.get()) != 0) {
+ fprintf(stderr, "A+A != 2A for nid %d", nid);
+ return false;
+ }
+
+ return true;
+}
+
+static bool ForEachCurve(bool (*test_func)(int nid)) {
+ const size_t num_curves = EC_get_builtin_curves(nullptr, 0);
+ std::vector<EC_builtin_curve> curves(num_curves);
+ EC_get_builtin_curves(curves.data(), num_curves);
+
+ for (const auto& curve : curves) {
+ if (!test_func(curve.nid)) {
+ fprintf(stderr, "Test failed for %s\n", curve.comment);
+ return false;
+ }
+ }
+
+ return true;
+}
+
int main(void) {
CRYPTO_library_init();
- ERR_load_crypto_strings();
if (!Testd2i_ECPrivateKey() ||
!TestZeroPadding() ||
- !TestSetAffine(NID_secp224r1) ||
- !TestSetAffine(NID_X9_62_prime256v1) ||
- !TestSetAffine(NID_secp384r1) ||
- !TestSetAffine(NID_secp521r1)) {
+ !TestSpecifiedCurve() ||
+ !ForEachCurve(TestSetAffine) ||
+ !ForEachCurve(TestAddingEqualPoints) ||
+ !TestArbitraryCurve()) {
fprintf(stderr, "failed\n");
return 1;
}
diff --git a/src/crypto/ec/example_mul.c b/src/crypto/ec/example_mul.c
index ebb724fa..a2bdd527 100644
--- a/src/crypto/ec/example_mul.c
+++ b/src/crypto/ec/example_mul.c
@@ -70,10 +70,10 @@
#include <openssl/bn.h>
#include <openssl/crypto.h>
#include <openssl/ec.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
-int example_EC_POINT_mul(void) {
+static int example_EC_POINT_mul(void) {
/* This example ensures that 10×∞ + G = G, in P-256. */
EC_GROUP *group = NULL;
EC_POINT *p = NULL, *result = NULL;
diff --git a/src/crypto/ec/internal.h b/src/crypto/ec/internal.h
index bcc0e37f..f2cbb961 100644
--- a/src/crypto/ec/internal.h
+++ b/src/crypto/ec/internal.h
@@ -80,18 +80,11 @@ extern "C" {
struct ec_method_st {
- /* 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 *);
- void (*group_clear_finish)(EC_GROUP *);
int (*group_copy)(EC_GROUP *, const EC_GROUP *);
-
- /* used by EC_GROUP_set_curve_GFp, EC_GROUP_get_curve_GFp, */
- /* 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 *);
-
- /* 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 *);
@@ -112,8 +105,6 @@ struct ec_method_st {
int (*check_pub_key_order)(const EC_GROUP *group, const EC_POINT *pub_key,
BN_CTX *ctx);
- /* internal functions */
-
/* '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: */
@@ -125,7 +116,6 @@ struct ec_method_st {
BN_CTX *); /* e.g. to Montgomery */
int (*field_decode)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
BN_CTX *); /* e.g. from Montgomery */
- int (*field_set_to_one)(const EC_GROUP *, BIGNUM *r, BN_CTX *);
} /* EC_METHOD */;
const EC_METHOD* EC_GFp_mont_method(void);
@@ -133,7 +123,7 @@ const EC_METHOD* EC_GFp_mont_method(void);
struct ec_group_st {
const EC_METHOD *meth;
- EC_POINT *generator; /* optional */
+ EC_POINT *generator;
BIGNUM order, cofactor;
int curve_name; /* optional NID for named curve */
@@ -150,20 +140,17 @@ struct ec_group_st {
int a_is_minus3; /* enable optimized point arithmetics for special case */
BN_MONT_CTX *mont; /* Montgomery structure. */
- BIGNUM *one; /* The value one */
+
+ BIGNUM one; /* The value one. */
} /* EC_GROUP */;
struct ec_point_st {
const EC_METHOD *meth;
- /* All members except 'meth' are handled by the method functions,
- * even if they appear generic */
-
BIGNUM X;
BIGNUM Y;
BIGNUM Z; /* Jacobian projective coordinates:
* (X, Y, Z) represents (X/Z^2, Y/Z^3) if Z != 0 */
- int Z_is_one; /* enable optimized point arithmetics for special case */
} /* EC_POINT */;
EC_GROUP *ec_group_new(const EC_METHOD *meth);
@@ -180,14 +167,12 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
/* method functions in simple.c */
int ec_GFp_simple_group_init(EC_GROUP *);
void ec_GFp_simple_group_finish(EC_GROUP *);
-void ec_GFp_simple_group_clear_finish(EC_GROUP *);
int ec_GFp_simple_group_copy(EC_GROUP *, const EC_GROUP *);
int ec_GFp_simple_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a,
const BIGNUM *b, BN_CTX *);
int ec_GFp_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a,
BIGNUM *b, BN_CTX *);
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 *);
void ec_GFp_simple_point_clear_finish(EC_POINT *);
@@ -204,9 +189,6 @@ int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *,
int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *,
const BIGNUM *x, const BIGNUM *y,
BN_CTX *);
-int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *,
- const EC_POINT *, BIGNUM *x,
- BIGNUM *y, BN_CTX *);
int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *,
const BIGNUM *x, int y_bit,
BN_CTX *);
@@ -232,7 +214,6 @@ int ec_GFp_mont_group_init(EC_GROUP *);
int ec_GFp_mont_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a,
const BIGNUM *b, BN_CTX *);
void ec_GFp_mont_group_finish(EC_GROUP *);
-void ec_GFp_mont_group_clear_finish(EC_GROUP *);
int ec_GFp_mont_group_copy(EC_GROUP *, const EC_GROUP *);
int ec_GFp_mont_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
const BIGNUM *b, BN_CTX *);
@@ -242,22 +223,12 @@ int ec_GFp_mont_field_encode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
BN_CTX *);
int ec_GFp_mont_field_decode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
BN_CTX *);
-int ec_GFp_mont_field_set_to_one(const EC_GROUP *, BIGNUM *r, BN_CTX *);
int 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);
-void ec_GFp_nistp_points_make_affine_internal(
- size_t num, void *point_array, size_t felem_size, void *tmp_felems,
- void (*felem_one)(void *out), int (*felem_is_zero)(const void *in),
- void (*felem_assign)(void *out, const void *in),
- void (*felem_square)(void *out, const void *in),
- void (*felem_mul)(void *out, const void *in1, const void *in2),
- void (*felem_inv)(void *out, const void *in),
- void (*felem_contract)(void *out, const void *in));
-
void ec_GFp_nistp_recode_scalar_bits(uint8_t *sign, uint8_t *digit, uint8_t in);
const EC_METHOD *EC_GFp_nistp224_method(void);
@@ -268,8 +239,6 @@ const EC_METHOD *EC_GFp_nistp256_method(void);
const EC_METHOD *EC_GFp_nistz256_method(void);
struct ec_key_st {
- int version;
-
EC_GROUP *group;
EC_POINT *pub_key;
@@ -279,7 +248,6 @@ struct ec_key_st {
point_conversion_form_t conv_form;
CRYPTO_refcount_t references;
- int flags;
ECDSA_METHOD *ecdsa_meth;
@@ -303,6 +271,8 @@ struct curve_data {
struct built_in_curve {
int nid;
+ uint8_t oid[8];
+ uint8_t oid_len;
const struct curve_data *data;
const EC_METHOD *(*method)(void);
};
diff --git a/src/crypto/ec/oct.c b/src/crypto/ec/oct.c
index e39337dd..bf1957ca 100644
--- a/src/crypto/ec/oct.c
+++ b/src/crypto/ec/oct.c
@@ -68,6 +68,7 @@
#include <openssl/ec.h>
#include <openssl/bn.h>
+#include <openssl/bytestring.h>
#include <openssl/err.h>
#include "internal.h"
@@ -268,11 +269,27 @@ size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point,
return ec_GFp_simple_point2oct(group, point, form, buf, len, ctx);
}
+int EC_POINT_point2cbb(CBB *out, const EC_GROUP *group, const EC_POINT *point,
+ point_conversion_form_t form, BN_CTX *ctx) {
+ size_t len = EC_POINT_point2oct(group, point, form, NULL, 0, ctx);
+ if (len == 0) {
+ return 0;
+ }
+ uint8_t *p;
+ return CBB_add_space(out, &p, len) &&
+ EC_POINT_point2oct(group, point, form, p, len, ctx) == len;
+}
+
int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group,
- EC_POINT *point, const BIGNUM *x_,
+ EC_POINT *point, const BIGNUM *x,
int y_bit, BN_CTX *ctx) {
+ if (BN_is_negative(x) || BN_cmp(x, &group->field) >= 0) {
+ OPENSSL_PUT_ERROR(EC, EC_R_INVALID_COMPRESSION_BIT);
+ return 0;
+ }
+
BN_CTX *new_ctx = NULL;
- BIGNUM *tmp1, *tmp2, *x, *y;
+ BIGNUM *tmp1, *tmp2, *y;
int ret = 0;
ERR_clear_error();
@@ -289,7 +306,6 @@ int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group,
BN_CTX_start(ctx);
tmp1 = BN_CTX_get(ctx);
tmp2 = BN_CTX_get(ctx);
- x = BN_CTX_get(ctx);
y = BN_CTX_get(ctx);
if (y == NULL) {
goto err;
@@ -300,19 +316,15 @@ int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group,
* so y is one of the square roots of x^3 + a*x + b. */
/* tmp1 := x^3 */
- if (!BN_nnmod(x, x_, &group->field, ctx)) {
- goto err;
- }
-
if (group->meth->field_decode == 0) {
/* field_{sqr,mul} work on standard representation */
- if (!group->meth->field_sqr(group, tmp2, x_, ctx) ||
- !group->meth->field_mul(group, tmp1, tmp2, x_, ctx)) {
+ if (!group->meth->field_sqr(group, tmp2, x, ctx) ||
+ !group->meth->field_mul(group, tmp1, tmp2, x, ctx)) {
goto err;
}
} else {
- if (!BN_mod_sqr(tmp2, x_, &group->field, ctx) ||
- !BN_mod_mul(tmp1, tmp2, x_, &group->field, ctx)) {
+ if (!BN_mod_sqr(tmp2, x, &group->field, ctx) ||
+ !BN_mod_mul(tmp1, tmp2, x, &group->field, ctx)) {
goto err;
}
}
diff --git a/src/crypto/ec/p224-64.c b/src/crypto/ec/p224-64.c
index e026fc47..7bf889c9 100644
--- a/src/crypto/ec/p224-64.c
+++ b/src/crypto/ec/p224-64.c
@@ -26,11 +26,11 @@
#include <openssl/ec.h>
#include <openssl/err.h>
#include <openssl/mem.h>
-#include <openssl/obj.h>
#include <string.h>
#include "internal.h"
+#include "../internal.h"
typedef uint8_t u8;
@@ -50,7 +50,7 @@ typedef int64_t s64;
* to the unique minimal representation at the end of the computation. */
typedef uint64_t limb;
-typedef __uint128_t widelimb;
+typedef uint128_t widelimb;
typedef limb felem[4];
typedef widelimb widefelem[7];
@@ -60,23 +60,6 @@ typedef widelimb widefelem[7];
* 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).
@@ -209,7 +192,7 @@ static void bin28_to_felem(felem out, const u8 in[28]) {
}
static void felem_to_bin28(u8 out[28], const felem in) {
- unsigned i;
+ size_t i;
for (i = 0; i < 7; ++i) {
out[i] = in[0] >> (8 * i);
out[i + 7] = in[1] >> (8 * i);
@@ -219,8 +202,8 @@ static void felem_to_bin28(u8 out[28], const felem in) {
}
/* To preserve endianness when using BN_bn2bin and BN_bin2bn */
-static void flip_endian(u8 *out, const u8 *in, unsigned len) {
- unsigned i;
+static void flip_endian(u8 *out, const u8 *in, size_t len) {
+ size_t i;
for (i = 0; i < len; ++i) {
out[i] = in[len - 1 - i];
}
@@ -231,7 +214,7 @@ 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);
+ size_t 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);
@@ -258,13 +241,6 @@ static BIGNUM *felem_to_BN(BIGNUM *out, const felem in) {
* 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];
@@ -476,18 +452,6 @@ static void felem_reduce(felem out, const widefelem in) {
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) {
@@ -555,16 +519,12 @@ static limb felem_is_zero(const felem in) {
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;
+ size_t i;
felem_square(tmp, in);
felem_reduce(ftmp, tmp); /* 2 */
@@ -644,7 +604,7 @@ static void felem_inv(felem out, const felem in) {
* 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;
+ size_t 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) {
@@ -901,12 +861,12 @@ static void point_add(felem x3, felem y3, felem z3, const felem x1,
/* 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,
+static void select_point(const u64 idx, size_t size,
const felem pre_comp[/*size*/][3], felem out[3]) {
- unsigned i, j;
limb *outlimbs = &out[0][0];
memset(outlimbs, 0, 3 * sizeof(felem));
+ size_t i;
for (i = 0; i < size; i++) {
const limb *inlimbs = &pre_comp[i][0][0];
u64 mask = i ^ idx;
@@ -915,6 +875,7 @@ static void select_point(const u64 idx, unsigned int size,
mask |= mask >> 1;
mask &= 1;
mask--;
+ size_t j;
for (j = 0; j < 4 * 3; j++) {
outlimbs[j] |= inlimbs[j] & mask;
}
@@ -922,7 +883,7 @@ static void select_point(const u64 idx, unsigned int size,
}
/* get_bit returns the |i|th bit in |in| */
-static char get_bit(const felem_bytearray in, unsigned i) {
+static char get_bit(const felem_bytearray in, size_t i) {
if (i >= 224) {
return 0;
}
@@ -936,11 +897,8 @@ static char get_bit(const felem_bytearray in, unsigned i) {
* 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);
+ const size_t num_points, const u8 *g_scalar,
+ const felem pre_comp[][17][3]) {
felem nq[3], tmp[4];
u64 bits;
u8 sign, digit;
@@ -951,15 +909,16 @@ static void batch_mul(felem x_out, felem y_out, felem z_out,
/* 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) {
+ int skip = 1; /* save two point operations in the first round */
+ size_t i = num_points != 0 ? 220 : 27;
+ for (;;) {
/* 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)) {
+ if (g_scalar != NULL && i <= 27) {
/* first, look 28 bits upwards */
bits = get_bit(g_scalar, i + 196) << 3;
bits |= get_bit(g_scalar, i + 140) << 2;
@@ -988,8 +947,9 @@ static void batch_mul(felem x_out, felem y_out, felem z_out,
}
/* do other additions every 5 doublings */
- if (num_points && (i % 5 == 0)) {
+ if (num_points != 0 && i % 5 == 0) {
/* loop over all scalars */
+ size_t num;
for (num = 0; num < num_points; ++num) {
bits = get_bit(scalars[num], i + 4) << 5;
bits |= get_bit(scalars[num], i + 3) << 4;
@@ -1005,70 +965,31 @@ static void batch_mul(felem x_out, felem y_out, felem z_out,
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]);
+ point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 0 /* mixed */,
+ tmp[0], tmp[1], tmp[2]);
} else {
memcpy(nq, tmp, 3 * sizeof(felem));
skip = 0;
}
}
}
+
+ if (i == 0) {
+ break;
+ }
+ --i;
}
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) {
+static 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;
@@ -1107,23 +1028,12 @@ int ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group,
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) {
+static 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_|. */
@@ -1132,17 +1042,12 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
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;
@@ -1165,19 +1070,10 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
}
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)) {
+ pre_comp == NULL) {
OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -1186,6 +1082,7 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
* 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));
+ size_t i;
for (i = 0; i < num_points; ++i) {
if (i == num) {
/* the generator */
@@ -1198,6 +1095,7 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
}
if (p_scalar != NULL && p != NULL) {
+ size_t num_bytes;
/* 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
@@ -1223,6 +1121,7 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
felem_assign(pre_comp[i][1][1], y_out);
felem_assign(pre_comp[i][1][2], z_out);
+ size_t j;
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],
@@ -1237,14 +1136,11 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
}
}
}
-
- if (mixed) {
- make_points_affine(num_points * 17, pre_comp[0], tmp_felems);
- }
}
if (g_scalar != NULL) {
memset(g_secret, 0, sizeof(g_secret));
+ size_t num_bytes;
/* 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 */
@@ -1260,7 +1156,7 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
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,
+ num_points, g_scalar != NULL ? g_secret : NULL,
(const felem(*)[17][3])pre_comp);
/* reduce the output to its unique minimal representation */
@@ -1280,24 +1176,21 @@ err:
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,
+ static const EC_METHOD ret = {ec_GFp_simple_group_init,
ec_GFp_simple_group_finish,
- ec_GFp_simple_group_clear_finish,
ec_GFp_simple_group_copy,
- ec_GFp_nistp224_group_set_curve,
+ ec_GFp_simple_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 */};
+ 0 /* field_decode */};
return &ret;
}
diff --git a/src/crypto/ec/p256-64.c b/src/crypto/ec/p256-64.c
index 32852dd6..c4259b62 100644
--- a/src/crypto/ec/p256-64.c
+++ b/src/crypto/ec/p256-64.c
@@ -27,44 +27,22 @@
#include <openssl/ec.h>
#include <openssl/err.h>
#include <openssl/mem.h>
-#include <openssl/obj.h>
#include <string.h>
#include "internal.h"
+#include "../internal.h"
typedef uint8_t u8;
typedef uint64_t u64;
typedef int64_t s64;
-typedef __uint128_t uint128_t;
-typedef __int128_t int128_t;
/* The underlying field. P256 operates over GF(2^256-2^224+2^192+2^96-1). We
* can serialise an element of this field into 32 bytes. We call this an
* felem_bytearray. */
typedef u8 felem_bytearray[32];
-/* These are the parameters of P256, taken from FIPS 186-3, page 86. These
- * values are big-endian. */
-static const felem_bytearray nistp256_curve_params[5] = {
- {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, /* p */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
- {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, /* a = -3 */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xfc}, /* b */
- {0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7, 0xb3, 0xeb, 0xbd, 0x55,
- 0x76, 0x98, 0x86, 0xbc, 0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53, 0xb0, 0xf6,
- 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b},
- {0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, /* x */
- 0xf8, 0xbc, 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81,
- 0x2d, 0xeb, 0x33, 0xa0, 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96},
- {0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, /* y */
- 0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57,
- 0x6b, 0x31, 0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5}};
-
/* The representation of field elements.
* ------------------------------------
*
@@ -99,10 +77,10 @@ static const u64 bottom63bits = 0x7ffffffffffffffful;
/* bin32_to_felem takes a little-endian byte array and converts it into felem
* form. This assumes that the CPU is little-endian. */
static void bin32_to_felem(felem out, const u8 in[32]) {
- out[0] = *((u64 *)&in[0]);
- out[1] = *((u64 *)&in[8]);
- out[2] = *((u64 *)&in[16]);
- out[3] = *((u64 *)&in[24]);
+ out[0] = *((const u64 *)&in[0]);
+ out[1] = *((const u64 *)&in[8]);
+ out[2] = *((const u64 *)&in[16]);
+ out[3] = *((const u64 *)&in[24]);
}
/* smallfelem_to_bin32 takes a smallfelem and serialises into a little endian,
@@ -115,8 +93,8 @@ static void smallfelem_to_bin32(u8 out[32], const smallfelem in) {
}
/* To preserve endianness when using BN_bn2bin and BN_bin2bn. */
-static void flip_endian(u8 *out, const u8 *in, unsigned len) {
- unsigned i;
+static void flip_endian(u8 *out, const u8 *in, size_t len) {
+ size_t i;
for (i = 0; i < len; ++i) {
out[i] = in[len - 1 - i];
}
@@ -132,7 +110,7 @@ static int BN_to_felem(felem out, const BIGNUM *bn) {
felem_bytearray b_out;
/* BN_bn2bin eats leading zeroes */
memset(b_out, 0, sizeof(b_out));
- unsigned num_bytes = BN_num_bytes(bn);
+ size_t num_bytes = BN_num_bytes(bn);
if (num_bytes > sizeof(b_out)) {
OPENSSL_PUT_ERROR(EC, EC_R_BIGNUM_OUT_OF_RANGE);
return 0;
@@ -155,20 +133,6 @@ static BIGNUM *smallfelem_to_BN(BIGNUM *out, const smallfelem in) {
/* Field operations. */
-static void smallfelem_one(smallfelem out) {
- out[0] = 1;
- out[1] = 0;
- out[2] = 0;
- out[3] = 0;
-}
-
-static void smallfelem_assign(smallfelem out, const smallfelem in) {
- out[0] = in[0];
- out[1] = in[1];
- out[2] = in[2];
- out[3] = in[3];
-}
-
static void felem_assign(felem out, const felem in) {
out[0] = in[0];
out[1] = in[1];
@@ -364,8 +328,7 @@ static void felem_shrink(smallfelem out, const felem in) {
* conditionally subtract kPrime if tmp[3] is large enough. */
high = tmp[3] >> 64;
/* As tmp[3] < 2^65, high is either 1 or 0 */
- high <<= 63;
- high >>= 63;
+ high = ~(high - 1);
/* high is:
* all ones if the high word of tmp[3] is 1
* all zeros if the high word of tmp[3] if 0 */
@@ -756,7 +719,7 @@ static void felem_contract(smallfelem out, const felem in) {
* each u64, from most-significant to least significant. For each one, if
* all words so far have been equal (m is all ones) then a non-equal
* result is the answer. Otherwise we continue. */
- unsigned i;
+ size_t i;
for (i = 3; i < 4; i--) {
u64 equal;
uint128_t a = ((uint128_t)kPrime[i]) - out[i];
@@ -800,25 +763,6 @@ static void felem_contract(smallfelem out, const felem in) {
subtract_u64(&out[3], &carry, result & kPrime[3]);
}
-static void smallfelem_square_contract(smallfelem out, const smallfelem in) {
- longfelem longtmp;
- felem tmp;
-
- smallfelem_square(longtmp, in);
- felem_reduce(tmp, longtmp);
- felem_contract(out, tmp);
-}
-
-static void smallfelem_mul_contract(smallfelem out, const smallfelem in1,
- const smallfelem in2) {
- longfelem longtmp;
- felem tmp;
-
- smallfelem_mul(longtmp, in1, in2);
- felem_reduce(tmp, longtmp);
- felem_contract(out, tmp);
-}
-
/* felem_is_zero returns a limb with all bits set if |in| == 0 (mod p) and 0
* otherwise.
* On entry:
@@ -855,10 +799,6 @@ static limb smallfelem_is_zero(const smallfelem small) {
return result;
}
-static int smallfelem_is_zero_int(const smallfelem small) {
- return (int)(smallfelem_is_zero(small) & ((limb)1));
-}
-
/* felem_inv calculates |out| = |in|^{-1}
*
* Based on Fermat's Little Theorem:
@@ -870,7 +810,7 @@ static void felem_inv(felem out, const felem in) {
/* each e_I will hold |in|^{2^I - 1} */
felem e2, e4, e8, e16, e32, e64;
longfelem tmp;
- unsigned i;
+ size_t i;
felem_square(tmp, in);
felem_reduce(ftmp, tmp); /* 2^1 */
@@ -958,14 +898,6 @@ static void felem_inv(felem out, const felem in) {
felem_reduce(out, tmp); /* 2^256 - 2^224 + 2^192 + 2^96 - 3 */
}
-static void smallfelem_inv_contract(smallfelem out, const smallfelem in) {
- felem tmp;
-
- smallfelem_expand(tmp, in);
- felem_inv(tmp, tmp);
- felem_contract(out, tmp);
-}
-
/* Group operations
* ----------------
*
@@ -1076,7 +1008,7 @@ static void point_double_small(smallfelem x_out, smallfelem y_out,
/* copy_conditional copies in to out iff mask is all ones. */
static void copy_conditional(felem out, const felem in, limb mask) {
- unsigned i;
+ size_t i;
for (i = 0; i < NLIMBS; ++i) {
const limb tmp = mask & (in[i] ^ out[i]);
out[i] ^= tmp;
@@ -1085,7 +1017,7 @@ static void copy_conditional(felem out, const felem in, limb mask) {
/* copy_small_conditional copies in to out iff mask is all ones. */
static void copy_small_conditional(felem out, const smallfelem in, limb mask) {
- unsigned i;
+ size_t i;
const u64 mask64 = mask;
for (i = 0; i < NLIMBS; ++i) {
out[i] = ((limb)(in[i] & mask64)) | (out[i] & ~mask);
@@ -1469,20 +1401,22 @@ static const smallfelem g_pre_comp[2][16][3] = {
/* 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 smallfelem pre_comp[16][3], smallfelem out[3]) {
- unsigned i, j;
+static void select_point(const u64 idx, size_t size,
+ const smallfelem pre_comp[/*size*/][3],
+ smallfelem out[3]) {
u64 *outlimbs = &out[0][0];
memset(outlimbs, 0, 3 * sizeof(smallfelem));
+ size_t i;
for (i = 0; i < size; i++) {
- const u64 *inlimbs = (u64 *)&pre_comp[i][0][0];
+ const u64 *inlimbs = (const u64 *)&pre_comp[i][0][0];
u64 mask = i ^ idx;
mask |= mask >> 4;
mask |= mask >> 2;
mask |= mask >> 1;
mask &= 1;
mask--;
+ size_t j;
for (j = 0; j < NLIMBS * 3; j++) {
outlimbs[j] |= inlimbs[j] & mask;
}
@@ -1504,10 +1438,8 @@ static char get_bit(const felem_bytearray in, int i) {
* 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 smallfelem pre_comp[][17][3]) {
- int i, skip;
- unsigned num, gen_mul = (g_scalar != NULL);
+ const size_t num_points, const u8 *g_scalar,
+ const smallfelem pre_comp[][17][3]) {
felem nq[3], ftmp;
smallfelem tmp[3];
u64 bits;
@@ -1520,16 +1452,16 @@ static void batch_mul(felem x_out, felem y_out, felem z_out,
* of the generator (two in each of the last 32 rounds) and additions of
* other points multiples (every 5th round). */
- skip = 1; /* save two point operations in the first
- * round */
- for (i = (num_points ? 255 : 31); i >= 0; --i) {
+ int skip = 1; /* save two point operations in the first round */
+ size_t i = num_points != 0 ? 255 : 31;
+ for (;;) {
/* 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 <= 31) {
+ if (g_scalar != NULL && i <= 31) {
/* first, look 32 bits upwards */
bits = get_bit(g_scalar, i + 224) << 3;
bits |= get_bit(g_scalar, i + 160) << 2;
@@ -1539,9 +1471,8 @@ static void batch_mul(felem x_out, felem y_out, felem z_out,
select_point(bits, 16, g_pre_comp[1], tmp);
if (!skip) {
- /* Arg 1 below is for "mixed" */
- point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1, tmp[0], tmp[1],
- tmp[2]);
+ point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1 /* mixed */,
+ tmp[0], tmp[1], tmp[2]);
} else {
smallfelem_expand(nq[0], tmp[0]);
smallfelem_expand(nq[1], tmp[1]);
@@ -1556,14 +1487,14 @@ static void batch_mul(felem x_out, felem y_out, felem z_out,
bits |= get_bit(g_scalar, i);
/* select the point to add, in constant time */
select_point(bits, 16, g_pre_comp[0], tmp);
- /* Arg 1 below is for "mixed" */
- point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1, tmp[0], tmp[1],
- tmp[2]);
+ 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)) {
+ if (num_points != 0 && i % 5 == 0) {
/* loop over all scalars */
+ size_t num;
for (num = 0; num < num_points; ++num) {
bits = get_bit(scalars[num], i + 4) << 5;
bits |= get_bit(scalars[num], i + 3) << 4;
@@ -1581,8 +1512,8 @@ static void batch_mul(felem x_out, felem y_out, felem z_out,
felem_contract(tmp[1], ftmp);
if (!skip) {
- point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], mixed, tmp[0],
- tmp[1], tmp[2]);
+ point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 0 /* mixed */,
+ tmp[0], tmp[1], tmp[2]);
} else {
smallfelem_expand(nq[0], tmp[0]);
smallfelem_expand(nq[1], tmp[1]);
@@ -1591,6 +1522,11 @@ static void batch_mul(felem x_out, felem y_out, felem z_out,
}
}
}
+
+ if (i == 0) {
+ break;
+ }
+ --i;
}
felem_assign(x_out, nq[0]);
felem_assign(y_out, nq[1]);
@@ -1602,53 +1538,12 @@ static void batch_mul(felem x_out, felem y_out, felem z_out,
* OPENSSL EC_METHOD FUNCTIONS
*/
-int ec_GFp_nistp256_group_init(EC_GROUP *group) {
- int ret = ec_GFp_simple_group_init(group);
- group->a_is_minus3 = 1;
- return ret;
-}
-
-int ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p,
- const BIGNUM *a, const BIGNUM *b,
- BN_CTX *ctx) {
- int ret = 0;
- BN_CTX *new_ctx = NULL;
- BIGNUM *curve_p, *curve_a, *curve_b;
-
- if (ctx == NULL) {
- if ((ctx = new_ctx = BN_CTX_new()) == 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(nistp256_curve_params[0], sizeof(felem_bytearray), curve_p);
- BN_bin2bn(nistp256_curve_params[1], sizeof(felem_bytearray), curve_a);
- BN_bin2bn(nistp256_curve_params[2], sizeof(felem_bytearray), curve_b);
- if (BN_cmp(curve_p, p) ||
- BN_cmp(curve_a, a) ||
- BN_cmp(curve_b, b)) {
- 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_nistp256_point_get_affine_coordinates(const EC_GROUP *group,
- const EC_POINT *point,
- BIGNUM *x, BIGNUM *y,
- BN_CTX *ctx) {
+static int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group,
+ const EC_POINT *point,
+ BIGNUM *x, BIGNUM *y,
+ BN_CTX *ctx) {
felem z1, z2, x_in, y_in;
smallfelem x_out, y_out;
longfelem tmp;
@@ -1665,45 +1560,38 @@ int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group,
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 && !smallfelem_to_BN(x, x_out)) {
- OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
- return 0;
+
+ if (x != NULL) {
+ felem_mul(tmp, x_in, z1);
+ felem_reduce(x_in, tmp);
+ felem_contract(x_out, x_in);
+ if (!smallfelem_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 && !smallfelem_to_BN(y, y_out)) {
- OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
- return 0;
+
+ if (y != NULL) {
+ 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 (!smallfelem_to_BN(y, y_out)) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
+ return 0;
+ }
}
- return 1;
-}
-/* points below is of size |num|, and tmp_smallfelems is of size |num+1| */
-static void make_points_affine(size_t num, smallfelem points[][3],
- smallfelem tmp_smallfelems[]) {
- /* Runs in constant time, unless an input is the point at infinity (which
- * normally shouldn't happen). */
- ec_GFp_nistp_points_make_affine_internal(
- num, points, sizeof(smallfelem), tmp_smallfelems,
- (void (*)(void *))smallfelem_one,
- (int (*)(const void *))smallfelem_is_zero_int,
- (void (*)(void *, const void *))smallfelem_assign,
- (void (*)(void *, const void *))smallfelem_square_contract,
- (void (*)(void *, const void *, const void *))smallfelem_mul_contract,
- (void (*)(void *, const void *))smallfelem_inv_contract,
- /* nothing to contract */
- (void (*)(void *, const void *))smallfelem_assign);
+ return 1;
}
-int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
- const BIGNUM *g_scalar, const EC_POINT *p_,
- const BIGNUM *p_scalar_, BN_CTX *ctx) {
+static int ec_GFp_nistp256_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|. */
@@ -1712,16 +1600,12 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
BIGNUM const *const *scalars = p_ != NULL ? &p_scalar_ : NULL;
int ret = 0;
- int j;
- int mixed = 0;
BN_CTX *new_ctx = NULL;
BIGNUM *x, *y, *z, *tmp_scalar;
felem_bytearray g_secret;
felem_bytearray *secrets = NULL;
smallfelem(*pre_comp)[17][3] = NULL;
- smallfelem *tmp_smallfelems = NULL;
felem_bytearray tmp;
- unsigned i, num_bytes;
size_t num_points = num;
smallfelem x_in, y_in, z_in;
felem x_out, y_out, z_out;
@@ -1744,19 +1628,9 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
}
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(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)) {
+ if (secrets == NULL || pre_comp == NULL) {
OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -1765,6 +1639,7 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
* 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(smallfelem));
+ size_t i;
for (i = 0; i < num_points; ++i) {
if (i == num) {
/* we didn't have a valid precomputation, so we pick the generator. */
@@ -1776,6 +1651,7 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
p_scalar = scalars[i];
}
if (p_scalar != NULL && p != NULL) {
+ size_t num_bytes;
/* 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
@@ -1798,6 +1674,7 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
felem_shrink(pre_comp[i][1][0], x_out);
felem_shrink(pre_comp[i][1][1], y_out);
felem_shrink(pre_comp[i][1][2], z_out);
+ size_t j;
for (j = 2; j <= 16; ++j) {
if (j & 1) {
point_add_small(pre_comp[i][j][0], pre_comp[i][j][1],
@@ -1813,12 +1690,11 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
}
}
}
- if (mixed) {
- make_points_affine(num_points * 17, pre_comp[0], tmp_smallfelems);
- }
}
if (g_scalar != NULL) {
+ size_t num_bytes;
+
memset(g_secret, 0, sizeof(g_secret));
/* reduce g_scalar to 0 <= g_scalar < 2^256 */
if (BN_num_bits(g_scalar) > 256 || BN_is_negative(g_scalar)) {
@@ -1835,7 +1711,7 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
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,
+ num_points, g_scalar != NULL ? g_secret : NULL,
(const smallfelem(*)[17][3])pre_comp);
/* reduce the output to its unique minimal representation */
@@ -1855,21 +1731,20 @@ err:
BN_CTX_free(new_ctx);
OPENSSL_free(secrets);
OPENSSL_free(pre_comp);
- OPENSSL_free(tmp_smallfelems);
return ret;
}
const EC_METHOD *EC_GFp_nistp256_method(void) {
static const EC_METHOD ret = {
- ec_GFp_nistp256_group_init,
+ ec_GFp_simple_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_copy,
+ ec_GFp_simple_group_set_curve,
ec_GFp_nistp256_point_get_affine_coordinates,
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 */
+ 0 /* field_encode */, 0 /* field_decode */,
};
return &ret;
diff --git a/src/crypto/ec/p256-x86_64-table.h b/src/crypto/ec/p256-x86_64-table.h
index 5b3254cc..e4705f8e 100644
--- a/src/crypto/ec/p256-x86_64-table.h
+++ b/src/crypto/ec/p256-x86_64-table.h
@@ -24,12 +24,7 @@
* 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
+static const alignas(4096) BN_ULONG
ecp_nistz256_precomputed[37][64 * sizeof(P256_POINT_AFFINE) /
sizeof(BN_ULONG)] = {
{TOBN(0x79e730d4, 0x18a9143c), TOBN(0x75ba95fc, 0x5fedb601),
diff --git a/src/crypto/ec/p256-x86_64.c b/src/crypto/ec/p256-x86_64.c
index 2f7023d6..e1afec48 100644
--- a/src/crypto/ec/p256-x86_64.c
+++ b/src/crypto/ec/p256-x86_64.c
@@ -39,15 +39,6 @@
!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 {
@@ -214,9 +205,7 @@ static void ecp_nistz256_mod_inverse(BN_ULONG r[P256_LIMBS],
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_mul_mont(r, res, in);
}
/* ecp_nistz256_bignum_to_field_elem copies the contents of |in| to |out| and
@@ -245,7 +234,7 @@ static int ecp_nistz256_windowed_mul(const EC_GROUP *group, P256_POINT *r,
/* 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];
+ alignas(64) P256_POINT table[16];
uint8_t p_str[33];
@@ -326,7 +315,7 @@ static int ecp_nistz256_windowed_mul(const EC_GROUP *group, P256_POINT *r,
ecp_nistz256_point_add(&row[16 - 1], &row[15 - 1], &row[1 - 1]);
BN_ULONG tmp[P256_LIMBS];
- ALIGN(32) P256_POINT h;
+ alignas(32) P256_POINT h;
unsigned index = 255;
unsigned wvalue = p_str[(index - 1) / 8];
wvalue = (wvalue >> ((index - 1) % 8)) & kMask;
@@ -390,7 +379,7 @@ static int ecp_nistz256_points_mul(
static const unsigned kWindowSize = 7;
static const unsigned kMask = (1 << (7 /* kWindowSize */ + 1)) - 1;
- ALIGN(32) union {
+ alignas(32) union {
P256_POINT p;
P256_POINT_AFFINE a;
} t, p;
@@ -399,17 +388,6 @@ static int ecp_nistz256_points_mul(
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) {
@@ -503,15 +481,12 @@ static int ecp_nistz256_points_mul(
}
}
- 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);
+ if (!bn_set_words(&r->X, p.p.X, P256_LIMBS) ||
+ !bn_set_words(&r->Y, p.p.Y, P256_LIMBS) ||
+ !bn_set_words(&r->Z, p.p.Z, P256_LIMBS)) {
+ return 0;
+ }
ret = 1;
@@ -527,8 +502,6 @@ 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)) {
@@ -545,7 +518,12 @@ static int ecp_nistz256_get_affine(const EC_GROUP *group, const EC_POINT *point,
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);
+
+ /* Instead of using |ecp_nistz256_from_mont| to convert the |x| coordinate
+ * and then calling |ecp_nistz256_from_mont| again to convert the |y|
+ * coordinate below, convert the common factor |z_inv2| once now, saving one
+ * reduction. */
+ ecp_nistz256_from_mont(z_inv2, z_inv2);
if (x != NULL) {
if (bn_wexpand(x, P256_LIMBS) == NULL) {
@@ -553,19 +531,20 @@ static int ecp_nistz256_get_affine(const EC_GROUP *group, const EC_POINT *point,
return 0;
}
x->top = P256_LIMBS;
- ecp_nistz256_from_mont(x->d, x_aff);
+ x->neg = 0;
+ ecp_nistz256_mul_mont(x->d, z_inv2, point_x);
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);
+ y->neg = 0;
+ ecp_nistz256_mul_mont(y->d, z_inv3, point_y);
bn_correct_top(y);
}
@@ -576,7 +555,6 @@ 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,
@@ -586,7 +564,6 @@ const EC_METHOD *EC_GFp_nistz256_method(void) {
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/simple.c b/src/crypto/ec/simple.c
index cef0e949..4508d83f 100644
--- a/src/crypto/ec/simple.c
+++ b/src/crypto/ec/simple.c
@@ -82,16 +82,16 @@
* field_sqr methods will be used for multiplication, and field_encode and
* field_decode (if defined) will be used for converting between
* representations.
-
- * Functions ec_GFp_simple_points_make_affine() and
- * ec_GFp_simple_point_get_affine_coordinates() specifically assume that if a
- * non-trivial representation is used, it is a Montgomery representation (i.e.
- * 'encoding' means multiplying by some factor R). */
+ *
+ * Functions here specifically assume that if a non-trivial representation is
+ * used, it is a Montgomery representation (i.e. 'encoding' means multiplying
+ * by some factor R). */
int ec_GFp_simple_group_init(EC_GROUP *group) {
BN_init(&group->field);
BN_init(&group->a);
BN_init(&group->b);
+ BN_init(&group->one);
group->a_is_minus3 = 0;
return 1;
}
@@ -100,18 +100,14 @@ void ec_GFp_simple_group_finish(EC_GROUP *group) {
BN_free(&group->field);
BN_free(&group->a);
BN_free(&group->b);
-}
-
-void ec_GFp_simple_group_clear_finish(EC_GROUP *group) {
- BN_clear_free(&group->field);
- BN_clear_free(&group->a);
- BN_clear_free(&group->b);
+ BN_free(&group->one);
}
int ec_GFp_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src) {
if (!BN_copy(&dest->field, &src->field) ||
!BN_copy(&dest->a, &src->a) ||
- !BN_copy(&dest->b, &src->b)) {
+ !BN_copy(&dest->b, &src->b) ||
+ !BN_copy(&dest->one, &src->one)) {
return 0;
}
@@ -178,6 +174,14 @@ int ec_GFp_simple_group_set_curve(EC_GROUP *group, const BIGNUM *p,
}
group->a_is_minus3 = (0 == BN_cmp(tmp_a, &group->field));
+ if (group->meth->field_encode != NULL) {
+ if (!group->meth->field_encode(group, &group->one, BN_value_one(), ctx)) {
+ goto err;
+ }
+ } else if (!BN_copy(&group->one, BN_value_one())) {
+ goto err;
+ }
+
ret = 1;
err:
@@ -230,81 +234,10 @@ unsigned ec_GFp_simple_group_get_degree(const EC_GROUP *group) {
return BN_num_bits(&group->field);
}
-int ec_GFp_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx) {
- int ret = 0;
- BIGNUM *a, *b, *order, *tmp_1, *tmp_2;
- const BIGNUM *p = &group->field;
- BN_CTX *new_ctx = NULL;
-
- if (ctx == NULL) {
- ctx = new_ctx = BN_CTX_new();
- if (ctx == NULL) {
- OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- }
- BN_CTX_start(ctx);
- a = BN_CTX_get(ctx);
- b = BN_CTX_get(ctx);
- tmp_1 = BN_CTX_get(ctx);
- tmp_2 = BN_CTX_get(ctx);
- order = BN_CTX_get(ctx);
- if (order == NULL) {
- goto err;
- }
-
- if (group->meth->field_decode) {
- if (!group->meth->field_decode(group, a, &group->a, ctx) ||
- !group->meth->field_decode(group, b, &group->b, ctx)) {
- goto err;
- }
- } else {
- if (!BN_copy(a, &group->a) || !BN_copy(b, &group->b)) {
- goto err;
- }
- }
-
- /* check the discriminant:
- * y^2 = x^3 + a*x + b is an elliptic curve <=> 4*a^3 + 27*b^2 != 0 (mod p)
- * 0 =< a, b < p */
- if (BN_is_zero(a)) {
- if (BN_is_zero(b)) {
- goto err;
- }
- } else if (!BN_is_zero(b)) {
- if (!BN_mod_sqr(tmp_1, a, p, ctx) ||
- !BN_mod_mul(tmp_2, tmp_1, a, p, ctx) ||
- !BN_lshift(tmp_1, tmp_2, 2)) {
- goto err;
- }
- /* tmp_1 = 4*a^3 */
-
- if (!BN_mod_sqr(tmp_2, b, p, ctx) ||
- !BN_mul_word(tmp_2, 27)) {
- goto err;
- }
- /* tmp_2 = 27*b^2 */
-
- if (!BN_mod_add(a, tmp_1, tmp_2, p, ctx) ||
- BN_is_zero(a)) {
- goto err;
- }
- }
- ret = 1;
-
-err:
- if (ctx != NULL) {
- BN_CTX_end(ctx);
- }
- BN_CTX_free(new_ctx);
- return ret;
-}
-
int ec_GFp_simple_point_init(EC_POINT *point) {
BN_init(&point->X);
BN_init(&point->Y);
BN_init(&point->Z);
- point->Z_is_one = 0;
return 1;
}
@@ -319,7 +252,6 @@ void ec_GFp_simple_point_clear_finish(EC_POINT *point) {
BN_clear_free(&point->X);
BN_clear_free(&point->Y);
BN_clear_free(&point->Z);
- point->Z_is_one = 0;
}
int ec_GFp_simple_point_copy(EC_POINT *dest, const EC_POINT *src) {
@@ -328,18 +260,32 @@ int ec_GFp_simple_point_copy(EC_POINT *dest, const EC_POINT *src) {
!BN_copy(&dest->Z, &src->Z)) {
return 0;
}
- dest->Z_is_one = src->Z_is_one;
return 1;
}
int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *group,
EC_POINT *point) {
- point->Z_is_one = 0;
BN_zero(&point->Z);
return 1;
}
+static int set_Jprojective_coordinate_GFp(const EC_GROUP *group, BIGNUM *out,
+ const BIGNUM *in, BN_CTX *ctx) {
+ if (in == NULL) {
+ return 1;
+ }
+ if (BN_is_negative(in) ||
+ BN_cmp(in, &group->field) >= 0) {
+ OPENSSL_PUT_ERROR(EC, EC_R_COORDINATES_OUT_OF_RANGE);
+ return 0;
+ }
+ if (group->meth->field_encode) {
+ return group->meth->field_encode(group, out, in, ctx);
+ }
+ return BN_copy(out, in) != NULL;
+}
+
int ec_GFp_simple_set_Jprojective_coordinates_GFp(
const EC_GROUP *group, EC_POINT *point, const BIGNUM *x, const BIGNUM *y,
const BIGNUM *z, BN_CTX *ctx) {
@@ -353,43 +299,10 @@ int ec_GFp_simple_set_Jprojective_coordinates_GFp(
}
}
- if (x != NULL) {
- if (!BN_nnmod(&point->X, x, &group->field, ctx)) {
- goto err;
- }
- if (group->meth->field_encode &&
- !group->meth->field_encode(group, &point->X, &point->X, ctx)) {
- goto err;
- }
- }
-
- if (y != NULL) {
- if (!BN_nnmod(&point->Y, y, &group->field, ctx)) {
- goto err;
- }
- if (group->meth->field_encode &&
- !group->meth->field_encode(group, &point->Y, &point->Y, ctx)) {
- goto err;
- }
- }
-
- if (z != NULL) {
- int Z_is_one;
-
- if (!BN_nnmod(&point->Z, z, &group->field, ctx)) {
- goto err;
- }
- Z_is_one = BN_is_one(&point->Z);
- if (group->meth->field_encode) {
- if (Z_is_one && (group->meth->field_set_to_one != 0)) {
- if (!group->meth->field_set_to_one(group, &point->Z, ctx)) {
- goto err;
- }
- } else if (!group->meth->field_encode(group, &point->Z, &point->Z, ctx)) {
- goto err;
- }
- }
- point->Z_is_one = Z_is_one;
+ if (!set_Jprojective_coordinate_GFp(group, &point->X, x, ctx) ||
+ !set_Jprojective_coordinate_GFp(group, &point->Y, y, ctx) ||
+ !set_Jprojective_coordinate_GFp(group, &point->Z, z, ctx)) {
+ goto err;
}
ret = 1;
@@ -455,109 +368,6 @@ int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *group,
BN_value_one(), ctx);
}
-int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group,
- const EC_POINT *point, BIGNUM *x,
- BIGNUM *y, BN_CTX *ctx) {
- BN_CTX *new_ctx = NULL;
- BIGNUM *Z, *Z_1, *Z_2, *Z_3;
- const BIGNUM *Z_;
- int ret = 0;
-
- if (EC_POINT_is_at_infinity(group, point)) {
- OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY);
- return 0;
- }
-
- if (ctx == NULL) {
- ctx = new_ctx = BN_CTX_new();
- if (ctx == NULL) {
- return 0;
- }
- }
-
- BN_CTX_start(ctx);
- Z = BN_CTX_get(ctx);
- Z_1 = BN_CTX_get(ctx);
- Z_2 = BN_CTX_get(ctx);
- Z_3 = BN_CTX_get(ctx);
- if (Z == NULL || Z_1 == NULL || Z_2 == NULL || Z_3 == NULL) {
- goto err;
- }
-
- /* transform (X, Y, Z) into (x, y) := (X/Z^2, Y/Z^3) */
-
- if (group->meth->field_decode) {
- if (!group->meth->field_decode(group, Z, &point->Z, ctx)) {
- goto err;
- }
- Z_ = Z;
- } else {
- Z_ = &point->Z;
- }
-
- if (BN_is_one(Z_)) {
- if (group->meth->field_decode) {
- if (x != NULL && !group->meth->field_decode(group, x, &point->X, ctx)) {
- goto err;
- }
- if (y != NULL && !group->meth->field_decode(group, y, &point->Y, ctx)) {
- goto err;
- }
- } else {
- if (x != NULL && !BN_copy(x, &point->X)) {
- goto err;
- }
- if (y != NULL && !BN_copy(y, &point->Y)) {
- goto err;
- }
- }
- } else {
- if (!BN_mod_inverse(Z_1, Z_, &group->field, ctx)) {
- OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
- goto err;
- }
-
- if (group->meth->field_encode == 0) {
- /* field_sqr works on standard representation */
- if (!group->meth->field_sqr(group, Z_2, Z_1, ctx)) {
- goto err;
- }
- } else if (!BN_mod_sqr(Z_2, Z_1, &group->field, ctx)) {
- goto err;
- }
-
- /* in the Montgomery case, field_mul will cancel out Montgomery factor in
- * X: */
- if (x != NULL && !group->meth->field_mul(group, x, &point->X, Z_2, ctx)) {
- goto err;
- }
-
- if (y != NULL) {
- if (group->meth->field_encode == 0) {
- /* field_mul works on standard representation */
- if (!group->meth->field_mul(group, Z_3, Z_2, Z_1, ctx)) {
- goto err;
- }
- } else if (!BN_mod_mul(Z_3, Z_2, Z_1, &group->field, ctx)) {
- goto err;
- }
-
- /* in the Montgomery case, field_mul will cancel out Montgomery factor in
- * Y: */
- if (!group->meth->field_mul(group, y, &point->Y, Z_3, ctx)) {
- goto err;
- }
- }
- }
-
- ret = 1;
-
-err:
- BN_CTX_end(ctx);
- BN_CTX_free(new_ctx);
- return ret;
-}
-
int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
const EC_POINT *b, BN_CTX *ctx) {
int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *,
@@ -607,7 +417,9 @@ int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
*/
/* n1, n2 */
- if (b->Z_is_one) {
+ int b_Z_is_one = BN_cmp(&b->Z, &group->one) == 0;
+
+ if (b_Z_is_one) {
if (!BN_copy(n1, &a->X) || !BN_copy(n2, &a->Y)) {
goto end;
}
@@ -628,7 +440,8 @@ int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
}
/* n3, n4 */
- if (a->Z_is_one) {
+ int a_Z_is_one = BN_cmp(&a->Z, &group->one) == 0;
+ if (a_Z_is_one) {
if (!BN_copy(n3, &b->X) || !BN_copy(n4, &b->Y)) {
goto end;
}
@@ -666,7 +479,6 @@ int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
} else {
/* a is the inverse of b */
BN_zero(&r->Z);
- r->Z_is_one = 0;
ret = 1;
goto end;
}
@@ -681,16 +493,16 @@ int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
/* 'n8' = n2 + n4 */
/* Z_r */
- if (a->Z_is_one && b->Z_is_one) {
+ if (a_Z_is_one && b_Z_is_one) {
if (!BN_copy(&r->Z, n5)) {
goto end;
}
} else {
- if (a->Z_is_one) {
+ if (a_Z_is_one) {
if (!BN_copy(n0, &b->Z)) {
goto end;
}
- } else if (b->Z_is_one) {
+ } else if (b_Z_is_one) {
if (!BN_copy(n0, &a->Z)) {
goto end;
}
@@ -701,7 +513,7 @@ int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
goto end;
}
}
- r->Z_is_one = 0;
+
/* Z_r = Z_a * Z_b * n5 */
/* X_r */
@@ -761,7 +573,6 @@ int ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
if (EC_POINT_is_at_infinity(group, a)) {
BN_zero(&r->Z);
- r->Z_is_one = 0;
return 1;
}
@@ -791,7 +602,7 @@ int ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
*/
/* n1 */
- if (a->Z_is_one) {
+ if (BN_cmp(&a->Z, &group->one) == 0) {
if (!field_sqr(group, n0, &a->X, ctx) ||
!BN_mod_lshift1_quick(n1, n0, p) ||
!BN_mod_add_quick(n0, n0, n1, p) ||
@@ -824,7 +635,7 @@ int ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
}
/* Z_r */
- if (a->Z_is_one) {
+ if (BN_cmp(&a->Z, &group->one) == 0) {
if (!BN_copy(n0, &a->Y)) {
goto err;
}
@@ -834,7 +645,6 @@ int ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
if (!BN_mod_lshift1_quick(&r->Z, n0, p)) {
goto err;
}
- r->Z_is_one = 0;
/* Z_r = 2 * Y_a * Z_a */
/* n2 */
@@ -886,7 +696,7 @@ int ec_GFp_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) {
}
int ec_GFp_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) {
- return !point->Z_is_one && BN_is_zero(&point->Z);
+ return BN_is_zero(&point->Z);
}
int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
@@ -897,7 +707,7 @@ int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
const BIGNUM *p;
BN_CTX *new_ctx = NULL;
BIGNUM *rh, *tmp, *Z4, *Z6;
- int ret = -1;
+ int ret = 0;
if (EC_POINT_is_at_infinity(group, point)) {
return 1;
@@ -910,7 +720,7 @@ int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
if (ctx == NULL) {
ctx = new_ctx = BN_CTX_new();
if (ctx == NULL) {
- return -1;
+ return 0;
}
}
@@ -938,7 +748,7 @@ int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
goto err;
}
- if (!point->Z_is_one) {
+ if (BN_cmp(&point->Z, &group->one) != 0) {
if (!field_sqr(group, tmp, &point->Z, ctx) ||
!field_sqr(group, Z4, tmp, ctx) ||
!field_mul(group, Z6, Z4, tmp, ctx)) {
@@ -967,8 +777,6 @@ int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
goto err;
}
} else {
- /* point->Z_is_one */
-
/* rh := (rh + a)*X */
if (!BN_mod_add_quick(rh, rh, &group->a, p) ||
!field_mul(group, rh, rh, &point->X, ctx)) {
@@ -1017,7 +825,10 @@ int ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a,
return 1;
}
- if (a->Z_is_one && b->Z_is_one) {
+ int a_Z_is_one = BN_cmp(&a->Z, &group->one) == 0;
+ int b_Z_is_one = BN_cmp(&b->Z, &group->one) == 0;
+
+ if (a_Z_is_one && b_Z_is_one) {
return ((BN_cmp(&a->X, &b->X) == 0) && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1;
}
@@ -1046,7 +857,7 @@ int ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a,
* (X_a*Z_b^2, Y_a*Z_b^3) = (X_b*Z_a^2, Y_b*Z_a^3).
*/
- if (!b->Z_is_one) {
+ if (!b_Z_is_one) {
if (!field_sqr(group, Zb23, &b->Z, ctx) ||
!field_mul(group, tmp1, &a->X, Zb23, ctx)) {
goto end;
@@ -1055,7 +866,7 @@ int ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a,
} else {
tmp1_ = &a->X;
}
- if (!a->Z_is_one) {
+ if (!a_Z_is_one) {
if (!field_sqr(group, Za23, &a->Z, ctx) ||
!field_mul(group, tmp2, &b->X, Za23, ctx)) {
goto end;
@@ -1072,7 +883,7 @@ int ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a,
}
- if (!b->Z_is_one) {
+ if (!b_Z_is_one) {
if (!field_mul(group, Zb23, Zb23, &b->Z, ctx) ||
!field_mul(group, tmp1, &a->Y, Zb23, ctx)) {
goto end;
@@ -1081,7 +892,7 @@ int ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a,
} else {
tmp1_ = &a->Y;
}
- if (!a->Z_is_one) {
+ if (!a_Z_is_one) {
if (!field_mul(group, Za23, Za23, &a->Z, ctx) ||
!field_mul(group, tmp2, &b->Y, Za23, ctx)) {
goto end;
@@ -1112,7 +923,8 @@ int ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point,
BIGNUM *x, *y;
int ret = 0;
- if (point->Z_is_one || EC_POINT_is_at_infinity(group, point)) {
+ if (BN_cmp(&point->Z, &group->one) == 0 ||
+ EC_POINT_is_at_infinity(group, point)) {
return 1;
}
@@ -1134,7 +946,7 @@ int ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point,
!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) {
goto err;
}
- if (!point->Z_is_one) {
+ if (BN_cmp(&point->Z, &group->one) != 0) {
OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
goto err;
}
@@ -1193,14 +1005,8 @@ int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num,
goto err;
}
} else {
- if (group->meth->field_set_to_one != 0) {
- if (!group->meth->field_set_to_one(group, prod_Z[0], ctx)) {
- goto err;
- }
- } else {
- if (!BN_one(prod_Z[0])) {
- goto err;
- }
+ if (BN_copy(prod_Z[0], &group->one) == NULL) {
+ goto err;
}
}
@@ -1271,16 +1077,9 @@ int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num,
goto err;
}
- if (group->meth->field_set_to_one != NULL) {
- if (!group->meth->field_set_to_one(group, &p->Z, ctx)) {
- goto err;
- }
- } else {
- if (!BN_one(&p->Z)) {
- goto err;
- }
+ if (BN_copy(&p->Z, &group->one) == NULL) {
+ goto err;
}
- p->Z_is_one = 1;
}
}
diff --git a/src/crypto/ec/util-64.c b/src/crypto/ec/util-64.c
index 171b0631..40062712 100644
--- a/src/crypto/ec/util-64.c
+++ b/src/crypto/ec/util-64.c
@@ -21,80 +21,6 @@
#include "internal.h"
-/* Convert an array of points into affine coordinates. (If the point at
- * infinity is found (Z = 0), it remains unchanged.) This function is
- * essentially an equivalent to EC_POINTs_make_affine(), but works with the
- * internal representation of points as used by ecp_nistp###.c rather than
- * with (BIGNUM-based) EC_POINT data structures. point_array is the
- * input/output buffer ('num' points in projective form, i.e. three
- * coordinates each), based on an internal representation of field elements
- * of size 'felem_size'. tmp_felems needs to point to a temporary array of
- * 'num'+1 field elements for storage of intermediate values. */
-void ec_GFp_nistp_points_make_affine_internal(
- size_t num, void *point_array, size_t felem_size, void *tmp_felems,
- void (*felem_one)(void *out), int (*felem_is_zero)(const void *in),
- void (*felem_assign)(void *out, const void *in),
- void (*felem_square)(void *out, const void *in),
- void (*felem_mul)(void *out, const void *in1, const void *in2),
- void (*felem_inv)(void *out, const void *in),
- void (*felem_contract)(void *out, const void *in)) {
- int i = 0;
-
-#define tmp_felem(I) (&((char *)tmp_felems)[(I)*felem_size])
-#define X(I) (&((char *)point_array)[3 * (I)*felem_size])
-#define Y(I) (&((char *)point_array)[(3 * (I) + 1) * felem_size])
-#define Z(I) (&((char *)point_array)[(3 * (I) + 2) * felem_size])
-
- if (!felem_is_zero(Z(0))) {
- felem_assign(tmp_felem(0), Z(0));
- } else {
- felem_one(tmp_felem(0));
- }
-
- for (i = 1; i < (int)num; i++) {
- if (!felem_is_zero(Z(i))) {
- felem_mul(tmp_felem(i), tmp_felem(i - 1), Z(i));
- } else {
- felem_assign(tmp_felem(i), tmp_felem(i - 1));
- }
- }
- /* Now each tmp_felem(i) is the product of Z(0) .. Z(i), skipping any
- * zero-valued factors: if Z(i) = 0, we essentially pretend that Z(i) = 1. */
-
- felem_inv(tmp_felem(num - 1), tmp_felem(num - 1));
- for (i = num - 1; i >= 0; i--) {
- if (i > 0) {
- /* tmp_felem(i-1) is the product of Z(0) .. Z(i-1), tmp_felem(i)
- * is the inverse of the product of Z(0) .. Z(i). */
- /* 1/Z(i) */
- felem_mul(tmp_felem(num), tmp_felem(i - 1), tmp_felem(i));
- } else {
- felem_assign(tmp_felem(num), tmp_felem(0)); /* 1/Z(0) */
- }
-
- if (!felem_is_zero(Z(i))) {
- if (i > 0) {
- /* For next iteration, replace tmp_felem(i-1) by its inverse. */
- felem_mul(tmp_felem(i - 1), tmp_felem(i), Z(i));
- }
-
- /* Convert point (X, Y, Z) into affine form (X/(Z^2), Y/(Z^3), 1). */
- felem_square(Z(i), tmp_felem(num)); /* 1/(Z^2) */
- felem_mul(X(i), X(i), Z(i)); /* X/(Z^2) */
- felem_mul(Z(i), Z(i), tmp_felem(num)); /* 1/(Z^3) */
- felem_mul(Y(i), Y(i), Z(i)); /* Y/(Z^3) */
- felem_contract(X(i), X(i));
- felem_contract(Y(i), Y(i));
- felem_one(Z(i));
- } else {
- if (i > 0) {
- /* For next iteration, replace tmp_felem(i-1) by its inverse. */
- felem_assign(tmp_felem(i - 1), tmp_felem(i));
- }
- }
- }
-}
-
/* This function looks at 5+1 scalar bits (5 current, 1 adjacent less
* significant bit), and recodes them into a signed digit for use in fast point
* multiplication: the use of signed rather than unsigned digits means that
diff --git a/src/crypto/ecdsa/ecdsa.c b/src/crypto/ecdsa/ecdsa.c
index 16760ed6..70cb1189 100644
--- a/src/crypto/ecdsa/ecdsa.c
+++ b/src/crypto/ecdsa/ecdsa.c
@@ -79,10 +79,6 @@ int ECDSA_verify(int type, const uint8_t *digest, size_t digest_len,
int ret = 0;
uint8_t *der = NULL;
- if (eckey->ecdsa_meth && eckey->ecdsa_meth->verify) {
- return eckey->ecdsa_meth->verify(digest, digest_len, sig, sig_len, eckey);
- }
-
/* Decode the ECDSA signature. */
s = ECDSA_SIG_from_bytes(sig, sig_len);
if (s == NULL) {
@@ -148,11 +144,6 @@ int ECDSA_do_verify(const uint8_t *digest, size_t digest_len,
const EC_GROUP *group;
const EC_POINT *pub_key;
- if (eckey->ecdsa_meth && eckey->ecdsa_meth->verify) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_NOT_IMPLEMENTED);
- return 0;
- }
-
/* check input values */
if ((group = EC_KEY_get0_group(eckey)) == NULL ||
(pub_key = EC_KEY_get0_public_key(eckey)) == NULL ||
@@ -224,7 +215,7 @@ int ECDSA_do_verify(const uint8_t *digest, size_t digest_len,
ret = (BN_ucmp(u1, sig->r) == 0);
err:
- BN_CTX_end(ctx);
+ BN_CTX_end(ctx);
BN_CTX_free(ctx);
EC_POINT_free(point);
return ret;
diff --git a/src/crypto/ecdsa/ecdsa_asn1.c b/src/crypto/ecdsa/ecdsa_asn1.c
index 3fee191e..d41a5366 100644
--- a/src/crypto/ecdsa/ecdsa_asn1.c
+++ b/src/crypto/ecdsa/ecdsa_asn1.c
@@ -61,6 +61,7 @@
#include <openssl/ec_key.h>
#include <openssl/mem.h>
+#include "../bytestring/internal.h"
#include "../ec/internal.h"
@@ -115,8 +116,8 @@ ECDSA_SIG *ECDSA_SIG_parse(CBS *cbs) {
}
CBS child;
if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) ||
- !BN_cbs2unsigned(&child, ret->r) ||
- !BN_cbs2unsigned(&child, ret->s) ||
+ !BN_parse_asn1_unsigned(&child, ret->r) ||
+ !BN_parse_asn1_unsigned(&child, ret->s) ||
CBS_len(&child) != 0) {
OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_BAD_SIGNATURE);
ECDSA_SIG_free(ret);
@@ -140,8 +141,8 @@ ECDSA_SIG *ECDSA_SIG_from_bytes(const uint8_t *in, size_t in_len) {
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) ||
+ !BN_marshal_asn1(&child, sig->r) ||
+ !BN_marshal_asn1(&child, sig->s) ||
!CBB_flush(cbb)) {
OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_ENCODE_ERROR);
return 0;
@@ -211,30 +212,16 @@ ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **out, const uint8_t **inp, long len) {
ECDSA_SIG_free(*out);
*out = ret;
}
- *inp += (size_t)len - CBS_len(&cbs);
+ *inp = CBS_data(&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);
+ CBB cbb;
+ if (!CBB_init(&cbb, 0) ||
+ !ECDSA_SIG_marshal(&cbb, sig)) {
+ CBB_cleanup(&cbb);
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;
+ return CBB_finish_i2d(&cbb, outp);
}
diff --git a/src/crypto/ecdsa/ecdsa_test.cc b/src/crypto/ecdsa/ecdsa_test.cc
index a0c8fbd0..8d7827df 100644
--- a/src/crypto/ecdsa/ecdsa_test.cc
+++ b/src/crypto/ecdsa/ecdsa_test.cc
@@ -59,7 +59,7 @@
#include <openssl/ec.h>
#include <openssl/err.h>
#include <openssl/mem.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
#include <openssl/rand.h>
#include "../test/scoped_types.h"
@@ -340,16 +340,19 @@ static bool TestECDSA_SIG_max_len(size_t order_len) {
return true;
}
+static size_t BitsToBytes(size_t bits) {
+ return (bits / 8) + (7 + (bits % 8)) / 8;
+}
+
int main(void) {
CRYPTO_library_init();
- ERR_load_crypto_strings();
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)) {
+ !TestECDSA_SIG_max_len(BitsToBytes(224)) ||
+ !TestECDSA_SIG_max_len(BitsToBytes(256)) ||
+ !TestECDSA_SIG_max_len(BitsToBytes(384)) ||
+ !TestECDSA_SIG_max_len(BitsToBytes(521)) ||
+ !TestECDSA_SIG_max_len(BitsToBytes(10000))) {
printf("\nECDSA test failed\n");
ERR_print_errors_fp(stdout);
return 1;
diff --git a/src/crypto/err/asn1.errordata b/src/crypto/err/asn1.errordata
index b1b04375..c304b2ca 100644
--- a/src/crypto/err/asn1.errordata
+++ b/src/crypto/err/asn1.errordata
@@ -6,82 +6,87 @@ 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
+ASN1,108,CONTEXT_NOT_INITIALISED
+ASN1,109,DECODE_ERROR
+ASN1,110,DEPTH_EXCEEDED
+ASN1,111,DIGEST_AND_KEY_TYPE_NOT_SUPPORTED
+ASN1,112,ENCODE_ERROR
+ASN1,113,ERROR_GETTING_TIME
+ASN1,114,EXPECTING_AN_ASN1_SEQUENCE
+ASN1,115,EXPECTING_AN_INTEGER
+ASN1,116,EXPECTING_AN_OBJECT
+ASN1,117,EXPECTING_A_BOOLEAN
+ASN1,118,EXPECTING_A_TIME
+ASN1,119,EXPLICIT_LENGTH_MISMATCH
+ASN1,120,EXPLICIT_TAG_NOT_CONSTRUCTED
+ASN1,121,FIELD_MISSING
+ASN1,122,FIRST_NUM_TOO_LARGE
+ASN1,123,HEADER_TOO_LONG
+ASN1,124,ILLEGAL_BITSTRING_FORMAT
+ASN1,125,ILLEGAL_BOOLEAN
+ASN1,126,ILLEGAL_CHARACTERS
+ASN1,127,ILLEGAL_FORMAT
+ASN1,128,ILLEGAL_HEX
+ASN1,129,ILLEGAL_IMPLICIT_TAG
+ASN1,130,ILLEGAL_INTEGER
+ASN1,131,ILLEGAL_NESTED_TAGGING
+ASN1,132,ILLEGAL_NULL
+ASN1,133,ILLEGAL_NULL_VALUE
+ASN1,134,ILLEGAL_OBJECT
+ASN1,135,ILLEGAL_OPTIONAL_ANY
+ASN1,136,ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE
+ASN1,137,ILLEGAL_TAGGED_ANY
+ASN1,138,ILLEGAL_TIME_VALUE
+ASN1,139,INTEGER_NOT_ASCII_FORMAT
+ASN1,140,INTEGER_TOO_LARGE_FOR_LONG
+ASN1,141,INVALID_BIT_STRING_BITS_LEFT
+ASN1,142,INVALID_BMPSTRING_LENGTH
+ASN1,143,INVALID_DIGIT
+ASN1,144,INVALID_MODIFIER
+ASN1,145,INVALID_NUMBER
+ASN1,146,INVALID_OBJECT_ENCODING
+ASN1,147,INVALID_SEPARATOR
+ASN1,148,INVALID_TIME_FORMAT
+ASN1,149,INVALID_UNIVERSALSTRING_LENGTH
+ASN1,150,INVALID_UTF8STRING
+ASN1,151,LIST_ERROR
+ASN1,152,MISSING_ASN1_EOS
+ASN1,153,MISSING_EOC
+ASN1,154,MISSING_SECOND_NUMBER
+ASN1,155,MISSING_VALUE
+ASN1,156,MSTRING_NOT_UNIVERSAL
+ASN1,157,MSTRING_WRONG_TAG
+ASN1,158,NESTED_ASN1_ERROR
+ASN1,159,NESTED_ASN1_STRING
+ASN1,160,NON_HEX_CHARACTERS
+ASN1,161,NOT_ASCII_FORMAT
+ASN1,162,NOT_ENOUGH_DATA
+ASN1,163,NO_MATCHING_CHOICE_TYPE
+ASN1,164,NULL_IS_WRONG_LENGTH
+ASN1,165,OBJECT_NOT_ASCII_FORMAT
+ASN1,166,ODD_NUMBER_OF_CHARS
+ASN1,167,SECOND_NUMBER_TOO_LARGE
+ASN1,168,SEQUENCE_LENGTH_MISMATCH
+ASN1,169,SEQUENCE_NOT_CONSTRUCTED
+ASN1,170,SEQUENCE_OR_SET_NEEDS_CONFIG
+ASN1,171,SHORT_LINE
+ASN1,172,STREAMING_NOT_SUPPORTED
+ASN1,173,STRING_TOO_LONG
+ASN1,174,STRING_TOO_SHORT
+ASN1,175,TAG_VALUE_TOO_HIGH
+ASN1,176,TIME_NOT_ASCII_FORMAT
+ASN1,177,TOO_LONG
+ASN1,178,TYPE_NOT_CONSTRUCTED
+ASN1,179,TYPE_NOT_PRIMITIVE
+ASN1,180,UNEXPECTED_EOC
+ASN1,181,UNIVERSALSTRING_IS_WRONG_LENGTH
+ASN1,182,UNKNOWN_FORMAT
+ASN1,183,UNKNOWN_MESSAGE_DIGEST_ALGORITHM
+ASN1,184,UNKNOWN_SIGNATURE_ALGORITHM
+ASN1,185,UNKNOWN_TAG
+ASN1,186,UNSUPPORTED_ANY_DEFINED_BY_TYPE
+ASN1,187,UNSUPPORTED_PUBLIC_KEY_TYPE
+ASN1,188,UNSUPPORTED_TYPE
+ASN1,189,WRONG_PUBLIC_KEY_TYPE
+ASN1,190,WRONG_TAG
+ASN1,191,WRONG_TYPE
diff --git a/src/crypto/err/dsa.errordata b/src/crypto/err/dsa.errordata
index 3c5764a1..6f4bc138 100644
--- a/src/crypto/err/dsa.errordata
+++ b/src/crypto/err/dsa.errordata
@@ -1,4 +1,7 @@
DSA,100,BAD_Q_VALUE
+DSA,104,BAD_VERSION
+DSA,105,DECODE_ERROR
+DSA,106,ENCODE_ERROR
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 e7b41756..d074afc9 100644
--- a/src/crypto/err/ec.errordata
+++ b/src/crypto/err/ec.errordata
@@ -2,8 +2,11 @@ EC,126,BIGNUM_OUT_OF_RANGE
EC,100,BUFFER_TOO_SMALL
EC,101,COORDINATES_OUT_OF_RANGE
EC,102,D2I_ECPKPARAMETERS_FAILURE
+EC,128,DECODE_ERROR
EC,103,EC_GROUP_NEW_BY_NAME_FAILURE
+EC,129,ENCODE_ERROR
EC,104,GROUP2PKPARAMETERS_FAILURE
+EC,130,GROUP_MISMATCH
EC,105,I2D_ECPKPARAMETERS_FAILURE
EC,106,INCOMPATIBLE_OBJECTS
EC,107,INVALID_COMPRESSED_POINT
diff --git a/src/crypto/err/err_data_generate.go b/src/crypto/err/err_data_generate.go
index 24e0d66f..893ebffe 100644
--- a/src/crypto/err/err_data_generate.go
+++ b/src/crypto/err/err_data_generate.go
@@ -18,6 +18,7 @@ import (
"bufio"
"bytes"
"errors"
+ "flag"
"fmt"
"io"
"os"
@@ -26,6 +27,8 @@ import (
"strings"
)
+var verbose = flag.Bool("verbose", false, "If true, prints a status message at the end.")
+
// libraryNames must be kept in sync with the enum in err.h. The generated code
// will contain static assertions to enforce this.
var libraryNames = []string{
@@ -138,7 +141,9 @@ type stringWriter interface {
func (st *stringList) WriteTo(out stringWriter, name string) {
list := st.buildList()
- fmt.Fprintf(os.Stderr, "%s: %d bytes of list and %d bytes of string data.\n", name, 4*len(list), len(st.stringData))
+ if *verbose {
+ fmt.Fprintf(os.Stderr, "%s: %d bytes of list and %d bytes of string data.\n", name, 4*len(list), len(st.stringData))
+ }
values := "kOpenSSL" + name + "Values"
out.WriteString("const uint32_t " + values + "[] = {\n")
@@ -215,6 +220,8 @@ func (e *errorData) readErrorDataFile(filename string) error {
}
func main() {
+ flag.Parse()
+
e := &errorData{
reasons: newStringList(),
libraryMap: make(map[string]uint32),
diff --git a/src/crypto/err/evp.errordata b/src/crypto/err/evp.errordata
index 8f8dd483..a482f769 100644
--- a/src/crypto/err/evp.errordata
+++ b/src/crypto/err/evp.errordata
@@ -1,46 +1,30 @@
-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
+EVP,102,DECODE_ERROR
+EVP,103,DIFFERENT_KEY_TYPES
+EVP,104,DIFFERENT_PARAMETERS
+EVP,105,ENCODE_ERROR
+EVP,106,EXPECTING_AN_EC_KEY_KEY
+EVP,107,EXPECTING_AN_RSA_KEY
+EVP,108,EXPECTING_A_DSA_KEY
+EVP,109,ILLEGAL_OR_UNSUPPORTED_PADDING_MODE
+EVP,110,INVALID_DIGEST_LENGTH
+EVP,111,INVALID_DIGEST_TYPE
+EVP,112,INVALID_KEYBITS
+EVP,113,INVALID_MGF1_MD
+EVP,114,INVALID_OPERATION
+EVP,115,INVALID_PADDING_MODE
+EVP,116,INVALID_PSS_SALTLEN
+EVP,117,KEYS_NOT_SET
+EVP,118,MISSING_PARAMETERS
+EVP,119,NO_DEFAULT_DIGEST
+EVP,120,NO_KEY_SET
+EVP,121,NO_MDC2_SUPPORT
+EVP,122,NO_NID_FOR_CURVE
+EVP,123,NO_OPERATION_SET
+EVP,124,NO_PARAMETERS_SET
+EVP,125,OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE
+EVP,126,OPERATON_NOT_INITIALIZED
+EVP,127,UNKNOWN_PUBLIC_KEY_TYPE
+EVP,128,UNSUPPORTED_ALGORITHM
+EVP,129,UNSUPPORTED_PUBLIC_KEY_TYPE
diff --git a/src/crypto/err/rsa.errordata b/src/crypto/err/rsa.errordata
index c19f73c7..62d286cc 100644
--- a/src/crypto/err/rsa.errordata
+++ b/src/crypto/err/rsa.errordata
@@ -1,46 +1,46 @@
-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
+RSA,100,BAD_ENCODING
+RSA,101,BAD_E_VALUE
+RSA,102,BAD_FIXED_HEADER_DECRYPT
+RSA,103,BAD_PAD_BYTE_COUNT
+RSA,104,BAD_RSA_PARAMETERS
+RSA,105,BAD_SIGNATURE
+RSA,106,BAD_VERSION
+RSA,107,BLOCK_TYPE_IS_NOT_01
+RSA,108,BN_NOT_INITIALIZED
+RSA,109,CANNOT_RECOVER_MULTI_PRIME_KEY
+RSA,110,CRT_PARAMS_ALREADY_GIVEN
+RSA,111,CRT_VALUES_INCORRECT
+RSA,112,DATA_LEN_NOT_EQUAL_TO_MOD_LEN
+RSA,113,DATA_TOO_LARGE
+RSA,114,DATA_TOO_LARGE_FOR_KEY_SIZE
+RSA,115,DATA_TOO_LARGE_FOR_MODULUS
+RSA,116,DATA_TOO_SMALL
+RSA,117,DATA_TOO_SMALL_FOR_KEY_SIZE
+RSA,118,DIGEST_TOO_BIG_FOR_RSA_KEY
+RSA,119,D_E_NOT_CONGRUENT_TO_1
+RSA,120,EMPTY_PUBLIC_KEY
+RSA,121,ENCODE_ERROR
+RSA,122,FIRST_OCTET_INVALID
+RSA,123,INCONSISTENT_SET_OF_CRT_VALUES
+RSA,124,INTERNAL_ERROR
+RSA,125,INVALID_MESSAGE_LENGTH
+RSA,126,KEY_SIZE_TOO_SMALL
+RSA,127,LAST_OCTET_INVALID
+RSA,128,MODULUS_TOO_LARGE
+RSA,129,MUST_HAVE_AT_LEAST_TWO_PRIMES
+RSA,130,NO_PUBLIC_EXPONENT
+RSA,131,NULL_BEFORE_BLOCK_MISSING
+RSA,132,N_NOT_EQUAL_P_Q
+RSA,133,OAEP_DECODING_ERROR
+RSA,134,ONLY_ONE_OF_P_Q_GIVEN
+RSA,135,OUTPUT_BUFFER_TOO_SMALL
+RSA,136,PADDING_CHECK_FAILED
+RSA,137,PKCS_DECODING_ERROR
+RSA,138,SLEN_CHECK_FAILED
+RSA,139,SLEN_RECOVERY_FAILED
+RSA,140,TOO_LONG
+RSA,141,TOO_MANY_ITERATIONS
+RSA,142,UNKNOWN_ALGORITHM_TYPE
+RSA,143,UNKNOWN_PADDING_TYPE
+RSA,144,VALUE_MISSING
+RSA,145,WRONG_SIGNATURE_LENGTH
diff --git a/src/crypto/err/ssl.errordata b/src/crypto/err/ssl.errordata
index 3766bb98..dfe4ac81 100644
--- a/src/crypto/err/ssl.errordata
+++ b/src/crypto/err/ssl.errordata
@@ -108,6 +108,7 @@ SSL,206,SCSV_RECEIVED_WHEN_RENEGOTIATING
SSL,207,SERVERHELLO_TLSEXT
SSL,208,SESSION_ID_CONTEXT_UNINITIALIZED
SSL,209,SESSION_MAY_NOT_BE_CREATED
+SSL,250,SHUTDOWN_WHILE_IN_INIT
SSL,210,SIGNATURE_ALGORITHMS_EXTENSION_SENT_BY_SERVER
SSL,211,SRTP_COULD_NOT_ALLOCATE_PROFILES
SSL,212,SRTP_UNKNOWN_PROTECTION_PROFILE
diff --git a/src/crypto/err/x509.errordata b/src/crypto/err/x509.errordata
index f4828ce8..a1d49b71 100644
--- a/src/crypto/err/x509.errordata
+++ b/src/crypto/err/x509.errordata
@@ -10,28 +10,26 @@ 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,112,INVALID_PSS_PARAMETERS
+X509,113,INVALID_TRUST
+X509,114,ISSUER_MISMATCH
+X509,115,KEY_TYPE_MISMATCH
+X509,116,KEY_VALUES_MISMATCH
+X509,117,LOADING_CERT_DIR
+X509,118,LOADING_DEFAULTS
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
+X509,123,NO_CRLS_INCLUDED
+X509,124,NO_CRL_NUMBER
+X509,125,PUBLIC_KEY_DECODE_ERROR
+X509,126,PUBLIC_KEY_ENCODE_ERROR
+X509,127,SHOULD_RETRY
+X509,128,UNKNOWN_KEY_TYPE
+X509,129,UNKNOWN_NID
+X509,130,UNKNOWN_PURPOSE_ID
+X509,131,UNKNOWN_TRUST_ID
+X509,132,UNSUPPORTED_ALGORITHM
+X509,133,WRONG_LOOKUP_TYPE
+X509,134,WRONG_TYPE
diff --git a/src/crypto/evp/CMakeLists.txt b/src/crypto/evp/CMakeLists.txt
index 000f0762..ca1b5112 100644
--- a/src/crypto/evp/CMakeLists.txt
+++ b/src/crypto/evp/CMakeLists.txt
@@ -5,7 +5,6 @@ add_library(
OBJECT
- algorithm.c
digestsign.c
evp.c
evp_asn1.c
@@ -16,6 +15,7 @@ add_library(
p_rsa.c
p_rsa_asn1.c
pbkdf.c
+ print.c
sign.c
)
diff --git a/src/crypto/evp/evp.c b/src/crypto/evp/evp.c
index afe5c38a..79993aab 100644
--- a/src/crypto/evp/evp.c
+++ b/src/crypto/evp/evp.c
@@ -59,12 +59,11 @@
#include <assert.h>
#include <string.h>
-#include <openssl/bio.h>
#include <openssl/dsa.h>
#include <openssl/ec.h>
#include <openssl/err.h>
#include <openssl/mem.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
#include <openssl/rsa.h>
#include <openssl/thread.h>
@@ -195,11 +194,12 @@ int EVP_PKEY_id(const EVP_PKEY *pkey) {
return pkey->type;
}
-/* TODO(fork): remove the first argument. */
-const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pengine, int nid) {
+/* 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. */
+static const EVP_PKEY_ASN1_METHOD *evp_pkey_asn1_find(int nid) {
switch (nid) {
case EVP_PKEY_RSA:
- case EVP_PKEY_RSA2:
return &rsa_asn1_meth;
case EVP_PKEY_EC:
return &ec_asn1_meth;
@@ -211,7 +211,7 @@ const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pengine, int nid) {
}
int EVP_PKEY_type(int nid) {
- const EVP_PKEY_ASN1_METHOD *meth = EVP_PKEY_asn1_find(NULL, nid);
+ const EVP_PKEY_ASN1_METHOD *meth = evp_pkey_asn1_find(nid);
if (meth == NULL) {
return NID_undef;
}
@@ -310,19 +310,6 @@ int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key) {
return key != NULL;
}
-const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pengine,
- const char *name,
- size_t len) {
- if (len == 3 && memcmp(name, "RSA", 3) == 0) {
- return &rsa_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;
-}
-
int EVP_PKEY_set_type(EVP_PKEY *pkey, int type) {
const EVP_PKEY_ASN1_METHOD *ameth;
@@ -330,10 +317,10 @@ int EVP_PKEY_set_type(EVP_PKEY *pkey, int type) {
free_it(pkey);
}
- ameth = EVP_PKEY_asn1_find(NULL, type);
+ ameth = evp_pkey_asn1_find(type);
if (ameth == NULL) {
OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM);
- ERR_add_error_dataf("algorithm %d (%s)", type, OBJ_nid2sn(type));
+ ERR_add_error_dataf("algorithm %d", type);
return 0;
}
@@ -357,41 +344,6 @@ int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) {
return -2;
}
-static int print_unsupported(BIO *out, const EVP_PKEY *pkey, int indent,
- const char *kstr) {
- BIO_indent(out, indent, 128);
- BIO_printf(out, "%s algorithm \"%s\" unsupported\n", kstr,
- OBJ_nid2ln(pkey->type));
- return 1;
-}
-
-int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, int indent,
- ASN1_PCTX *pctx) {
- if (pkey->ameth && pkey->ameth->pub_print) {
- return pkey->ameth->pub_print(out, pkey, indent, pctx);
- }
-
- return print_unsupported(out, pkey, indent, "Public Key");
-}
-
-int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, int indent,
- ASN1_PCTX *pctx) {
- if (pkey->ameth && pkey->ameth->priv_print) {
- return pkey->ameth->priv_print(out, pkey, indent, pctx);
- }
-
- return print_unsupported(out, pkey, indent, "Private Key");
-}
-
-int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, int indent,
- ASN1_PCTX *pctx) {
- if (pkey->ameth && pkey->ameth->param_print) {
- return pkey->ameth->param_print(out, pkey, indent, pctx);
- }
-
- return print_unsupported(out, pkey, indent, "Parameters");
-}
-
int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) {
return EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, EVP_PKEY_CTRL_MD, 0,
(void *)md);
diff --git a/src/crypto/evp/evp_asn1.c b/src/crypto/evp/evp_asn1.c
index c57f4113..3681d4fc 100644
--- a/src/crypto/evp/evp_asn1.c
+++ b/src/crypto/evp/evp_asn1.c
@@ -56,112 +56,269 @@
#include <openssl/evp.h>
-#include <openssl/asn1.h>
+#include <string.h>
+
+#include <openssl/bytestring.h>
+#include <openssl/dsa.h>
+#include <openssl/ec_key.h>
#include <openssl/err.h>
-#include <openssl/obj.h>
-#include <openssl/x509.h>
+#include <openssl/rsa.h>
#include "internal.h"
-EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **out, const uint8_t **inp,
- long len) {
- EVP_PKEY *ret;
+static const EVP_PKEY_ASN1_METHOD *const kASN1Methods[] = {
+ &rsa_asn1_meth,
+ &ec_asn1_meth,
+ &dsa_asn1_meth,
+};
- if (out == NULL || *out == NULL) {
- ret = EVP_PKEY_new();
- if (ret == NULL) {
- OPENSSL_PUT_ERROR(EVP, ERR_R_EVP_LIB);
- return NULL;
+static int parse_key_type(CBS *cbs, int *out_type) {
+ CBS oid;
+ if (!CBS_get_asn1(cbs, &oid, CBS_ASN1_OBJECT)) {
+ return 0;
+ }
+
+ unsigned i;
+ for (i = 0; i < sizeof(kASN1Methods)/sizeof(kASN1Methods[0]); i++) {
+ const EVP_PKEY_ASN1_METHOD *method = kASN1Methods[i];
+ if (CBS_len(&oid) == method->oid_len &&
+ memcmp(CBS_data(&oid), method->oid, method->oid_len) == 0) {
+ *out_type = method->pkey_id;
+ return 1;
}
- } else {
- ret = *out;
}
- if (!EVP_PKEY_set_type(ret, type)) {
- OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_PUBLIC_KEY_TYPE);
+ return 0;
+}
+
+EVP_PKEY *EVP_parse_public_key(CBS *cbs) {
+ /* Parse the SubjectPublicKeyInfo. */
+ CBS spki, algorithm, key;
+ int type;
+ uint8_t padding;
+ if (!CBS_get_asn1(cbs, &spki, CBS_ASN1_SEQUENCE) ||
+ !CBS_get_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) ||
+ !parse_key_type(&algorithm, &type) ||
+ !CBS_get_asn1(&spki, &key, CBS_ASN1_BITSTRING) ||
+ CBS_len(&spki) != 0 ||
+ /* Every key type defined encodes the key as a byte string with the same
+ * conversion to BIT STRING. */
+ !CBS_get_u8(&key, &padding) ||
+ padding != 0) {
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
+ return NULL;
+ }
+
+ /* Set up an |EVP_PKEY| of the appropriate type. */
+ EVP_PKEY *ret = EVP_PKEY_new();
+ if (ret == NULL ||
+ !EVP_PKEY_set_type(ret, type)) {
+ goto err;
+ }
+
+ /* Call into the type-specific SPKI decoding function. */
+ if (ret->ameth->pub_decode == NULL) {
+ OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM);
+ goto err;
+ }
+ if (!ret->ameth->pub_decode(ret, &algorithm, &key)) {
+ goto err;
+ }
+
+ return ret;
+
+err:
+ EVP_PKEY_free(ret);
+ return NULL;
+}
+
+int EVP_marshal_public_key(CBB *cbb, const EVP_PKEY *key) {
+ if (key->ameth == NULL || key->ameth->pub_encode == NULL) {
+ OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM);
+ return 0;
+ }
+
+ return key->ameth->pub_encode(cbb, key);
+}
+
+EVP_PKEY *EVP_parse_private_key(CBS *cbs) {
+ /* Parse the PrivateKeyInfo. */
+ CBS pkcs8, algorithm, key;
+ uint64_t version;
+ int type;
+ if (!CBS_get_asn1(cbs, &pkcs8, CBS_ASN1_SEQUENCE) ||
+ !CBS_get_asn1_uint64(&pkcs8, &version) ||
+ version != 0 ||
+ !CBS_get_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) ||
+ !parse_key_type(&algorithm, &type) ||
+ !CBS_get_asn1(&pkcs8, &key, CBS_ASN1_OCTETSTRING)) {
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
+ return NULL;
+ }
+
+ /* A PrivateKeyInfo ends with a SET of Attributes which we ignore. */
+
+ /* Set up an |EVP_PKEY| of the appropriate type. */
+ EVP_PKEY *ret = EVP_PKEY_new();
+ if (ret == NULL ||
+ !EVP_PKEY_set_type(ret, type)) {
goto err;
}
- const uint8_t *in = *inp;
- if (!ret->ameth->old_priv_decode ||
- !ret->ameth->old_priv_decode(ret, &in, len)) {
- if (ret->ameth->priv_decode) {
- /* 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) {
+ /* Call into the type-specific PrivateKeyInfo decoding function. */
+ if (ret->ameth->priv_decode == NULL) {
+ OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM);
+ goto err;
+ }
+ if (!ret->ameth->priv_decode(ret, &algorithm, &key)) {
+ goto err;
+ }
+
+ return ret;
+
+err:
+ EVP_PKEY_free(ret);
+ return NULL;
+}
+
+int EVP_marshal_private_key(CBB *cbb, const EVP_PKEY *key) {
+ if (key->ameth == NULL || key->ameth->priv_encode == NULL) {
+ OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM);
+ return 0;
+ }
+
+ return key->ameth->priv_encode(cbb, key);
+}
+
+static EVP_PKEY *old_priv_decode(CBS *cbs, int type) {
+ EVP_PKEY *ret = EVP_PKEY_new();
+ if (ret == NULL) {
+ return NULL;
+ }
+
+ switch (type) {
+ case EVP_PKEY_EC: {
+ EC_KEY *ec_key = EC_KEY_parse_private_key(cbs, NULL);
+ if (ec_key == NULL || !EVP_PKEY_assign_EC_KEY(ret, ec_key)) {
+ EC_KEY_free(ec_key);
goto err;
}
- EVP_PKEY_free(ret);
- ret = EVP_PKCS82PKEY(p8);
- PKCS8_PRIV_KEY_INFO_free(p8);
- if (ret == NULL) {
+ return ret;
+ }
+ case EVP_PKEY_DSA: {
+ DSA *dsa = DSA_parse_private_key(cbs);
+ if (dsa == NULL || !EVP_PKEY_assign_DSA(ret, dsa)) {
+ DSA_free(dsa);
+ goto err;
+ }
+ return ret;
+ }
+ case EVP_PKEY_RSA: {
+ RSA *rsa = RSA_parse_private_key(cbs);
+ if (rsa == NULL || !EVP_PKEY_assign_RSA(ret, rsa)) {
+ RSA_free(rsa);
goto err;
}
- } else {
- OPENSSL_PUT_ERROR(EVP, ERR_R_ASN1_LIB);
+ return ret;
+ }
+ default:
+ OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_PUBLIC_KEY_TYPE);
goto err;
+ }
+
+err:
+ EVP_PKEY_free(ret);
+ return NULL;
+}
+
+EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **out, const uint8_t **inp,
+ long len) {
+ if (len < 0) {
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
+ return NULL;
+ }
+
+ /* Parse with the legacy format. */
+ CBS cbs;
+ CBS_init(&cbs, *inp, (size_t)len);
+ EVP_PKEY *ret = old_priv_decode(&cbs, type);
+ if (ret == NULL) {
+ /* Try again with PKCS#8. */
+ ERR_clear_error();
+ CBS_init(&cbs, *inp, (size_t)len);
+ ret = EVP_parse_private_key(&cbs);
+ if (ret == NULL) {
+ return NULL;
+ }
+ if (ret->type != type) {
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_KEY_TYPES);
+ EVP_PKEY_free(ret);
+ return NULL;
}
}
if (out != NULL) {
+ EVP_PKEY_free(*out);
*out = ret;
}
- *inp = in;
+ *inp = CBS_data(&cbs);
return ret;
+}
-err:
- if (out == NULL || *out != ret) {
- EVP_PKEY_free(ret);
+/* num_elements parses one SEQUENCE from |in| and returns the number of elements
+ * in it. On parse error, it returns zero. */
+static size_t num_elements(const uint8_t *in, size_t in_len) {
+ CBS cbs, sequence;
+ CBS_init(&cbs, in, (size_t)in_len);
+
+ if (!CBS_get_asn1(&cbs, &sequence, CBS_ASN1_SEQUENCE)) {
+ return 0;
}
- return NULL;
+
+ size_t count = 0;
+ while (CBS_len(&sequence) > 0) {
+ if (!CBS_get_any_asn1_element(&sequence, NULL, NULL, NULL)) {
+ return 0;
+ }
+
+ count++;
+ }
+
+ return count;
}
EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **out, const uint8_t **inp, long len) {
- STACK_OF(ASN1_TYPE) *inkey;
- const uint8_t *p;
- int keytype;
- p = *inp;
-
- /* Dirty trick: read in the ASN1 data into out STACK_OF(ASN1_TYPE):
- * by analyzing it we can determine the passed structure: this
- * assumes the input is surrounded by an ASN1 SEQUENCE. */
- inkey = d2i_ASN1_SEQUENCE_ANY(NULL, &p, len);
- /* Since we only need to discern "traditional format" RSA and DSA
- * keys we can just count the elements. */
- if (sk_ASN1_TYPE_num(inkey) == 6) {
- keytype = EVP_PKEY_DSA;
- } else if (sk_ASN1_TYPE_num(inkey) == 4) {
- keytype = EVP_PKEY_EC;
- } else if (sk_ASN1_TYPE_num(inkey) == 3) {
- /* This seems to be PKCS8, not traditional format */
- 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, EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
- return NULL;
- }
- ret = EVP_PKCS82PKEY(p8);
- PKCS8_PRIV_KEY_INFO_free(p8);
- if (ret == NULL) {
- return NULL;
- }
+ if (len < 0) {
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
+ return NULL;
+ }
- *inp = p;
- if (out) {
+ /* Parse the input as a PKCS#8 PrivateKeyInfo. */
+ CBS cbs;
+ CBS_init(&cbs, *inp, (size_t)len);
+ EVP_PKEY *ret = EVP_parse_private_key(&cbs);
+ if (ret != NULL) {
+ if (out != NULL) {
+ EVP_PKEY_free(*out);
*out = ret;
}
+ *inp = CBS_data(&cbs);
return ret;
- } else {
- keytype = EVP_PKEY_RSA;
}
+ ERR_clear_error();
+
+ /* Count the elements to determine the legacy key format. */
+ switch (num_elements(*inp, (size_t)len)) {
+ case 4:
+ return d2i_PrivateKey(EVP_PKEY_EC, out, inp, len);
+
+ case 6:
+ return d2i_PrivateKey(EVP_PKEY_DSA, out, inp, len);
- sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
- return d2i_PrivateKey(keytype, out, inp, len);
+ default:
+ return d2i_PrivateKey(EVP_PKEY_RSA, out, inp, len);
+ }
}
int i2d_PublicKey(EVP_PKEY *key, uint8_t **outp) {
diff --git a/src/crypto/evp/evp_ctx.c b/src/crypto/evp/evp_ctx.c
index 9e038cd2..f510f6c7 100644
--- a/src/crypto/evp/evp_ctx.c
+++ b/src/crypto/evp/evp_ctx.c
@@ -56,12 +56,10 @@
#include <openssl/evp.h>
-#include <stdio.h>
#include <string.h>
#include <openssl/err.h>
#include <openssl/mem.h>
-#include <openssl/obj.h>
#include "internal.h"
@@ -98,8 +96,7 @@ static EVP_PKEY_CTX *evp_pkey_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id) {
if (pmeth == NULL) {
OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM);
- const char *name = OBJ_nid2sn(id);
- ERR_add_error_dataf("algorithm %d (%s)", id, name);
+ ERR_add_error_dataf("algorithm %d", id);
return NULL;
}
@@ -193,12 +190,6 @@ err:
EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx) { return ctx->pkey; }
-void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data) {
- ctx->app_data = data;
-}
-
-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) {
@@ -229,15 +220,6 @@ int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx) {
}
ctx->operation = EVP_PKEY_OP_SIGN;
- if (!ctx->pmeth->sign_init) {
- return 1;
- }
-
- if (!ctx->pmeth->sign_init(ctx)) {
- ctx->operation = EVP_PKEY_OP_UNDEFINED;
- return 0;
- }
-
return 1;
}
@@ -260,14 +242,6 @@ int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx) {
return 0;
}
ctx->operation = EVP_PKEY_OP_VERIFY;
- if (!ctx->pmeth->verify_init) {
- return 1;
- }
- if (!ctx->pmeth->verify_init(ctx)) {
- ctx->operation = EVP_PKEY_OP_UNDEFINED;
- return 0;
- }
-
return 1;
}
@@ -290,13 +264,6 @@ int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx) {
return 0;
}
ctx->operation = EVP_PKEY_OP_ENCRYPT;
- if (!ctx->pmeth->encrypt_init) {
- return 1;
- }
- if (!ctx->pmeth->encrypt_init(ctx)) {
- ctx->operation = EVP_PKEY_OP_UNDEFINED;
- return 0;
- }
return 1;
}
@@ -319,13 +286,6 @@ int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx) {
return 0;
}
ctx->operation = EVP_PKEY_OP_DECRYPT;
- if (!ctx->pmeth->decrypt_init) {
- return 1;
- }
- if (!ctx->pmeth->decrypt_init(ctx)) {
- ctx->operation = EVP_PKEY_OP_UNDEFINED;
- return 0;
- }
return 1;
}
@@ -342,19 +302,34 @@ int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen,
return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen);
}
-int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx) {
- if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) {
+int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx) {
+ if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) {
OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return 0;
}
- ctx->operation = EVP_PKEY_OP_DERIVE;
- if (!ctx->pmeth->derive_init) {
- return 1;
+ ctx->operation = EVP_PKEY_OP_VERIFYRECOVER;
+ return 1;
+}
+
+int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *out_len,
+ const uint8_t *sig, size_t sig_len) {
+ if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) {
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ return 0;
+ }
+ if (ctx->operation != EVP_PKEY_OP_VERIFYRECOVER) {
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED);
+ return 0;
}
- if (!ctx->pmeth->derive_init(ctx)) {
- ctx->operation = EVP_PKEY_OP_UNDEFINED;
+ return ctx->pmeth->verify_recover(ctx, out, out_len, sig, sig_len);
+}
+
+int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx) {
+ if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) {
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return 0;
}
+ ctx->operation = EVP_PKEY_OP_DERIVE;
return 1;
}
@@ -436,13 +411,6 @@ int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx) {
return 0;
}
ctx->operation = EVP_PKEY_OP_KEYGEN;
- if (!ctx->pmeth->keygen_init) {
- return 1;
- }
- if (!ctx->pmeth->keygen_init(ctx)) {
- ctx->operation = EVP_PKEY_OP_UNDEFINED;
- return 0;
- }
return 1;
}
diff --git a/src/crypto/evp/evp_extra_test.cc b/src/crypto/evp/evp_extra_test.cc
index fe7a0024..9bc36ad8 100644
--- a/src/crypto/evp/evp_extra_test.cc
+++ b/src/crypto/evp/evp_extra_test.cc
@@ -15,6 +15,7 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <utility>
#include <vector>
@@ -25,7 +26,6 @@
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/rsa.h>
-#include <openssl/x509.h>
#include "../test/scoped_types.h"
@@ -177,142 +177,6 @@ static const uint8_t kSignature[] = {
0x55, 0xa7, 0xab, 0x45, 0x02, 0x97, 0x60, 0x42,
};
-// kExamplePSSCert is an example self-signed certificate, signed with
-// kExampleRSAKeyDER using RSA-PSS with default hash functions.
-static const uint8_t kExamplePSSCert[] = {
- 0x30, 0x82, 0x02, 0x62, 0x30, 0x82, 0x01, 0xc6, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x09, 0x00, 0x8d, 0xea, 0x53, 0x24, 0xfa, 0x48, 0x87, 0xf3,
- 0x30, 0x12, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
- 0x0a, 0x30, 0x05, 0xa2, 0x03, 0x02, 0x01, 0x6a, 0x30, 0x45, 0x31, 0x0b,
- 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31,
- 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x53, 0x6f,
- 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f,
- 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72,
- 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20,
- 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x30, 0x1e, 0x17, 0x0d, 0x31,
- 0x34, 0x31, 0x30, 0x30, 0x39, 0x31, 0x39, 0x30, 0x39, 0x35, 0x35, 0x5a,
- 0x17, 0x0d, 0x31, 0x35, 0x31, 0x30, 0x30, 0x39, 0x31, 0x39, 0x30, 0x39,
- 0x35, 0x35, 0x5a, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
- 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
- 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74,
- 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a,
- 0x0c, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57,
- 0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c,
- 0x74, 0x64, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
- 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00,
- 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xf8, 0xb8, 0x6c, 0x83, 0xb4,
- 0xbc, 0xd9, 0xa8, 0x57, 0xc0, 0xa5, 0xb4, 0x59, 0x76, 0x8c, 0x54, 0x1d,
- 0x79, 0xeb, 0x22, 0x52, 0x04, 0x7e, 0xd3, 0x37, 0xeb, 0x41, 0xfd, 0x83,
- 0xf9, 0xf0, 0xa6, 0x85, 0x15, 0x34, 0x75, 0x71, 0x5a, 0x84, 0xa8, 0x3c,
- 0xd2, 0xef, 0x5a, 0x4e, 0xd3, 0xde, 0x97, 0x8a, 0xdd, 0xff, 0xbb, 0xcf,
- 0x0a, 0xaa, 0x86, 0x92, 0xbe, 0xb8, 0x50, 0xe4, 0xcd, 0x6f, 0x80, 0x33,
- 0x30, 0x76, 0x13, 0x8f, 0xca, 0x7b, 0xdc, 0xec, 0x5a, 0xca, 0x63, 0xc7,
- 0x03, 0x25, 0xef, 0xa8, 0x8a, 0x83, 0x58, 0x76, 0x20, 0xfa, 0x16, 0x77,
- 0xd7, 0x79, 0x92, 0x63, 0x01, 0x48, 0x1a, 0xd8, 0x7b, 0x67, 0xf1, 0x52,
- 0x55, 0x49, 0x4e, 0xd6, 0x6e, 0x4a, 0x5c, 0xd7, 0x7a, 0x37, 0x36, 0x0c,
- 0xde, 0xdd, 0x8f, 0x44, 0xe8, 0xc2, 0xa7, 0x2c, 0x2b, 0xb5, 0xaf, 0x64,
- 0x4b, 0x61, 0x07, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x50, 0x30, 0x4e,
- 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xd0,
- 0x41, 0xfb, 0x89, 0x41, 0x1e, 0xa7, 0xad, 0x5a, 0xec, 0x34, 0x5d, 0x49,
- 0x11, 0xf9, 0x55, 0x81, 0x78, 0x1f, 0x13, 0x30, 0x1f, 0x06, 0x03, 0x55,
- 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xd0, 0x41, 0xfb, 0x89,
- 0x41, 0x1e, 0xa7, 0xad, 0x5a, 0xec, 0x34, 0x5d, 0x49, 0x11, 0xf9, 0x55,
- 0x81, 0x78, 0x1f, 0x13, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04,
- 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x12, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30, 0x05, 0xa2, 0x03, 0x02,
- 0x01, 0x6a, 0x03, 0x81, 0x81, 0x00, 0x49, 0x4c, 0xb6, 0x45, 0x97, 0x20,
- 0x35, 0xb3, 0x50, 0x64, 0x0d, 0x3f, 0xec, 0x5f, 0x95, 0xd5, 0x84, 0xcb,
- 0x11, 0x7c, 0x03, 0xd7, 0xa6, 0xe6, 0xfa, 0x24, 0x95, 0x9f, 0x31, 0xb0,
- 0xb5, 0xec, 0x66, 0x41, 0x51, 0x18, 0x21, 0x91, 0xbb, 0xe0, 0xaf, 0xf0,
- 0xc5, 0xb7, 0x59, 0x41, 0xd4, 0xdb, 0xa4, 0xd2, 0x64, 0xa7, 0x54, 0x0f,
- 0x8c, 0xf7, 0xe1, 0xd3, 0x3b, 0x1a, 0xb7, 0x0e, 0x9d, 0x9a, 0xde, 0x50,
- 0xa1, 0x9f, 0x0a, 0xf0, 0xda, 0x34, 0x0e, 0x34, 0x7d, 0x76, 0x07, 0xfe,
- 0x5a, 0xfb, 0xf9, 0x58, 0x9b, 0xc9, 0x50, 0x84, 0x01, 0xa0, 0x05, 0x4d,
- 0x67, 0x42, 0x0b, 0xf8, 0xe4, 0x05, 0xcf, 0xaf, 0x8b, 0x71, 0x31, 0xf1,
- 0x0f, 0x6e, 0xc9, 0x24, 0x27, 0x9b, 0xac, 0x04, 0xd7, 0x64, 0x0d, 0x30,
- 0x4e, 0x11, 0x93, 0x40, 0x39, 0xbb, 0x72, 0xb2, 0xfe, 0x6b, 0xe4, 0xae,
- 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[] = {
@@ -387,6 +251,61 @@ static const uint8_t kExampleECKeyDER[] = {
0xc1,
};
+// kExampleECKeyPKCS8 is a sample EC private key encoded as a PKCS#8
+// PrivateKeyInfo.
+static const uint8_t kExampleECKeyPKCS8[] = {
+ 0x30, 0x81, 0x87, 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, 0x6d, 0x30, 0x6b, 0x02, 0x01, 0x01, 0x04, 0x20,
+ 0x43, 0x09, 0xc0, 0x67, 0x75, 0x21, 0x47, 0x9d, 0xa8, 0xfa, 0x16, 0xdf,
+ 0x15, 0x73, 0x61, 0x34, 0x68, 0x6f, 0xe3, 0x8e, 0x47, 0x91, 0x95, 0xab,
+ 0x79, 0x4a, 0x72, 0x14, 0xcb, 0xe2, 0x49, 0x4f, 0xa1, 0x44, 0x03, 0x42,
+ 0x00, 0x04, 0xde, 0x09, 0x08, 0x07, 0x03, 0x2e, 0x8f, 0x37, 0x9a, 0xd5,
+ 0xad, 0xe5, 0xc6, 0x9d, 0xd4, 0x63, 0xc7, 0x4a, 0xe7, 0x20, 0xcb, 0x90,
+ 0xa0, 0x1f, 0x18, 0x18, 0x72, 0xb5, 0x21, 0x88, 0x38, 0xc0, 0xdb, 0xba,
+ 0xf6, 0x99, 0xd8, 0xa5, 0x3b, 0x83, 0xe9, 0xe3, 0xd5, 0x61, 0x99, 0x73,
+ 0x42, 0xc6, 0x6c, 0xe8, 0x0a, 0x95, 0x40, 0x41, 0x3b, 0x0d, 0x10, 0xa7,
+ 0x4a, 0x93, 0xdb, 0x5a, 0xe7, 0xec,
+};
+
+// kExampleECKeySpecifiedCurvePKCS8 is a sample EC private key encoded as a
+// PKCS#8 PrivateKeyInfo with P-256's parameters spelled out rather than using
+// the curve OID.
+static const uint8_t kExampleECKeySpecifiedCurvePKCS8[] = {
+ 0x30, 0x82, 0x01, 0x79, 0x02, 0x01, 0x00, 0x30, 0x82, 0x01, 0x03, 0x06,
+ 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x30, 0x81, 0xf7, 0x02,
+ 0x01, 0x01, 0x30, 0x2c, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01,
+ 0x01, 0x02, 0x21, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x30, 0x5b, 0x04, 0x20, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
+ 0x04, 0x20, 0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7, 0xb3, 0xeb,
+ 0xbd, 0x55, 0x76, 0x98, 0x86, 0xbc, 0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53,
+ 0xb0, 0xf6, 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b, 0x03, 0x15,
+ 0x00, 0xc4, 0x9d, 0x36, 0x08, 0x86, 0xe7, 0x04, 0x93, 0x6a, 0x66, 0x78,
+ 0xe1, 0x13, 0x9d, 0x26, 0xb7, 0x81, 0x9f, 0x7e, 0x90, 0x04, 0x41, 0x04,
+ 0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc, 0xe6, 0xe5,
+ 0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0,
+ 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96, 0x4f, 0xe3, 0x42, 0xe2,
+ 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16,
+ 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68,
+ 0x37, 0xbf, 0x51, 0xf5, 0x02, 0x21, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbc,
+ 0xe6, 0xfa, 0xad, 0xa7, 0x17, 0x9e, 0x84, 0xf3, 0xb9, 0xca, 0xc2, 0xfc,
+ 0x63, 0x25, 0x51, 0x02, 0x01, 0x01, 0x04, 0x6d, 0x30, 0x6b, 0x02, 0x01,
+ 0x01, 0x04, 0x20, 0x43, 0x09, 0xc0, 0x67, 0x75, 0x21, 0x47, 0x9d, 0xa8,
+ 0xfa, 0x16, 0xdf, 0x15, 0x73, 0x61, 0x34, 0x68, 0x6f, 0xe3, 0x8e, 0x47,
+ 0x91, 0x95, 0xab, 0x79, 0x4a, 0x72, 0x14, 0xcb, 0xe2, 0x49, 0x4f, 0xa1,
+ 0x44, 0x03, 0x42, 0x00, 0x04, 0xde, 0x09, 0x08, 0x07, 0x03, 0x2e, 0x8f,
+ 0x37, 0x9a, 0xd5, 0xad, 0xe5, 0xc6, 0x9d, 0xd4, 0x63, 0xc7, 0x4a, 0xe7,
+ 0x20, 0xcb, 0x90, 0xa0, 0x1f, 0x18, 0x18, 0x72, 0xb5, 0x21, 0x88, 0x38,
+ 0xc0, 0xdb, 0xba, 0xf6, 0x99, 0xd8, 0xa5, 0x3b, 0x83, 0xe9, 0xe3, 0xd5,
+ 0x61, 0x99, 0x73, 0x42, 0xc6, 0x6c, 0xe8, 0x0a, 0x95, 0x40, 0x41, 0x3b,
+ 0x0d, 0x10, 0xa7, 0x4a, 0x93, 0xdb, 0x5a, 0xe7, 0xec,
+};
+
// kExampleBadECKeyDER is a sample EC private key encoded as an ECPrivateKey
// structure. The private key is equal to the order and will fail to import.
static const uint8_t kExampleBadECKeyDER[] = {
@@ -502,179 +421,81 @@ static bool TestEVP_DigestVerifyInit(void) {
return true;
}
-// TestAlgorithmRoundtrip signs a message using an already-initialized
-// |md_ctx|, sampling the AlgorithmIdentifier. It then uses |pkey| and the
-// AlgorithmIdentifier to verify the signature.
-static bool TestAlgorithmRoundtrip(EVP_MD_CTX *md_ctx, EVP_PKEY *pkey) {
- if (!EVP_DigestSignUpdate(md_ctx, kMsg, sizeof(kMsg))) {
- return false;
- }
-
- // Save the algorithm.
- ScopedX509_ALGOR algor(X509_ALGOR_new());
- if (!algor || !EVP_DigestSignAlgorithm(md_ctx, algor.get())) {
- return false;
- }
-
- // Determine the size of the signature.
- size_t sig_len = 0;
- if (!EVP_DigestSignFinal(md_ctx, NULL, &sig_len)) {
- return false;
- }
- // Sanity check for testing.
- if (sig_len != (size_t)EVP_PKEY_size(pkey)) {
- fprintf(stderr, "sig_len mismatch\n");
- return false;
- }
-
- std::vector<uint8_t> sig;
- sig.resize(sig_len);
- if (!EVP_DigestSignFinal(md_ctx, sig.data(), &sig_len)) {
- return false;
- }
- sig.resize(sig_len);
-
- // Ensure that the signature round-trips.
- ScopedEVP_MD_CTX md_ctx_verify;
- 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(), sig.data(), sig_len)) {
- return false;
- }
-
- return true;
-}
-
-static bool TestEVP_DigestSignAlgorithm(void) {
+static bool TestVerifyRecover() {
ScopedEVP_PKEY pkey = LoadExampleRSAKey();
-
- // Test a simple AlgorithmIdentifier.
- ScopedEVP_MD_CTX md_ctx;
- if (!pkey ||
- !EVP_DigestSignInit(md_ctx.get(), NULL, EVP_sha256(), NULL, pkey.get()) ||
- !TestAlgorithmRoundtrip(md_ctx.get(), pkey.get())) {
- fprintf(stderr, "RSA with SHA-256 failed\n");
+ if (!pkey) {
return false;
}
- // Test RSA-PSS with custom parameters.
- md_ctx.Reset();
- EVP_PKEY_CTX *pkey_ctx;
- if (!EVP_DigestSignInit(md_ctx.get(), &pkey_ctx, EVP_sha256(), NULL,
- pkey.get()) ||
- !EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) ||
- !EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, EVP_sha512()) ||
- !TestAlgorithmRoundtrip(md_ctx.get(), pkey.get())) {
- fprintf(stderr, "RSA-PSS failed\n");
+ ScopedRSA rsa(EVP_PKEY_get1_RSA(pkey.get()));
+ if (!rsa) {
return false;
}
- return true;
-}
+ const uint8_t kDummyHash[32] = {0};
+ uint8_t sig[2048/8];
+ unsigned sig_len = sizeof(sig);
-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) {
+ if (!RSA_sign(NID_sha256, kDummyHash, sizeof(kDummyHash), sig, &sig_len,
+ rsa.get())) {
+ fprintf(stderr, "RSA_sign failed.\n");
+ ERR_print_errors_fp(stderr);
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)) {
+ size_t out_len;
+ ScopedEVP_PKEY_CTX ctx(EVP_PKEY_CTX_new(pkey.get(), nullptr));
+ if (!EVP_PKEY_verify_recover_init(ctx.get()) ||
+ !EVP_PKEY_CTX_set_rsa_padding(ctx.get(), RSA_PKCS1_PADDING) ||
+ !EVP_PKEY_CTX_set_signature_md(ctx.get(), EVP_sha256()) ||
+ !EVP_PKEY_verify_recover(ctx.get(), nullptr, &out_len, sig, sig_len)) {
+ fprintf(stderr, "verify_recover failed will nullptr buffer.\n");
+ ERR_print_errors_fp(stderr);
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;
- }
+ std::vector<uint8_t> recovered;
+ recovered.resize(out_len);
- derp = CBS_data(&algorithm);
- ScopedX509_ALGOR algor(d2i_X509_ALGOR(NULL, &derp, CBS_len(&algorithm)));
- if (!algor || derp != CBS_data(&algorithm) + CBS_len(&algorithm)) {
+ if (!EVP_PKEY_verify_recover(ctx.get(), recovered.data(), &out_len, sig,
+ sig_len)) {
+ fprintf(stderr, "verify_recover failed.\n");
+ ERR_print_errors_fp(stderr);
return false;
}
- // Signatures are BIT STRINGs, but they have are multiple of 8 bytes, so the
- // leading phase byte is just a zero.
- uint8_t padding;
- if (!CBS_get_u8(&signature, &padding) || padding != 0) {
+ if (out_len != sizeof(kDummyHash)) {
+ fprintf(stderr, "verify_recover length is %u, expected %u.\n",
+ static_cast<unsigned>(out_len),
+ static_cast<unsigned>(sizeof(kDummyHash)));
return false;
}
- *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");
+ if (memcmp(recovered.data(), kDummyHash, sizeof(kDummyHash)) != 0) {
+ fprintf(stderr, "verify_recover got wrong value.\n");
+ ERR_print_errors_fp(stderr);
return false;
}
- ScopedEVP_MD_CTX md_ctx;
- if (!EVP_DigestVerifyInitFromAlgorithm(md_ctx.get(), algor.get(),
- pkey.get()) ||
- !EVP_DigestVerifyUpdate(md_ctx.get(), CBS_data(&tbs_cert),
- CBS_len(&tbs_cert)) ||
- !EVP_DigestVerifyFinal(md_ctx.get(), CBS_data(&signature),
- CBS_len(&signature))) {
+ out_len = recovered.size();
+ if (!EVP_PKEY_CTX_set_signature_md(ctx.get(), nullptr) ||
+ !EVP_PKEY_verify_recover(ctx.get(), recovered.data(), &out_len, sig,
+ sig_len)) {
+ fprintf(stderr, "verify_recover failed with NULL MD.\n");
+ ERR_print_errors_fp(stderr);
return false;
}
- return true;
-}
-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");
+ /* The size of a SHA-256 hash plus PKCS#1 v1.5 ASN.1 stuff happens to be 51
+ * bytes. */
+ static const size_t kExpectedASN1Size = 51;
+ if (out_len != kExpectedASN1Size) {
+ fprintf(stderr, "verify_recover length without MD is %u, expected %u.\n",
+ static_cast<unsigned>(out_len),
+ static_cast<unsigned>(kExpectedASN1Size));
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;
}
@@ -714,6 +535,20 @@ static bool Testd2i_AutoPrivateKey() {
return false;
}
+ if (!TestValidPrivateKey(kExampleECKeyPKCS8, sizeof(kExampleECKeyPKCS8),
+ EVP_PKEY_EC)) {
+ fprintf(stderr, "d2i_AutoPrivateKey(kExampleECKeyPKCS8) failed\n");
+ return false;
+ }
+
+ if (!TestValidPrivateKey(kExampleECKeySpecifiedCurvePKCS8,
+ sizeof(kExampleECKeySpecifiedCurvePKCS8),
+ EVP_PKEY_EC)) {
+ fprintf(stderr,
+ "d2i_AutoPrivateKey(kExampleECKeySpecifiedCurvePKCS8) failed\n");
+ return false;
+ }
+
if (!TestValidPrivateKey(kExampleDSAKeyDER, sizeof(kExampleDSAKeyDER),
EVP_PKEY_DSA)) {
fprintf(stderr, "d2i_AutoPrivateKey(kExampleDSAKeyDER) failed\n");
@@ -751,6 +586,25 @@ static bool TestEVP_PKCS82PKEY(void) {
return true;
}
+// TestEVPMarshalEmptyPublicKey tests |EVP_marshal_public_key| on an empty key.
+static bool TestEVPMarshalEmptyPublicKey(void) {
+ ScopedEVP_PKEY empty(EVP_PKEY_new());
+ if (!empty) {
+ return false;
+ }
+ ScopedCBB cbb;
+ if (EVP_marshal_public_key(cbb.get(), empty.get())) {
+ fprintf(stderr, "Marshalled empty public key.\n");
+ return false;
+ }
+ if (ERR_GET_REASON(ERR_peek_last_error()) != EVP_R_UNSUPPORTED_ALGORITHM) {
+ fprintf(stderr, "Marshalling an empty public key gave wrong error.\n");
+ return false;
+ }
+ ERR_clear_error();
+ return true;
+}
+
// Testd2i_PrivateKey tests |d2i_PrivateKey|.
static bool Testd2i_PrivateKey(void) {
const uint8_t *derp = kExampleRSAKeyDER;
@@ -805,12 +659,20 @@ static bool Testd2i_PrivateKey(void) {
}
ERR_clear_error();
+ derp = kExampleRSAKeyPKCS8;
+ pkey.reset(d2i_PrivateKey(EVP_PKEY_EC, nullptr, &derp,
+ sizeof(kExampleRSAKeyPKCS8)));
+ if (pkey) {
+ fprintf(stderr, "Imported RSA key as EC key.\n");
+ return false;
+ }
+ ERR_clear_error();
+
return true;
}
int main(void) {
CRYPTO_library_init();
- ERR_load_crypto_strings();
if (!TestEVP_DigestSignInit()) {
fprintf(stderr, "EVP_DigestSignInit failed\n");
@@ -824,20 +686,8 @@ int main(void) {
return 1;
}
- if (!TestEVP_DigestSignAlgorithm()) {
- fprintf(stderr, "EVP_DigestSignInit failed\n");
- ERR_print_errors_fp(stderr);
- return 1;
- }
-
- if (!TestEVP_DigestVerifyInitFromAlgorithm()) {
- fprintf(stderr, "EVP_DigestVerifyInitFromAlgorithm failed\n");
- ERR_print_errors_fp(stderr);
- return 1;
- }
-
- if (!TestBadPSSParameters()) {
- fprintf(stderr, "TestBadPSSParameters failed\n");
+ if (!TestVerifyRecover()) {
+ fprintf(stderr, "EVP_PKEY_verify_recover failed\n");
ERR_print_errors_fp(stderr);
return 1;
}
@@ -854,6 +704,12 @@ int main(void) {
return 1;
}
+ if (!TestEVPMarshalEmptyPublicKey()) {
+ fprintf(stderr, "TestEVPMarshalEmptyPublicKey failed\n");
+ ERR_print_errors_fp(stderr);
+ return 1;
+ }
+
if (!Testd2i_PrivateKey()) {
fprintf(stderr, "Testd2i_PrivateKey failed\n");
ERR_print_errors_fp(stderr);
diff --git a/src/crypto/evp/evp_test.cc b/src/crypto/evp/evp_test.cc
index 7fedc152..a7dac2bf 100644
--- a/src/crypto/evp/evp_test.cc
+++ b/src/crypto/evp/evp_test.cc
@@ -63,18 +63,18 @@
#include <map>
#include <string>
+#include <utility>
#include <vector>
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
-#include <openssl/bio.h>
+#include <openssl/bytestring.h>
#include <openssl/crypto.h>
#include <openssl/digest.h>
#include <openssl/err.h>
#include <openssl/evp.h>
-#include <openssl/pem.h>
#include "../test/file_test.h"
#include "../test/scoped_types.h"
@@ -103,34 +103,86 @@ static const EVP_MD *GetDigest(FileTest *t, const std::string &name) {
return nullptr;
}
-using KeyMap = std::map<std::string, EVP_PKEY*>;
+static int GetKeyType(FileTest *t, const std::string &name) {
+ if (name == "RSA") {
+ return EVP_PKEY_RSA;
+ }
+ if (name == "EC") {
+ return EVP_PKEY_EC;
+ }
+ if (name == "DSA") {
+ return EVP_PKEY_DSA;
+ }
+ t->PrintLine("Unknown key type: '%s'", name.c_str());
+ return EVP_PKEY_NONE;
+}
-// ImportPrivateKey evaluates a PrivateKey test in |t| and writes the resulting
-// private key to |key_map|.
-static bool ImportPrivateKey(FileTest *t, KeyMap *key_map) {
- const std::string &key_name = t->GetParameter();
- if (key_map->count(key_name) > 0) {
- t->PrintLine("Duplicate key '%s'.", key_name.c_str());
+using KeyMap = std::map<std::string, ScopedEVP_PKEY>;
+
+static bool ImportKey(FileTest *t, KeyMap *key_map,
+ EVP_PKEY *(*parse_func)(CBS *cbs),
+ int (*marshal_func)(CBB *cbb, const EVP_PKEY *key)) {
+ std::vector<uint8_t> input;
+ if (!t->GetBytes(&input, "Input")) {
return false;
}
- const std::string &block = t->GetBlock();
- ScopedBIO bio(BIO_new_mem_buf(const_cast<char*>(block.data()), block.size()));
- if (!bio) {
+
+ CBS cbs;
+ CBS_init(&cbs, input.data(), input.size());
+ ScopedEVP_PKEY pkey(parse_func(&cbs));
+ if (!pkey) {
return false;
}
- ScopedEVP_PKEY pkey(PEM_read_bio_PrivateKey(bio.get(), nullptr, 0, nullptr));
- if (!pkey) {
- t->PrintLine("Error reading private key.");
+
+ std::string key_type;
+ if (!t->GetAttribute(&key_type, "Type")) {
+ return false;
+ }
+ if (EVP_PKEY_id(pkey.get()) != GetKeyType(t, key_type)) {
+ t->PrintLine("Bad key type.");
+ return false;
+ }
+
+ // The key must re-encode correctly.
+ ScopedCBB cbb;
+ uint8_t *der;
+ size_t der_len;
+ if (!CBB_init(cbb.get(), 0) ||
+ !marshal_func(cbb.get(), pkey.get()) ||
+ !CBB_finish(cbb.get(), &der, &der_len)) {
+ return false;
+ }
+ ScopedOpenSSLBytes free_der(der);
+
+ std::vector<uint8_t> output = input;
+ if (t->HasAttribute("Output") &&
+ !t->GetBytes(&output, "Output")) {
+ return false;
+ }
+ if (!t->ExpectBytesEqual(output.data(), output.size(), der, der_len)) {
+ t->PrintLine("Re-encoding the key did not match.");
+ return false;
+ }
+
+ // Save the key for future tests.
+ const std::string &key_name = t->GetParameter();
+ if (key_map->count(key_name) > 0) {
+ t->PrintLine("Duplicate key '%s'.", key_name.c_str());
return false;
}
- (*key_map)[key_name] = pkey.release();
+ (*key_map)[key_name] = std::move(pkey);
return true;
}
static bool TestEVP(FileTest *t, void *arg) {
KeyMap *key_map = reinterpret_cast<KeyMap*>(arg);
if (t->GetType() == "PrivateKey") {
- return ImportPrivateKey(t, key_map);
+ return ImportKey(t, key_map, EVP_parse_private_key,
+ EVP_marshal_private_key);
+ }
+
+ if (t->GetType() == "PublicKey") {
+ return ImportKey(t, key_map, EVP_parse_public_key, EVP_marshal_public_key);
}
int (*key_op_init)(EVP_PKEY_CTX *ctx);
@@ -156,7 +208,7 @@ static bool TestEVP(FileTest *t, void *arg) {
t->PrintLine("Could not find key '%s'.", key_name.c_str());
return false;
}
- EVP_PKEY *key = (*key_map)[key_name];
+ EVP_PKEY *key = (*key_map)[key_name].get();
std::vector<uint8_t> input, output;
if (!t->GetBytes(&input, "Input") ||
@@ -212,11 +264,5 @@ int main(int argc, char **argv) {
}
KeyMap map;
- int ret = FileTestMain(TestEVP, &map, argv[1]);
- // TODO(davidben): When we can rely on a move-aware std::map, make KeyMap a
- // map of ScopedEVP_PKEY instead.
- for (const auto &pair : map) {
- EVP_PKEY_free(pair.second);
- }
- return ret;
+ return FileTestMain(TestEVP, &map, argv[1]);
}
diff --git a/src/crypto/evp/evp_tests.txt b/src/crypto/evp/evp_tests.txt
index 97ddaa0e..7c316d81 100644
--- a/src/crypto/evp/evp_tests.txt
+++ b/src/crypto/evp/evp_tests.txt
@@ -1,47 +1,79 @@
# Public key algorithm tests
-# Private keys used for PKEY operations.
+# Keys used for PKEY operations.
# RSA 2048 bit key.
-
PrivateKey = RSA-2048
------BEGIN PRIVATE KEY-----
-MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDNAIHqeyrh6gbV
-n3xz2f+5SglhXC5Lp8Y2zvCN01M+wxhVJbAVx2m5mnfWclv5w1Mqm25fZifV+4UW
-B2jT3anL01l0URcX3D0wnS/EfuQfl+Mq23+d2GShxHZ6Zm7NcbwarPXnUX9LOFlP
-6psF5C1a2pkSAIAT5FMWpNm7jtCGuI0odYusr5ItRqhotIXSOcm66w4rZFknEPQr
-LR6gpLSALAvsqzKPimiwBzvbVG/uqYCdKEmRKzkMFTK8finHZY+BdfrkbzQzL/h7
-yrPkBkm5hXeGnaDqcYNT8HInVIhpE2SHYNEivmduD8SD3SD/wxvalqMZZsmqLnWt
-A95H4cRPAgMBAAECggEAYCl6x5kbFnoG1rJHWLjL4gi+ubLZ7Jc4vYD5Ci41AF3X
-ziktnim6iFvTFv7x8gkTvArJDWsICLJBTYIQREHYYkozzgIzyPeApIs3Wv8C12cS
-IopwJITbP56+zM+77hcJ26GCgA2Unp5CFuC/81WDiPi9kNo3Oh2CdD7D+90UJ/0W
-glplejFpEuhpU2URfKL4RckJQF/KxV+JX8FdIDhsJu54yemQdQKaF4psHkzwwgDo
-qc+yfp0Vb4bmwq3CKxqEoc1cpbJ5CHXXlAfISzUjlcuBzD/tW7BDtp7eDAcgRVAC
-XO6MX0QBcLYSC7SOD3R7zY9SIRCFDfBDxCjf0YcFMQKBgQD2+WG0fLwDXTrt68fe
-hQqVa2Xs25z2B2QGPxWqSFU8WNly/mZ1BW413f3De/O58vYi7icTNyVoScm+8hdv
-6PfD+LuRujdN1TuvPeyBTSvewQwf3IjN0Wh28mse36PwlBl+301C/x+ylxEDuJjK
-hZxCcocIaoQqtBC7ac8tNa9r4wKBgQDUfnJKf/QQSLJwwlJKQQGHi3MVm7c9PbwY
-eyIOY1s1NPluJDoYTZP4YLa/u2txwe2aHh9FhYMCPDAelqaSwaCLU9DsnKkQEA2A
-RR47fcagG6xK7O+N95iEa8I1oIy7os9MBoBMwRIZ6VYIxxTj8UMNSR+tu6MqV1Gg
-T5d0WDTJpQKBgCHyRSu5uV39AoyRS/eZ8cp36JqV1Q08FtOE+EVfi9evnrPfo9WR
-2YQt7yNfdjCo5IwIj/ZkLhAXlFNakz4el2+oUJ/HKLLaDEoaCNf883q6rh/zABrK
-HcG7sF2d/7qhoJ9/se7zgjfZ68zHIrkzhDbd5xGREnmMJoCcGo3sQyBhAoGAH3UQ
-qmLC2N5KPFMoJ4H0HgLQ6LQCrnhDLkScSBEBYaEUA/AtAYgKjcyTgVLXlyGkcRpg
-esRHHr+WSBD5W+R6ReYEmeKfTJdzyDdzQE9gZjdyjC0DUbsDwybIu3OnIef6VEDq
-IXK7oUZfzDDcsNn4mTDoFaoff5cpqFfgDgM43VkCgYBNHw11b+d+AQmaZS9QqIt7
-aF3FvwCYHV0jdv0Mb+Kc1bY4c0R5MFpzrTwVmdOerjuuA1+9b+0Hwo3nBZM4eaBu
-SOamA2hu2OJWCl9q8fLCT69KqWDjghhvFe7c6aJJGucwaA3Uz3eLcPqoaCarMiNH
-fMkTd7GabVourqIZdgvu1Q==
------END PRIVATE KEY-----
+Type = RSA
+Input = 308204bc020100300d06092a864886f70d0101010500048204a6308204a20201000282010100cd0081ea7b2ae1ea06d59f7c73d9ffb94a09615c2e4ba7c636cef08dd3533ec3185525b015c769b99a77d6725bf9c3532a9b6e5f6627d5fb85160768d3dda9cbd35974511717dc3d309d2fc47ee41f97e32adb7f9dd864a1c4767a666ecd71bc1aacf5e7517f4b38594fea9b05e42d5ada9912008013e45316a4d9bb8ed086b88d28758bacaf922d46a868b485d239c9baeb0e2b64592710f42b2d1ea0a4b4802c0becab328f8a68b0073bdb546feea9809d2849912b390c1532bc7e29c7658f8175fae46f34332ff87bcab3e40649b98577869da0ea718353f0722754886913648760d122be676e0fc483dd20ffc31bda96a31966c9aa2e75ad03de47e1c44f02030100010282010060297ac7991b167a06d6b24758b8cbe208beb9b2d9ec9738bd80f90a2e35005dd7ce292d9e29ba885bd316fef1f20913bc0ac90d6b0808b2414d82104441d8624a33ce0233c8f780a48b375aff02d76712228a702484db3f9ebecccfbbee1709dba182800d949e9e4216e0bff3558388f8bd90da373a1d82743ec3fbdd1427fd16825a657a316912e8695365117ca2f845c909405fcac55f895fc15d20386c26ee78c9e99075029a178a6c1e4cf0c200e8a9cfb27e9d156f86e6c2adc22b1a84a1cd5ca5b2790875d79407c84b352395cb81cc3fed5bb043b69ede0c07204550025cee8c5f440170b6120bb48e0f747bcd8f522110850df043c428dfd187053102818100f6f961b47cbc035d3aedebc7de850a956b65ecdb9cf60764063f15aa48553c58d972fe6675056e35ddfdc37bf3b9f2f622ee271337256849c9bef2176fe8f7c3f8bb91ba374dd53baf3dec814d2bdec10c1fdc88cdd16876f26b1edfa3f094197edf4d42ff1fb2971103b898ca859c427287086a842ab410bb69cf2d35af6be302818100d47e724a7ff41048b270c2524a4101878b73159bb73d3dbc187b220e635b3534f96e243a184d93f860b6bfbb6b71c1ed9a1e1f458583023c301e96a692c1a08b53d0ec9ca910100d80451e3b7dc6a01bac4aecef8df798846bc235a08cbba2cf4c06804cc11219e95608c714e3f1430d491fadbba32a5751a04f97745834c9a502818021f2452bb9b95dfd028c914bf799f1ca77e89a95d50d3c16d384f8455f8bd7af9eb3dfa3d591d9842def235f7630a8e48c088ff6642e101794535a933e1e976fa8509fc728b2da0c4a1a08d7fcf37abaae1ff3001aca1dc1bbb05d9dffbaa1a09f7fb1eef38237d9ebccc722b9338436dde7119112798c26809c1a8dec4320610281801f7510aa62c2d8de4a3c53282781f41e02d0e8b402ae78432e449c48110161a11403f02d01880a8dcc938152d79721a4711a607ac4471ebf964810f95be47a45e60499e29f4c9773c83773404f606637728c2d0351bb03c326c8bb73a721e7fa5440ea2172bba1465fcc30dcb0d9f89930e815aa1f7f9729a857e00e0338dd590281804d1f0d756fe77e01099a652f50a88b7b685dc5bf00981d5d2376fd0c6fe29cd5b638734479305a73ad3c1599d39eae3bae035fbd6fed07c28de705933879a06e48e6a603686ed8e2560a5f6af1f2c24faf4aa960e382186f15eedce9a2491ae730680dd4cf778b70faa86826ab3223477cc91377b19a6d5a2eaea219760beed5
-# EC P-256 key
+# The public half of the same key encoded as a SubjectPublicKeyInfo.
+PublicKey = RSA-2048-SPKI
+Type = RSA
+Input = 30820122300d06092a864886f70d01010105000382010f003082010a0282010100cd0081ea7b2ae1ea06d59f7c73d9ffb94a09615c2e4ba7c636cef08dd3533ec3185525b015c769b99a77d6725bf9c3532a9b6e5f6627d5fb85160768d3dda9cbd35974511717dc3d309d2fc47ee41f97e32adb7f9dd864a1c4767a666ecd71bc1aacf5e7517f4b38594fea9b05e42d5ada9912008013e45316a4d9bb8ed086b88d28758bacaf922d46a868b485d239c9baeb0e2b64592710f42b2d1ea0a4b4802c0becab328f8a68b0073bdb546feea9809d2849912b390c1532bc7e29c7658f8175fae46f34332ff87bcab3e40649b98577869da0ea718353f0722754886913648760d122be676e0fc483dd20ffc31bda96a31966c9aa2e75ad03de47e1c44f0203010001
+
+# The same key but with missing parameters rather than a NULL.
+PublicKey = RSA-2048-SPKI-Invalid
+Input = 30820120300b06092a864886f70d0101010382010f003082010a0282010100cd0081ea7b2ae1ea06d59f7c73d9ffb94a09615c2e4ba7c636cef08dd3533ec3185525b015c769b99a77d6725bf9c3532a9b6e5f6627d5fb85160768d3dda9cbd35974511717dc3d309d2fc47ee41f97e32adb7f9dd864a1c4767a666ecd71bc1aacf5e7517f4b38594fea9b05e42d5ada9912008013e45316a4d9bb8ed086b88d28758bacaf922d46a868b485d239c9baeb0e2b64592710f42b2d1ea0a4b4802c0becab328f8a68b0073bdb546feea9809d2849912b390c1532bc7e29c7658f8175fae46f34332ff87bcab3e40649b98577869da0ea718353f0722754886913648760d122be676e0fc483dd20ffc31bda96a31966c9aa2e75ad03de47e1c44f0203010001
+Error = DECODE_ERROR
+
+# The same key but with an incorrectly-encoded length prefix.
+PublicKey = RSA-2048-SPKI-Invalid2
+Input = 3083000122300d06092a864886f70d01010105000382010f003082010a0282010100cd0081ea7b2ae1ea06d59f7c73d9ffb94a09615c2e4ba7c636cef08dd3533ec3185525b015c769b99a77d6725bf9c3532a9b6e5f6627d5fb85160768d3dda9cbd35974511717dc3d309d2fc47ee41f97e32adb7f9dd864a1c4767a666ecd71bc1aacf5e7517f4b38594fea9b05e42d5ada9912008013e45316a4d9bb8ed086b88d28758bacaf922d46a868b485d239c9baeb0e2b64592710f42b2d1ea0a4b4802c0becab328f8a68b0073bdb546feea9809d2849912b390c1532bc7e29c7658f8175fae46f34332ff87bcab3e40649b98577869da0ea718353f0722754886913648760d122be676e0fc483dd20ffc31bda96a31966c9aa2e75ad03de47e1c44f0203010001
+Error = DECODE_ERROR
+# EC P-256 key
PrivateKey = P-256
------BEGIN PRIVATE KEY-----
-MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgiocvtiiTxNH/xbnw
-+RdYBp+DUuCPoFpJ+NuSbLVyhyWhRANCAAQsFQ9CnOcPIWwlLPXgYs4fY5zV0WXH
-+JQkBywnGX14szuSDpXNtmTpkNzwz+oNlOKo5q+dDlgFbmUxBJJbn+bJ
------END PRIVATE KEY-----
+Type = EC
+Input = 308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725a144034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9
+
+# The same key as above with the optional public key omitted.
+PrivateKey = P-256-MissingPublic
+Type = EC
+Input = 3041020100301306072a8648ce3d020106082a8648ce3d0301070427302502010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725
+
+# The same key as above with redundant parameters.
+PrivateKey = P-256-ExtraParameters
+Type = EC
+Input = 308193020100301306072a8648ce3d020106082a8648ce3d0301070479307702010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725a00a06082a8648ce3d030107a144034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9
+# The key re-encodes with the parameters removed.
+Output = 308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725a144034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9
+
+# The same key, but with the redundant parameters in the ECPrivateKey mismatched.
+PrivateKey = P-256-BadInnerParameters
+Input = 308190020100301306072a8648ce3d020106082a8648ce3d0301070476307402010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725a00706052b81040022a144034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9
+Error = GROUP_MISMATCH
+
+# The public half of the same key encoded as a PublicKey.
+PublicKey = P-256-SPKI
+Type = EC
+Input = 3059301306072a8648ce3d020106082a8648ce3d030107034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9
+
+# The same as above, but with the curve explicitly spelled out.
+PublicKey = P-256-SPKI
+Input = 3082014b3082010306072a8648ce3d02013081f7020101302c06072a8648ce3d0101022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff305b0420ffffffff00000001000000000000000000000000fffffffffffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b031500c49d360886e704936a6678e1139d26b7819f7e900441046b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551020101034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9
+Error = DECODE_ERROR
+
+# The same as above, but with trailing data after the curve name.
+PublicKey = P-256-SPKI
+Input = 305b301506072a8648ce3d020106082a8648ce3d0301070500034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9
+Error = DECODE_ERROR
+
+# A DSA private key.
+PrivateKey = DSA-1024
+Type = DSA
+Input = 308202650201003082023906072a8648ce3804013082022c02820101009e12fab3de12213501dd82aa10ca2d101d2d4ebfef4d2a3f8daa0fe0cedad8d6af85616aa2f3252c0a2b5a6db09e6f14900e0ddb8311876dd8f9669525f99ed65949e184d5064793271169a228680b95ec12f59a8e20b21f2b58eb2a2012d35bde2ee351822fe8f32d0a330565dcce5c672b7259c14b2433d0b5b2ca2b2db0ab626e8f13f47fe0345d904e7294bb038e9ce21a9e580b83356278706cfe768436c69de149ccff98b4aab8cb4f6385c9f102ce59346eaeef27e0ad222d53d6e89cc8cde5776dd00057b03f2d88ab3cedbafd7b585f0b7f7835e17a3728bbf25ea62572f245dc111f3ce39cb6ffacc31b0a2790e7bde90224ea9b09315362af3d2b022100f381dcf53ebf724f8b2e5ca82c010fb4b5eda9358d0fd88ed278589488b54fc3028201000c402a725dcc3a62e02bf4cf43cd17f4a493591220223669cf4193edab423ad08dfb552e308a6a57a5ffbc7cd0fb2087f81f8df0cb08ab2133287d2b6968714a94f633c940845a48a3e16708dde761cc6a8eab2d84db21b6ea5b07681493cc9c31fbc368b243f6ddf8c932a8b4038f44e7b15ca876344a147859f2b43b39458668ad5e0a1a9a669546dd2812e3b3617a0aef99d58e3bb4cc87fd94225e01d2dcc469a77268146c51918f18e8b4d70aa1f0c7623bcc52cf3731d38641b2d2830b7eecb2f09552ff137d046e494e7f33c3590002b16d1b97d936fda28f90c3ed3ca35338168ac16f77c3c57adc2e8f7c6c2256e41a5f65450590dbb5bcf06d66610423022100b0c768702743bc51242993a971a52889795444f7c6452203d0ce84fe6117d46e
+
+# A DSA public key.
+PublicKey = DSA-1024-SPKI
+Type = DSA
+Input = 308201b73082012c06072a8648ce3804013082011f02818100b3429b8b128c9079f9b72e86857e98d265e5d91661ed8b5f4cc56e5eed1e571da30186983a9dd76297eab73ee13a1db841f8800d04a7cab478af6cde2ea4a2868531af169a24858c6268efa39ceb7ed0d4227eb5bbb01124a2a5a26038c7bcfb8cc827f68f5202345166e4718596799b65c9def82828ce44e62e38e41a0d24b1021500c5a56c81ddd87f47e676546c56d05706421624cf0281810094de40d27314fe929e47ff9b1ac65cfc73ef38c4d381c890be6217b15039ae18190e6b421af8c0bda35a5cfd050f58ae2644adce83e68c8e5ba11729df56bbb21e227a60b816cc033fa799a38fe1ba5b4aa1801b6f841ce3df99feb3b4fb96950c960af13fa2ce920aabc12dd24ad2044a35063ea0e25f67f560f4cfbdc5598303818400028180258c30ebbb7f34fdc873ce679f6cea373c7886d75d4421b90920db034daedd292c64d8edd8cdbdd7f3ad23d74cfa2135247d0cef6ecf2e14f99e19d22a8c1266bd8fb8719c0e5667c716c45c7adbdabe548085bdad2dfee636f8d52fd6adb2193df6c4f0520fbd171b91882e0e4f321f8250ffecf4dbea00e114427d3ef96c1a
+
+# The same key as above, but without the parameters.
+PublicKey = DSA-1024-SPKI-No-Params
+Type = DSA
+Input = 308192300906072a8648ce38040103818400028180258c30ebbb7f34fdc873ce679f6cea373c7886d75d4421b90920db034daedd292c64d8edd8cdbdd7f3ad23d74cfa2135247d0cef6ecf2e14f99e19d22a8c1266bd8fb8719c0e5667c716c45c7adbdabe548085bdad2dfee636f8d52fd6adb2193df6c4f0520fbd171b91882e0e4f321f8250ffecf4dbea00e114427d3ef96c1a
+
# RSA tests
@@ -55,6 +87,11 @@ Digest = SHA1
Input = "0123456789ABCDEF1234"
Output = c09d402423cbf233d26cae21f954547bc43fe80fd41360a0336cfdbe9aedad05bef6fd2eaee6cd60089a52482d4809a238149520df3bdde4cb9e23d9307b05c0a6f327052325a29adf2cc95b66523be7024e2a585c3d4db15dfbe146efe0ecdc0402e33fe5d40324ee96c5c3edd374a15cdc0f5d84aa243c0f07e188c6518fbfceae158a9943be398e31097da81b62074f626eff738be6160741d5a26957a482b3251fd85d8df78b98148459de10aa93305dbb4a5230aa1da291a9b0e481918f99b7638d72bb687f97661d304ae145d64a474437a4ef39d7b8059332ddeb07e92bf6e0e3acaf8afedc93795e4511737ec1e7aab6d5bc9466afc950c1c17b48ad
+Verify = RSA-2048-SPKI
+Digest = SHA1
+Input = "0123456789ABCDEF1234"
+Output = c09d402423cbf233d26cae21f954547bc43fe80fd41360a0336cfdbe9aedad05bef6fd2eaee6cd60089a52482d4809a238149520df3bdde4cb9e23d9307b05c0a6f327052325a29adf2cc95b66523be7024e2a585c3d4db15dfbe146efe0ecdc0402e33fe5d40324ee96c5c3edd374a15cdc0f5d84aa243c0f07e188c6518fbfceae158a9943be398e31097da81b62074f626eff738be6160741d5a26957a482b3251fd85d8df78b98148459de10aa93305dbb4a5230aa1da291a9b0e481918f99b7638d72bb687f97661d304ae145d64a474437a4ef39d7b8059332ddeb07e92bf6e0e3acaf8afedc93795e4511737ec1e7aab6d5bc9466afc950c1c17b48ad
+
# Digest too long
Sign = RSA-2048
Digest = SHA1
@@ -125,6 +162,11 @@ Digest = SHA1
Input = "0123456789ABCDEF1234"
Output = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec8
+Verify = P-256-SPKI
+Digest = SHA1
+Input = "0123456789ABCDEF1234"
+Output = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec8
+
# Digest too long
Verify = P-256
Digest = SHA1
diff --git a/src/crypto/evp/internal.h b/src/crypto/evp/internal.h
index aa52d535..0783143d 100644
--- a/src/crypto/evp/internal.h
+++ b/src/crypto/evp/internal.h
@@ -59,47 +59,42 @@
#include <openssl/base.h>
+#include <openssl/rsa.h>
+
#if defined(__cplusplus)
extern "C" {
#endif
-/* These values are flags for EVP_PKEY_ASN1_METHOD.flags. */
-
-/* ASN1_PKEY_SIGPARAM_NULL controls whether the default behavior of
- * EVP_DigestSignAlgorithm writes an explicit NULL parameter in the
- * AlgorithmIdentifier. */
-#define ASN1_PKEY_SIGPARAM_NULL 0x1
-
-/* evp_digest_sign_algorithm_result_t is the return value of the
- * digest_sign_algorithm function in EVP_PKEY_ASN1_METHOD. */
-typedef enum {
- /* EVP_DIGEST_SIGN_ALGORITHM_ERROR signals an error. */
- EVP_DIGEST_SIGN_ALGORITHM_ERROR = 0,
- /* EVP_DIGEST_SIGN_ALGORITHM_SUCCESS signals that the parameters were
- * serialized in the AlgorithmIdentifier. */
- EVP_DIGEST_SIGN_ALGORITHM_SUCCESS = 1,
- /* EVP_DIGEST_SIGN_ALGORITHM_DEFAULT signals that the parameters are
- * serialized using the default behavior. */
- EVP_DIGEST_SIGN_ALGORITHM_DEFAULT = 2,
-} evp_digest_sign_algorithm_result_t;
-
struct evp_pkey_asn1_method_st {
int pkey_id;
- int pkey_base_id;
- unsigned long pkey_flags;
+ uint8_t oid[9];
+ uint8_t oid_len;
+
+ /* pub_decode decodes |params| and |key| as a SubjectPublicKeyInfo
+ * and writes the result into |out|. It returns one on success and zero on
+ * error. |params| is the AlgorithmIdentifier after the OBJECT IDENTIFIER
+ * type field, and |key| is the contents of the subjectPublicKey with the
+ * leading padding byte checked and removed. Although X.509 uses BIT STRINGs
+ * to represent SubjectPublicKeyInfo, every key type defined encodes the key
+ * as a byte string with the same conversion to BIT STRING. */
+ int (*pub_decode)(EVP_PKEY *out, CBS *params, CBS *key);
+
+ /* pub_encode encodes |key| as a SubjectPublicKeyInfo and appends the result
+ * to |out|. It returns one on success and zero on error. */
+ int (*pub_encode)(CBB *out, const EVP_PKEY *key);
- const char *pem_str;
-
- int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub);
- int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk);
int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b);
- int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx);
- int (*priv_decode)(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf);
- int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk);
- int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent,
- ASN1_PCTX *pctx);
+ /* priv_decode decodes |params| and |key| as a PrivateKeyInfo and writes the
+ * result into |out|. It returns one on success and zero on error. |params| is
+ * the AlgorithmIdentifier after the OBJECT IDENTIFIER type field, and |key|
+ * is the contents of the OCTET STRING privateKey field. */
+ int (*priv_decode)(EVP_PKEY *out, CBS *params, CBS *key);
+
+ /* priv_encode encodes |key| as a PrivateKeyInfo and appends the result to
+ * |out|. It returns one on success and zero on error. */
+ int (*priv_encode)(CBB *out, const EVP_PKEY *key);
/* pkey_opaque returns 1 if the |pk| is opaque. Opaque keys are backed by
* custom implementations which do not expose key material and parameters.*/
@@ -114,40 +109,15 @@ 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 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);
- int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent,
- ASN1_PCTX *pctx);
- int (*sig_print)(BIO *out, const X509_ALGOR *sigalg, const ASN1_STRING *sig,
- int indent, ASN1_PCTX *pctx);
-
void (*pkey_free)(EVP_PKEY *pkey);
-
- /* Legacy functions for old PEM */
-
- int (*old_priv_decode)(EVP_PKEY *pkey, const uint8_t **pder,
- int derlen);
- 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,
- X509_ALGOR *algor,
- EVP_PKEY *pkey);
- evp_digest_sign_algorithm_result_t (*digest_sign_algorithm)(
- EVP_MD_CTX *ctx,
- X509_ALGOR *algor);
-
} /* EVP_PKEY_ASN1_METHOD */;
-typedef int EVP_PKEY_gen_cb(EVP_PKEY_CTX *ctx);
-
#define EVP_PKEY_OP_UNDEFINED 0
-#define EVP_PKEY_OP_PARAMGEN (1 << 1)
#define EVP_PKEY_OP_KEYGEN (1 << 2)
#define EVP_PKEY_OP_SIGN (1 << 3)
#define EVP_PKEY_OP_VERIFY (1 << 4)
@@ -156,7 +126,7 @@ typedef int EVP_PKEY_gen_cb(EVP_PKEY_CTX *ctx);
#define EVP_PKEY_OP_DECRYPT (1 << 7)
#define EVP_PKEY_OP_DERIVE (1 << 8)
-#define EVP_PKEY_OP_TYPE_SIG \
+#define EVP_PKEY_OP_TYPE_SIG \
(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)
@@ -164,7 +134,7 @@ typedef int EVP_PKEY_gen_cb(EVP_PKEY_CTX *ctx);
#define EVP_PKEY_OP_TYPE_NOGEN \
(EVP_PKEY_OP_SIG | EVP_PKEY_OP_CRYPT | EVP_PKEY_OP_DERIVE)
-#define EVP_PKEY_OP_TYPE_GEN (EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN)
+#define EVP_PKEY_OP_TYPE_GEN EVP_PKEY_OP_KEYGEN
/* EVP_PKEY_CTX_ctrl performs |cmd| on |ctx|. The |keytype| and |optype|
* arguments can be -1 to specify that any type and operation are acceptable,
@@ -208,8 +178,6 @@ OPENSSL_EXPORT int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
#define EVP_PKEY_CTRL_RSA_OAEP_LABEL (EVP_PKEY_ALG_CTRL + 11)
#define EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL (EVP_PKEY_ALG_CTRL + 12)
-#define EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID (EVP_PKEY_ALG_CTRL + 1)
-
struct evp_pkey_ctx_st {
/* Method associated with this operation */
const EVP_PKEY_METHOD *pmeth;
@@ -223,41 +191,32 @@ struct evp_pkey_ctx_st {
int operation;
/* Algorithm specific data */
void *data;
- /* Application specific data */
- void *app_data;
} /* EVP_PKEY_CTX */;
struct evp_pkey_method_st {
int pkey_id;
- int flags;
int (*init)(EVP_PKEY_CTX *ctx);
int (*copy)(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src);
void (*cleanup)(EVP_PKEY_CTX *ctx);
- int (*paramgen_init)(EVP_PKEY_CTX *ctx);
- int (*paramgen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey);
-
- int (*keygen_init)(EVP_PKEY_CTX *ctx);
int (*keygen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey);
- int (*sign_init)(EVP_PKEY_CTX *ctx);
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 uint8_t *sig, size_t siglen,
const uint8_t *tbs, size_t tbslen);
- int (*encrypt_init)(EVP_PKEY_CTX *ctx);
+ int (*verify_recover)(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *out_len,
+ const uint8_t *sig, size_t sig_len);
+
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, 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, uint8_t *key, size_t *keylen);
int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2);
diff --git a/src/crypto/evp/p_dsa_asn1.c b/src/crypto/evp/p_dsa_asn1.c
index c92068f8..1f022f1a 100644
--- a/src/crypto/evp/p_dsa_asn1.c
+++ b/src/crypto/evp/p_dsa_asn1.c
@@ -55,290 +55,139 @@
#include <openssl/evp.h>
-#include <openssl/asn1.h>
-#include <openssl/asn1t.h>
#include <openssl/digest.h>
+#include <openssl/bn.h>
+#include <openssl/bytestring.h>
#include <openssl/dsa.h>
#include <openssl/err.h>
-#include <openssl/mem.h>
-#include <openssl/obj.h>
-#include <openssl/x509.h>
-#include "../dsa/internal.h"
#include "internal.h"
-static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) {
- const uint8_t *p, *pm;
- int pklen, pmlen;
- int ptype;
- void *pval;
- ASN1_STRING *pstr;
- X509_ALGOR *palg;
- ASN1_INTEGER *public_key = NULL;
+static int dsa_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) {
+ /* See RFC 3279, section 2.3.2. */
- DSA *dsa = NULL;
-
- if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) {
- return 0;
- }
- X509_ALGOR_get0(NULL, &ptype, &pval, palg);
-
- if (ptype == V_ASN1_SEQUENCE) {
- pstr = pval;
- pm = pstr->data;
- pmlen = pstr->length;
-
- dsa = d2i_DSAparams(NULL, &pm, pmlen);
- if (dsa == NULL) {
- OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
- goto err;
- }
- } else if (ptype == V_ASN1_NULL || ptype == V_ASN1_UNDEF) {
+ /* Parameters may or may not be present. */
+ DSA *dsa;
+ if (CBS_len(params) == 0) {
dsa = DSA_new();
if (dsa == NULL) {
- OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
- goto err;
+ return 0;
}
} else {
- OPENSSL_PUT_ERROR(EVP, EVP_R_PARAMETER_ENCODING_ERROR);
- goto err;
+ dsa = DSA_parse_parameters(params);
+ if (dsa == NULL || CBS_len(params) != 0) {
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
+ goto err;
+ }
}
- public_key = d2i_ASN1_INTEGER(NULL, &p, pklen);
- if (public_key == NULL) {
- OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
+ dsa->pub_key = BN_new();
+ if (dsa->pub_key == NULL) {
goto err;
}
- dsa->pub_key = ASN1_INTEGER_to_BN(public_key, NULL);
- if (dsa->pub_key == NULL) {
- OPENSSL_PUT_ERROR(EVP, EVP_R_BN_DECODE_ERROR);
+ if (!BN_parse_asn1_unsigned(key, dsa->pub_key) ||
+ CBS_len(key) != 0) {
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
goto err;
}
- ASN1_INTEGER_free(public_key);
- EVP_PKEY_assign_DSA(pkey, dsa);
+ EVP_PKEY_assign_DSA(out, dsa);
return 1;
err:
- ASN1_INTEGER_free(public_key);
DSA_free(dsa);
return 0;
}
-static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) {
- DSA *dsa;
- ASN1_STRING *pval = NULL;
- uint8_t *penc = NULL;
- int penclen;
-
- dsa = pkey->pkey.dsa;
- dsa->write_params = 0;
-
- 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, ERR_R_MALLOC_FAILURE);
- goto err;
- }
-
- if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DSA), ptype, pval,
- penc, penclen)) {
- return 1;
- }
-
-err:
- OPENSSL_free(penc);
- ASN1_STRING_free(pval);
-
- return 0;
-}
-
-static int dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) {
- const uint8_t *p, *pm;
- int pklen, pmlen;
- int ptype;
- void *pval;
- ASN1_STRING *pstr;
- X509_ALGOR *palg;
- ASN1_INTEGER *privkey = NULL;
- BN_CTX *ctx = NULL;
-
- /* In PKCS#8 DSA: you just get a private key integer and parameters in the
- * AlgorithmIdentifier the pubkey must be recalculated. */
-
- STACK_OF(ASN1_TYPE) *ndsa = NULL;
- DSA *dsa = NULL;
-
- if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) {
+static int dsa_pub_encode(CBB *out, const EVP_PKEY *key) {
+ const DSA *dsa = key->pkey.dsa;
+ const int has_params = dsa->p != NULL && dsa->q != NULL && dsa->g != NULL;
+
+ /* See RFC 5480, section 2. */
+ CBB spki, algorithm, oid, key_bitstring;
+ if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) ||
+ !CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) ||
+ !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
+ !CBB_add_bytes(&oid, dsa_asn1_meth.oid, dsa_asn1_meth.oid_len) ||
+ (has_params &&
+ !DSA_marshal_parameters(&algorithm, dsa)) ||
+ !CBB_add_asn1(&spki, &key_bitstring, CBS_ASN1_BITSTRING) ||
+ !CBB_add_u8(&key_bitstring, 0 /* padding */) ||
+ !BN_marshal_asn1(&key_bitstring, dsa->pub_key) ||
+ !CBB_flush(out)) {
+ OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR);
return 0;
}
- X509_ALGOR_get0(NULL, &ptype, &pval, palg);
-
- /* Check for broken DSA PKCS#8, UGH! */
- if (*p == (V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED)) {
- ASN1_TYPE *t1, *t2;
- ndsa = d2i_ASN1_SEQUENCE_ANY(NULL, &p, pklen);
- if (ndsa == NULL) {
- goto decerr;
- }
- if (sk_ASN1_TYPE_num(ndsa) != 2) {
- goto decerr;
- }
- /* Handle Two broken types:
- * SEQUENCE {parameters, priv_key}
- * SEQUENCE {pub_key, priv_key}. */
-
- t1 = sk_ASN1_TYPE_value(ndsa, 0);
- t2 = sk_ASN1_TYPE_value(ndsa, 1);
- if (t1->type == V_ASN1_SEQUENCE) {
- p8->broken = PKCS8_EMBEDDED_PARAM;
- pval = t1->value.ptr;
- } else if (ptype == V_ASN1_SEQUENCE) {
- p8->broken = PKCS8_NS_DB;
- } else {
- goto decerr;
- }
+ return 1;
+}
- if (t2->type != V_ASN1_INTEGER) {
- goto decerr;
- }
+static int dsa_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) {
+ /* See PKCS#11, v2.40, section 2.5. */
- privkey = t2->value.integer;
- } else {
- const uint8_t *q = p;
- privkey = d2i_ASN1_INTEGER(NULL, &p, pklen);
- if (privkey == NULL) {
- goto decerr;
- }
- if (privkey->type == V_ASN1_NEG_INTEGER) {
- p8->broken = PKCS8_NEG_PRIVKEY;
- ASN1_INTEGER_free(privkey);
- privkey = d2i_ASN1_UINTEGER(NULL, &q, pklen);
- if (privkey == NULL) {
- goto decerr;
- }
- }
- if (ptype != V_ASN1_SEQUENCE) {
- goto decerr;
- }
+ /* Decode parameters. */
+ BN_CTX *ctx = NULL;
+ DSA *dsa = DSA_parse_parameters(params);
+ if (dsa == NULL || CBS_len(params) != 0) {
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
+ goto err;
}
- pstr = pval;
- pm = pstr->data;
- pmlen = pstr->length;
- dsa = d2i_DSAparams(NULL, &pm, pmlen);
- if (dsa == NULL) {
- goto decerr;
- }
- /* 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, ERR_LIB_BN);
- goto dsaerr;
- }
- /* Calculate public key. */
+ dsa->priv_key = BN_new();
dsa->pub_key = BN_new();
- if (dsa->pub_key == NULL) {
- OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
- goto dsaerr;
+ if (dsa->priv_key == NULL || dsa->pub_key == NULL) {
+ goto err;
}
- ctx = BN_CTX_new();
- if (ctx == NULL) {
- OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
- goto dsaerr;
+
+ /* Decode the key. */
+ if (!BN_parse_asn1_unsigned(key, dsa->priv_key) ||
+ CBS_len(key) != 0) {
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
+ goto err;
}
- if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) {
- OPENSSL_PUT_ERROR(EVP, ERR_LIB_BN);
- goto dsaerr;
+ /* Calculate the public key. */
+ ctx = BN_CTX_new();
+ if (ctx == NULL ||
+ !BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) {
+ goto err;
}
- EVP_PKEY_assign_DSA(pkey, dsa);
BN_CTX_free(ctx);
- sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
- ASN1_INTEGER_free(privkey);
-
+ EVP_PKEY_assign_DSA(out, dsa);
return 1;
-decerr:
- OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
-
-dsaerr:
+err:
BN_CTX_free(ctx);
- ASN1_INTEGER_free(privkey);
- sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
DSA_free(dsa);
return 0;
}
-static int dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) {
- ASN1_STRING *params = NULL;
- ASN1_INTEGER *prkey = NULL;
- uint8_t *dp = NULL;
- int dplen;
-
- if (!pkey->pkey.dsa || !pkey->pkey.dsa->priv_key) {
+static int dsa_priv_encode(CBB *out, const EVP_PKEY *key) {
+ const DSA *dsa = key->pkey.dsa;
+ if (dsa == NULL || dsa->priv_key == NULL) {
OPENSSL_PUT_ERROR(EVP, EVP_R_MISSING_PARAMETERS);
- goto err;
- }
-
- params = ASN1_STRING_new();
- if (!params) {
- 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, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- params->type = V_ASN1_SEQUENCE;
-
- /* Get private key into integer. */
- prkey = BN_to_ASN1_INTEGER(pkey->pkey.dsa->priv_key, NULL);
-
- if (!prkey) {
- OPENSSL_PUT_ERROR(EVP, ERR_LIB_BN);
- goto err;
+ return 0;
}
- 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)) {
- goto err;
+ /* See PKCS#11, v2.40, section 2.5. */
+ CBB pkcs8, algorithm, oid, private_key;
+ if (!CBB_add_asn1(out, &pkcs8, CBS_ASN1_SEQUENCE) ||
+ !CBB_add_asn1_uint64(&pkcs8, 0 /* version */) ||
+ !CBB_add_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) ||
+ !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
+ !CBB_add_bytes(&oid, dsa_asn1_meth.oid, dsa_asn1_meth.oid_len) ||
+ !DSA_marshal_parameters(&algorithm, dsa) ||
+ !CBB_add_asn1(&pkcs8, &private_key, CBS_ASN1_OCTETSTRING) ||
+ !BN_marshal_asn1(&private_key, dsa->priv_key) ||
+ !CBB_flush(out)) {
+ OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR);
+ return 0;
}
return 1;
-
-err:
- OPENSSL_free(dp);
- ASN1_STRING_free(params);
- ASN1_INTEGER_free(prkey);
- return 0;
}
static int int_dsa_size(const EVP_PKEY *pkey) {
@@ -393,177 +242,17 @@ static int dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) {
static void int_dsa_free(EVP_PKEY *pkey) { DSA_free(pkey->pkey.dsa); }
-static void update_buflen(const BIGNUM *b, size_t *pbuflen) {
- size_t i;
-
- if (!b) {
- return;
- }
- i = BN_num_bytes(b);
- if (*pbuflen < i) {
- *pbuflen = i;
- }
-}
-
-static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype) {
- uint8_t *m = NULL;
- int ret = 0;
- size_t buf_len = 0;
- const char *ktype = NULL;
-
- const BIGNUM *priv_key, *pub_key;
-
- priv_key = NULL;
- if (ptype == 2) {
- priv_key = x->priv_key;
- }
-
- pub_key = NULL;
- if (ptype > 0) {
- pub_key = x->pub_key;
- }
-
- ktype = "DSA-Parameters";
- if (ptype == 2) {
- ktype = "Private-Key";
- } else if (ptype == 1) {
- ktype = "Public-Key";
- }
-
- update_buflen(x->p, &buf_len);
- update_buflen(x->q, &buf_len);
- update_buflen(x->g, &buf_len);
- update_buflen(priv_key, &buf_len);
- update_buflen(pub_key, &buf_len);
-
- m = (uint8_t *)OPENSSL_malloc(buf_len + 10);
- if (m == NULL) {
- OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
- goto err;
- }
-
- if (priv_key) {
- if (!BIO_indent(bp, off, 128) ||
- BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0) {
- goto err;
- }
- }
-
- if (!ASN1_bn_print(bp, "priv:", priv_key, m, off) ||
- !ASN1_bn_print(bp, "pub: ", pub_key, m, off) ||
- !ASN1_bn_print(bp, "P: ", x->p, m, off) ||
- !ASN1_bn_print(bp, "Q: ", x->q, m, off) ||
- !ASN1_bn_print(bp, "G: ", x->g, m, off)) {
- goto err;
- }
- ret = 1;
-
-err:
- OPENSSL_free(m);
- return ret;
-}
-
-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, ERR_R_DSA_LIB);
- return 0;
- }
- EVP_PKEY_assign_DSA(pkey, dsa);
- return 1;
-}
-
-static int dsa_param_encode(const EVP_PKEY *pkey, uint8_t **pder) {
- return i2d_DSAparams(pkey->pkey.dsa, pder);
-}
-
-static int dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
- ASN1_PCTX *ctx) {
- return do_dsa_print(bp, pkey->pkey.dsa, indent, 0);
-}
-
-static int dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
- ASN1_PCTX *ctx) {
- return do_dsa_print(bp, pkey->pkey.dsa, indent, 1);
-}
-
-static int dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
- ASN1_PCTX *ctx) {
- return do_dsa_print(bp, pkey->pkey.dsa, indent, 2);
-}
-
-static int old_dsa_priv_decode(EVP_PKEY *pkey, const uint8_t **pder,
- int derlen) {
- DSA *dsa;
- dsa = d2i_DSAPrivateKey(NULL, pder, derlen);
- if (dsa == NULL) {
- OPENSSL_PUT_ERROR(EVP, ERR_R_DSA_LIB);
- return 0;
- }
- EVP_PKEY_assign_DSA(pkey, dsa);
- return 1;
-}
-
-static int old_dsa_priv_encode(const EVP_PKEY *pkey, uint8_t **pder) {
- return i2d_DSAPrivateKey(pkey->pkey.dsa, pder);
-}
-
-static int dsa_sig_print(BIO *bp, const X509_ALGOR *sigalg,
- const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx) {
- DSA_SIG *dsa_sig;
- const uint8_t *p;
-
- if (!sig) {
- return BIO_puts(bp, "\n") > 0;
- }
-
- p = sig->data;
- dsa_sig = d2i_DSA_SIG(NULL, &p, sig->length);
- if (dsa_sig == NULL) {
- return X509_signature_dump(bp, sig, indent);
- }
-
- int rv = 0;
- size_t buf_len = 0;
- uint8_t *m = NULL;
-
- update_buflen(dsa_sig->r, &buf_len);
- update_buflen(dsa_sig->s, &buf_len);
- m = OPENSSL_malloc(buf_len + 10);
- if (m == NULL) {
- OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
- goto err;
- }
-
- if (BIO_write(bp, "\n", 1) != 1 ||
- !ASN1_bn_print(bp, "r: ", dsa_sig->r, m, indent) ||
- !ASN1_bn_print(bp, "s: ", dsa_sig->s, m, indent)) {
- goto err;
- }
- rv = 1;
-
-err:
- OPENSSL_free(m);
- DSA_SIG_free(dsa_sig);
- return rv;
-}
-
const EVP_PKEY_ASN1_METHOD dsa_asn1_meth = {
EVP_PKEY_DSA,
- EVP_PKEY_DSA,
- 0,
-
- "DSA",
+ /* 1.2.840.10040.4.1 */
+ {0x2a, 0x86, 0x48, 0xce, 0x38, 0x04, 0x01}, 7,
dsa_pub_decode,
dsa_pub_encode,
dsa_pub_cmp,
- dsa_pub_print,
dsa_priv_decode,
dsa_priv_encode,
- dsa_priv_print,
NULL /* pkey_opaque */,
NULL /* pkey_supports_digest */,
@@ -571,18 +260,9 @@ const EVP_PKEY_ASN1_METHOD dsa_asn1_meth = {
int_dsa_size,
dsa_bits,
- dsa_param_decode,
- dsa_param_encode,
dsa_missing_parameters,
dsa_copy_parameters,
dsa_cmp_parameters,
- dsa_param_print,
- dsa_sig_print,
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 77f213db..f92c87cf 100644
--- a/src/crypto/evp/p_ec.c
+++ b/src/crypto/evp/p_ec.c
@@ -57,7 +57,6 @@
#include <string.h>
-#include <openssl/asn1.h>
#include <openssl/bn.h>
#include <openssl/buf.h>
#include <openssl/digest.h>
@@ -67,15 +66,13 @@
#include <openssl/ecdsa.h>
#include <openssl/err.h>
#include <openssl/mem.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
#include "internal.h"
#include "../ec/internal.h"
typedef struct {
- /* Key and paramgen group */
- EC_GROUP *gen_group;
/* message digest */
const EVP_MD *md;
} EC_PKEY_CTX;
@@ -102,12 +99,6 @@ static int pkey_ec_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) {
sctx = src->data;
dctx = dst->data;
- if (sctx->gen_group) {
- dctx->gen_group = EC_GROUP_dup(sctx->gen_group);
- if (!dctx->gen_group) {
- return 0;
- }
- }
dctx->md = sctx->md;
return 1;
@@ -119,7 +110,6 @@ static void pkey_ec_cleanup(EVP_PKEY_CTX *ctx) {
return;
}
- EC_GROUP_free(dctx->gen_group);
OPENSSL_free(dctx);
}
@@ -185,19 +175,8 @@ static int pkey_ec_derive(EVP_PKEY_CTX *ctx, uint8_t *key,
static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
EC_PKEY_CTX *dctx = ctx->data;
- EC_GROUP *group;
switch (type) {
- case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID:
- group = EC_GROUP_new_by_curve_name(p1);
- if (group == NULL) {
- OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_CURVE);
- return 0;
- }
- EC_GROUP_free(dctx->gen_group);
- dctx->gen_group = group;
- return 1;
-
case EVP_PKEY_CTRL_MD:
if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 &&
EVP_MD_type((const EVP_MD *)p2) != NID_ecdsa_with_SHA1 &&
@@ -225,59 +204,33 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
}
}
-static int pkey_ec_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) {
- EC_KEY *ec = NULL;
- EC_PKEY_CTX *dctx = ctx->data;
- int ret = 0;
-
- if (dctx->gen_group == NULL) {
- OPENSSL_PUT_ERROR(EVP, EVP_R_NO_PARAMETERS_SET);
- return 0;
- }
- ec = EC_KEY_new();
- if (!ec) {
- return 0;
- }
- ret = EC_KEY_set_group(ec, dctx->gen_group);
- if (ret) {
- EVP_PKEY_assign_EC_KEY(pkey, ec);
- } else {
- EC_KEY_free(ec);
- }
- return ret;
-}
-
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) {
+ if (ctx->pkey == NULL) {
OPENSSL_PUT_ERROR(EVP, EVP_R_NO_PARAMETERS_SET);
return 0;
}
- ec = EC_KEY_new();
- if (!ec) {
+ EC_KEY *ec = EC_KEY_new();
+ if (ec == NULL ||
+ !EC_KEY_set_group(ec, EC_KEY_get0_group(ctx->pkey->pkey.ec)) ||
+ !EC_KEY_generate_key(ec)) {
+ EC_KEY_free(ec);
return 0;
}
EVP_PKEY_assign_EC_KEY(pkey, ec);
- if (ctx->pkey) {
- /* Note: if error return, pkey is freed by parent routine */
- if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey)) {
- return 0;
- }
- } else {
- if (!EC_KEY_set_group(ec, dctx->gen_group)) {
- return 0;
- }
- }
- return EC_KEY_generate_key(pkey->pkey.ec);
+ return 1;
}
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 /* encrypt_init */, 0 /* encrypt */,
- 0 /* decrypt_init */, 0 /* decrypt */, 0 /* derive_init */,
- pkey_ec_derive, pkey_ec_ctrl,
+ EVP_PKEY_EC,
+ pkey_ec_init,
+ pkey_ec_copy,
+ pkey_ec_cleanup,
+ pkey_ec_keygen,
+ pkey_ec_sign,
+ pkey_ec_verify,
+ 0 /* verify_recover */,
+ 0 /* encrypt */,
+ 0 /* decrypt */,
+ 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 f40b9764..8d44dcdc 100644
--- a/src/crypto/evp/p_ec_asn1.c
+++ b/src/crypto/evp/p_ec_asn1.c
@@ -55,145 +55,73 @@
#include <openssl/evp.h>
-#include <openssl/asn1t.h>
#include <openssl/bn.h>
+#include <openssl/bytestring.h>
#include <openssl/ec.h>
+#include <openssl/ec_key.h>
+#include <openssl/ecdsa.h>
#include <openssl/err.h>
-#include <openssl/mem.h>
-#include <openssl/obj.h>
-#include <openssl/x509.h>
#include "internal.h"
-static int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key) {
- const EC_GROUP *group;
- int nid;
-
- if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) {
- 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, EVP_R_NO_NID_FOR_CURVE);
+static int eckey_pub_encode(CBB *out, const EVP_PKEY *key) {
+ const EC_KEY *ec_key = key->pkey.ec;
+ const EC_GROUP *group = EC_KEY_get0_group(ec_key);
+ const EC_POINT *public_key = EC_KEY_get0_public_key(ec_key);
+
+ /* See RFC 5480, section 2. */
+ CBB spki, algorithm, oid, key_bitstring;
+ if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) ||
+ !CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) ||
+ !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
+ !CBB_add_bytes(&oid, ec_asn1_meth.oid, ec_asn1_meth.oid_len) ||
+ !EC_KEY_marshal_curve_name(&algorithm, group) ||
+ !CBB_add_asn1(&spki, &key_bitstring, CBS_ASN1_BITSTRING) ||
+ !CBB_add_u8(&key_bitstring, 0 /* padding */) ||
+ !EC_POINT_point2cbb(&key_bitstring, group, public_key,
+ POINT_CONVERSION_UNCOMPRESSED, NULL) ||
+ !CBB_flush(out)) {
+ OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR);
return 0;
}
- *ppval = (void*) OBJ_nid2obj(nid);
- *pptype = V_ASN1_OBJECT;
return 1;
}
-static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) {
- EC_KEY *ec_key = pkey->pkey.ec;
- void *pval = NULL;
- int ptype;
- uint8_t *penc = NULL, *p;
- int penclen;
-
- if (!eckey_param2type(&ptype, &pval, ec_key)) {
- OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
- return 0;
- }
- penclen = i2o_ECPublicKey(ec_key, NULL);
- if (penclen <= 0) {
- goto err;
- }
- penc = OPENSSL_malloc(penclen);
- if (!penc) {
- goto err;
- }
- p = penc;
- penclen = i2o_ECPublicKey(ec_key, &p);
- if (penclen <= 0) {
- goto err;
- }
- if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_EC), ptype, pval, penc,
- penclen)) {
- return 1;
- }
-
-err:
- if (ptype == V_ASN1_OBJECT) {
- ASN1_OBJECT_free(pval);
- } else {
- ASN1_STRING_free(pval);
- }
- if (penc) {
- OPENSSL_free(penc);
- }
- return 0;
-}
+static int eckey_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) {
+ /* See RFC 5480, section 2. */
-static EC_KEY *eckey_type2param(int ptype, void *pval) {
+ /* The parameters are a named curve. */
+ EC_POINT *point = NULL;
EC_KEY *eckey = NULL;
-
- if (ptype == V_ASN1_SEQUENCE) {
- ASN1_STRING *pstr = pval;
- const uint8_t *pm = pstr->data;
- int pmlen = pstr->length;
-
- eckey = d2i_ECParameters(NULL, &pm, pmlen);
- if (eckey == NULL) {
- OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
- goto err;
- }
- } else if (ptype == V_ASN1_OBJECT) {
- ASN1_OBJECT *poid = pval;
-
- /* type == V_ASN1_OBJECT => the parameters are given
- * by an asn1 OID */
- eckey = EC_KEY_new_by_curve_name(OBJ_obj2nid(poid));
- if (eckey == NULL) {
- goto err;
- }
- } else {
+ EC_GROUP *group = EC_KEY_parse_curve_name(params);
+ if (group == NULL || CBS_len(params) != 0) {
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
goto err;
}
- return eckey;
-
-err:
- if (eckey) {
- EC_KEY_free(eckey);
- }
- return NULL;
-}
-
-static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) {
- const uint8_t *p = NULL;
- void *pval;
- int ptype, pklen;
- EC_KEY *eckey = NULL;
- X509_ALGOR *palg;
-
- if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) {
- return 0;
- }
- X509_ALGOR_get0(NULL, &ptype, &pval, palg);
-
- eckey = eckey_type2param(ptype, pval);
- if (!eckey) {
- OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
- return 0;
+ eckey = EC_KEY_new();
+ if (eckey == NULL || !EC_KEY_set_group(eckey, group)) {
+ goto err;
}
- /* We have parameters now set public key */
- if (!o2i_ECPublicKey(&eckey, &p, pklen)) {
- OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
+ point = EC_POINT_new(group);
+ if (point == NULL ||
+ !EC_POINT_oct2point(group, point, CBS_data(key), CBS_len(key), NULL) ||
+ !EC_KEY_set_public_key(eckey, point)) {
goto err;
}
- EVP_PKEY_assign_EC_KEY(pkey, eckey);
+ EC_GROUP_free(group);
+ EC_POINT_free(point);
+ EVP_PKEY_assign_EC_KEY(out, eckey);
return 1;
err:
- if (eckey) {
- EC_KEY_free(eckey);
- }
+ EC_GROUP_free(group);
+ EC_POINT_free(point);
+ EC_KEY_free(eckey);
return 0;
}
@@ -212,120 +140,48 @@ static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) {
}
}
-static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) {
- const uint8_t *p = NULL;
- void *pval;
- int ptype, pklen;
- EC_KEY *eckey = NULL;
- X509_ALGOR *palg;
-
- if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) {
+static int eckey_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) {
+ /* See RFC 5915. */
+ EC_GROUP *group = EC_KEY_parse_parameters(params);
+ if (group == NULL || CBS_len(params) != 0) {
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
+ EC_GROUP_free(group);
return 0;
}
- X509_ALGOR_get0(NULL, &ptype, &pval, palg);
-
- eckey = eckey_type2param(ptype, pval);
- if (!eckey) {
- goto ecliberr;
- }
-
- /* We have parameters now set private key */
- if (!d2i_ECPrivateKey(&eckey, &p, pklen)) {
+ EC_KEY *ec_key = EC_KEY_parse_private_key(key, group);
+ EC_GROUP_free(group);
+ if (ec_key == NULL || CBS_len(key) != 0) {
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
- goto ecerr;
- }
-
- /* calculate public key (if necessary) */
- if (EC_KEY_get0_public_key(eckey) == NULL) {
- const BIGNUM *priv_key;
- const EC_GROUP *group;
- EC_POINT *pub_key;
- /* the public key was not included in the SEC1 private
- * key => calculate the public key */
- group = EC_KEY_get0_group(eckey);
- pub_key = EC_POINT_new(group);
- if (pub_key == NULL) {
- 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, 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, 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, ERR_R_EC_LIB);
- goto ecliberr;
- }
- EC_POINT_free(pub_key);
+ EC_KEY_free(ec_key);
+ return 0;
}
- EVP_PKEY_assign_EC_KEY(pkey, eckey);
+ EVP_PKEY_assign_EC_KEY(out, ec_key);
return 1;
-
-ecliberr:
- OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
-ecerr:
- if (eckey) {
- EC_KEY_free(eckey);
- }
- return 0;
}
-static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) {
- EC_KEY *ec_key;
- uint8_t *ep, *p;
- int eplen, ptype;
- void *pval;
- unsigned int tmp_flags, old_flags;
-
- ec_key = pkey->pkey.ec;
-
- if (!eckey_param2type(&ptype, &pval, ec_key)) {
- OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
- return 0;
- }
-
- /* set the private key */
-
- /* do not include the parameters in the SEC1 private key
- * see PKCS#11 12.11 */
- old_flags = EC_KEY_get_enc_flags(ec_key);
- tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS;
- EC_KEY_set_enc_flags(ec_key, tmp_flags);
- eplen = i2d_ECPrivateKey(ec_key, NULL);
- if (!eplen) {
- EC_KEY_set_enc_flags(ec_key, old_flags);
- 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, 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, ERR_R_EC_LIB);
- return 0;
- }
- /* restore old encoding flags */
- EC_KEY_set_enc_flags(ec_key, old_flags);
-
- if (!PKCS8_pkey_set0(p8, (ASN1_OBJECT *)OBJ_nid2obj(NID_X9_62_id_ecPublicKey),
- 0, ptype, pval, ep, eplen)) {
- OPENSSL_free(ep);
+static int eckey_priv_encode(CBB *out, const EVP_PKEY *key) {
+ const EC_KEY *ec_key = key->pkey.ec;
+
+ /* Omit the redundant copy of the curve name. This contradicts RFC 5915 but
+ * aligns with PKCS #11. SEC 1 only says they may be omitted if known by other
+ * means. Both OpenSSL and NSS omit the redundant parameters, so we omit them
+ * as well. */
+ unsigned enc_flags = EC_KEY_get_enc_flags(ec_key) | EC_PKEY_NO_PARAMETERS;
+
+ /* See RFC 5915. */
+ CBB pkcs8, algorithm, oid, private_key;
+ if (!CBB_add_asn1(out, &pkcs8, CBS_ASN1_SEQUENCE) ||
+ !CBB_add_asn1_uint64(&pkcs8, 0 /* version */) ||
+ !CBB_add_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) ||
+ !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
+ !CBB_add_bytes(&oid, ec_asn1_meth.oid, ec_asn1_meth.oid_len) ||
+ !EC_KEY_marshal_curve_name(&algorithm, EC_KEY_get0_group(ec_key)) ||
+ !CBB_add_asn1(&pkcs8, &private_key, CBS_ASN1_OCTETSTRING) ||
+ !EC_KEY_marshal_private_key(&private_key, ec_key, enc_flags) ||
+ !CBB_flush(out)) {
+ OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR);
return 0;
}
@@ -371,173 +227,21 @@ static int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) {
static void int_ec_free(EVP_PKEY *pkey) { EC_KEY_free(pkey->pkey.ec); }
-static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) {
- uint8_t *buffer = NULL;
- const char *ecstr;
- size_t buf_len = 0, i;
- int ret = 0, reason = ERR_R_BIO_LIB;
- BN_CTX *ctx = NULL;
- const EC_GROUP *group;
- const EC_POINT *public_key;
- const BIGNUM *priv_key;
- uint8_t *pub_key_bytes = NULL;
- size_t pub_key_bytes_len = 0;
-
- if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) {
- reason = ERR_R_PASSED_NULL_PARAMETER;
- goto err;
- }
-
- ctx = BN_CTX_new();
- if (ctx == NULL) {
- reason = ERR_R_MALLOC_FAILURE;
- goto err;
- }
-
- if (ktype > 0) {
- public_key = EC_KEY_get0_public_key(x);
- if (public_key != NULL) {
- pub_key_bytes_len = EC_POINT_point2oct(
- group, public_key, EC_KEY_get_conv_form(x), NULL, 0, ctx);
- if (pub_key_bytes_len == 0) {
- reason = ERR_R_MALLOC_FAILURE;
- goto err;
- }
- pub_key_bytes = OPENSSL_malloc(pub_key_bytes_len);
- if (pub_key_bytes == NULL) {
- reason = ERR_R_MALLOC_FAILURE;
- goto err;
- }
- pub_key_bytes_len =
- EC_POINT_point2oct(group, public_key, EC_KEY_get_conv_form(x),
- pub_key_bytes, pub_key_bytes_len, ctx);
- if (pub_key_bytes_len == 0) {
- reason = ERR_R_MALLOC_FAILURE;
- goto err;
- }
- buf_len = pub_key_bytes_len;
- }
- }
-
- if (ktype == 2) {
- priv_key = EC_KEY_get0_private_key(x);
- if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len) {
- buf_len = i;
- }
- } else {
- priv_key = NULL;
- }
-
- if (ktype > 0) {
- buf_len += 10;
- if ((buffer = OPENSSL_malloc(buf_len)) == NULL) {
- reason = ERR_R_MALLOC_FAILURE;
- goto err;
- }
- }
- if (ktype == 2) {
- ecstr = "Private-Key";
- } else if (ktype == 1) {
- ecstr = "Public-Key";
- } else {
- ecstr = "ECDSA-Parameters";
- }
-
- if (!BIO_indent(bp, off, 128)) {
- goto err;
- }
- const BIGNUM *order = EC_GROUP_get0_order(group);
- if (BIO_printf(bp, "%s: (%d bit)\n", ecstr, BN_num_bits(order)) <= 0) {
- goto err;
- }
-
- if ((priv_key != NULL) &&
- !ASN1_bn_print(bp, "priv:", priv_key, buffer, off)) {
- goto err;
- }
- if (pub_key_bytes != NULL) {
- BIO_hexdump(bp, pub_key_bytes, pub_key_bytes_len, off);
- }
- /* TODO(fork): implement */
- /*
- if (!ECPKParameters_print(bp, group, off))
- goto err; */
- ret = 1;
-
-err:
- if (!ret) {
- OPENSSL_PUT_ERROR(EVP, reason);
- }
- OPENSSL_free(pub_key_bytes);
- BN_CTX_free(ctx);
- OPENSSL_free(buffer);
- return ret;
-}
-
-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, ERR_R_EC_LIB);
- return 0;
- }
- EVP_PKEY_assign_EC_KEY(pkey, eckey);
- return 1;
-}
-
-static int eckey_param_encode(const EVP_PKEY *pkey, uint8_t **pder) {
- return i2d_ECParameters(pkey->pkey.ec, pder);
-}
-
-static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
- ASN1_PCTX *ctx) {
- return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0);
-}
-
-static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
- ASN1_PCTX *ctx) {
- return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1);
-}
-
-
-static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
- ASN1_PCTX *ctx) {
- return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2);
-}
-
static int eckey_opaque(const EVP_PKEY *pkey) {
return EC_KEY_is_opaque(pkey->pkey.ec);
}
-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, EVP_R_DECODE_ERROR);
- return 0;
- }
- EVP_PKEY_assign_EC_KEY(pkey, ec);
- return 1;
-}
-
-static int old_ec_priv_encode(const EVP_PKEY *pkey, uint8_t **pder) {
- return i2d_ECPrivateKey(pkey->pkey.ec, pder);
-}
-
const EVP_PKEY_ASN1_METHOD ec_asn1_meth = {
EVP_PKEY_EC,
- EVP_PKEY_EC,
- 0,
- "EC",
+ /* 1.2.840.10045.2.1 */
+ {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01}, 7,
eckey_pub_decode,
eckey_pub_encode,
eckey_pub_cmp,
- eckey_pub_print,
eckey_priv_decode,
eckey_priv_encode,
- eckey_priv_print,
eckey_opaque,
0 /* pkey_supports_digest */,
@@ -545,18 +249,9 @@ const EVP_PKEY_ASN1_METHOD ec_asn1_meth = {
int_ec_size,
ec_bits,
- eckey_param_decode,
- eckey_param_encode,
ec_missing_parameters,
ec_copy_parameters,
ec_cmp_parameters,
- eckey_param_print,
- 0,
int_ec_free,
- old_ec_priv_decode,
- old_ec_priv_encode,
-
- NULL /* digest_verify_init_from_algorithm */,
- NULL /* digest_sign_algorithm */,
};
diff --git a/src/crypto/evp/p_rsa.c b/src/crypto/evp/p_rsa.c
index 895d3513..a2106572 100644
--- a/src/crypto/evp/p_rsa.c
+++ b/src/crypto/evp/p_rsa.c
@@ -64,7 +64,7 @@
#include <openssl/digest.h>
#include <openssl/err.h>
#include <openssl/mem.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
#include <openssl/rsa.h>
#include "../rsa/internal.h"
@@ -256,6 +256,81 @@ static int pkey_rsa_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig,
return 1;
}
+static int pkey_rsa_verify_recover(EVP_PKEY_CTX *ctx, uint8_t *out,
+ size_t *out_len, const uint8_t *sig,
+ size_t sig_len) {
+ RSA_PKEY_CTX *rctx = ctx->data;
+ RSA *rsa = ctx->pkey->pkey.rsa;
+ const size_t key_len = EVP_PKEY_size(ctx->pkey);
+
+ if (out == NULL) {
+ *out_len = key_len;
+ return 1;
+ }
+
+ if (*out_len < key_len) {
+ OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL);
+ return 0;
+ }
+
+ if (!setup_tbuf(rctx, ctx)) {
+ return 0;
+ }
+
+ if (rctx->md == NULL) {
+ const int ret = RSA_public_decrypt(sig_len, sig, rctx->tbuf,
+ ctx->pkey->pkey.rsa, rctx->pad_mode);
+ if (ret < 0) {
+ return 0;
+ }
+ *out_len = ret;
+ memcpy(out, rctx->tbuf, *out_len);
+ return 1;
+ }
+
+ if (rctx->pad_mode != RSA_PKCS1_PADDING) {
+ return 0;
+ }
+
+ uint8_t *asn1_prefix;
+ size_t asn1_prefix_len;
+ int asn1_prefix_allocated;
+ if (!RSA_add_pkcs1_prefix(&asn1_prefix, &asn1_prefix_len,
+ &asn1_prefix_allocated, EVP_MD_type(rctx->md), NULL,
+ 0)) {
+ return 0;
+ }
+
+ size_t rslen;
+ int ok = 1;
+ if (!RSA_verify_raw(rsa, &rslen, rctx->tbuf, key_len, sig, sig_len,
+ RSA_PKCS1_PADDING) ||
+ rslen < asn1_prefix_len ||
+ CRYPTO_memcmp(rctx->tbuf, asn1_prefix, asn1_prefix_len) != 0) {
+ ok = 0;
+ }
+
+ if (asn1_prefix_allocated) {
+ OPENSSL_free(asn1_prefix);
+ }
+
+ if (!ok) {
+ return 0;
+ }
+
+ const size_t result_len = rslen - asn1_prefix_len;
+ if (result_len != EVP_MD_size(rctx->md)) {
+ return 0;
+ }
+
+ if (out != NULL) {
+ memcpy(out, rctx->tbuf + asn1_prefix_len, result_len);
+ }
+ *out_len = result_len;
+
+ return 1;
+}
+
static int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen,
const uint8_t *in, size_t inlen) {
RSA_PKEY_CTX *rctx = ctx->data;
@@ -503,13 +578,18 @@ 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 /* encrypt_init */, pkey_rsa_encrypt,
- 0 /* decrypt_init */, pkey_rsa_decrypt, 0 /* derive_init */,
- 0 /* derive */, pkey_rsa_ctrl,
+ EVP_PKEY_RSA,
+ pkey_rsa_init,
+ pkey_rsa_copy,
+ pkey_rsa_cleanup,
+ pkey_rsa_keygen,
+ pkey_rsa_sign,
+ pkey_rsa_verify,
+ pkey_rsa_verify_recover,
+ pkey_rsa_encrypt,
+ pkey_rsa_decrypt,
+ 0 /* derive */,
+ pkey_rsa_ctrl,
};
int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int padding) {
@@ -566,15 +646,14 @@ int EVP_PKEY_CTX_get_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD **out_md) {
EVP_PKEY_CTRL_GET_RSA_MGF1_MD, 0, (void*) out_md);
}
-int EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX *ctx, const uint8_t *label,
+int EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX *ctx, uint8_t *label,
size_t label_len) {
- int label_len_int = label_len;
- if (((size_t) label_len_int) != label_len) {
+ if (label_len > INT_MAX) {
return 0;
}
return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,
- EVP_PKEY_CTRL_RSA_OAEP_LABEL, label_len,
+ EVP_PKEY_CTRL_RSA_OAEP_LABEL, (int)label_len,
(void *)label);
}
diff --git a/src/crypto/evp/p_rsa_asn1.c b/src/crypto/evp/p_rsa_asn1.c
index db38d5cf..2c4b266d 100644
--- a/src/crypto/evp/p_rsa_asn1.c
+++ b/src/crypto/evp/p_rsa_asn1.c
@@ -55,40 +55,45 @@
#include <openssl/evp.h>
-#include <openssl/asn1.h>
-#include <openssl/asn1t.h>
+#include <openssl/bn.h>
#include <openssl/bytestring.h>
#include <openssl/digest.h>
#include <openssl/err.h>
#include <openssl/mem.h>
-#include <openssl/obj.h>
#include <openssl/rsa.h>
-#include <openssl/x509.h>
#include "../rsa/internal.h"
#include "internal.h"
-static int rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) {
- 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, encoded_len)) {
- OPENSSL_free(encoded);
+static int rsa_pub_encode(CBB *out, const EVP_PKEY *key) {
+ /* See RFC 3279, section 2.3.1. */
+ CBB spki, algorithm, oid, null, key_bitstring;
+ if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) ||
+ !CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) ||
+ !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
+ !CBB_add_bytes(&oid, rsa_asn1_meth.oid, rsa_asn1_meth.oid_len) ||
+ !CBB_add_asn1(&algorithm, &null, CBS_ASN1_NULL) ||
+ !CBB_add_asn1(&spki, &key_bitstring, CBS_ASN1_BITSTRING) ||
+ !CBB_add_u8(&key_bitstring, 0 /* padding */) ||
+ !RSA_marshal_public_key(&key_bitstring, key->pkey.rsa) ||
+ !CBB_flush(out)) {
+ OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR);
return 0;
}
return 1;
}
-static int rsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) {
- const uint8_t *p;
- int pklen;
- if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, NULL, pubkey)) {
+static int rsa_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) {
+ /* See RFC 3279, section 2.3.1. */
+
+ /* The parameters must be NULL. */
+ CBS null;
+ if (!CBS_get_asn1(params, &null, CBS_ASN1_NULL) ||
+ CBS_len(&null) != 0 ||
+ CBS_len(params) != 0) {
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
return 0;
}
@@ -98,16 +103,14 @@ static int rsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) {
* 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) {
+ RSA *rsa = RSA_parse_public_key_buggy(key);
+ if (rsa == NULL || CBS_len(key) != 0) {
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
RSA_free(rsa);
return 0;
}
- EVP_PKEY_assign_RSA(pkey, rsa);
+ EVP_PKEY_assign_RSA(out, rsa);
return 1;
}
@@ -116,39 +119,42 @@ static int rsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) {
BN_cmp(b->pkey.rsa->e, a->pkey.rsa->e) == 0;
}
-static int rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) {
- 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, encoded, encoded_len)) {
- OPENSSL_free(encoded);
- OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
+static int rsa_priv_encode(CBB *out, const EVP_PKEY *key) {
+ CBB pkcs8, algorithm, oid, null, private_key;
+ if (!CBB_add_asn1(out, &pkcs8, CBS_ASN1_SEQUENCE) ||
+ !CBB_add_asn1_uint64(&pkcs8, 0 /* version */) ||
+ !CBB_add_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) ||
+ !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
+ !CBB_add_bytes(&oid, rsa_asn1_meth.oid, rsa_asn1_meth.oid_len) ||
+ !CBB_add_asn1(&algorithm, &null, CBS_ASN1_NULL) ||
+ !CBB_add_asn1(&pkcs8, &private_key, CBS_ASN1_OCTETSTRING) ||
+ !RSA_marshal_private_key(&private_key, key->pkey.rsa) ||
+ !CBB_flush(out)) {
+ OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR);
return 0;
}
return 1;
}
-static int rsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) {
- const uint8_t *p;
- int pklen;
- if (!PKCS8_pkey_get0(NULL, &p, &pklen, NULL, p8)) {
- OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
+static int rsa_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) {
+ /* Per RFC 3447, A.1, the parameters have type NULL. */
+ CBS null;
+ if (!CBS_get_asn1(params, &null, CBS_ASN1_NULL) ||
+ CBS_len(&null) != 0 ||
+ CBS_len(params) != 0) {
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
return 0;
}
- RSA *rsa = RSA_private_key_from_bytes(p, pklen);
- if (rsa == NULL) {
- OPENSSL_PUT_ERROR(EVP, ERR_R_RSA_LIB);
+ RSA *rsa = RSA_parse_private_key(key);
+ if (rsa == NULL || CBS_len(key) != 0) {
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
+ RSA_free(rsa);
return 0;
}
- EVP_PKEY_assign_RSA(pkey, rsa);
+ EVP_PKEY_assign_RSA(out, rsa);
return 1;
}
@@ -170,553 +176,17 @@ static int rsa_bits(const EVP_PKEY *pkey) {
static void int_rsa_free(EVP_PKEY *pkey) { RSA_free(pkey->pkey.rsa); }
-static void update_buflen(const BIGNUM *b, size_t *pbuflen) {
- size_t i;
-
- if (!b) {
- return;
- }
-
- i = BN_num_bytes(b);
- if (*pbuflen < i) {
- *pbuflen = i;
- }
-}
-
-static int do_rsa_print(BIO *out, const RSA *rsa, int off,
- int include_private) {
- char *str;
- const char *s;
- uint8_t *m = NULL;
- int ret = 0, mod_len = 0;
- size_t buf_len = 0;
-
- update_buflen(rsa->n, &buf_len);
- update_buflen(rsa->e, &buf_len);
-
- if (include_private) {
- update_buflen(rsa->d, &buf_len);
- update_buflen(rsa->p, &buf_len);
- update_buflen(rsa->q, &buf_len);
- 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, ERR_R_MALLOC_FAILURE);
- goto err;
- }
-
- if (rsa->n != NULL) {
- mod_len = BN_num_bits(rsa->n);
- }
-
- if (!BIO_indent(out, off, 128)) {
- goto err;
- }
-
- if (include_private && rsa->d) {
- if (BIO_printf(out, "Private-Key: (%d bit)\n", mod_len) <= 0) {
- goto err;
- }
- str = "modulus:";
- s = "publicExponent:";
- } else {
- if (BIO_printf(out, "Public-Key: (%d bit)\n", mod_len) <= 0) {
- goto err;
- }
- str = "Modulus:";
- s = "Exponent:";
- }
- if (!ASN1_bn_print(out, str, rsa->n, m, off) ||
- !ASN1_bn_print(out, s, rsa->e, m, off)) {
- goto err;
- }
-
- if (include_private) {
- if (!ASN1_bn_print(out, "privateExponent:", rsa->d, m, off) ||
- !ASN1_bn_print(out, "prime1:", rsa->p, m, off) ||
- !ASN1_bn_print(out, "prime2:", rsa->q, m, off) ||
- !ASN1_bn_print(out, "exponent1:", rsa->dmp1, m, off) ||
- !ASN1_bn_print(out, "exponent2:", rsa->dmq1, m, 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;
-
-err:
- OPENSSL_free(m);
- return ret;
-}
-
-static int rsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
- ASN1_PCTX *ctx) {
- return do_rsa_print(bp, pkey->pkey.rsa, indent, 0);
-}
-
-
-static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
- ASN1_PCTX *ctx) {
- return do_rsa_print(bp, pkey->pkey.rsa, indent, 1);
-}
-
-/* Given an MGF1 Algorithm ID decode to an Algorithm Identifier */
-static X509_ALGOR *rsa_mgf1_decode(X509_ALGOR *alg) {
- const uint8_t *p;
- int plen;
-
- if (alg == NULL || alg->parameter == NULL ||
- OBJ_obj2nid(alg->algorithm) != NID_mgf1 ||
- alg->parameter->type != V_ASN1_SEQUENCE) {
- return NULL;
- }
-
- p = alg->parameter->value.sequence->data;
- plen = alg->parameter->value.sequence->length;
- return d2i_X509_ALGOR(NULL, &p, plen);
-}
-
-static RSA_PSS_PARAMS *rsa_pss_decode(const X509_ALGOR *alg,
- X509_ALGOR **pmaskHash) {
- const uint8_t *p;
- int plen;
- RSA_PSS_PARAMS *pss;
-
- *pmaskHash = NULL;
-
- if (!alg->parameter || alg->parameter->type != V_ASN1_SEQUENCE) {
- return NULL;
- }
- p = alg->parameter->value.sequence->data;
- plen = alg->parameter->value.sequence->length;
- pss = d2i_RSA_PSS_PARAMS(NULL, &p, plen);
-
- if (!pss) {
- return NULL;
- }
-
- *pmaskHash = rsa_mgf1_decode(pss->maskGenAlgorithm);
-
- return pss;
-}
-
-static int rsa_pss_param_print(BIO *bp, RSA_PSS_PARAMS *pss,
- X509_ALGOR *maskHash, int indent) {
- int rv = 0;
-
- if (!pss) {
- if (BIO_puts(bp, " (INVALID PSS PARAMETERS)\n") <= 0) {
- return 0;
- }
- return 1;
- }
-
- if (BIO_puts(bp, "\n") <= 0 ||
- !BIO_indent(bp, indent, 128) ||
- BIO_puts(bp, "Hash Algorithm: ") <= 0) {
- goto err;
- }
-
- if (pss->hashAlgorithm) {
- if (i2a_ASN1_OBJECT(bp, pss->hashAlgorithm->algorithm) <= 0) {
- goto err;
- }
- } else if (BIO_puts(bp, "sha1 (default)") <= 0) {
- goto err;
- }
-
- if (BIO_puts(bp, "\n") <= 0 ||
- !BIO_indent(bp, indent, 128) ||
- BIO_puts(bp, "Mask Algorithm: ") <= 0) {
- goto err;
- }
-
- if (pss->maskGenAlgorithm) {
- if (i2a_ASN1_OBJECT(bp, pss->maskGenAlgorithm->algorithm) <= 0 ||
- BIO_puts(bp, " with ") <= 0) {
- goto err;
- }
-
- if (maskHash) {
- if (i2a_ASN1_OBJECT(bp, maskHash->algorithm) <= 0) {
- goto err;
- }
- } else if (BIO_puts(bp, "INVALID") <= 0) {
- goto err;
- }
- } else if (BIO_puts(bp, "mgf1 with sha1 (default)") <= 0) {
- goto err;
- }
- BIO_puts(bp, "\n");
-
- if (!BIO_indent(bp, indent, 128) ||
- BIO_puts(bp, "Salt Length: 0x") <= 0) {
- goto err;
- }
-
- if (pss->saltLength) {
- if (i2a_ASN1_INTEGER(bp, pss->saltLength) <= 0) {
- goto err;
- }
- } else if (BIO_puts(bp, "14 (default)") <= 0) {
- goto err;
- }
- BIO_puts(bp, "\n");
-
- if (!BIO_indent(bp, indent, 128) ||
- BIO_puts(bp, "Trailer Field: 0x") <= 0) {
- goto err;
- }
-
- if (pss->trailerField) {
- if (i2a_ASN1_INTEGER(bp, pss->trailerField) <= 0) {
- goto err;
- }
- } else if (BIO_puts(bp, "BC (default)") <= 0) {
- goto err;
- }
- BIO_puts(bp, "\n");
-
- rv = 1;
-
-err:
- return rv;
-}
-
-static int rsa_sig_print(BIO *bp, const X509_ALGOR *sigalg,
- const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx) {
- if (OBJ_obj2nid(sigalg->algorithm) == NID_rsassaPss) {
- int rv;
- RSA_PSS_PARAMS *pss;
- X509_ALGOR *maskHash;
-
- pss = rsa_pss_decode(sigalg, &maskHash);
- rv = rsa_pss_param_print(bp, pss, maskHash, indent);
- RSA_PSS_PARAMS_free(pss);
- X509_ALGOR_free(maskHash);
- if (!rv) {
- return 0;
- }
- } else if (!sig && BIO_puts(bp, "\n") <= 0) {
- return 0;
- }
-
- if (sig) {
- return X509_signature_dump(bp, sig, indent);
- }
- return 1;
-}
-
-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, ERR_R_RSA_LIB);
- return 0;
- }
- EVP_PKEY_assign_RSA(pkey, rsa);
- return 1;
-}
-
-static int old_rsa_priv_encode(const EVP_PKEY *pkey, uint8_t **pder) {
- return i2d_RSAPrivateKey(pkey->pkey.rsa, pder);
-}
-
-/* allocate and set algorithm ID from EVP_MD, default SHA1 */
-static int rsa_md_to_algor(X509_ALGOR **palg, const EVP_MD *md) {
- if (EVP_MD_type(md) == NID_sha1) {
- return 1;
- }
- *palg = X509_ALGOR_new();
- if (!*palg) {
- return 0;
- }
- X509_ALGOR_set_md(*palg, md);
- return 1;
-}
-
-/* Allocate and set MGF1 algorithm ID from EVP_MD */
-static int rsa_md_to_mgf1(X509_ALGOR **palg, const EVP_MD *mgf1md) {
- X509_ALGOR *algtmp = NULL;
- ASN1_STRING *stmp = NULL;
- *palg = NULL;
-
- if (EVP_MD_type(mgf1md) == NID_sha1) {
- return 1;
- }
- /* need to embed algorithm ID inside another */
- if (!rsa_md_to_algor(&algtmp, mgf1md) ||
- !ASN1_item_pack(algtmp, ASN1_ITEM_rptr(X509_ALGOR), &stmp)) {
- goto err;
- }
- *palg = X509_ALGOR_new();
- if (!*palg) {
- goto err;
- }
- X509_ALGOR_set0(*palg, OBJ_nid2obj(NID_mgf1), V_ASN1_SEQUENCE, stmp);
- stmp = NULL;
-
-err:
- ASN1_STRING_free(stmp);
- X509_ALGOR_free(algtmp);
- if (*palg) {
- return 1;
- }
-
- return 0;
-}
-
-/* convert algorithm ID to EVP_MD, default SHA1 */
-static const EVP_MD *rsa_algor_to_md(X509_ALGOR *alg) {
- const EVP_MD *md;
- if (!alg) {
- return EVP_sha1();
- }
- md = EVP_get_digestbyobj(alg->algorithm);
- if (md == NULL) {
- OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_DIGEST);
- }
- return md;
-}
-
-/* convert MGF1 algorithm ID to EVP_MD, default SHA1 */
-static const EVP_MD *rsa_mgf1_to_md(X509_ALGOR *alg, X509_ALGOR *maskHash) {
- const EVP_MD *md;
- if (!alg) {
- return EVP_sha1();
- }
- /* Check mask and lookup mask hash algorithm */
- if (OBJ_obj2nid(alg->algorithm) != NID_mgf1) {
- OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_MASK_ALGORITHM);
- return NULL;
- }
- if (!maskHash) {
- OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_MASK_PARAMETER);
- return NULL;
- }
- md = EVP_get_digestbyobj(maskHash->algorithm);
- if (md == NULL) {
- OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_MASK_DIGEST);
- return NULL;
- }
- return md;
-}
-
-/* rsa_ctx_to_pss converts EVP_PKEY_CTX in PSS mode into corresponding
- * algorithm parameter, suitable for setting as an AlgorithmIdentifier. */
-static ASN1_STRING *rsa_ctx_to_pss(EVP_PKEY_CTX *pkctx) {
- const EVP_MD *sigmd, *mgf1md;
- RSA_PSS_PARAMS *pss = NULL;
- ASN1_STRING *os = NULL;
- EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(pkctx);
- int saltlen, rv = 0;
-
- if (!EVP_PKEY_CTX_get_signature_md(pkctx, &sigmd) ||
- !EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) ||
- !EVP_PKEY_CTX_get_rsa_pss_saltlen(pkctx, &saltlen)) {
- goto err;
- }
-
- if (saltlen == -1) {
- saltlen = EVP_MD_size(sigmd);
- } else if (saltlen == -2) {
- saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2;
- if (((EVP_PKEY_bits(pk) - 1) & 0x7) == 0) {
- saltlen--;
- }
- } else {
- goto err;
- }
-
- pss = RSA_PSS_PARAMS_new();
- if (!pss) {
- goto err;
- }
-
- if (saltlen != 20) {
- pss->saltLength = ASN1_INTEGER_new();
- if (!pss->saltLength ||
- !ASN1_INTEGER_set(pss->saltLength, saltlen)) {
- goto err;
- }
- }
-
- if (!rsa_md_to_algor(&pss->hashAlgorithm, sigmd) ||
- !rsa_md_to_mgf1(&pss->maskGenAlgorithm, mgf1md)) {
- goto err;
- }
-
- /* Finally create string with pss parameter encoding. */
- if (!ASN1_item_pack(pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), &os)) {
- goto err;
- }
- rv = 1;
-
-err:
- if (pss) {
- RSA_PSS_PARAMS_free(pss);
- }
- if (rv) {
- return os;
- }
- if (os) {
- ASN1_STRING_free(os);
- }
- return NULL;
-}
-
-/* From PSS AlgorithmIdentifier set public key parameters. */
-static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, X509_ALGOR *sigalg, EVP_PKEY *pkey) {
- int ret = 0;
- int saltlen;
- const EVP_MD *mgf1md = NULL, *md = NULL;
- RSA_PSS_PARAMS *pss;
- X509_ALGOR *maskHash;
- EVP_PKEY_CTX *pkctx;
-
- /* Sanity check: make sure it is PSS */
- if (OBJ_obj2nid(sigalg->algorithm) != NID_rsassaPss) {
- 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, EVP_R_INVALID_PSS_PARAMETERS);
- goto err;
- }
-
- mgf1md = rsa_mgf1_to_md(pss->maskGenAlgorithm, maskHash);
- if (!mgf1md) {
- goto err;
- }
- md = rsa_algor_to_md(pss->hashAlgorithm);
- if (!md) {
- goto err;
- }
-
- saltlen = 20;
- if (pss->saltLength) {
- saltlen = ASN1_INTEGER_get(pss->saltLength);
-
- /* 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, EVP_R_INVALID_SALT_LENGTH);
- goto err;
- }
- }
-
- /* 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, EVP_R_INVALID_TRAILER);
- goto err;
- }
-
- if (!EVP_DigestVerifyInit(ctx, &pkctx, md, NULL, pkey) ||
- !EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) ||
- !EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) ||
- !EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md)) {
- goto err;
- }
-
- ret = 1;
-
-err:
- RSA_PSS_PARAMS_free(pss);
- if (maskHash) {
- X509_ALGOR_free(maskHash);
- }
- return ret;
-}
-
-/* Customised RSA AlgorithmIdentifier handling. This is called when a signature
- * is encountered requiring special handling. We currently only handle PSS. */
-static int rsa_digest_verify_init_from_algorithm(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, EVP_R_UNSUPPORTED_SIGNATURE_TYPE);
- return 0;
- }
- return rsa_pss_to_ctx(ctx, sigalg, pkey);
-}
-
-static evp_digest_sign_algorithm_result_t rsa_digest_sign_algorithm(
- EVP_MD_CTX *ctx, X509_ALGOR *sigalg) {
- int pad_mode;
- EVP_PKEY_CTX *pkctx = ctx->pctx;
- if (!EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode)) {
- return EVP_DIGEST_SIGN_ALGORITHM_ERROR;
- }
- if (pad_mode == RSA_PKCS1_PSS_PADDING) {
- ASN1_STRING *os1 = rsa_ctx_to_pss(pkctx);
- if (!os1) {
- return EVP_DIGEST_SIGN_ALGORITHM_ERROR;
- }
- X509_ALGOR_set0(sigalg, OBJ_nid2obj(NID_rsassaPss), V_ASN1_SEQUENCE, os1);
- return EVP_DIGEST_SIGN_ALGORITHM_SUCCESS;
- }
-
- /* Other padding schemes use the default behavior. */
- return EVP_DIGEST_SIGN_ALGORITHM_DEFAULT;
-}
-
const EVP_PKEY_ASN1_METHOD rsa_asn1_meth = {
EVP_PKEY_RSA,
- EVP_PKEY_RSA,
- ASN1_PKEY_SIGPARAM_NULL,
-
- "RSA",
+ /* 1.2.840.113549.1.1.1 */
+ {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01}, 9,
rsa_pub_decode,
rsa_pub_encode,
rsa_pub_cmp,
- rsa_pub_print,
rsa_priv_decode,
rsa_priv_encode,
- rsa_priv_print,
rsa_opaque,
rsa_supports_digest,
@@ -724,14 +194,7 @@ const EVP_PKEY_ASN1_METHOD rsa_asn1_meth = {
int_rsa_size,
rsa_bits,
- 0,0,0,0,0,0,
+ 0,0,0,
- rsa_sig_print,
int_rsa_free,
-
- old_rsa_priv_decode,
- old_rsa_priv_encode,
-
- rsa_digest_verify_init_from_algorithm,
- rsa_digest_sign_algorithm,
};
diff --git a/src/crypto/evp/pbkdf_test.cc b/src/crypto/evp/pbkdf_test.cc
index a39189f5..438ab644 100644
--- a/src/crypto/evp/pbkdf_test.cc
+++ b/src/crypto/evp/pbkdf_test.cc
@@ -15,7 +15,6 @@
#include <stdio.h>
#include <string.h>
-#include <openssl/bio.h>
#include <openssl/crypto.h>
#include <openssl/digest.h>
#include <openssl/err.h>
@@ -189,7 +188,6 @@ static bool TestZeroIterations() {
int main(void) {
CRYPTO_library_init();
- ERR_load_crypto_strings();
if (!TestEmptyPassword()) {
fprintf(stderr, "TestEmptyPassword failed\n");
diff --git a/src/crypto/evp/print.c b/src/crypto/evp/print.c
new file mode 100644
index 00000000..56521ec5
--- /dev/null
+++ b/src/crypto/evp/print.c
@@ -0,0 +1,527 @@
+/* ====================================================================
+ * Copyright (c) 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
+ * 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/bio.h>
+#include <openssl/bn.h>
+#include <openssl/dsa.h>
+#include <openssl/ec.h>
+#include <openssl/ec_key.h>
+#include <openssl/mem.h>
+#include <openssl/rsa.h>
+
+#include "../rsa/internal.h"
+
+
+static int bn_print(BIO *bp, const char *number, const BIGNUM *num,
+ uint8_t *buf, int off) {
+ if (num == NULL) {
+ return 1;
+ }
+
+ if (!BIO_indent(bp, off, 128)) {
+ return 0;
+ }
+ if (BN_is_zero(num)) {
+ if (BIO_printf(bp, "%s 0\n", number) <= 0) {
+ return 0;
+ }
+ return 1;
+ }
+
+ if (BN_num_bytes(num) <= sizeof(long)) {
+ const char *neg = BN_is_negative(num) ? "-" : "";
+ if (BIO_printf(bp, "%s %s%lu (%s0x%lx)\n", number, neg,
+ (unsigned long)num->d[0], neg,
+ (unsigned long)num->d[0]) <= 0) {
+ return 0;
+ }
+ } else {
+ buf[0] = 0;
+ if (BIO_printf(bp, "%s%s", number,
+ (BN_is_negative(num)) ? " (Negative)" : "") <= 0) {
+ return 0;
+ }
+ int n = BN_bn2bin(num, &buf[1]);
+
+ if (buf[1] & 0x80) {
+ n++;
+ } else {
+ buf++;
+ }
+
+ int i;
+ for (i = 0; i < n; i++) {
+ if ((i % 15) == 0) {
+ if (BIO_puts(bp, "\n") <= 0 ||
+ !BIO_indent(bp, off + 4, 128)) {
+ return 0;
+ }
+ }
+ if (BIO_printf(bp, "%02x%s", buf[i], ((i + 1) == n) ? "" : ":") <= 0) {
+ return 0;
+ }
+ }
+ if (BIO_write(bp, "\n", 1) <= 0) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static void update_buflen(const BIGNUM *b, size_t *pbuflen) {
+ size_t i;
+
+ if (!b) {
+ return;
+ }
+
+ i = BN_num_bytes(b);
+ if (*pbuflen < i) {
+ *pbuflen = i;
+ }
+}
+
+/* RSA keys. */
+
+static int do_rsa_print(BIO *out, const RSA *rsa, int off,
+ int include_private) {
+ const char *s, *str;
+ uint8_t *m = NULL;
+ int ret = 0, mod_len = 0;
+ size_t buf_len = 0;
+
+ update_buflen(rsa->n, &buf_len);
+ update_buflen(rsa->e, &buf_len);
+
+ if (include_private) {
+ update_buflen(rsa->d, &buf_len);
+ update_buflen(rsa->p, &buf_len);
+ update_buflen(rsa->q, &buf_len);
+ 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, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (rsa->n != NULL) {
+ mod_len = BN_num_bits(rsa->n);
+ }
+
+ if (!BIO_indent(out, off, 128)) {
+ goto err;
+ }
+
+ if (include_private && rsa->d) {
+ if (BIO_printf(out, "Private-Key: (%d bit)\n", mod_len) <= 0) {
+ goto err;
+ }
+ str = "modulus:";
+ s = "publicExponent:";
+ } else {
+ if (BIO_printf(out, "Public-Key: (%d bit)\n", mod_len) <= 0) {
+ goto err;
+ }
+ str = "Modulus:";
+ s = "Exponent:";
+ }
+ if (!bn_print(out, str, rsa->n, m, off) ||
+ !bn_print(out, s, rsa->e, m, off)) {
+ goto err;
+ }
+
+ if (include_private) {
+ if (!bn_print(out, "privateExponent:", rsa->d, m, off) ||
+ !bn_print(out, "prime1:", rsa->p, m, off) ||
+ !bn_print(out, "prime2:", rsa->q, m, off) ||
+ !bn_print(out, "exponent1:", rsa->dmp1, m, off) ||
+ !bn_print(out, "exponent2:", rsa->dmq1, m, off) ||
+ !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 ||
+ !bn_print(out, "prime:", ap->prime, m, off) ||
+ !bn_print(out, "exponent:", ap->exp, m, off) ||
+ !bn_print(out, "coeff:", ap->coeff, m, off)) {
+ goto err;
+ }
+ }
+ }
+ }
+ ret = 1;
+
+err:
+ OPENSSL_free(m);
+ return ret;
+}
+
+static int rsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+ ASN1_PCTX *ctx) {
+ return do_rsa_print(bp, pkey->pkey.rsa, indent, 0);
+}
+
+static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+ ASN1_PCTX *ctx) {
+ return do_rsa_print(bp, pkey->pkey.rsa, indent, 1);
+}
+
+
+/* DSA keys. */
+
+static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype) {
+ uint8_t *m = NULL;
+ int ret = 0;
+ size_t buf_len = 0;
+ const char *ktype = NULL;
+
+ const BIGNUM *priv_key, *pub_key;
+
+ priv_key = NULL;
+ if (ptype == 2) {
+ priv_key = x->priv_key;
+ }
+
+ pub_key = NULL;
+ if (ptype > 0) {
+ pub_key = x->pub_key;
+ }
+
+ ktype = "DSA-Parameters";
+ if (ptype == 2) {
+ ktype = "Private-Key";
+ } else if (ptype == 1) {
+ ktype = "Public-Key";
+ }
+
+ update_buflen(x->p, &buf_len);
+ update_buflen(x->q, &buf_len);
+ update_buflen(x->g, &buf_len);
+ update_buflen(priv_key, &buf_len);
+ update_buflen(pub_key, &buf_len);
+
+ m = (uint8_t *)OPENSSL_malloc(buf_len + 10);
+ if (m == NULL) {
+ OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (priv_key) {
+ if (!BIO_indent(bp, off, 128) ||
+ BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0) {
+ goto err;
+ }
+ }
+
+ if (!bn_print(bp, "priv:", priv_key, m, off) ||
+ !bn_print(bp, "pub: ", pub_key, m, off) ||
+ !bn_print(bp, "P: ", x->p, m, off) ||
+ !bn_print(bp, "Q: ", x->q, m, off) ||
+ !bn_print(bp, "G: ", x->g, m, off)) {
+ goto err;
+ }
+ ret = 1;
+
+err:
+ OPENSSL_free(m);
+ return ret;
+}
+
+static int dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+ ASN1_PCTX *ctx) {
+ return do_dsa_print(bp, pkey->pkey.dsa, indent, 0);
+}
+
+static int dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+ ASN1_PCTX *ctx) {
+ return do_dsa_print(bp, pkey->pkey.dsa, indent, 1);
+}
+
+static int dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+ ASN1_PCTX *ctx) {
+ return do_dsa_print(bp, pkey->pkey.dsa, indent, 2);
+}
+
+
+/* EC keys. */
+
+static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) {
+ uint8_t *buffer = NULL;
+ 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;
+ const BIGNUM *priv_key;
+ uint8_t *pub_key_bytes = NULL;
+ size_t pub_key_bytes_len = 0;
+
+ if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) {
+ reason = ERR_R_PASSED_NULL_PARAMETER;
+ goto err;
+ }
+
+ ctx = BN_CTX_new();
+ if (ctx == NULL) {
+ reason = ERR_R_MALLOC_FAILURE;
+ goto err;
+ }
+
+ if (ktype > 0) {
+ public_key = EC_KEY_get0_public_key(x);
+ if (public_key != NULL) {
+ pub_key_bytes_len = EC_POINT_point2oct(
+ group, public_key, EC_KEY_get_conv_form(x), NULL, 0, ctx);
+ if (pub_key_bytes_len == 0) {
+ reason = ERR_R_MALLOC_FAILURE;
+ goto err;
+ }
+ pub_key_bytes = OPENSSL_malloc(pub_key_bytes_len);
+ if (pub_key_bytes == NULL) {
+ reason = ERR_R_MALLOC_FAILURE;
+ goto err;
+ }
+ pub_key_bytes_len =
+ EC_POINT_point2oct(group, public_key, EC_KEY_get_conv_form(x),
+ pub_key_bytes, pub_key_bytes_len, ctx);
+ if (pub_key_bytes_len == 0) {
+ reason = ERR_R_MALLOC_FAILURE;
+ goto err;
+ }
+ buf_len = pub_key_bytes_len;
+ }
+ }
+
+ if (ktype == 2) {
+ priv_key = EC_KEY_get0_private_key(x);
+ if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len) {
+ buf_len = i;
+ }
+ } else {
+ priv_key = NULL;
+ }
+
+ if (ktype > 0) {
+ buf_len += 10;
+ if ((buffer = OPENSSL_malloc(buf_len)) == NULL) {
+ reason = ERR_R_MALLOC_FAILURE;
+ goto err;
+ }
+ }
+ if (ktype == 2) {
+ ecstr = "Private-Key";
+ } else if (ktype == 1) {
+ ecstr = "Public-Key";
+ } else {
+ ecstr = "ECDSA-Parameters";
+ }
+
+ 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) {
+ goto err;
+ }
+
+ if ((priv_key != NULL) &&
+ !bn_print(bp, "priv:", priv_key, buffer, off)) {
+ goto err;
+ }
+ if (pub_key_bytes != NULL) {
+ BIO_hexdump(bp, pub_key_bytes, pub_key_bytes_len, off);
+ }
+ /* TODO(fork): implement */
+ /*
+ if (!ECPKParameters_print(bp, group, off))
+ goto err; */
+ ret = 1;
+
+err:
+ if (!ret) {
+ OPENSSL_PUT_ERROR(EVP, reason);
+ }
+ OPENSSL_free(pub_key_bytes);
+ BN_free(order);
+ BN_CTX_free(ctx);
+ OPENSSL_free(buffer);
+ return ret;
+}
+
+static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+ ASN1_PCTX *ctx) {
+ return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0);
+}
+
+static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+ ASN1_PCTX *ctx) {
+ return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1);
+}
+
+
+static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+ ASN1_PCTX *ctx) {
+ return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2);
+}
+
+
+typedef struct {
+ int type;
+ int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx);
+ int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent,
+ ASN1_PCTX *pctx);
+ int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent,
+ ASN1_PCTX *pctx);
+} EVP_PKEY_PRINT_METHOD;
+
+static EVP_PKEY_PRINT_METHOD kPrintMethods[] = {
+ {
+ EVP_PKEY_RSA,
+ rsa_pub_print,
+ rsa_priv_print,
+ NULL /* param_print */,
+ },
+ {
+ EVP_PKEY_DSA,
+ dsa_pub_print,
+ dsa_priv_print,
+ dsa_param_print,
+ },
+ {
+ EVP_PKEY_EC,
+ eckey_pub_print,
+ eckey_priv_print,
+ eckey_param_print,
+ },
+};
+
+static size_t kPrintMethodsLen =
+ sizeof(kPrintMethods) / sizeof(kPrintMethods[0]);
+
+static EVP_PKEY_PRINT_METHOD *find_method(int type) {
+ size_t i;
+ for (i = 0; i < kPrintMethodsLen; i++) {
+ if (kPrintMethods[i].type == type) {
+ return &kPrintMethods[i];
+ }
+ }
+ return NULL;
+}
+
+static int print_unsupported(BIO *out, const EVP_PKEY *pkey, int indent,
+ const char *kstr) {
+ BIO_indent(out, indent, 128);
+ BIO_printf(out, "%s algorithm unsupported\n", kstr);
+ return 1;
+}
+
+int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, int indent,
+ ASN1_PCTX *pctx) {
+ EVP_PKEY_PRINT_METHOD *method = find_method(pkey->type);
+ if (method != NULL && method->pub_print != NULL) {
+ return method->pub_print(out, pkey, indent, pctx);
+ }
+ return print_unsupported(out, pkey, indent, "Public Key");
+}
+
+int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, int indent,
+ ASN1_PCTX *pctx) {
+ EVP_PKEY_PRINT_METHOD *method = find_method(pkey->type);
+ if (method != NULL && method->priv_print != NULL) {
+ return method->priv_print(out, pkey, indent, pctx);
+ }
+ return print_unsupported(out, pkey, indent, "Private Key");
+}
+
+int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, int indent,
+ ASN1_PCTX *pctx) {
+ EVP_PKEY_PRINT_METHOD *method = find_method(pkey->type);
+ if (method != NULL && method->param_print != NULL) {
+ return method->param_print(out, pkey, indent, pctx);
+ }
+ return print_unsupported(out, pkey, indent, "Parameters");
+}
diff --git a/src/crypto/hkdf/hkdf_test.c b/src/crypto/hkdf/hkdf_test.c
index 63070dc4..b11061ae 100644
--- a/src/crypto/hkdf/hkdf_test.c
+++ b/src/crypto/hkdf/hkdf_test.c
@@ -20,6 +20,8 @@
#include <openssl/err.h>
#include <openssl/hkdf.h>
+#include "../test/test_util.h"
+
typedef struct {
const EVP_MD *(*md_func)(void);
@@ -216,7 +218,6 @@ int main(void) {
size_t i;
CRYPTO_library_init();
- ERR_load_crypto_strings();
for (i = 0; i < sizeof(kTests) / sizeof(kTests[0]); i++) {
const hkdf_test_vector_t *test = &kTests[i];
@@ -227,8 +228,9 @@ int main(void) {
return 1;
}
if (memcmp(buf, test->out, test->out_len) != 0) {
- fprintf(stderr, "%u: Resulting key material does not match test vector\n",
- (unsigned)i);
+ fprintf(stderr, "%" OPENSSL_PR_SIZE_T
+ ": Resulting key material does not match test vector\n",
+ i);
return 1;
}
}
diff --git a/src/crypto/hmac/hmac.c b/src/crypto/hmac/hmac.c
index be2dccec..bccc5c02 100644
--- a/src/crypto/hmac/hmac.c
+++ b/src/crypto/hmac/hmac.c
@@ -59,6 +59,7 @@
#include <assert.h>
#include <string.h>
+#include <openssl/digest.h>
#include <openssl/mem.h>
@@ -115,8 +116,8 @@ int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, size_t key_len,
* case. Fix to API to avoid this. */
if (md != ctx->md || key != NULL) {
size_t i;
- uint8_t pad[HMAC_MAX_MD_CBLOCK];
- uint8_t key_block[HMAC_MAX_MD_CBLOCK];
+ uint8_t pad[EVP_MAX_MD_BLOCK_SIZE];
+ uint8_t key_block[EVP_MAX_MD_BLOCK_SIZE];
unsigned key_block_len;
size_t block_size = EVP_MD_block_size(md);
@@ -134,11 +135,11 @@ int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, size_t key_len,
key_block_len = (unsigned)key_len;
}
/* Keys are then padded with zeros. */
- if (key_block_len != HMAC_MAX_MD_CBLOCK) {
+ if (key_block_len != EVP_MAX_MD_BLOCK_SIZE) {
memset(&key_block[key_block_len], 0, sizeof(key_block) - key_block_len);
}
- for (i = 0; i < HMAC_MAX_MD_CBLOCK; i++) {
+ for (i = 0; i < EVP_MAX_MD_BLOCK_SIZE; i++) {
pad[i] = 0x36 ^ key_block[i];
}
if (!EVP_DigestInit_ex(&ctx->i_ctx, md, impl) ||
@@ -146,7 +147,7 @@ int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, size_t key_len,
return 0;
}
- for (i = 0; i < HMAC_MAX_MD_CBLOCK; i++) {
+ for (i = 0; i < EVP_MAX_MD_BLOCK_SIZE; i++) {
pad[i] = 0x5c ^ key_block[i];
}
if (!EVP_DigestInit_ex(&ctx->o_ctx, md, impl) ||
diff --git a/src/crypto/internal.h b/src/crypto/internal.h
index bf45349e..ded43fe2 100644
--- a/src/crypto/internal.h
+++ b/src/crypto/internal.h
@@ -112,6 +112,15 @@
#include <openssl/ex_data.h>
#include <openssl/thread.h>
+#if defined(_MSC_VER)
+#if !defined(__cplusplus) || _MSC_VER < 1900
+#define alignas(x) __declspec(align(x))
+#define alignof __alignof
+#endif
+#else
+#include <stdalign.h>
+#endif
+
#if defined(OPENSSL_NO_THREADS)
#elif defined(OPENSSL_WINDOWS)
#pragma warning(push, 3)
@@ -126,48 +135,6 @@ extern "C" {
#endif
-/* MSVC's C4701 warning about the use of *potentially*--as opposed to
- * *definitely*--uninitialized values sometimes has false positives. Usually
- * the false positives can and should be worked around by simplifying the
- * control flow. When that is not practical, annotate the function containing
- * the code that triggers the warning with
- * OPENSSL_SUPPRESS_POTENTIALLY_UNINITIALIZED_WARNINGS after its parameters:
- *
- * void f() OPENSSL_SUPPRESS_POTENTIALLY_UNINITIALIZED_WARNINGS {
- * ...
- * }
- *
- * Note that MSVC's control flow analysis seems to operate on a whole-function
- * basis, so the annotation must be placed on the entire function, not just a
- * block within the function. */
-#if defined(_MSC_VER)
-#define OPENSSL_SUPPRESS_POTENTIALLY_UNINITIALIZED_WARNINGS \
- __pragma(warning(suppress:4701))
-#else
-#define OPENSSL_SUPPRESS_POTENTIALLY_UNINITIALIZED_WARNINGS
-#endif
-
-/* MSVC will sometimes correctly detect unreachable code and issue a warning,
- * which breaks the build since we treat errors as warnings, in some rare cases
- * where we want to allow the dead code to continue to exist. In these
- * situations, annotate the function containing the unreachable code with
- * OPENSSL_SUPPRESS_UNREACHABLE_CODE_WARNINGS after its parameters:
- *
- * void f() OPENSSL_SUPPRESS_UNREACHABLE_CODE_WARNINGS {
- * ...
- * }
- *
- * Note that MSVC's reachability analysis seems to operate on a whole-function
- * basis, so the annotation must be placed on the entire function, not just a
- * block within the function. */
-#if defined(_MSC_VER)
-#define OPENSSL_SUPPRESS_UNREACHABLE_CODE_WARNINGS \
- __pragma(warning(suppress:4702))
-#else
-#define OPENSSL_SUPPRESS_UNREACHABLE_CODE_WARNINGS
-#endif
-
-
#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || defined(OPENSSL_ARM) || \
defined(OPENSSL_AARCH64)
/* OPENSSL_cpuid_setup initializes OPENSSL_ia32cap_P. */
@@ -179,6 +146,12 @@ void OPENSSL_cpuid_setup(void);
#endif
+#if !defined(_MSC_VER) && defined(OPENSSL_64_BIT)
+typedef __int128_t int128_t;
+typedef __uint128_t uint128_t;
+#endif
+
+
/* Constant-time utility functions.
*
* The following methods return a bitmask of all ones (0xff...f) for true and 0
@@ -321,12 +294,22 @@ static inline int constant_time_select_int(unsigned int mask, int a, int b) {
/* Thread-safe initialisation. */
+/* Android's mingw-w64 has some prototypes for INIT_ONCE, but is missing
+ * others. Work around the missing ones.
+ *
+ * TODO(davidben): Remove this once Android's mingw-w64 is upgraded. See
+ * b/26523949. */
+#if defined(__MINGW32__) && !defined(INIT_ONCE_STATIC_INIT)
+typedef RTL_RUN_ONCE INIT_ONCE;
+#define INIT_ONCE_STATIC_INIT RTL_RUN_ONCE_INIT
+#endif
+
#if defined(OPENSSL_NO_THREADS)
typedef uint32_t CRYPTO_once_t;
#define CRYPTO_ONCE_INIT 0
#elif defined(OPENSSL_WINDOWS)
-typedef LONG CRYPTO_once_t;
-#define CRYPTO_ONCE_INIT 0
+typedef INIT_ONCE CRYPTO_once_t;
+#define CRYPTO_ONCE_INIT INIT_ONCE_STATIC_INIT
#else
typedef pthread_once_t CRYPTO_once_t;
#define CRYPTO_ONCE_INIT PTHREAD_ONCE_INIT
@@ -380,8 +363,10 @@ OPENSSL_EXPORT int CRYPTO_refcount_dec_and_test_zero(CRYPTO_refcount_t *count);
* automatically by |CRYPTO_STATIC_MUTEX_lock_*|. */
#if defined(OPENSSL_NO_THREADS)
-struct CRYPTO_STATIC_MUTEX {};
-#define CRYPTO_STATIC_MUTEX_INIT {}
+struct CRYPTO_STATIC_MUTEX {
+ char padding; /* Empty structs have different sizes in C and C++. */
+};
+#define CRYPTO_STATIC_MUTEX_INIT { 0 }
#elif defined(OPENSSL_WINDOWS)
struct CRYPTO_STATIC_MUTEX {
CRYPTO_once_t once;
diff --git a/src/crypto/md4/md4.c b/src/crypto/md4/md4.c
index 86a540b4..f79da9fd 100644
--- a/src/crypto/md4/md4.c
+++ b/src/crypto/md4/md4.c
@@ -60,6 +60,15 @@
#include <string.h>
+uint8_t *MD4(const uint8_t *data, size_t len, uint8_t *out) {
+ MD4_CTX ctx;
+ MD4_Init(&ctx);
+ MD4_Update(&ctx, data, len);
+ MD4_Final(out, &ctx);
+
+ return out;
+}
+
/* Implemented from RFC1186 The MD4 Message-Digest Algorithm. */
int MD4_Init(MD4_CTX *md4) {
diff --git a/src/crypto/mem.c b/src/crypto/mem.c
index edd14a81..df8e0e33 100644
--- a/src/crypto/mem.c
+++ b/src/crypto/mem.c
@@ -104,9 +104,9 @@ void *OPENSSL_realloc_clean(void *ptr, size_t old_size, size_t new_size) {
void OPENSSL_cleanse(void *ptr, size_t len) {
#if defined(OPENSSL_WINDOWS)
- SecureZeroMemory(ptr, len);
+ SecureZeroMemory(ptr, len);
#else
- memset(ptr, 0, len);
+ memset(ptr, 0, len);
#if !defined(OPENSSL_NO_ASM)
/* As best as we can tell, this is sufficient to break any optimisations that
diff --git a/src/crypto/modes/asm/aesni-gcm-x86_64.pl b/src/crypto/modes/asm/aesni-gcm-x86_64.pl
index 0ca89c7d..5d58bbbb 100644
--- a/src/crypto/modes/asm/aesni-gcm-x86_64.pl
+++ b/src/crypto/modes/asm/aesni-gcm-x86_64.pl
@@ -41,11 +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";
+# This must be kept in sync with |$avx| in ghash-x86_64.pl; otherwise tags will
+# be computed incorrectly.
+#
# 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";
@@ -96,6 +97,23 @@ _aesni_ctr32_ghash_6x:
vpxor $rndkey,$inout3,$inout3
vmovups 0x10-0x80($key),$T2 # borrow $T2 for $rndkey
vpclmulqdq \$0x01,$Hkey,$Z3,$Z2
+
+ # At this point, the current block of 96 (0x60) bytes has already been
+ # loaded into registers. Concurrently with processing it, we want to
+ # load the next 96 bytes of input for the next round. Obviously, we can
+ # only do this if there are at least 96 more bytes of input beyond the
+ # input we're currently processing, or else we'd read past the end of
+ # the input buffer. Here, we set |%r12| to 96 if there are at least 96
+ # bytes of input beyond the 96 bytes we're already processing, and we
+ # set |%r12| to 0 otherwise. In the case where we set |%r12| to 96,
+ # we'll read in the next block so that it is in registers for the next
+ # loop iteration. In the case where we set |%r12| to 0, we'll re-read
+ # the current block and then ignore what we re-read.
+ #
+ # At this point, |$in0| points to the current (already read into
+ # registers) block, and |$end0| points to 2*96 bytes before the end of
+ # the input. Thus, |$in0| > |$end0| means that we do not have the next
+ # 96-byte block to read in, and |$in0| <= |$end0| means we do.
xor %r12,%r12
cmp $in0,$end0
@@ -388,6 +406,9 @@ $code.=<<___;
.align 32
aesni_gcm_decrypt:
xor $ret,$ret
+
+ # We call |_aesni_ctr32_ghash_6x|, which requires at least 96 (0x60)
+ # bytes of input.
cmp \$0x60,$len # minimal accepted length
jb .Lgcm_dec_abort
@@ -442,7 +463,15 @@ $code.=<<___;
vmovdqu 0x50($inp),$Z3 # I[5]
lea ($inp),$in0
vmovdqu 0x40($inp),$Z0
+
+ # |_aesni_ctr32_ghash_6x| requires |$end0| to point to 2*96 (0xc0)
+ # bytes before the end of the input. Note, in particular, that this is
+ # correct even if |$len| is not an even multiple of 96 or 16. XXX: This
+ # seems to require that |$inp| + |$len| >= 2*96 (0xc0); i.e. |$inp| must
+ # not be near the very beginning of the address space when |$len| < 2*96
+ # (0xc0).
lea -0xc0($inp,$len),$end0
+
vmovdqu 0x30($inp),$Z1
shr \$4,$len
xor $ret,$ret
@@ -477,7 +506,7 @@ $code.=<<___;
___
$code.=<<___ if ($win64);
movaps -0xd8(%rax),%xmm6
- movaps -0xd8(%rax),%xmm7
+ movaps -0xc8(%rax),%xmm7
movaps -0xb8(%rax),%xmm8
movaps -0xa8(%rax),%xmm9
movaps -0x98(%rax),%xmm10
@@ -598,6 +627,10 @@ _aesni_ctr32_6x:
.align 32
aesni_gcm_encrypt:
xor $ret,$ret
+
+ # We call |_aesni_ctr32_6x| twice, each call consuming 96 bytes of
+ # input. Then we call |_aesni_ctr32_ghash_6x|, which requires at
+ # least 96 more bytes of input.
cmp \$0x60*3,$len # minimal accepted length
jb .Lgcm_enc_abort
@@ -647,7 +680,16 @@ $code.=<<___;
.Lenc_no_key_aliasing:
lea ($out),$in0
+
+ # |_aesni_ctr32_ghash_6x| requires |$end0| to point to 2*96 (0xc0)
+ # bytes before the end of the input. Note, in particular, that this is
+ # correct even if |$len| is not an even multiple of 96 or 16. Unlike in
+ # the decryption case, there's no caveat that |$out| must not be near
+ # the very beginning of the address space, because we know that
+ # |$len| >= 3*96 from the check above, and so we know
+ # |$out| + |$len| >= 2*96 (0xc0).
lea -0xc0($out,$len),$end0
+
shr \$4,$len
call _aesni_ctr32_6x
diff --git a/src/crypto/modes/asm/ghash-armv4.pl b/src/crypto/modes/asm/ghash-armv4.pl
index d3288223..bb0dba5f 100644
--- a/src/crypto/modes/asm/ghash-armv4.pl
+++ b/src/crypto/modes/asm/ghash-armv4.pl
@@ -163,7 +163,6 @@ rem_4bit_get:
.size rem_4bit_get,.-rem_4bit_get
.global gcm_ghash_4bit
-.hidden gcm_ghash_4bit
.type gcm_ghash_4bit,%function
gcm_ghash_4bit:
sub r12,pc,#8
@@ -260,7 +259,6 @@ $code.=<<___;
.size gcm_ghash_4bit,.-gcm_ghash_4bit
.global gcm_gmult_4bit
-.hidden gcm_gmult_4bit
.type gcm_gmult_4bit,%function
gcm_gmult_4bit:
stmdb sp!,{r4-r11,lr}
@@ -391,7 +389,6 @@ $code.=<<___;
.fpu neon
.global gcm_init_neon
-.hidden gcm_init_neon
.type gcm_init_neon,%function
.align 4
gcm_init_neon:
@@ -413,7 +410,6 @@ gcm_init_neon:
.size gcm_init_neon,.-gcm_init_neon
.global gcm_gmult_neon
-.hidden gcm_gmult_neon
.type gcm_gmult_neon,%function
.align 4
gcm_gmult_neon:
@@ -432,7 +428,6 @@ gcm_gmult_neon:
.size gcm_gmult_neon,.-gcm_gmult_neon
.global gcm_ghash_neon
-.hidden gcm_ghash_neon
.type gcm_ghash_neon,%function
.align 4
gcm_ghash_neon:
diff --git a/src/crypto/modes/asm/ghash-x86_64.pl b/src/crypto/modes/asm/ghash-x86_64.pl
index e42ca321..5a11fb94 100644
--- a/src/crypto/modes/asm/ghash-x86_64.pl
+++ b/src/crypto/modes/asm/ghash-x86_64.pl
@@ -90,11 +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";
+# This must be kept in sync with |$avx| in aesni-gcm-x86_64.pl; otherwise tags
+# will be computed incorrectly.
+#
# 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";
diff --git a/src/crypto/modes/cfb.c b/src/crypto/modes/cfb.c
index c58614ba..51b883e8 100644
--- a/src/crypto/modes/cfb.c
+++ b/src/crypto/modes/cfb.c
@@ -57,14 +57,13 @@
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) {
- unsigned int n;
+ const void *key, uint8_t ivec[16], unsigned *num,
+ int enc, block128_f block) {
size_t l = 0;
assert(in && out && key && ivec && num);
- n = *num;
+ unsigned n = *num;
if (enc) {
while (n && len) {
@@ -199,7 +198,7 @@ static void cfbr_encrypt_block(const uint8_t *in, uint8_t *out, unsigned nbits,
/* N.B. This expects the input to be packed, MS bit first */
void CRYPTO_cfb128_1_encrypt(const uint8_t *in, uint8_t *out, size_t bits,
- const void *key, uint8_t ivec[16], int *num,
+ const void *key, uint8_t ivec[16], unsigned *num,
int enc, block128_f block) {
size_t n;
uint8_t c[1], d[1];
@@ -217,7 +216,7 @@ void CRYPTO_cfb128_1_encrypt(const uint8_t *in, uint8_t *out, size_t bits,
void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const void *key,
- unsigned char ivec[16], int *num, int enc,
+ unsigned char ivec[16], unsigned *num, int enc,
block128_f block) {
size_t n;
diff --git a/src/crypto/modes/ctr.c b/src/crypto/modes/ctr.c
index 52ff048f..b84e72c5 100644
--- a/src/crypto/modes/ctr.c
+++ b/src/crypto/modes/ctr.c
@@ -59,17 +59,13 @@
/* increment counter (128-bit int) by 1 */
static void ctr128_inc(uint8_t *counter) {
- uint32_t n = 16;
- uint8_t c;
+ uint32_t n = 16, c = 1;
do {
--n;
- c = counter[n];
- ++c;
- counter[n] = c;
- if (c) {
- return;
- }
+ c += counter[n];
+ counter[n] = (uint8_t) c;
+ c >>= 8;
} while (n);
}
@@ -104,7 +100,7 @@ void CRYPTO_ctr128_encrypt(const uint8_t *in, uint8_t *out, size_t len,
}
#if STRICT_ALIGNMENT
- if (((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) {
+ if (((size_t)in | (size_t)out | (size_t)ecount_buf) % sizeof(size_t) != 0) {
size_t l = 0;
while (l < len) {
if (n == 0) {
@@ -124,8 +120,9 @@ void CRYPTO_ctr128_encrypt(const uint8_t *in, uint8_t *out, size_t len,
while (len >= 16) {
(*block)(ivec, ecount_buf, key);
ctr128_inc(ivec);
- for (; n < 16; n += sizeof(size_t)) {
- *(size_t *)(out + n) = *(size_t *)(in + n) ^ *(size_t *)(ecount_buf + n);
+ for (n = 0; n < 16; n += sizeof(size_t)) {
+ *(size_t *)(out + n) = *(const size_t *)(in + n) ^
+ *(const size_t *)(ecount_buf + n);
}
len -= 16;
out += 16;
@@ -145,17 +142,13 @@ void CRYPTO_ctr128_encrypt(const uint8_t *in, uint8_t *out, size_t len,
/* increment upper 96 bits of 128-bit counter by 1 */
static void ctr96_inc(uint8_t *counter) {
- uint32_t n = 12;
- uint8_t c;
+ uint32_t n = 12, c = 1;
do {
--n;
- c = counter[n];
- ++c;
- counter[n] = c;
- if (c) {
- return;
- }
+ c += counter[n];
+ counter[n] = (uint8_t) c;
+ c >>= 8;
} while (n);
}
diff --git a/src/crypto/modes/gcm.c b/src/crypto/modes/gcm.c
index 65451a6c..b8571313 100644
--- a/src/crypto/modes/gcm.c
+++ b/src/crypto/modes/gcm.c
@@ -55,6 +55,7 @@
#include <openssl/cpu.h>
#include "internal.h"
+#include "../internal.h"
#if !defined(OPENSSL_NO_ASM) && \
@@ -337,7 +338,18 @@ void gcm_ghash_clmul(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp,
#else
void gcm_init_avx(u128 Htable[16], const uint64_t Xi[2]);
void gcm_gmult_avx(uint64_t Xi[2], const u128 Htable[16]);
-void gcm_ghash_avx(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, size_t len);
+void gcm_ghash_avx(uint64_t Xi[2], const u128 Htable[16], const uint8_t *in,
+ size_t len);
+#define AESNI_GCM
+static int aesni_gcm_enabled(GCM128_CONTEXT *ctx, ctr128_f stream) {
+ return stream == aesni_ctr32_encrypt_blocks &&
+ ctx->ghash == gcm_ghash_avx;
+}
+
+size_t aesni_gcm_encrypt(const uint8_t *in, uint8_t *out, size_t len,
+ const void *key, uint8_t ivec[16], uint64_t *Xi);
+size_t aesni_gcm_decrypt(const uint8_t *in, uint8_t *out, size_t len,
+ const void *key, uint8_t ivec[16], uint64_t *Xi);
#endif
#if defined(OPENSSL_X86)
@@ -380,14 +392,14 @@ void gcm_ghash_neon(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp,
static int neon_capable(void) {
return 0;
}
-void gcm_init_neon(u128 Htable[16], const uint64_t Xi[2]) {
+static void gcm_init_neon(u128 Htable[16], const uint64_t Xi[2]) {
abort();
}
-void gcm_gmult_neon(uint64_t Xi[2], const u128 Htable[16]) {
+static void gcm_gmult_neon(uint64_t Xi[2], const u128 Htable[16]) {
abort();
}
-void gcm_ghash_neon(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp,
- size_t len) {
+static void gcm_ghash_neon(uint64_t Xi[2], const u128 Htable[16],
+ const uint8_t *inp, size_t len) {
abort();
}
#endif
@@ -405,17 +417,6 @@ void gcm_ghash_neon(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp,
#endif
#endif
-GCM128_CONTEXT *CRYPTO_gcm128_new(const void *key, block128_f block) {
- GCM128_CONTEXT *ret;
-
- ret = (GCM128_CONTEXT *)OPENSSL_malloc(sizeof(GCM128_CONTEXT));
- if (ret != NULL) {
- CRYPTO_gcm128_init(ret, key, block);
- }
-
- return ret;
-}
-
void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, const void *key,
block128_f block) {
const union {
@@ -606,7 +607,8 @@ int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const uint8_t *aad, size_t len) {
}
#ifdef GHASH
- if ((i = (len & (size_t) - 16))) {
+ i = len & kSizeTWithoutLower4Bits;
+ if (i != 0) {
GHASH(ctx, aad, i);
aad += i;
len -= i;
@@ -895,7 +897,8 @@ int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, const void *key,
}
len -= GHASH_CHUNK;
}
- if ((i = (len & (size_t) - 16))) {
+ i = len & kSizeTWithoutLower4Bits;
+ if (i != 0) {
GHASH(ctx, in, i);
while (len >= 16) {
size_t *out_t = (size_t *)out;
@@ -989,12 +992,6 @@ int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, const void *key,
ctx->ares = 0;
}
- if (is_endian.little) {
- ctr = GETU32(ctx->Yi.c + 12);
- } else {
- ctr = ctx->Yi.d[3];
- }
-
n = ctx->mres;
if (n) {
while (n && len) {
@@ -1009,6 +1006,24 @@ int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, const void *key,
return 1;
}
}
+
+#if defined(AESNI_GCM)
+ if (aesni_gcm_enabled(ctx, stream)) {
+ /* |aesni_gcm_encrypt| may not process all the input given to it. It may
+ * not process *any* of its input if it is deemed too small. */
+ size_t bulk = aesni_gcm_encrypt(in, out, len, key, ctx->Yi.c, ctx->Xi.u);
+ in += bulk;
+ out += bulk;
+ len -= bulk;
+ }
+#endif
+
+ if (is_endian.little) {
+ ctr = GETU32(ctx->Yi.c + 12);
+ } else {
+ ctr = ctx->Yi.d[3];
+ }
+
#if defined(GHASH)
while (len >= GHASH_CHUNK) {
(*stream)(in, out, GHASH_CHUNK / 16, key, ctx->Yi.c);
@@ -1098,12 +1113,6 @@ int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, const void *key,
ctx->ares = 0;
}
- if (is_endian.little) {
- ctr = GETU32(ctx->Yi.c + 12);
- } else {
- ctr = ctx->Yi.d[3];
- }
-
n = ctx->mres;
if (n) {
while (n && len) {
@@ -1120,6 +1129,24 @@ int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, const void *key,
return 1;
}
}
+
+#if defined(AESNI_GCM)
+ if (aesni_gcm_enabled(ctx, stream)) {
+ /* |aesni_gcm_decrypt| may not process all the input given to it. It may
+ * not process *any* of its input if it is deemed too small. */
+ size_t bulk = aesni_gcm_decrypt(in, out, len, key, ctx->Yi.c, ctx->Xi.u);
+ in += bulk;
+ out += bulk;
+ len -= bulk;
+ }
+#endif
+
+ if (is_endian.little) {
+ ctr = GETU32(ctx->Yi.c + 12);
+ } else {
+ ctr = ctx->Yi.d[3];
+ }
+
#if defined(GHASH)
while (len >= GHASH_CHUNK) {
GHASH(ctx, in, GHASH_CHUNK);
@@ -1233,13 +1260,6 @@ void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, unsigned char *tag, size_t len) {
memcpy(tag, ctx->Xi.c, len <= sizeof(ctx->Xi.c) ? len : sizeof(ctx->Xi.c));
}
-void CRYPTO_gcm128_release(GCM128_CONTEXT *ctx) {
- if (ctx) {
- OPENSSL_cleanse(ctx, sizeof(*ctx));
- OPENSSL_free(ctx);
- }
-}
-
#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
int crypto_gcm_clmul_enabled(void) {
#ifdef GHASH_ASM
diff --git a/src/crypto/modes/gcm_test.c b/src/crypto/modes/gcm_test.c
index 9414ac6e..56639e6e 100644
--- a/src/crypto/modes/gcm_test.c
+++ b/src/crypto/modes/gcm_test.c
@@ -282,8 +282,10 @@ static int decode_hex(uint8_t **out, size_t *out_len, const char *in,
uint8_t v, v2;
if (!from_hex(&v, in[i]) ||
!from_hex(&v2, in[i+1])) {
- fprintf(stderr, "%u: invalid hex digit in %s around offset %u.\n",
- test_num, description, (unsigned)i);
+ fprintf(stderr,
+ "%u: invalid hex digit in %s around offset %" OPENSSL_PR_SIZE_T
+ ".\n",
+ test_num, description, i);
goto err;
}
buf[i/2] = (v << 4) | v2;
@@ -336,7 +338,7 @@ static int run_test_case(unsigned test_num, const struct test_case *test) {
}
out = OPENSSL_malloc(plaintext_len);
- if (out == NULL) {
+ if (plaintext_len != 0 && out == NULL) {
goto out;
}
if (AES_set_encrypt_key(key, key_len*8, &aes_key)) {
diff --git a/src/crypto/modes/internal.h b/src/crypto/modes/internal.h
index 7255a7ca..b46e8369 100644
--- a/src/crypto/modes/internal.h
+++ b/src/crypto/modes/internal.h
@@ -179,16 +179,6 @@ struct gcm128_context {
block128_f block;
};
-struct ccm128_context {
- union {
- uint64_t u[2];
- uint8_t c[16];
- } nonce, cmac;
- uint64_t blocks;
- block128_f block;
- void *key;
-};
-
#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
/* crypto_gcm_clmul_enabled returns one if the CLMUL implementation of GCM is
* used. */
@@ -210,7 +200,7 @@ typedef void (*ctr128_f)(const uint8_t *in, uint8_t *out, size_t blocks,
* 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,
+ uint8_t ecount_buf[16], unsigned *num,
block128_f block);
/* CRYPTO_ctr128_encrypt_ctr32 acts like |CRYPTO_ctr128_encrypt| but takes
@@ -219,7 +209,7 @@ void CRYPTO_ctr128_encrypt(const uint8_t *in, uint8_t *out, size_t len,
* 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,
+ uint8_t ecount_buf[16], unsigned *num,
ctr128_f ctr);
@@ -232,11 +222,6 @@ void CRYPTO_ctr128_encrypt_ctr32(const uint8_t *in, uint8_t *out, size_t len,
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,
@@ -297,9 +282,6 @@ OPENSSL_EXPORT int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const uint8_t *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. */
@@ -331,7 +313,7 @@ void CRYPTO_cbc128_decrypt(const uint8_t *in, uint8_t *out, size_t len,
* 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);
+ unsigned *num, block128_f block);
/* CFB. */
@@ -341,21 +323,21 @@ void CRYPTO_ofb128_encrypt(const uint8_t *in, uint8_t *out,
* |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);
+ const void *key, uint8_t ivec[16], unsigned *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,
+ const void *key, uint8_t ivec[16], unsigned *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,
+ const void *key, uint8_t ivec[16], unsigned *num,
int enc, block128_f block);
size_t CRYPTO_cts128_encrypt_block(const uint8_t *in, uint8_t *out, size_t len,
@@ -363,6 +345,12 @@ size_t CRYPTO_cts128_encrypt_block(const uint8_t *in, uint8_t *out, size_t len,
block128_f block);
+#if !defined(OPENSSL_NO_ASM) && \
+ (defined(OPENSSL_X86) || defined(OPENSSL_X86_64))
+void aesni_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t blocks,
+ const void *key, const uint8_t *ivec);
+#endif
+
#if defined(__cplusplus)
} /* extern C */
#endif
diff --git a/src/crypto/modes/ofb.c b/src/crypto/modes/ofb.c
index 63c3165a..2c5bdc9a 100644
--- a/src/crypto/modes/ofb.c
+++ b/src/crypto/modes/ofb.c
@@ -56,13 +56,11 @@
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,
+ const void *key, uint8_t ivec[16], unsigned *num,
block128_f block) {
- unsigned int n;
-
assert(in && out && key && ivec && num);
- n = *num;
+ unsigned n = *num;
while (n && len) {
*(out++) = *(in++) ^ ivec[n];
diff --git a/src/crypto/newhope/CMakeLists.txt b/src/crypto/newhope/CMakeLists.txt
new file mode 100644
index 00000000..385cd6a7
--- /dev/null
+++ b/src/crypto/newhope/CMakeLists.txt
@@ -0,0 +1,22 @@
+add_library(
+ newhope
+
+ OBJECT
+
+ error_correction.c
+ newhope.c
+ ntt.c
+ poly.c
+ precomp.c
+ reduce.c
+)
+
+add_executable(
+ newhope_test
+
+ newhope_test.c
+ $<TARGET_OBJECTS:test_support>
+)
+
+target_link_libraries(newhope_test crypto)
+add_dependencies(all_tests newhope_test)
diff --git a/src/crypto/newhope/error_correction.c b/src/crypto/newhope/error_correction.c
new file mode 100644
index 00000000..e4ac1c26
--- /dev/null
+++ b/src/crypto/newhope/error_correction.c
@@ -0,0 +1,134 @@
+/* Copyright (c) 2016, 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.h>
+
+#include <openssl/base.h>
+#include <openssl/rand.h>
+
+#include "internal.h"
+
+
+/* See paper for details on the error reconciliation */
+
+static int32_t abs_32(int32_t v) {
+ int32_t mask = v >> 31;
+ return (v ^ mask) - mask;
+}
+
+static int32_t f(int32_t* v0, int32_t* v1, int32_t x) {
+ int32_t xit, t, r, b;
+
+ /* Next 6 lines compute t = x/PARAM_Q */
+ b = x * 2730;
+ t = b >> 25;
+ b = x - t * 12289;
+ b = 12288 - b;
+ b >>= 31;
+ t -= b;
+
+ r = t & 1;
+ xit = (t >> 1);
+ *v0 = xit + r; /* v0 = round(x/(2*PARAM_Q)) */
+
+ t -= 1;
+ r = t & 1;
+ *v1 = (t >> 1) + r;
+
+ return abs_32(x - ((*v0) * 2 * PARAM_Q));
+}
+
+static int32_t g(int32_t x) {
+ int32_t t, c, b;
+
+ /* Next 6 lines compute t = x/(4*PARAM_Q); */
+ b = x * 2730;
+ t = b >> 27;
+ b = x - t * 49156;
+ b = 49155 - b;
+ b >>= 31;
+ t -= b;
+
+ c = t & 1;
+ t = (t >> 1) + c; /* t = round(x/(8*PARAM_Q)) */
+
+ t *= 8 * PARAM_Q;
+
+ return abs_32(t - x);
+}
+
+static int16_t LDDecode(int32_t xi0, int32_t xi1, int32_t xi2, int32_t xi3) {
+ int32_t t;
+
+ t = g(xi0);
+ t += g(xi1);
+ t += g(xi2);
+ t += g(xi3);
+
+ t -= 8 * PARAM_Q;
+ t >>= 31;
+ return t & 1;
+}
+
+void newhope_helprec(NEWHOPE_POLY* c, const NEWHOPE_POLY* v) {
+ int32_t v0[4], v1[4], v_tmp[4], k;
+ uint8_t rbit;
+ uint8_t rand[32];
+ unsigned i;
+
+ /* The reference implementation calls ChaCha20 here. */
+ RAND_bytes(rand, sizeof(rand));
+
+ for (i = 0; i < 256; i++) {
+ rbit = (rand[i >> 3] >> (i & 7)) & 1;
+
+ k = f(v0 + 0, v1 + 0, 8 * v->coeffs[0 + i] + 4 * rbit);
+ k += f(v0 + 1, v1 + 1, 8 * v->coeffs[256 + i] + 4 * rbit);
+ k += f(v0 + 2, v1 + 2, 8 * v->coeffs[512 + i] + 4 * rbit);
+ k += f(v0 + 3, v1 + 3, 8 * v->coeffs[768 + i] + 4 * rbit);
+
+ k = (2 * PARAM_Q - 1 - k) >> 31;
+
+ v_tmp[0] = ((~k) & v0[0]) ^ (k & v1[0]);
+ v_tmp[1] = ((~k) & v0[1]) ^ (k & v1[1]);
+ v_tmp[2] = ((~k) & v0[2]) ^ (k & v1[2]);
+ v_tmp[3] = ((~k) & v0[3]) ^ (k & v1[3]);
+
+ c->coeffs[0 + i] = (v_tmp[0] - v_tmp[3]) & 3;
+ c->coeffs[256 + i] = (v_tmp[1] - v_tmp[3]) & 3;
+ c->coeffs[512 + i] = (v_tmp[2] - v_tmp[3]) & 3;
+ c->coeffs[768 + i] = (-k + 2 * v_tmp[3]) & 3;
+ }
+}
+
+void newhope_reconcile(uint8_t* key, const NEWHOPE_POLY* v,
+ const NEWHOPE_POLY* c) {
+ int i;
+ int32_t tmp[4];
+
+ memset(key, 0, KEY_LENGTH);
+
+ for (i = 0; i < 256; i++) {
+ tmp[0] = 16 * PARAM_Q + 8 * (int32_t)v->coeffs[0 + i] -
+ PARAM_Q * (2 * c->coeffs[0 + i] + c->coeffs[768 + i]);
+ tmp[1] = 16 * PARAM_Q + 8 * (int32_t)v->coeffs[256 + i] -
+ PARAM_Q * (2 * c->coeffs[256 + i] + c->coeffs[768 + i]);
+ tmp[2] = 16 * PARAM_Q + 8 * (int32_t)v->coeffs[512 + i] -
+ PARAM_Q * (2 * c->coeffs[512 + i] + c->coeffs[768 + i]);
+ tmp[3] = 16 * PARAM_Q + 8 * (int32_t)v->coeffs[768 + i] -
+ PARAM_Q * (c->coeffs[768 + i]);
+
+ key[i >> 3] |= LDDecode(tmp[0], tmp[1], tmp[2], tmp[3]) << (i & 7);
+ }
+}
diff --git a/src/crypto/newhope/internal.h b/src/crypto/newhope/internal.h
new file mode 100644
index 00000000..a5473d8e
--- /dev/null
+++ b/src/crypto/newhope/internal.h
@@ -0,0 +1,95 @@
+/* Copyright (c) 2016, 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_NEWHOPE_INTERNAL_H
+#define OPENSSL_HEADER_NEWHOPE_INTERNAL_H
+
+#include <openssl/newhope.h>
+#include <openssl/sha.h>
+
+#include "../internal.h"
+
+
+/* The number of polynomial coefficients. */
+#define PARAM_N 1024
+
+/* The width the noise distribution. */
+#define PARAM_K 16
+
+/* Modulus. */
+#define PARAM_Q 12289
+
+/* KEY_LENGTH is the size of the result of the key agreement. This result is
+ * not exposed to callers: instead, it is whitened with SHA-256, whose output
+ * happens to be the same size. */
+#define KEY_LENGTH 32
+
+/* Polynomial coefficients in unpacked form. */
+struct newhope_poly_st {
+ alignas(32) uint16_t coeffs[PARAM_N];
+};
+
+/* The packed form is 14 bits per coefficient, or 1792 bytes. */
+#define POLY_BYTES ((1024 * 14) / 8)
+
+/* SEED_LENGTH is the length of the AES-CTR seed used to derive a polynomial. */
+#define SEED_LENGTH 32
+
+/* newhope_poly_uniform generates the polynomial |a| using AES-CTR mode with the
+ * seed
+ * |seed|. (In the reference implementation this was done with SHAKE-128.) */
+void newhope_poly_uniform(NEWHOPE_POLY* a, const uint8_t* seed);
+
+/* newhope_poly_getnoise sets |r| to a random polynomial where the coefficients
+ * are
+ * sampled from the noise distribution. (In the reference implementation, this
+ * is given a random seed and a nonce.)*/
+void newhope_poly_getnoise(NEWHOPE_POLY* r);
+
+/* newhope_poly_frombytes unpacks the packed polynomial coefficients in |a| into
+ * |r|. */
+void newhope_poly_frombytes(NEWHOPE_POLY* r, const uint8_t* a);
+
+/* newhope_poly_tobytes packs the polynomial |p| into the compact representation
+ * |r|. */
+void newhope_poly_tobytes(uint8_t* r, const NEWHOPE_POLY* p);
+
+void newhope_helprec(NEWHOPE_POLY* c, const NEWHOPE_POLY* v);
+
+/* newhope_reconcile performs the error-reconciliation step using the input |v|
+ * and
+ * reconciliation data |c|, writing the resulting key to |key|. */
+void newhope_reconcile(uint8_t* key, const NEWHOPE_POLY* v,
+ const NEWHOPE_POLY* c);
+
+/* newhope_poly_ntt performs NTT(r) in-place. */
+void newhope_poly_ntt(NEWHOPE_POLY* r);
+
+/* newhope_poly_invntt performs the inverse of NTT(r) in-place. */
+void newhope_poly_invntt(NEWHOPE_POLY* r);
+
+void newhope_poly_add(NEWHOPE_POLY* r, const NEWHOPE_POLY* a,
+ const NEWHOPE_POLY* b);
+void newhope_poly_pointwise(NEWHOPE_POLY* r, const NEWHOPE_POLY* a,
+ const NEWHOPE_POLY* b);
+
+uint16_t newhope_montgomery_reduce(uint32_t a);
+uint16_t newhope_barrett_reduce(uint16_t a);
+
+void newhope_bitrev_vector(uint16_t* poly);
+void newhope_mul_coefficients(uint16_t* poly, const uint16_t* factors);
+void newhope_ntt(uint16_t* poly, const uint16_t* omegas);
+
+
+#endif /* OPENSSL_HEADER_NEWHOPE_INTERNAL_H */
diff --git a/src/crypto/newhope/newhope.c b/src/crypto/newhope/newhope.c
new file mode 100644
index 00000000..29e189f0
--- /dev/null
+++ b/src/crypto/newhope/newhope.c
@@ -0,0 +1,160 @@
+/* Copyright (c) 2016, 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.h>
+
+#include <openssl/mem.h>
+#include <openssl/rand.h>
+
+#include "internal.h"
+
+
+NEWHOPE_POLY *NEWHOPE_POLY_new(void) {
+ return (NEWHOPE_POLY *)OPENSSL_malloc(sizeof(NEWHOPE_POLY));
+}
+
+void NEWHOPE_POLY_free(NEWHOPE_POLY *p) { OPENSSL_free(p); }
+
+/* Encodes reconciliation data from |c| into |r|. */
+static void encode_rec(const NEWHOPE_POLY *c, uint8_t *r) {
+ int i;
+ for (i = 0; i < PARAM_N / 4; i++) {
+ r[i] = c->coeffs[4 * i] | (c->coeffs[4 * i + 1] << 2) |
+ (c->coeffs[4 * i + 2] << 4) | (c->coeffs[4 * i + 3] << 6);
+ }
+}
+
+/* Decodes reconciliation data from |r| into |c|. */
+static void decode_rec(const uint8_t *r, NEWHOPE_POLY *c) {
+ int i;
+ for (i = 0; i < PARAM_N / 4; i++) {
+ c->coeffs[4 * i + 0] = r[i] & 0x03;
+ c->coeffs[4 * i + 1] = (r[i] >> 2) & 0x03;
+ c->coeffs[4 * i + 2] = (r[i] >> 4) & 0x03;
+ c->coeffs[4 * i + 3] = (r[i] >> 6);
+ }
+}
+
+void NEWHOPE_keygen(uint8_t *servermsg, NEWHOPE_POLY *sk) {
+ newhope_poly_getnoise(sk);
+ newhope_poly_ntt(sk);
+
+ /* The first part of the server's message is the seed, which compactly encodes
+ * a. */
+ NEWHOPE_POLY a;
+ uint8_t *seed = &servermsg[POLY_BYTES];
+ RAND_bytes(seed, SEED_LENGTH);
+ newhope_poly_uniform(&a, seed);
+
+ NEWHOPE_POLY e;
+ newhope_poly_getnoise(&e);
+ newhope_poly_ntt(&e);
+
+ /* The second part of the server's message is the polynomial pk = a*sk+e */
+ NEWHOPE_POLY r, pk;
+ newhope_poly_pointwise(&r, sk, &a);
+ newhope_poly_add(&pk, &e, &r);
+ newhope_poly_tobytes(servermsg, &pk);
+}
+
+int NEWHOPE_client_compute_key(
+ uint8_t key[SHA256_DIGEST_LENGTH],
+ uint8_t clientmsg[NEWHOPE_CLIENTMSG_LENGTH],
+ const uint8_t servermsg[NEWHOPE_SERVERMSG_LENGTH], size_t msg_len) {
+ if (msg_len != NEWHOPE_SERVERMSG_LENGTH) {
+ return 0;
+ }
+
+ NEWHOPE_POLY sp;
+ newhope_poly_getnoise(&sp);
+ newhope_poly_ntt(&sp);
+
+ /* The first part of the client's message is the polynomial bp=e'+a*s' */
+ {
+ NEWHOPE_POLY ep;
+ newhope_poly_getnoise(&ep);
+ newhope_poly_ntt(&ep);
+
+ /* Generate the same |a| as the server, from the server's seed. */
+ NEWHOPE_POLY a;
+ const uint8_t *seed = &servermsg[POLY_BYTES];
+ newhope_poly_uniform(&a, seed);
+
+ NEWHOPE_POLY bp;
+ newhope_poly_pointwise(&bp, &a, &sp);
+ newhope_poly_add(&bp, &bp, &ep);
+ newhope_poly_tobytes(clientmsg, &bp);
+ }
+
+ /* v = pk * s' + e'' */
+ NEWHOPE_POLY v;
+ {
+ NEWHOPE_POLY pk;
+ newhope_poly_frombytes(&pk, servermsg);
+
+ NEWHOPE_POLY epp;
+ newhope_poly_getnoise(&epp);
+
+ newhope_poly_pointwise(&v, &pk, &sp);
+ newhope_poly_invntt(&v);
+ newhope_poly_add(&v, &v, &epp);
+ }
+
+ /* The second part of the client's message is the reconciliation data derived
+ * from v. */
+ NEWHOPE_POLY c;
+ uint8_t *reconciliation = &clientmsg[POLY_BYTES];
+ newhope_helprec(&c, &v);
+ encode_rec(&c, reconciliation);
+
+ uint8_t k[KEY_LENGTH];
+ newhope_reconcile(k, &v, &c);
+ SHA256_CTX ctx;
+ if (!SHA256_Init(&ctx) ||
+ !SHA256_Update(&ctx, k, KEY_LENGTH) ||
+ !SHA256_Final(key, &ctx)) {
+ return 0;
+ }
+
+ return 1;
+}
+
+int NEWHOPE_server_compute_key(
+ uint8_t key[SHA256_DIGEST_LENGTH], const NEWHOPE_POLY *sk,
+ const uint8_t clientmsg[NEWHOPE_CLIENTMSG_LENGTH], size_t msg_len) {
+ if (msg_len != NEWHOPE_CLIENTMSG_LENGTH) {
+ return 0;
+ }
+ NEWHOPE_POLY bp;
+ newhope_poly_frombytes(&bp, clientmsg);
+
+ NEWHOPE_POLY v;
+ newhope_poly_pointwise(&v, sk, &bp);
+ newhope_poly_invntt(&v);
+
+ NEWHOPE_POLY c;
+ const uint8_t *reconciliation = &clientmsg[POLY_BYTES];
+ decode_rec(reconciliation, &c);
+
+ uint8_t k[KEY_LENGTH];
+ newhope_reconcile(k, &v, &c);
+ SHA256_CTX ctx;
+ if (!SHA256_Init(&ctx) ||
+ !SHA256_Update(&ctx, k, KEY_LENGTH) ||
+ !SHA256_Final(key, &ctx)) {
+ return 0;
+ }
+
+ return 1;
+}
diff --git a/src/crypto/newhope/newhope_test.c b/src/crypto/newhope/newhope_test.c
new file mode 100644
index 00000000..5d960072
--- /dev/null
+++ b/src/crypto/newhope/newhope_test.c
@@ -0,0 +1,144 @@
+/* Copyright (c) 2016, 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 <math.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <openssl/crypto.h>
+#include <openssl/rand.h>
+
+#include "internal.h"
+
+
+#define NTESTS 1000
+
+static int test_keys(void) {
+ NEWHOPE_POLY *sk = NEWHOPE_POLY_new();
+ uint8_t server_key[SHA256_DIGEST_LENGTH], client_key[SHA256_DIGEST_LENGTH];
+ uint8_t servermsg[NEWHOPE_SERVERMSG_LENGTH];
+ uint8_t clientmsg[NEWHOPE_CLIENTMSG_LENGTH];
+ int i;
+
+ for (i = 0; i < NTESTS; i++) {
+ /* Alice generates a public key */
+ NEWHOPE_keygen(servermsg, sk);
+
+ /* Bob derives a secret key and creates a response */
+ if (!NEWHOPE_client_compute_key(client_key, clientmsg, servermsg,
+ sizeof(servermsg))) {
+ fprintf(stderr, "ERROR client key exchange failed\n");
+ return 0;
+ }
+
+ /* Alice uses Bob's response to get her secret key */
+ if (!NEWHOPE_server_compute_key(server_key, sk, clientmsg,
+ sizeof(clientmsg))) {
+ fprintf(stderr, "ERROR server key exchange failed\n");
+ return 0;
+ }
+
+ if (memcmp(server_key, client_key, SHA256_DIGEST_LENGTH) != 0) {
+ fprintf(stderr, "ERROR keys did not agree\n");
+ return 0;
+ }
+ }
+
+ NEWHOPE_POLY_free(sk);
+ return 1;
+}
+
+static int test_invalid_sk_a(void) {
+ NEWHOPE_POLY *sk = NEWHOPE_POLY_new();
+ uint8_t server_key[SHA256_DIGEST_LENGTH], client_key[SHA256_DIGEST_LENGTH];
+ uint8_t servermsg[NEWHOPE_SERVERMSG_LENGTH];
+ uint8_t clientmsg[NEWHOPE_CLIENTMSG_LENGTH];
+ int i;
+
+ for (i = 0; i < NTESTS; i++) {
+ /* Alice generates a public key */
+ NEWHOPE_keygen(servermsg, sk);
+
+ /* Bob derives a secret key and creates a response */
+ if (!NEWHOPE_client_compute_key(client_key, clientmsg, servermsg,
+ sizeof(servermsg))) {
+ fprintf(stderr, "ERROR client key exchange failed\n");
+ return 0;
+ }
+
+ /* Corrupt the secret key */
+ NEWHOPE_keygen(servermsg /* not used below */, sk);
+
+ /* Alice uses Bob's response to get her secret key */
+ if (!NEWHOPE_server_compute_key(server_key, sk, clientmsg,
+ sizeof(clientmsg))) {
+ fprintf(stderr, "ERROR server key exchange failed\n");
+ return 0;
+ }
+
+ if (memcmp(server_key, client_key, SHA256_DIGEST_LENGTH) == 0) {
+ fprintf(stderr, "ERROR invalid sk_a\n");
+ return 0;
+ }
+ }
+
+ NEWHOPE_POLY_free(sk);
+ return 1;
+}
+
+static int test_invalid_ciphertext(void) {
+ NEWHOPE_POLY *sk = NEWHOPE_POLY_new();
+ uint8_t server_key[SHA256_DIGEST_LENGTH], client_key[SHA256_DIGEST_LENGTH];
+ uint8_t servermsg[NEWHOPE_SERVERMSG_LENGTH];
+ uint8_t clientmsg[NEWHOPE_CLIENTMSG_LENGTH];
+ int i;
+
+ for (i = 0; i < 10; i++) {
+ /* Alice generates a public key */
+ NEWHOPE_keygen(servermsg, sk);
+
+ /* Bob derives a secret key and creates a response */
+ if (!NEWHOPE_client_compute_key(client_key, clientmsg, servermsg,
+ sizeof(servermsg))) {
+ fprintf(stderr, "ERROR client key exchange failed\n");
+ return 0;
+ }
+
+ /* Change some byte in the "ciphertext" */
+ clientmsg[42] ^= 1;
+
+ /* Alice uses Bob's response to get her secret key */
+ if (!NEWHOPE_server_compute_key(server_key, sk, clientmsg,
+ sizeof(clientmsg))) {
+ fprintf(stderr, "ERROR server key exchange failed\n");
+ return 0;
+ }
+
+ if (!memcmp(server_key, client_key, SHA256_DIGEST_LENGTH)) {
+ fprintf(stderr, "ERROR invalid clientmsg\n");
+ return 0;
+ }
+ }
+
+ NEWHOPE_POLY_free(sk);
+ return 1;
+}
+
+int main(void) {
+ if (!test_keys() || !test_invalid_sk_a() || !test_invalid_ciphertext()) {
+ return 1;
+ }
+ printf("PASS\n");
+ return 0;
+}
diff --git a/src/crypto/newhope/ntt.c b/src/crypto/newhope/ntt.c
new file mode 100644
index 00000000..163a9d1a
--- /dev/null
+++ b/src/crypto/newhope/ntt.c
@@ -0,0 +1,148 @@
+/* Copyright (c) 2016, 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 "internal.h"
+
+
+static uint16_t bitrev_table[1024] = {
+ 0, 512, 256, 768, 128, 640, 384, 896, 64, 576, 320, 832, 192, 704,
+ 448, 960, 32, 544, 288, 800, 160, 672, 416, 928, 96, 608, 352, 864,
+ 224, 736, 480, 992, 16, 528, 272, 784, 144, 656, 400, 912, 80, 592,
+ 336, 848, 208, 720, 464, 976, 48, 560, 304, 816, 176, 688, 432, 944,
+ 112, 624, 368, 880, 240, 752, 496, 1008, 8, 520, 264, 776, 136, 648,
+ 392, 904, 72, 584, 328, 840, 200, 712, 456, 968, 40, 552, 296, 808,
+ 168, 680, 424, 936, 104, 616, 360, 872, 232, 744, 488, 1000, 24, 536,
+ 280, 792, 152, 664, 408, 920, 88, 600, 344, 856, 216, 728, 472, 984,
+ 56, 568, 312, 824, 184, 696, 440, 952, 120, 632, 376, 888, 248, 760,
+ 504, 1016, 4, 516, 260, 772, 132, 644, 388, 900, 68, 580, 324, 836,
+ 196, 708, 452, 964, 36, 548, 292, 804, 164, 676, 420, 932, 100, 612,
+ 356, 868, 228, 740, 484, 996, 20, 532, 276, 788, 148, 660, 404, 916,
+ 84, 596, 340, 852, 212, 724, 468, 980, 52, 564, 308, 820, 180, 692,
+ 436, 948, 116, 628, 372, 884, 244, 756, 500, 1012, 12, 524, 268, 780,
+ 140, 652, 396, 908, 76, 588, 332, 844, 204, 716, 460, 972, 44, 556,
+ 300, 812, 172, 684, 428, 940, 108, 620, 364, 876, 236, 748, 492, 1004,
+ 28, 540, 284, 796, 156, 668, 412, 924, 92, 604, 348, 860, 220, 732,
+ 476, 988, 60, 572, 316, 828, 188, 700, 444, 956, 124, 636, 380, 892,
+ 252, 764, 508, 1020, 2, 514, 258, 770, 130, 642, 386, 898, 66, 578,
+ 322, 834, 194, 706, 450, 962, 34, 546, 290, 802, 162, 674, 418, 930,
+ 98, 610, 354, 866, 226, 738, 482, 994, 18, 530, 274, 786, 146, 658,
+ 402, 914, 82, 594, 338, 850, 210, 722, 466, 978, 50, 562, 306, 818,
+ 178, 690, 434, 946, 114, 626, 370, 882, 242, 754, 498, 1010, 10, 522,
+ 266, 778, 138, 650, 394, 906, 74, 586, 330, 842, 202, 714, 458, 970,
+ 42, 554, 298, 810, 170, 682, 426, 938, 106, 618, 362, 874, 234, 746,
+ 490, 1002, 26, 538, 282, 794, 154, 666, 410, 922, 90, 602, 346, 858,
+ 218, 730, 474, 986, 58, 570, 314, 826, 186, 698, 442, 954, 122, 634,
+ 378, 890, 250, 762, 506, 1018, 6, 518, 262, 774, 134, 646, 390, 902,
+ 70, 582, 326, 838, 198, 710, 454, 966, 38, 550, 294, 806, 166, 678,
+ 422, 934, 102, 614, 358, 870, 230, 742, 486, 998, 22, 534, 278, 790,
+ 150, 662, 406, 918, 86, 598, 342, 854, 214, 726, 470, 982, 54, 566,
+ 310, 822, 182, 694, 438, 950, 118, 630, 374, 886, 246, 758, 502, 1014,
+ 14, 526, 270, 782, 142, 654, 398, 910, 78, 590, 334, 846, 206, 718,
+ 462, 974, 46, 558, 302, 814, 174, 686, 430, 942, 110, 622, 366, 878,
+ 238, 750, 494, 1006, 30, 542, 286, 798, 158, 670, 414, 926, 94, 606,
+ 350, 862, 222, 734, 478, 990, 62, 574, 318, 830, 190, 702, 446, 958,
+ 126, 638, 382, 894, 254, 766, 510, 1022, 1, 513, 257, 769, 129, 641,
+ 385, 897, 65, 577, 321, 833, 193, 705, 449, 961, 33, 545, 289, 801,
+ 161, 673, 417, 929, 97, 609, 353, 865, 225, 737, 481, 993, 17, 529,
+ 273, 785, 145, 657, 401, 913, 81, 593, 337, 849, 209, 721, 465, 977,
+ 49, 561, 305, 817, 177, 689, 433, 945, 113, 625, 369, 881, 241, 753,
+ 497, 1009, 9, 521, 265, 777, 137, 649, 393, 905, 73, 585, 329, 841,
+ 201, 713, 457, 969, 41, 553, 297, 809, 169, 681, 425, 937, 105, 617,
+ 361, 873, 233, 745, 489, 1001, 25, 537, 281, 793, 153, 665, 409, 921,
+ 89, 601, 345, 857, 217, 729, 473, 985, 57, 569, 313, 825, 185, 697,
+ 441, 953, 121, 633, 377, 889, 249, 761, 505, 1017, 5, 517, 261, 773,
+ 133, 645, 389, 901, 69, 581, 325, 837, 197, 709, 453, 965, 37, 549,
+ 293, 805, 165, 677, 421, 933, 101, 613, 357, 869, 229, 741, 485, 997,
+ 21, 533, 277, 789, 149, 661, 405, 917, 85, 597, 341, 853, 213, 725,
+ 469, 981, 53, 565, 309, 821, 181, 693, 437, 949, 117, 629, 373, 885,
+ 245, 757, 501, 1013, 13, 525, 269, 781, 141, 653, 397, 909, 77, 589,
+ 333, 845, 205, 717, 461, 973, 45, 557, 301, 813, 173, 685, 429, 941,
+ 109, 621, 365, 877, 237, 749, 493, 1005, 29, 541, 285, 797, 157, 669,
+ 413, 925, 93, 605, 349, 861, 221, 733, 477, 989, 61, 573, 317, 829,
+ 189, 701, 445, 957, 125, 637, 381, 893, 253, 765, 509, 1021, 3, 515,
+ 259, 771, 131, 643, 387, 899, 67, 579, 323, 835, 195, 707, 451, 963,
+ 35, 547, 291, 803, 163, 675, 419, 931, 99, 611, 355, 867, 227, 739,
+ 483, 995, 19, 531, 275, 787, 147, 659, 403, 915, 83, 595, 339, 851,
+ 211, 723, 467, 979, 51, 563, 307, 819, 179, 691, 435, 947, 115, 627,
+ 371, 883, 243, 755, 499, 1011, 11, 523, 267, 779, 139, 651, 395, 907,
+ 75, 587, 331, 843, 203, 715, 459, 971, 43, 555, 299, 811, 171, 683,
+ 427, 939, 107, 619, 363, 875, 235, 747, 491, 1003, 27, 539, 283, 795,
+ 155, 667, 411, 923, 91, 603, 347, 859, 219, 731, 475, 987, 59, 571,
+ 315, 827, 187, 699, 443, 955, 123, 635, 379, 891, 251, 763, 507, 1019,
+ 7, 519, 263, 775, 135, 647, 391, 903, 71, 583, 327, 839, 199, 711,
+ 455, 967, 39, 551, 295, 807, 167, 679, 423, 935, 103, 615, 359, 871,
+ 231, 743, 487, 999, 23, 535, 279, 791, 151, 663, 407, 919, 87, 599,
+ 343, 855, 215, 727, 471, 983, 55, 567, 311, 823, 183, 695, 439, 951,
+ 119, 631, 375, 887, 247, 759, 503, 1015, 15, 527, 271, 783, 143, 655,
+ 399, 911, 79, 591, 335, 847, 207, 719, 463, 975, 47, 559, 303, 815,
+ 175, 687, 431, 943, 111, 623, 367, 879, 239, 751, 495, 1007, 31, 543,
+ 287, 799, 159, 671, 415, 927, 95, 607, 351, 863, 223, 735, 479, 991,
+ 63, 575, 319, 831, 191, 703, 447, 959, 127, 639, 383, 895, 255, 767,
+ 511, 1023};
+
+void newhope_bitrev_vector(uint16_t* poly) {
+ unsigned int i, r;
+ uint16_t tmp;
+
+ for (i = 0; i < PARAM_N; i++) {
+ r = bitrev_table[i];
+ if (i < r) {
+ tmp = poly[i];
+ poly[i] = poly[r];
+ poly[r] = tmp;
+ }
+ }
+}
+
+void newhope_mul_coefficients(uint16_t* poly, const uint16_t* factors) {
+ unsigned int i;
+
+ for (i = 0; i < PARAM_N; i++) {
+ poly[i] = newhope_montgomery_reduce((poly[i] * factors[i]));
+ }
+}
+
+/* GS_bo_to_no; omegas need to be in Montgomery domain */
+void newhope_ntt(uint16_t* a, const uint16_t* omega) {
+ int i, start, j, jTwiddle, distance;
+ uint16_t temp, W;
+
+ for (i = 0; i < 10; i += 2) {
+ /* Even level */
+ distance = (1 << i);
+ for (start = 0; start < distance; start++) {
+ jTwiddle = 0;
+ for (j = start; j < PARAM_N - 1; j += 2 * distance) {
+ W = omega[jTwiddle++];
+ temp = a[j];
+ a[j] = (temp + a[j + distance]); /* Omit reduction (be lazy) */
+ a[j + distance] = newhope_montgomery_reduce(
+ (W * ((uint32_t)temp + 3 * PARAM_Q - a[j + distance])));
+ }
+ }
+
+ /* Odd level */
+ distance <<= 1;
+ for (start = 0; start < distance; start++) {
+ jTwiddle = 0;
+ for (j = start; j < PARAM_N - 1; j += 2 * distance) {
+ W = omega[jTwiddle++];
+ temp = a[j];
+ a[j] = newhope_barrett_reduce((temp + a[j + distance]));
+ a[j + distance] = newhope_montgomery_reduce(
+ (W * ((uint32_t)temp + 3 * PARAM_Q - a[j + distance])));
+ }
+ }
+ }
+}
diff --git a/src/crypto/newhope/poly.c b/src/crypto/newhope/poly.c
new file mode 100644
index 00000000..a9839faf
--- /dev/null
+++ b/src/crypto/newhope/poly.c
@@ -0,0 +1,183 @@
+/* Copyright (c) 2016, 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 <assert.h>
+#include <string.h>
+
+#include <openssl/aes.h>
+#include <openssl/rand.h>
+
+#include "internal.h"
+
+
+extern uint16_t newhope_omegas_montgomery[];
+extern uint16_t newhope_omegas_inv_montgomery[];
+
+extern uint16_t newhope_psis_bitrev_montgomery[];
+extern uint16_t newhope_psis_inv_montgomery[];
+
+void newhope_poly_frombytes(NEWHOPE_POLY* r, const uint8_t* a) {
+ int i;
+ for (i = 0; i < PARAM_N / 4; i++) {
+ r->coeffs[4 * i + 0] =
+ a[7 * i + 0] | (((uint16_t)a[7 * i + 1] & 0x3f) << 8);
+ r->coeffs[4 * i + 1] = (a[7 * i + 1] >> 6) |
+ (((uint16_t)a[7 * i + 2]) << 2) |
+ (((uint16_t)a[7 * i + 3] & 0x0f) << 10);
+ r->coeffs[4 * i + 2] = (a[7 * i + 3] >> 4) |
+ (((uint16_t)a[7 * i + 4]) << 4) |
+ (((uint16_t)a[7 * i + 5] & 0x03) << 12);
+ r->coeffs[4 * i + 3] =
+ (a[7 * i + 5] >> 2) | (((uint16_t)a[7 * i + 6]) << 6);
+ }
+}
+
+void newhope_poly_tobytes(uint8_t* r, const NEWHOPE_POLY* p) {
+ int i;
+ uint16_t t0, t1, t2, t3, m;
+ int16_t c;
+ for (i = 0; i < PARAM_N / 4; i++) {
+ t0 = newhope_barrett_reduce(
+ p->coeffs[4 * i + 0]); /* Make sure that coefficients
+ have only 14 bits */
+ t1 = newhope_barrett_reduce(p->coeffs[4 * i + 1]);
+ t2 = newhope_barrett_reduce(p->coeffs[4 * i + 2]);
+ t3 = newhope_barrett_reduce(p->coeffs[4 * i + 3]);
+
+ m = t0 - PARAM_Q;
+ c = m;
+ c >>= 15;
+ t0 = m ^ ((t0 ^ m) & c); /* Make sure that coefficients are in [0,q] */
+
+ m = t1 - PARAM_Q;
+ c = m;
+ c >>= 15;
+ t1 = m ^ ((t1 ^ m) & c); /* <Make sure that coefficients are in [0,q] */
+
+ m = t2 - PARAM_Q;
+ c = m;
+ c >>= 15;
+ t2 = m ^ ((t2 ^ m) & c); /* <Make sure that coefficients are in [0,q] */
+
+ m = t3 - PARAM_Q;
+ c = m;
+ c >>= 15;
+ t3 = m ^ ((t3 ^ m) & c); /* Make sure that coefficients are in [0,q] */
+
+ r[7 * i + 0] = t0 & 0xff;
+ r[7 * i + 1] = (t0 >> 8) | (t1 << 6);
+ r[7 * i + 2] = (t1 >> 2);
+ r[7 * i + 3] = (t1 >> 10) | (t2 << 4);
+ r[7 * i + 4] = (t2 >> 4);
+ r[7 * i + 5] = (t2 >> 12) | (t3 << 2);
+ r[7 * i + 6] = (t3 >> 6);
+ }
+}
+
+void newhope_poly_uniform(NEWHOPE_POLY* a, const uint8_t* seed) {
+/* The reference implementation uses SHAKE-128 here; this implementation uses
+ * AES-CTR. Use half the seed for the initialization vector and half for the
+ * key. */
+#if SEED_LENGTH != 2 * AES_BLOCK_SIZE
+#error "2 * seed length != AES_BLOCK_SIZE"
+#endif
+ uint8_t ivec[AES_BLOCK_SIZE];
+ memcpy(ivec, &seed[SEED_LENGTH / 2], SEED_LENGTH / 2);
+ AES_KEY key;
+ AES_set_encrypt_key(seed, 8 * SEED_LENGTH / 2, &key);
+
+ /* AES state. */
+ uint8_t ecount[AES_BLOCK_SIZE];
+ memset(ecount, 0, AES_BLOCK_SIZE);
+
+ /* Encrypt a block of zeros just to get the random bytes. With luck, 2688
+ * bytes is enough. */
+ uint8_t buf[AES_BLOCK_SIZE * 168];
+ memset(buf, 0, sizeof(buf));
+
+ unsigned int block_num = 0;
+ AES_ctr128_encrypt(buf, buf, sizeof(buf), &key, ivec, ecount, &block_num);
+
+ size_t pos = 0, coeff_num = 0;
+ while (coeff_num < PARAM_N) {
+ /* Specialized for q = 12889 */
+ uint16_t val = (buf[pos] | ((uint16_t)buf[pos + 1] << 8)) & 0x3fff;
+ if (val < PARAM_Q) {
+ a->coeffs[coeff_num++] = val;
+ }
+
+ pos += 2;
+ if (pos > sizeof(buf) - 2) {
+ memset(buf, 0, sizeof(buf));
+ AES_ctr128_encrypt(buf, buf, sizeof(buf), &key, ivec, ecount, &block_num);
+ pos = 0;
+ }
+ }
+}
+
+void newhope_poly_getnoise(NEWHOPE_POLY* r) {
+#if PARAM_K != 16
+#error "poly_getnoise in poly.c only supports k=16"
+#endif
+
+ uint32_t tp[PARAM_N];
+
+ /* The reference implementation calls ChaCha20 here. */
+ RAND_bytes((uint8_t *) tp, sizeof(tp));
+
+ size_t i;
+ for (i = 0; i < PARAM_N; i++) {
+ const uint32_t t = tp[i];
+
+ size_t j;
+ uint32_t d = 0;
+ for (j = 0; j < 8; j++) {
+ d += (t >> j) & 0x01010101;
+ }
+
+ const uint32_t a = ((d >> 8) & 0xff) + (d & 0xff);
+ const uint32_t b = (d >> 24) + ((d >> 16) & 0xff);
+ r->coeffs[i] = a + PARAM_Q - b;
+ }
+}
+
+void newhope_poly_pointwise(NEWHOPE_POLY* r, const NEWHOPE_POLY* a,
+ const NEWHOPE_POLY* b) {
+ size_t i;
+ for (i = 0; i < PARAM_N; i++) {
+ uint16_t t = newhope_montgomery_reduce(3186 * b->coeffs[i]);
+ /* t is now in Montgomery domain */
+ r->coeffs[i] = newhope_montgomery_reduce(a->coeffs[i] * t);
+ /* r->coeffs[i] is back in normal domain */
+ }
+}
+
+void newhope_poly_add(NEWHOPE_POLY* r, const NEWHOPE_POLY* a,
+ const NEWHOPE_POLY* b) {
+ size_t i;
+ for (i = 0; i < PARAM_N; i++) {
+ r->coeffs[i] = newhope_barrett_reduce(a->coeffs[i] + b->coeffs[i]);
+ }
+}
+
+void newhope_poly_ntt(NEWHOPE_POLY* r) {
+ newhope_mul_coefficients(r->coeffs, newhope_psis_bitrev_montgomery);
+ newhope_ntt((uint16_t *) r->coeffs, newhope_omegas_montgomery);
+}
+
+void newhope_poly_invntt(NEWHOPE_POLY* r) {
+ newhope_bitrev_vector(r->coeffs);
+ newhope_ntt((uint16_t *) r->coeffs, newhope_omegas_inv_montgomery);
+ newhope_mul_coefficients(r->coeffs, newhope_psis_inv_montgomery);
+}
diff --git a/src/crypto/newhope/precomp.c b/src/crypto/newhope/precomp.c
new file mode 100644
index 00000000..d0c478ee
--- /dev/null
+++ b/src/crypto/newhope/precomp.c
@@ -0,0 +1,306 @@
+/* Copyright (c) 2016, 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 "internal.h"
+
+
+uint16_t newhope_omegas_montgomery[PARAM_N / 2] = {
+ 4075, 6974, 7373, 7965, 3262, 5079, 522, 2169, 6364, 1018, 1041,
+ 8775, 2344, 11011, 5574, 1973, 4536, 1050, 6844, 3860, 3818, 6118,
+ 2683, 1190, 4789, 7822, 7540, 6752, 5456, 4449, 3789, 12142, 11973,
+ 382, 3988, 468, 6843, 5339, 6196, 3710, 11316, 1254, 5435, 10930,
+ 3998, 10256, 10367, 3879, 11889, 1728, 6137, 4948, 5862, 6136, 3643,
+ 6874, 8724, 654, 10302, 1702, 7083, 6760, 56, 3199, 9987, 605,
+ 11785, 8076, 5594, 9260, 6403, 4782, 6212, 4624, 9026, 8689, 4080,
+ 11868, 6221, 3602, 975, 8077, 8851, 9445, 5681, 3477, 1105, 142,
+ 241, 12231, 1003, 3532, 5009, 1956, 6008, 11404, 7377, 2049, 10968,
+ 12097, 7591, 5057, 3445, 4780, 2920, 7048, 3127, 8120, 11279, 6821,
+ 11502, 8807, 12138, 2127, 2839, 3957, 431, 1579, 6383, 9784, 5874,
+ 677, 3336, 6234, 2766, 1323, 9115, 12237, 2031, 6956, 6413, 2281,
+ 3969, 3991, 12133, 9522, 4737, 10996, 4774, 5429, 11871, 3772, 453,
+ 5908, 2882, 1805, 2051, 1954, 11713, 3963, 2447, 6142, 8174, 3030,
+ 1843, 2361, 12071, 2908, 3529, 3434, 3202, 7796, 2057, 5369, 11939,
+ 1512, 6906, 10474, 11026, 49, 10806, 5915, 1489, 9789, 5942, 10706,
+ 10431, 7535, 426, 8974, 3757, 10314, 9364, 347, 5868, 9551, 9634,
+ 6554, 10596, 9280, 11566, 174, 2948, 2503, 6507, 10723, 11606, 2459,
+ 64, 3656, 8455, 5257, 5919, 7856, 1747, 9166, 5486, 9235, 6065,
+ 835, 3570, 4240, 11580, 4046, 10970, 9139, 1058, 8210, 11848, 922,
+ 7967, 1958, 10211, 1112, 3728, 4049, 11130, 5990, 1404, 325, 948,
+ 11143, 6190, 295, 11637, 5766, 8212, 8273, 2919, 8527, 6119, 6992,
+ 8333, 1360, 2555, 6167, 1200, 7105, 7991, 3329, 9597, 12121, 5106,
+ 5961, 10695, 10327, 3051, 9923, 4896, 9326, 81, 3091, 1000, 7969,
+ 4611, 726, 1853, 12149, 4255, 11112, 2768, 10654, 1062, 2294, 3553,
+ 4805, 2747, 4846, 8577, 9154, 1170, 2319, 790, 11334, 9275, 9088,
+ 1326, 5086, 9094, 6429, 11077, 10643, 3504, 3542, 8668, 9744, 1479,
+ 1, 8246, 7143, 11567, 10984, 4134, 5736, 4978, 10938, 5777, 8961,
+ 4591, 5728, 6461, 5023, 9650, 7468, 949, 9664, 2975, 11726, 2744,
+ 9283, 10092, 5067, 12171, 2476, 3748, 11336, 6522, 827, 9452, 5374,
+ 12159, 7935, 3296, 3949, 9893, 4452, 10908, 2525, 3584, 8112, 8011,
+ 10616, 4989, 6958, 11809, 9447, 12280, 1022, 11950, 9821, 11745, 5791,
+ 5092, 2089, 9005, 2881, 3289, 2013, 9048, 729, 7901, 1260, 5755,
+ 4632, 11955, 2426, 10593, 1428, 4890, 5911, 3932, 9558, 8830, 3637,
+ 5542, 145, 5179, 8595, 3707, 10530, 355, 3382, 4231, 9741, 1207,
+ 9041, 7012, 1168, 10146, 11224, 4645, 11885, 10911, 10377, 435, 7952,
+ 4096, 493, 9908, 6845, 6039, 2422, 2187, 9723, 8643, 9852, 9302,
+ 6022, 7278, 1002, 4284, 5088, 1607, 7313, 875, 8509, 9430, 1045,
+ 2481, 5012, 7428, 354, 6591, 9377, 11847, 2401, 1067, 7188, 11516,
+ 390, 8511, 8456, 7270, 545, 8585, 9611, 12047, 1537, 4143, 4714,
+ 4885, 1017, 5084, 1632, 3066, 27, 1440, 8526, 9273, 12046, 11618,
+ 9289, 3400, 9890, 3136, 7098, 8758, 11813, 7384, 3985, 11869, 6730,
+ 10745, 10111, 2249, 4048, 2884, 11136, 2126, 1630, 9103, 5407, 2686,
+ 9042, 2969, 8311, 9424, 9919, 8779, 5332, 10626, 1777, 4654, 10863,
+ 7351, 3636, 9585, 5291, 8374, 2166, 4919, 12176, 9140, 12129, 7852,
+ 12286, 4895, 10805, 2780, 5195, 2305, 7247, 9644, 4053, 10600, 3364,
+ 3271, 4057, 4414, 9442, 7917, 2174};
+
+uint16_t newhope_omegas_inv_montgomery[PARAM_N / 2] = {
+ 4075, 5315, 4324, 4916, 10120, 11767, 7210, 9027, 10316, 6715, 1278,
+ 9945, 3514, 11248, 11271, 5925, 147, 8500, 7840, 6833, 5537, 4749,
+ 4467, 7500, 11099, 9606, 6171, 8471, 8429, 5445, 11239, 7753, 9090,
+ 12233, 5529, 5206, 10587, 1987, 11635, 3565, 5415, 8646, 6153, 6427,
+ 7341, 6152, 10561, 400, 8410, 1922, 2033, 8291, 1359, 6854, 11035,
+ 973, 8579, 6093, 6950, 5446, 11821, 8301, 11907, 316, 52, 3174,
+ 10966, 9523, 6055, 8953, 11612, 6415, 2505, 5906, 10710, 11858, 8332,
+ 9450, 10162, 151, 3482, 787, 5468, 1010, 4169, 9162, 5241, 9369,
+ 7509, 8844, 7232, 4698, 192, 1321, 10240, 4912, 885, 6281, 10333,
+ 7280, 8757, 11286, 58, 12048, 12147, 11184, 8812, 6608, 2844, 3438,
+ 4212, 11314, 8687, 6068, 421, 8209, 3600, 3263, 7665, 6077, 7507,
+ 5886, 3029, 6695, 4213, 504, 11684, 2302, 1962, 1594, 6328, 7183,
+ 168, 2692, 8960, 4298, 5184, 11089, 6122, 9734, 10929, 3956, 5297,
+ 6170, 3762, 9370, 4016, 4077, 6523, 652, 11994, 6099, 1146, 11341,
+ 11964, 10885, 6299, 1159, 8240, 8561, 11177, 2078, 10331, 4322, 11367,
+ 441, 4079, 11231, 3150, 1319, 8243, 709, 8049, 8719, 11454, 6224,
+ 3054, 6803, 3123, 10542, 4433, 6370, 7032, 3834, 8633, 12225, 9830,
+ 683, 1566, 5782, 9786, 9341, 12115, 723, 3009, 1693, 5735, 2655,
+ 2738, 6421, 11942, 2925, 1975, 8532, 3315, 11863, 4754, 1858, 1583,
+ 6347, 2500, 10800, 6374, 1483, 12240, 1263, 1815, 5383, 10777, 350,
+ 6920, 10232, 4493, 9087, 8855, 8760, 9381, 218, 9928, 10446, 9259,
+ 4115, 6147, 9842, 8326, 576, 10335, 10238, 10484, 9407, 6381, 11836,
+ 8517, 418, 6860, 7515, 1293, 7552, 2767, 156, 8298, 8320, 10008,
+ 5876, 5333, 10258, 10115, 4372, 2847, 7875, 8232, 9018, 8925, 1689,
+ 8236, 2645, 5042, 9984, 7094, 9509, 1484, 7394, 3, 4437, 160,
+ 3149, 113, 7370, 10123, 3915, 6998, 2704, 8653, 4938, 1426, 7635,
+ 10512, 1663, 6957, 3510, 2370, 2865, 3978, 9320, 3247, 9603, 6882,
+ 3186, 10659, 10163, 1153, 9405, 8241, 10040, 2178, 1544, 5559, 420,
+ 8304, 4905, 476, 3531, 5191, 9153, 2399, 8889, 3000, 671, 243,
+ 3016, 3763, 10849, 12262, 9223, 10657, 7205, 11272, 7404, 7575, 8146,
+ 10752, 242, 2678, 3704, 11744, 5019, 3833, 3778, 11899, 773, 5101,
+ 11222, 9888, 442, 2912, 5698, 11935, 4861, 7277, 9808, 11244, 2859,
+ 3780, 11414, 4976, 10682, 7201, 8005, 11287, 5011, 6267, 2987, 2437,
+ 3646, 2566, 10102, 9867, 6250, 5444, 2381, 11796, 8193, 4337, 11854,
+ 1912, 1378, 404, 7644, 1065, 2143, 11121, 5277, 3248, 11082, 2548,
+ 8058, 8907, 11934, 1759, 8582, 3694, 7110, 12144, 6747, 8652, 3459,
+ 2731, 8357, 6378, 7399, 10861, 1696, 9863, 334, 7657, 6534, 11029,
+ 4388, 11560, 3241, 10276, 9000, 9408, 3284, 10200, 7197, 6498, 544,
+ 2468, 339, 11267, 9, 2842, 480, 5331, 7300, 1673, 4278, 4177,
+ 8705, 9764, 1381, 7837, 2396, 8340, 8993, 4354, 130, 6915, 2837,
+ 11462, 5767, 953, 8541, 9813, 118, 7222, 2197, 3006, 9545, 563,
+ 9314, 2625, 11340, 4821, 2639, 7266, 5828, 6561, 7698, 3328, 6512,
+ 1351, 7311, 6553, 8155, 1305, 722, 5146, 4043, 12288, 10810, 2545,
+ 3621, 8747, 8785, 1646, 1212, 5860, 3195, 7203, 10963, 3201, 3014,
+ 955, 11499, 9970, 11119, 3135, 3712, 7443, 9542, 7484, 8736, 9995,
+ 11227, 1635, 9521, 1177, 8034, 140, 10436, 11563, 7678, 4320, 11289,
+ 9198, 12208, 2963, 7393, 2366, 9238};
+
+uint16_t newhope_psis_bitrev_montgomery[PARAM_N] = {
+ 4075, 6974, 7373, 7965, 3262, 5079, 522, 2169, 6364, 1018, 1041,
+ 8775, 2344, 11011, 5574, 1973, 4536, 1050, 6844, 3860, 3818, 6118,
+ 2683, 1190, 4789, 7822, 7540, 6752, 5456, 4449, 3789, 12142, 11973,
+ 382, 3988, 468, 6843, 5339, 6196, 3710, 11316, 1254, 5435, 10930,
+ 3998, 10256, 10367, 3879, 11889, 1728, 6137, 4948, 5862, 6136, 3643,
+ 6874, 8724, 654, 10302, 1702, 7083, 6760, 56, 3199, 9987, 605,
+ 11785, 8076, 5594, 9260, 6403, 4782, 6212, 4624, 9026, 8689, 4080,
+ 11868, 6221, 3602, 975, 8077, 8851, 9445, 5681, 3477, 1105, 142,
+ 241, 12231, 1003, 3532, 5009, 1956, 6008, 11404, 7377, 2049, 10968,
+ 12097, 7591, 5057, 3445, 4780, 2920, 7048, 3127, 8120, 11279, 6821,
+ 11502, 8807, 12138, 2127, 2839, 3957, 431, 1579, 6383, 9784, 5874,
+ 677, 3336, 6234, 2766, 1323, 9115, 12237, 2031, 6956, 6413, 2281,
+ 3969, 3991, 12133, 9522, 4737, 10996, 4774, 5429, 11871, 3772, 453,
+ 5908, 2882, 1805, 2051, 1954, 11713, 3963, 2447, 6142, 8174, 3030,
+ 1843, 2361, 12071, 2908, 3529, 3434, 3202, 7796, 2057, 5369, 11939,
+ 1512, 6906, 10474, 11026, 49, 10806, 5915, 1489, 9789, 5942, 10706,
+ 10431, 7535, 426, 8974, 3757, 10314, 9364, 347, 5868, 9551, 9634,
+ 6554, 10596, 9280, 11566, 174, 2948, 2503, 6507, 10723, 11606, 2459,
+ 64, 3656, 8455, 5257, 5919, 7856, 1747, 9166, 5486, 9235, 6065,
+ 835, 3570, 4240, 11580, 4046, 10970, 9139, 1058, 8210, 11848, 922,
+ 7967, 1958, 10211, 1112, 3728, 4049, 11130, 5990, 1404, 325, 948,
+ 11143, 6190, 295, 11637, 5766, 8212, 8273, 2919, 8527, 6119, 6992,
+ 8333, 1360, 2555, 6167, 1200, 7105, 7991, 3329, 9597, 12121, 5106,
+ 5961, 10695, 10327, 3051, 9923, 4896, 9326, 81, 3091, 1000, 7969,
+ 4611, 726, 1853, 12149, 4255, 11112, 2768, 10654, 1062, 2294, 3553,
+ 4805, 2747, 4846, 8577, 9154, 1170, 2319, 790, 11334, 9275, 9088,
+ 1326, 5086, 9094, 6429, 11077, 10643, 3504, 3542, 8668, 9744, 1479,
+ 1, 8246, 7143, 11567, 10984, 4134, 5736, 4978, 10938, 5777, 8961,
+ 4591, 5728, 6461, 5023, 9650, 7468, 949, 9664, 2975, 11726, 2744,
+ 9283, 10092, 5067, 12171, 2476, 3748, 11336, 6522, 827, 9452, 5374,
+ 12159, 7935, 3296, 3949, 9893, 4452, 10908, 2525, 3584, 8112, 8011,
+ 10616, 4989, 6958, 11809, 9447, 12280, 1022, 11950, 9821, 11745, 5791,
+ 5092, 2089, 9005, 2881, 3289, 2013, 9048, 729, 7901, 1260, 5755,
+ 4632, 11955, 2426, 10593, 1428, 4890, 5911, 3932, 9558, 8830, 3637,
+ 5542, 145, 5179, 8595, 3707, 10530, 355, 3382, 4231, 9741, 1207,
+ 9041, 7012, 1168, 10146, 11224, 4645, 11885, 10911, 10377, 435, 7952,
+ 4096, 493, 9908, 6845, 6039, 2422, 2187, 9723, 8643, 9852, 9302,
+ 6022, 7278, 1002, 4284, 5088, 1607, 7313, 875, 8509, 9430, 1045,
+ 2481, 5012, 7428, 354, 6591, 9377, 11847, 2401, 1067, 7188, 11516,
+ 390, 8511, 8456, 7270, 545, 8585, 9611, 12047, 1537, 4143, 4714,
+ 4885, 1017, 5084, 1632, 3066, 27, 1440, 8526, 9273, 12046, 11618,
+ 9289, 3400, 9890, 3136, 7098, 8758, 11813, 7384, 3985, 11869, 6730,
+ 10745, 10111, 2249, 4048, 2884, 11136, 2126, 1630, 9103, 5407, 2686,
+ 9042, 2969, 8311, 9424, 9919, 8779, 5332, 10626, 1777, 4654, 10863,
+ 7351, 3636, 9585, 5291, 8374, 2166, 4919, 12176, 9140, 12129, 7852,
+ 12286, 4895, 10805, 2780, 5195, 2305, 7247, 9644, 4053, 10600, 3364,
+ 3271, 4057, 4414, 9442, 7917, 2174, 3947, 11951, 2455, 6599, 10545,
+ 10975, 3654, 2894, 7681, 7126, 7287, 12269, 4119, 3343, 2151, 1522,
+ 7174, 7350, 11041, 2442, 2148, 5959, 6492, 8330, 8945, 5598, 3624,
+ 10397, 1325, 6565, 1945, 11260, 10077, 2674, 3338, 3276, 11034, 506,
+ 6505, 1392, 5478, 8778, 1178, 2776, 3408, 10347, 11124, 2575, 9489,
+ 12096, 6092, 10058, 4167, 6085, 923, 11251, 11912, 4578, 10669, 11914,
+ 425, 10453, 392, 10104, 8464, 4235, 8761, 7376, 2291, 3375, 7954,
+ 8896, 6617, 7790, 1737, 11667, 3982, 9342, 6680, 636, 6825, 7383,
+ 512, 4670, 2900, 12050, 7735, 994, 1687, 11883, 7021, 146, 10485,
+ 1403, 5189, 6094, 2483, 2054, 3042, 10945, 3981, 10821, 11826, 8882,
+ 8151, 180, 9600, 7684, 5219, 10880, 6780, 204, 11232, 2600, 7584,
+ 3121, 3017, 11053, 7814, 7043, 4251, 4739, 11063, 6771, 7073, 9261,
+ 2360, 11925, 1928, 11825, 8024, 3678, 3205, 3359, 11197, 5209, 8581,
+ 3238, 8840, 1136, 9363, 1826, 3171, 4489, 7885, 346, 2068, 1389,
+ 8257, 3163, 4840, 6127, 8062, 8921, 612, 4238, 10763, 8067, 125,
+ 11749, 10125, 5416, 2110, 716, 9839, 10584, 11475, 11873, 3448, 343,
+ 1908, 4538, 10423, 7078, 4727, 1208, 11572, 3589, 2982, 1373, 1721,
+ 10753, 4103, 2429, 4209, 5412, 5993, 9011, 438, 3515, 7228, 1218,
+ 8347, 5232, 8682, 1327, 7508, 4924, 448, 1014, 10029, 12221, 4566,
+ 5836, 12229, 2717, 1535, 3200, 5588, 5845, 412, 5102, 7326, 3744,
+ 3056, 2528, 7406, 8314, 9202, 6454, 6613, 1417, 10032, 7784, 1518,
+ 3765, 4176, 5063, 9828, 2275, 6636, 4267, 6463, 2065, 7725, 3495,
+ 8328, 8755, 8144, 10533, 5966, 12077, 9175, 9520, 5596, 6302, 8400,
+ 579, 6781, 11014, 5734, 11113, 11164, 4860, 1131, 10844, 9068, 8016,
+ 9694, 3837, 567, 9348, 7000, 6627, 7699, 5082, 682, 11309, 5207,
+ 4050, 7087, 844, 7434, 3769, 293, 9057, 6940, 9344, 10883, 2633,
+ 8190, 3944, 5530, 5604, 3480, 2171, 9282, 11024, 2213, 8136, 3805,
+ 767, 12239, 216, 11520, 6763, 10353, 7, 8566, 845, 7235, 3154,
+ 4360, 3285, 10268, 2832, 3572, 1282, 7559, 3229, 8360, 10583, 6105,
+ 3120, 6643, 6203, 8536, 8348, 6919, 3536, 9199, 10891, 11463, 5043,
+ 1658, 5618, 8787, 5789, 4719, 751, 11379, 6389, 10783, 3065, 7806,
+ 6586, 2622, 5386, 510, 7628, 6921, 578, 10345, 11839, 8929, 4684,
+ 12226, 7154, 9916, 7302, 8481, 3670, 11066, 2334, 1590, 7878, 10734,
+ 1802, 1891, 5103, 6151, 8820, 3418, 7846, 9951, 4693, 417, 9996,
+ 9652, 4510, 2946, 5461, 365, 881, 1927, 1015, 11675, 11009, 1371,
+ 12265, 2485, 11385, 5039, 6742, 8449, 1842, 12217, 8176, 9577, 4834,
+ 7937, 9461, 2643, 11194, 3045, 6508, 4094, 3451, 7911, 11048, 5406,
+ 4665, 3020, 6616, 11345, 7519, 3669, 5287, 1790, 7014, 5410, 11038,
+ 11249, 2035, 6125, 10407, 4565, 7315, 5078, 10506, 2840, 2478, 9270,
+ 4194, 9195, 4518, 7469, 1160, 6878, 2730, 10421, 10036, 1734, 3815,
+ 10939, 5832, 10595, 10759, 4423, 8420, 9617, 7119, 11010, 11424, 9173,
+ 189, 10080, 10526, 3466, 10588, 7592, 3578, 11511, 7785, 9663, 530,
+ 12150, 8957, 2532, 3317, 9349, 10243, 1481, 9332, 3454, 3758, 7899,
+ 4218, 2593, 11410, 2276, 982, 6513, 1849, 8494, 9021, 4523, 7988,
+ 8, 457, 648, 150, 8000, 2307, 2301, 874, 5650, 170, 9462,
+ 2873, 9855, 11498, 2535, 11169, 5808, 12268, 9687, 1901, 7171, 11787,
+ 3846, 1573, 6063, 3793, 466, 11259, 10608, 3821, 6320, 4649, 6263,
+ 2929};
+
+uint16_t newhope_psis_inv_montgomery[PARAM_N] = {
+ 256, 10570, 1510, 7238, 1034, 7170, 6291, 7921, 11665, 3422, 4000,
+ 2327, 2088, 5565, 795, 10647, 1521, 5484, 2539, 7385, 1055, 7173,
+ 8047, 11683, 1669, 1994, 3796, 5809, 4341, 9398, 11876, 12230, 10525,
+ 12037, 12253, 3506, 4012, 9351, 4847, 2448, 7372, 9831, 3160, 2207,
+ 5582, 2553, 7387, 6322, 9681, 1383, 10731, 1533, 219, 5298, 4268,
+ 7632, 6357, 9686, 8406, 4712, 9451, 10128, 4958, 5975, 11387, 8649,
+ 11769, 6948, 11526, 12180, 1740, 10782, 6807, 2728, 7412, 4570, 4164,
+ 4106, 11120, 12122, 8754, 11784, 3439, 5758, 11356, 6889, 9762, 11928,
+ 1704, 1999, 10819, 12079, 12259, 7018, 11536, 1648, 1991, 2040, 2047,
+ 2048, 10826, 12080, 8748, 8272, 8204, 1172, 1923, 7297, 2798, 7422,
+ 6327, 4415, 7653, 6360, 11442, 12168, 7005, 8023, 9924, 8440, 8228,
+ 2931, 7441, 1063, 3663, 5790, 9605, 10150, 1450, 8985, 11817, 10466,
+ 10273, 12001, 3470, 7518, 1074, 1909, 7295, 9820, 4914, 702, 5367,
+ 7789, 8135, 9940, 1420, 3714, 11064, 12114, 12264, 1752, 5517, 9566,
+ 11900, 1700, 3754, 5803, 829, 1874, 7290, 2797, 10933, 5073, 7747,
+ 8129, 6428, 6185, 11417, 1631, 233, 5300, 9535, 10140, 11982, 8734,
+ 8270, 2937, 10953, 8587, 8249, 2934, 9197, 4825, 5956, 4362, 9401,
+ 1343, 3703, 529, 10609, 12049, 6988, 6265, 895, 3639, 4031, 4087,
+ 4095, 585, 10617, 8539, 4731, 4187, 9376, 3095, 9220, 10095, 10220,
+ 1460, 10742, 12068, 1724, 5513, 11321, 6884, 2739, 5658, 6075, 4379,
+ 11159, 10372, 8504, 4726, 9453, 3106, 7466, 11600, 10435, 8513, 9994,
+ 8450, 9985, 3182, 10988, 8592, 2983, 9204, 4826, 2445, 5616, 6069,
+ 867, 3635, 5786, 11360, 5134, 2489, 10889, 12089, 1727, 7269, 2794,
+ 9177, 1311, 5454, 9557, 6632, 2703, 9164, 10087, 1441, 3717, 531,
+ 3587, 2268, 324, 5313, 759, 1864, 5533, 2546, 7386, 9833, 8427,
+ 4715, 11207, 1601, 7251, 4547, 11183, 12131, 1733, 10781, 10318, 1474,
+ 10744, 5046, 4232, 11138, 10369, 6748, 964, 7160, 4534, 7670, 8118,
+ 8182, 4680, 11202, 6867, 981, 8918, 1274, 182, 26, 7026, 8026,
+ 11680, 12202, 10521, 1503, 7237, 4545, 5916, 9623, 8397, 11733, 10454,
+ 3249, 9242, 6587, 941, 1890, 270, 10572, 6777, 9746, 6659, 6218,
+ 6155, 6146, 878, 1881, 7291, 11575, 12187, 1741, 7271, 8061, 11685,
+ 6936, 4502, 9421, 4857, 4205, 7623, 1089, 10689, 1527, 8996, 10063,
+ 11971, 10488, 6765, 2722, 3900, 9335, 11867, 6962, 11528, 5158, 4248,
+ 4118, 5855, 2592, 5637, 6072, 2623, 7397, 8079, 9932, 4930, 5971,
+ 853, 3633, 519, 8852, 11798, 3441, 11025, 1575, 225, 8810, 11792,
+ 12218, 3501, 9278, 3081, 9218, 4828, 7712, 8124, 11694, 12204, 3499,
+ 4011, 573, 3593, 5780, 7848, 9899, 10192, 1456, 208, 7052, 2763,
+ 7417, 11593, 10434, 12024, 8740, 11782, 10461, 3250, 5731, 7841, 9898,
+ 1414, 202, 3540, 7528, 2831, 2160, 10842, 5060, 4234, 4116, 588,
+ 84, 12, 7024, 2759, 9172, 6577, 11473, 1639, 9012, 3043, 7457,
+ 6332, 11438, 1634, 1989, 9062, 11828, 8712, 11778, 12216, 10523, 6770,
+ 9745, 10170, 4964, 9487, 6622, 946, 8913, 6540, 6201, 4397, 9406,
+ 8366, 9973, 8447, 8229, 11709, 8695, 10020, 3187, 5722, 2573, 10901,
+ 6824, 4486, 4152, 9371, 8361, 2950, 2177, 311, 1800, 9035, 8313,
+ 11721, 3430, 490, 70, 10, 1757, 251, 3547, 7529, 11609, 3414,
+ 7510, 4584, 4166, 9373, 1339, 5458, 7802, 11648, 1664, 7260, 9815,
+ 10180, 6721, 9738, 10169, 8475, 8233, 9954, 1422, 8981, 1283, 5450,
+ 11312, 1616, 3742, 11068, 10359, 4991, 713, 3613, 9294, 8350, 4704,
+ 672, 96, 7036, 9783, 11931, 3460, 5761, 823, 10651, 12055, 10500,
+ 1500, 5481, 783, 3623, 11051, 8601, 8251, 8201, 11705, 10450, 5004,
+ 4226, 7626, 2845, 2162, 3820, 7568, 9859, 3164, 452, 10598, 1514,
+ 5483, 6050, 6131, 4387, 7649, 8115, 6426, 918, 8909, 8295, 1185,
+ 5436, 11310, 8638, 1234, 5443, 11311, 5127, 2488, 2111, 10835, 5059,
+ 7745, 2862, 3920, 560, 80, 1767, 2008, 3798, 11076, 6849, 2734,
+ 10924, 12094, 8750, 1250, 10712, 6797, 971, 7161, 1023, 8924, 4786,
+ 7706, 4612, 4170, 7618, 6355, 4419, 5898, 11376, 10403, 10264, 6733,
+ 4473, 639, 5358, 2521, 9138, 3061, 5704, 4326, 618, 5355, 765,
+ 5376, 768, 7132, 4530, 9425, 3102, 9221, 6584, 11474, 10417, 10266,
+ 12000, 6981, 6264, 4406, 2385, 7363, 4563, 4163, 7617, 9866, 3165,
+ 9230, 11852, 10471, 5007, 5982, 11388, 5138, 734, 3616, 11050, 12112,
+ 6997, 11533, 12181, 10518, 12036, 3475, 2252, 7344, 9827, 4915, 9480,
+ 6621, 4457, 7659, 9872, 6677, 4465, 4149, 7615, 4599, 657, 3605,
+ 515, 10607, 6782, 4480, 640, 1847, 3775, 5806, 2585, 5636, 9583,
+ 1369, 10729, 8555, 10000, 11962, 5220, 7768, 8132, 8184, 9947, 1421,
+ 203, 29, 8782, 11788, 1684, 10774, 10317, 4985, 9490, 8378, 4708,
+ 11206, 5112, 5997, 7879, 11659, 12199, 8765, 10030, 4944, 5973, 6120,
+ 6141, 6144, 7900, 11662, 1666, 238, 34, 3516, 5769, 9602, 8394,
+ 9977, 6692, 956, 10670, 6791, 9748, 11926, 8726, 11780, 5194, 742,
+ 106, 8793, 10034, 3189, 10989, 5081, 4237, 5872, 4350, 2377, 10873,
+ 6820, 6241, 11425, 10410, 10265, 3222, 5727, 9596, 4882, 2453, 2106,
+ 3812, 11078, 12116, 5242, 4260, 11142, 8614, 11764, 12214, 5256, 4262,
+ 4120, 11122, 5100, 11262, 5120, 2487, 5622, 9581, 8391, 8221, 2930,
+ 10952, 12098, 6995, 6266, 9673, 4893, 699, 3611, 4027, 5842, 11368,
+ 1624, 232, 8811, 8281, 1183, 169, 8802, 3013, 2186, 5579, 797,
+ 3625, 4029, 11109, 1587, 7249, 11569, 8675, 6506, 2685, 10917, 12093,
+ 12261, 12285, 1755, 7273, 1039, 1904, 272, 3550, 9285, 3082, 5707,
+ 6082, 4380, 7648, 11626, 5172, 4250, 9385, 8363, 8217, 4685, 5936,
+ 848, 8899, 6538, 934, 1889, 3781, 9318, 10109, 10222, 6727, 961,
+ 5404, 772, 5377, 9546, 8386, 1198, 8949, 3034, 2189, 7335, 4559,
+ 5918, 2601, 10905, 5069, 9502, 3113, 7467, 8089, 11689, 5181, 9518,
+ 8382, 2953, 3933, 4073, 4093, 7607, 8109, 2914, 5683, 4323, 11151,
+ 1593, 10761, 6804, 972, 3650, 2277, 5592, 4310, 7638, 9869, 4921,
+ 703, 1856, 9043, 4803, 9464, 1352, 8971, 11815, 5199, 7765, 6376,
+ 4422, 7654, 2849, 407, 8836, 6529, 7955, 2892, 9191, 1313, 10721,
+ 12065, 12257, 1751, 9028, 8312, 2943, 2176, 3822, 546, 78, 8789,
+ 11789, 10462, 12028, 6985, 4509, 9422, 1346, 5459, 4291, 613, 10621,
+ 6784, 9747, 3148, 7472, 2823, 5670, 810, 7138, 8042, 4660, 7688,
+ 6365, 6176, 6149, 2634, 5643, 9584, 10147, 11983, 5223, 9524, 11894,
+ 10477, 8519, 1217, 3685, 2282, 326, 10580, 3267, 7489, 4581, 2410,
+ 5611, 11335, 6886, 8006, 8166, 11700, 3427, 11023, 8597, 10006, 3185,
+ 455, 65, 5276, 7776, 4622, 5927, 7869, 9902, 11948, 5218, 2501,
+ 5624, 2559, 10899, 1557, 1978, 10816, 10323, 8497, 4725, 675, 1852,
+ 10798, 12076, 10503, 3256, 9243, 3076, 2195, 10847, 12083, 10504, 12034,
+ 10497};
diff --git a/src/crypto/newhope/reduce.c b/src/crypto/newhope/reduce.c
new file mode 100644
index 00000000..e7f13649
--- /dev/null
+++ b/src/crypto/newhope/reduce.c
@@ -0,0 +1,42 @@
+/* Copyright (c) 2016, 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 "internal.h"
+
+
+/* Incomplete-reduction routines; for details on allowed input ranges
+ * and produced output ranges, see the description in the paper:
+ * https://cryptojedi.org/papers/#newhope */
+
+static const uint32_t kQInv = 12287; /* -inverse_mod(p,2^18) */
+static const uint32_t kRLog = 18;
+
+uint16_t newhope_montgomery_reduce(uint32_t a) {
+ uint32_t u;
+
+ u = (a * kQInv);
+ u &= ((1 << kRLog) - 1);
+ u *= PARAM_Q;
+ a = a + u;
+ return a >> 18;
+}
+
+uint16_t newhope_barrett_reduce(uint16_t a) {
+ uint32_t u;
+
+ u = ((uint32_t)a * 5) >> 16;
+ u *= PARAM_Q;
+ a -= u;
+ return a;
+}
diff --git a/src/crypto/obj/CMakeLists.txt b/src/crypto/obj/CMakeLists.txt
index b8a4ef37..f49d499d 100644
--- a/src/crypto/obj/CMakeLists.txt
+++ b/src/crypto/obj/CMakeLists.txt
@@ -8,3 +8,14 @@ add_library(
obj.c
obj_xref.c
)
+
+add_executable(
+ obj_test
+
+ obj_test.cc
+
+ $<TARGET_OBJECTS:test_support>
+)
+
+target_link_libraries(obj_test crypto)
+add_dependencies(all_tests obj_test)
diff --git a/src/crypto/obj/README b/src/crypto/obj/README
index 8826e598..6199fb4b 100644
--- a/src/crypto/obj/README
+++ b/src/crypto/obj/README
@@ -1,17 +1,17 @@
OID information is generated via a series of perl scripts. In order, the full
list of commands to run are:
- perl objects.pl objects.txt obj_mac.num ../../include/openssl/obj_mac.h
- perl obj_dat.pl ../../include/openssl/obj_mac.h obj_dat.h
+ perl objects.pl objects.txt obj_mac.num ../../include/openssl/nid.h
+ perl obj_dat.pl ../../include/openssl/nid.h obj_dat.h
perl obj_xref.pl obj_mac.num obj_xref.txt > obj_xref.h
objects.txt contains the list of all built-in OIDs. It is processed by
-objects.pl to output obj_mac.num and obj_mac.h. obj_mac.num is the list of NID
+objects.pl to output obj_mac.num and nid.h. obj_mac.num is the list of NID
values for each OID. This is an input/output parameter so NID values are stable
-across regenerations. obj_mac.h is the header which defines macros for all the
+across regenerations. nid.h is the header which defines macros for all the
built-in OIDs in C.
-obj_mac.h is read by obj_dat.pl to generate obj_dat.h. obj_dat.h contains the
+nid.h is read by obj_dat.pl to generate obj_dat.h. obj_dat.h contains the
ASN1_OBJECTs corresponding to built-in OIDs themselves along with lookup tables
for search by short name, OID, etc.
@@ -28,7 +28,7 @@ Dependency graph:
[objects.pl] <--+
/ \ |
V V |
- obj_mac.h obj_mac.num obj_xref.txt
+ nid.h obj_mac.num obj_xref.txt
| \ /
V V V
[obj_dat.pl] [obj_xref.pl]
diff --git a/src/crypto/obj/obj_dat.h b/src/crypto/obj/obj_dat.h
index bf44c6d9..1d779de6 100644
--- a/src/crypto/obj/obj_dat.h
+++ b/src/crypto/obj/obj_dat.h
@@ -1,6 +1,6 @@
/* THIS FILE IS GENERATED FROM objects.h by obj_dat.pl via the
* following command:
- * perl obj_dat.pl ../../include/openssl/obj_mac.h obj_dat.h */
+ * perl obj_dat.pl ../../include/openssl/nid.h obj_dat.h */
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
* All rights reserved.
@@ -61,7 +61,7 @@
#define NUM_NID 949
#define NUM_SN 941
#define NUM_LN 941
-#define NUM_OBJ 882
+#define NUM_OBJ 876
static const unsigned char lvalues[6176]={
0x2A,0x86,0x48,0x86,0xF7,0x0D, /* [ 0] OBJ_rsadsi */
@@ -2482,7 +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},
+{"X25519","X25519",NID_X25519,0,NULL,0},
};
static const unsigned int kNIDsInShortNameOrder[NUM_SN]={
@@ -3538,6 +3538,7 @@ static const unsigned int kNIDsInLongNameOrder[NUM_LN]={
129, /* "TLS Web Server Authentication" */
133, /* "Time Stamping" */
375, /* "Trust Root" */
+948, /* "X25519" */
12, /* "X509" */
402, /* "X509v3 AC Targeting" */
746, /* "X509v3 Any Policy" */
@@ -4366,7 +4367,6 @@ 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" */
@@ -4374,12 +4374,6 @@ static const unsigned int kNIDsInLongNameOrder[NUM_LN]={
};
static const unsigned int kNIDsInOIDOrder[NUM_OBJ]={
- 0, /* OBJ_undef 0 */
-181, /* OBJ_iso 1 */
-393, /* OBJ_joint_iso_ccitt OBJ_joint_iso_itu_t */
-404, /* OBJ_ccitt OBJ_itu_t */
-645, /* OBJ_itu_t 0 */
-646, /* OBJ_joint_iso_itu_t 2 */
434, /* OBJ_data 0 9 */
182, /* OBJ_member_body 1 2 */
379, /* OBJ_org 1 3 */
diff --git a/src/crypto/obj/obj_dat.pl b/src/crypto/obj/obj_dat.pl
index 201ec722..036ded54 100644
--- a/src/crypto/obj/obj_dat.pl
+++ b/src/crypto/obj/obj_dat.pl
@@ -6,7 +6,7 @@ use integer;
if (scalar @ARGV != 2)
{
- print "Usage: perl obj_dat.pl ../../include/openssl/obj_mac.h obj_dat.h\n";
+ print "Usage: perl obj_dat.pl ../../include/openssl/nid.h obj_dat.h\n";
exit 1;
}
@@ -163,7 +163,7 @@ foreach (sort { $ln{$nid{$a}} cmp $ln{$nid{$b}} } @a)
push(@ln,sprintf("%2d,\t/* \"$ln{$nid{$_}}\" */\n",$_));
}
-@a=grep(defined($obj{$nid{$_}}),0 .. $n);
+@a=grep(defined($obj{$nid{$_}}) && $objd{$obj{$nid{$_}}} =~ /,/,0 .. $n);
foreach (sort obj_cmp @a)
{
$m=$obj{$nid{$_}};
@@ -176,7 +176,7 @@ foreach (sort obj_cmp @a)
print OUT <<'EOF';
/* THIS FILE IS GENERATED FROM objects.h by obj_dat.pl via the
* following command:
- * perl obj_dat.pl ../../include/openssl/obj_mac.h obj_dat.h */
+ * perl obj_dat.pl ../../include/openssl/nid.h obj_dat.h */
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
* All rights reserved.
diff --git a/src/crypto/obj/obj_mac.num b/src/crypto/obj/obj_mac.num
index a0e09b80..074657ae 100644
--- a/src/crypto/obj/obj_mac.num
+++ b/src/crypto/obj/obj_mac.num
@@ -945,4 +945,4 @@ dhSinglePass_cofactorDH_sha384kdf_scheme 944
dhSinglePass_cofactorDH_sha512kdf_scheme 945
dh_std_kdf 946
dh_cofactor_kdf 947
-x25519 948
+X25519 948
diff --git a/src/crypto/obj/obj_test.cc b/src/crypto/obj/obj_test.cc
new file mode 100644
index 00000000..2948941a
--- /dev/null
+++ b/src/crypto/obj/obj_test.cc
@@ -0,0 +1,106 @@
+/* Copyright (c) 2016, 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/bytestring.h>
+#include <openssl/crypto.h>
+#include <openssl/obj.h>
+
+
+static bool TestBasic() {
+ static const int kNID = NID_sha256WithRSAEncryption;
+ static const char kShortName[] = "RSA-SHA256";
+ static const char kLongName[] = "sha256WithRSAEncryption";
+ static const char kText[] = "1.2.840.113549.1.1.11";
+ static const uint8_t kDER[] = {
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
+ };
+
+ CBS cbs;
+ CBS_init(&cbs, kDER, sizeof(kDER));
+ if (OBJ_cbs2nid(&cbs) != kNID ||
+ OBJ_sn2nid(kShortName) != kNID ||
+ OBJ_ln2nid(kLongName) != kNID ||
+ OBJ_txt2nid(kShortName) != kNID ||
+ OBJ_txt2nid(kLongName) != kNID ||
+ OBJ_txt2nid(kText) != kNID) {
+ return false;
+ }
+
+ if (strcmp(kShortName, OBJ_nid2sn(kNID)) != 0 ||
+ strcmp(kLongName, OBJ_nid2ln(kNID)) != 0) {
+ return false;
+ }
+
+ if (OBJ_sn2nid("this is not an OID") != NID_undef ||
+ OBJ_ln2nid("this is not an OID") != NID_undef ||
+ OBJ_txt2nid("this is not an OID") != NID_undef) {
+ return false;
+ }
+
+ CBS_init(&cbs, NULL, 0);
+ if (OBJ_cbs2nid(&cbs) != NID_undef) {
+ return false;
+ }
+
+ // 1.2.840.113554.4.1.72585.2 (https://davidben.net/oid).
+ static const uint8_t kUnknownDER[] = {
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04, 0x01, 0x84, 0xb7, 0x09, 0x02,
+ };
+ CBS_init(&cbs, kUnknownDER, sizeof(kUnknownDER));
+ if (OBJ_cbs2nid(&cbs) != NID_undef) {
+ return false;
+ }
+
+ return true;
+}
+
+static bool TestSignatureAlgorithms() {
+ int digest_nid, pkey_nid;
+ if (!OBJ_find_sigid_algs(NID_sha256WithRSAEncryption, &digest_nid,
+ &pkey_nid) ||
+ digest_nid != NID_sha256 || pkey_nid != NID_rsaEncryption) {
+ return false;
+ }
+
+ if (OBJ_find_sigid_algs(NID_sha256, &digest_nid, &pkey_nid)) {
+ return false;
+ }
+
+ int sign_nid;
+ if (!OBJ_find_sigid_by_algs(&sign_nid, NID_sha256, NID_rsaEncryption) ||
+ sign_nid != NID_sha256WithRSAEncryption) {
+ return false;
+ }
+
+ if (OBJ_find_sigid_by_algs(&sign_nid, NID_dsa, NID_rsaEncryption)) {
+ return false;
+ }
+
+ return true;
+}
+
+int main() {
+ CRYPTO_library_init();
+
+ if (!TestBasic() ||
+ !TestSignatureAlgorithms()) {
+ return 1;
+ }
+
+ printf("PASS\n");
+ return 0;
+}
diff --git a/src/crypto/obj/objects.pl b/src/crypto/obj/objects.pl
index 7073e855..165429b4 100644
--- a/src/crypto/obj/objects.pl
+++ b/src/crypto/obj/objects.pl
@@ -2,7 +2,7 @@
if (scalar @ARGV != 3)
{
- print "Usage: perl objects.pl objects.txt obj_mac.num ../../include/openssl/obj_mac.h\n";
+ print "Usage: perl objects.pl objects.txt obj_mac.num ../../include/openssl/nid.h\n";
exit 1;
}
@@ -127,7 +127,7 @@ open (OUT,">$ARGV[2]") || die "Can't open output file $ARGV[2]";
print OUT <<'EOF';
/* THIS FILE IS GENERATED FROM objects.txt by objects.pl via the
* following command:
- * perl objects.pl objects.txt obj_mac.num ../../include/openssl/obj_mac.h */
+ * perl objects.pl objects.txt obj_mac.num ../../include/openssl/nid.h */
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
* All rights reserved.
@@ -186,23 +186,43 @@ print OUT <<'EOF';
* [including the GNU Public Licence.]
*/
-#define SN_undef "UNDEF"
-#define LN_undef "undefined"
-#define NID_undef 0
-#define OBJ_undef 0L
+#ifndef OPENSSL_HEADER_NID_H
+#define OPENSSL_HEADER_NID_H
+
+
+/* The nid library provides numbered values for ASN.1 object identifiers and
+ * other symbols. These values are used by other libraries to identify
+ * cryptographic primitives.
+ *
+ * A separate objects library, obj.h, provides functions for converting between
+ * nids and object identifiers. However it depends on large internal tables with
+ * the encodings of every nid defind. Consumers concerned with binary size
+ * should instead embed the encodings of the few consumed OIDs and compare
+ * against those.
+ *
+ * These values should not be used outside of a single process; they are not
+ * stable identifiers. */
+
+
+#define SN_undef "UNDEF"
+#define LN_undef "undefined"
+#define NID_undef 0
+#define OBJ_undef 0L
EOF
foreach (sort { $a <=> $b } keys %ordern)
{
$Cname=$ordern{$_};
- print OUT "#define SN_",$Cname,"\t\t\"",$sn{$Cname},"\"\n" if $sn{$Cname} ne "";
- print OUT "#define LN_",$Cname,"\t\t\"",$ln{$Cname},"\"\n" if $ln{$Cname} ne "";
- print OUT "#define NID_",$Cname,"\t\t",$nid{$Cname},"\n" if $nid{$Cname} ne "";
- print OUT "#define OBJ_",$Cname,"\t\t",$obj{$Cname},"\n" if $obj{$Cname} ne "";
+ print OUT "#define SN_",$Cname," \"",$sn{$Cname},"\"\n" if $sn{$Cname} ne "";
+ print OUT "#define LN_",$Cname," \"",$ln{$Cname},"\"\n" if $ln{$Cname} ne "";
+ print OUT "#define NID_",$Cname," ",$nid{$Cname},"\n" if $nid{$Cname} ne "";
+ print OUT "#define OBJ_",$Cname," ",$obj{$Cname},"\n" if $obj{$Cname} ne "";
print OUT "\n";
}
+print OUT "\n#endif /* OPENSSL_HEADER_NID_H */\n";
+
close OUT;
sub process_oid
diff --git a/src/crypto/obj/objects.txt b/src/crypto/obj/objects.txt
index 93cf53aa..f3990d00 100644
--- a/src/crypto/obj/objects.txt
+++ b/src/crypto/obj/objects.txt
@@ -1332,4 +1332,4 @@ secg-scheme 14 3 : dhSinglePass-cofactorDH-sha512kdf-scheme
: dh-cofactor-kdf
# NID for X25519 (no corresponding OID).
- : X25519 : x25519
+ : X25519
diff --git a/src/crypto/pem/pem_all.c b/src/crypto/pem/pem_all.c
index c9f8b6ee..e94ff265 100644
--- a/src/crypto/pem/pem_all.c
+++ b/src/crypto/pem/pem_all.c
@@ -113,159 +113,150 @@
#include <openssl/dsa.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
-/*#include <openssl/pkcs7.h> */
+/*
+ * #include <openssl/pkcs7.h>
+ */
#include <openssl/rsa.h>
#include <openssl/x509.h>
-
static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa);
static DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa);
static EC_KEY *pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey);
-
IMPLEMENT_PEM_rw(X509_REQ, X509_REQ, PEM_STRING_X509_REQ, X509_REQ)
IMPLEMENT_PEM_write(X509_REQ_NEW, X509_REQ, PEM_STRING_X509_REQ_OLD, X509_REQ)
-
IMPLEMENT_PEM_rw(X509_CRL, X509_CRL, PEM_STRING_X509_CRL, X509_CRL)
-
-
-/* We treat RSA or DSA private keys as a special case.
- *
- * For private keys we read in an EVP_PKEY structure with
- * PEM_read_bio_PrivateKey() and extract the relevant private
- * key: this means can handle "traditional" and PKCS#8 formats
- * transparently.
+/*
+ * We treat RSA or DSA private keys as a special case. For private keys we
+ * read in an EVP_PKEY structure with PEM_read_bio_PrivateKey() and extract
+ * the relevant private key: this means can handle "traditional" and PKCS#8
+ * formats transparently.
*/
-
static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa)
{
- RSA *rtmp;
- if(!key) return NULL;
- rtmp = EVP_PKEY_get1_RSA(key);
- EVP_PKEY_free(key);
- if(!rtmp) return NULL;
- if(rsa) {
- RSA_free(*rsa);
- *rsa = rtmp;
- }
- return rtmp;
+ RSA *rtmp;
+ if (!key)
+ return NULL;
+ rtmp = EVP_PKEY_get1_RSA(key);
+ EVP_PKEY_free(key);
+ if (!rtmp)
+ return NULL;
+ if (rsa) {
+ RSA_free(*rsa);
+ *rsa = rtmp;
+ }
+ return rtmp;
}
RSA *PEM_read_bio_RSAPrivateKey(BIO *bp, RSA **rsa, pem_password_cb *cb,
- void *u)
+ void *u)
{
- EVP_PKEY *pktmp;
- pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
- return pkey_get_rsa(pktmp, rsa);
+ EVP_PKEY *pktmp;
+ pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
+ return pkey_get_rsa(pktmp, rsa);
}
#ifndef OPENSSL_NO_FP_API
-RSA *PEM_read_RSAPrivateKey(FILE *fp, RSA **rsa, pem_password_cb *cb,
- void *u)
+RSA *PEM_read_RSAPrivateKey(FILE *fp, RSA **rsa, pem_password_cb *cb, void *u)
{
- EVP_PKEY *pktmp;
- pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
- return pkey_get_rsa(pktmp, rsa);
+ EVP_PKEY *pktmp;
+ pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
+ return pkey_get_rsa(pktmp, rsa);
}
#endif
-IMPLEMENT_PEM_write_cb_const(RSAPrivateKey, RSA, PEM_STRING_RSA, RSAPrivateKey)
+IMPLEMENT_PEM_write_cb_const(RSAPrivateKey, RSA, PEM_STRING_RSA,
+ RSAPrivateKey)
-IMPLEMENT_PEM_rw_const(RSAPublicKey, RSA, PEM_STRING_RSA_PUBLIC, RSAPublicKey)
-IMPLEMENT_PEM_rw(RSA_PUBKEY, RSA, PEM_STRING_PUBLIC, RSA_PUBKEY)
+IMPLEMENT_PEM_rw_const(RSAPublicKey, RSA, PEM_STRING_RSA_PUBLIC,
+ RSAPublicKey) IMPLEMENT_PEM_rw(RSA_PUBKEY, RSA,
+ PEM_STRING_PUBLIC,
+ RSA_PUBKEY)
#ifndef OPENSSL_NO_DSA
-
static DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa)
{
- DSA *dtmp;
- if(!key) return NULL;
- dtmp = EVP_PKEY_get1_DSA(key);
- EVP_PKEY_free(key);
- if(!dtmp) return NULL;
- if(dsa) {
- DSA_free(*dsa);
- *dsa = dtmp;
- }
- return dtmp;
+ DSA *dtmp;
+ if (!key)
+ return NULL;
+ dtmp = EVP_PKEY_get1_DSA(key);
+ EVP_PKEY_free(key);
+ if (!dtmp)
+ return NULL;
+ if (dsa) {
+ DSA_free(*dsa);
+ *dsa = dtmp;
+ }
+ return dtmp;
}
DSA *PEM_read_bio_DSAPrivateKey(BIO *bp, DSA **dsa, pem_password_cb *cb,
- void *u)
+ void *u)
{
- EVP_PKEY *pktmp;
- pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
- return pkey_get_dsa(pktmp, dsa); /* will free pktmp */
+ EVP_PKEY *pktmp;
+ pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
+ return pkey_get_dsa(pktmp, dsa); /* will free pktmp */
}
+IMPLEMENT_PEM_write_cb_const(DSAPrivateKey, DSA, PEM_STRING_DSA,
+ DSAPrivateKey)
-IMPLEMENT_PEM_write_cb_const(DSAPrivateKey, DSA, PEM_STRING_DSA, DSAPrivateKey)
-
-IMPLEMENT_PEM_rw(DSA_PUBKEY, DSA, PEM_STRING_PUBLIC, DSA_PUBKEY)
-
-#ifndef OPENSSL_NO_FP_API
-
-DSA *PEM_read_DSAPrivateKey(FILE *fp, DSA **dsa, pem_password_cb *cb,
- void *u)
+ IMPLEMENT_PEM_rw(DSA_PUBKEY, DSA, PEM_STRING_PUBLIC, DSA_PUBKEY)
+# ifndef OPENSSL_NO_FP_API
+DSA *PEM_read_DSAPrivateKey(FILE *fp, DSA **dsa, pem_password_cb *cb, void *u)
{
- EVP_PKEY *pktmp;
- pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
- return pkey_get_dsa(pktmp, dsa); /* will free pktmp */
+ EVP_PKEY *pktmp;
+ pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
+ return pkey_get_dsa(pktmp, dsa); /* will free pktmp */
}
-#endif
+# endif
IMPLEMENT_PEM_rw_const(DSAparams, DSA, PEM_STRING_DSAPARAMS, DSAparams)
-
#endif
-
-
static EC_KEY *pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey)
{
- EC_KEY *dtmp;
- if(!key) return NULL;
- dtmp = EVP_PKEY_get1_EC_KEY(key);
- EVP_PKEY_free(key);
- if(!dtmp) return NULL;
- if(eckey)
- {
- EC_KEY_free(*eckey);
- *eckey = dtmp;
- }
- return dtmp;
+ EC_KEY *dtmp;
+ if (!key)
+ return NULL;
+ dtmp = EVP_PKEY_get1_EC_KEY(key);
+ EVP_PKEY_free(key);
+ if (!dtmp)
+ return NULL;
+ if (eckey) {
+ EC_KEY_free(*eckey);
+ *eckey = dtmp;
+ }
+ return dtmp;
}
EC_KEY *PEM_read_bio_ECPrivateKey(BIO *bp, EC_KEY **key, pem_password_cb *cb,
- void *u)
+ void *u)
{
- EVP_PKEY *pktmp;
- pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
- return pkey_get_eckey(pktmp, key); /* will free pktmp */
+ EVP_PKEY *pktmp;
+ pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
+ return pkey_get_eckey(pktmp, key); /* will free pktmp */
}
-IMPLEMENT_PEM_write_cb(ECPrivateKey, EC_KEY, PEM_STRING_ECPRIVATEKEY, ECPrivateKey)
-
-
-IMPLEMENT_PEM_rw(EC_PUBKEY, EC_KEY, PEM_STRING_PUBLIC, EC_PUBKEY)
+IMPLEMENT_PEM_write_cb(ECPrivateKey, EC_KEY, PEM_STRING_ECPRIVATEKEY,
+ ECPrivateKey)
+ IMPLEMENT_PEM_rw(EC_PUBKEY, EC_KEY, PEM_STRING_PUBLIC, EC_PUBKEY)
#ifndef OPENSSL_NO_FP_API
-
EC_KEY *PEM_read_ECPrivateKey(FILE *fp, EC_KEY **eckey, pem_password_cb *cb,
- void *u)
+ void *u)
{
- EVP_PKEY *pktmp;
- pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
- return pkey_get_eckey(pktmp, eckey); /* will free pktmp */
+ EVP_PKEY *pktmp;
+ pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
+ return pkey_get_eckey(pktmp, eckey); /* will free pktmp */
}
#endif
-
-
IMPLEMENT_PEM_write_const(DHparams, DH, PEM_STRING_DHPARAMS, DHparams)
-IMPLEMENT_PEM_rw(PUBKEY, EVP_PKEY, PEM_STRING_PUBLIC, PUBKEY)
+ 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 2a39a5be..57c87d4f 100644
--- a/src/crypto/pem/pem_info.c
+++ b/src/crypto/pem/pem_info.c
@@ -5,21 +5,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.
- *
+ *
* 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:
@@ -34,10 +34,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) from
+ * 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
@@ -49,7 +49,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.
- *
+ *
* 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
@@ -71,334 +71,311 @@
#include <openssl/rsa.h>
#include <openssl/x509.h>
-
#ifndef OPENSSL_NO_FP_API
-STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u)
- {
- BIO *b;
- STACK_OF(X509_INFO) *ret;
+STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk,
+ pem_password_cb *cb, void *u)
+{
+ BIO *b;
+ STACK_OF(X509_INFO) *ret;
- if ((b=BIO_new(BIO_s_file())) == NULL)
- {
- OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
- return(0);
- }
- BIO_set_fp(b,fp,BIO_NOCLOSE);
- ret=PEM_X509_INFO_read_bio(b,sk,cb,u);
- BIO_free(b);
- return(ret);
- }
+ if ((b = BIO_new(BIO_s_file())) == NULL) {
+ OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
+ return (0);
+ }
+ BIO_set_fp(b, fp, BIO_NOCLOSE);
+ ret = PEM_X509_INFO_read_bio(b, sk, cb, u);
+ BIO_free(b);
+ return (ret);
+}
#endif
-STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u)
- {
- X509_INFO *xi=NULL;
- char *name=NULL,*header=NULL;
- void *pp;
- unsigned char *data=NULL;
- const unsigned char *p;
- long len,error=0;
- int ok=0;
- STACK_OF(X509_INFO) *ret=NULL;
- unsigned int i,raw,ptype;
- d2i_of_void *d2i = 0;
+STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk,
+ pem_password_cb *cb, void *u)
+{
+ X509_INFO *xi = NULL;
+ char *name = NULL, *header = NULL;
+ void *pp;
+ unsigned char *data = NULL;
+ const unsigned char *p;
+ long len, error = 0;
+ int ok = 0;
+ STACK_OF(X509_INFO) *ret = NULL;
+ unsigned int i, raw, ptype;
+ d2i_of_void *d2i = 0;
- if (sk == NULL)
- {
- if ((ret=sk_X509_INFO_new_null()) == NULL)
- {
- OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- }
- else
- ret=sk;
+ if (sk == NULL) {
+ if ((ret = sk_X509_INFO_new_null()) == NULL) {
+ OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ } else
+ ret = sk;
- if ((xi=X509_INFO_new()) == NULL) goto err;
- for (;;)
- {
- raw=0;
- ptype = 0;
- i=PEM_read_bio(bp,&name,&header,&data,&len);
- if (i == 0)
- {
- error=ERR_GET_REASON(ERR_peek_last_error());
- if (error == PEM_R_NO_START_LINE)
- {
- ERR_clear_error();
- break;
- }
- goto err;
- }
-start:
- if ( (strcmp(name,PEM_STRING_X509) == 0) ||
- (strcmp(name,PEM_STRING_X509_OLD) == 0))
- {
- d2i=(D2I_OF(void))d2i_X509;
- if (xi->x509 != NULL)
- {
- if (!sk_X509_INFO_push(ret,xi)) goto err;
- if ((xi=X509_INFO_new()) == NULL) goto err;
- goto start;
- }
- pp=&(xi->x509);
- }
- else if ((strcmp(name,PEM_STRING_X509_TRUSTED) == 0))
- {
- d2i=(D2I_OF(void))d2i_X509_AUX;
- if (xi->x509 != NULL)
- {
- if (!sk_X509_INFO_push(ret,xi)) goto err;
- if ((xi=X509_INFO_new()) == NULL) goto err;
- goto start;
- }
- pp=&(xi->x509);
- }
- else if (strcmp(name,PEM_STRING_X509_CRL) == 0)
- {
- d2i=(D2I_OF(void))d2i_X509_CRL;
- if (xi->crl != NULL)
- {
- if (!sk_X509_INFO_push(ret,xi)) goto err;
- if ((xi=X509_INFO_new()) == NULL) goto err;
- goto start;
- }
- pp=&(xi->crl);
- }
- else
- if (strcmp(name,PEM_STRING_RSA) == 0)
- {
- d2i=(D2I_OF(void))d2i_RSAPrivateKey;
- if (xi->x_pkey != NULL)
- {
- if (!sk_X509_INFO_push(ret,xi)) goto err;
- if ((xi=X509_INFO_new()) == NULL) goto err;
- goto start;
- }
+ if ((xi = X509_INFO_new()) == NULL)
+ goto err;
+ for (;;) {
+ raw = 0;
+ ptype = 0;
+ i = PEM_read_bio(bp, &name, &header, &data, &len);
+ if (i == 0) {
+ error = ERR_GET_REASON(ERR_peek_last_error());
+ if (error == PEM_R_NO_START_LINE) {
+ ERR_clear_error();
+ break;
+ }
+ goto err;
+ }
+ start:
+ if ((strcmp(name, PEM_STRING_X509) == 0) ||
+ (strcmp(name, PEM_STRING_X509_OLD) == 0)) {
+ d2i = (D2I_OF(void)) d2i_X509;
+ if (xi->x509 != NULL) {
+ if (!sk_X509_INFO_push(ret, xi))
+ goto err;
+ if ((xi = X509_INFO_new()) == NULL)
+ goto err;
+ goto start;
+ }
+ pp = &(xi->x509);
+ } else if ((strcmp(name, PEM_STRING_X509_TRUSTED) == 0)) {
+ d2i = (D2I_OF(void)) d2i_X509_AUX;
+ if (xi->x509 != NULL) {
+ if (!sk_X509_INFO_push(ret, xi))
+ goto err;
+ if ((xi = X509_INFO_new()) == NULL)
+ goto err;
+ goto start;
+ }
+ pp = &(xi->x509);
+ } else if (strcmp(name, PEM_STRING_X509_CRL) == 0) {
+ d2i = (D2I_OF(void)) d2i_X509_CRL;
+ if (xi->crl != NULL) {
+ if (!sk_X509_INFO_push(ret, xi))
+ goto err;
+ if ((xi = X509_INFO_new()) == NULL)
+ goto err;
+ goto start;
+ }
+ pp = &(xi->crl);
+ } else if (strcmp(name, PEM_STRING_RSA) == 0) {
+ d2i = (D2I_OF(void)) d2i_RSAPrivateKey;
+ if (xi->x_pkey != NULL) {
+ if (!sk_X509_INFO_push(ret, xi))
+ goto err;
+ if ((xi = X509_INFO_new()) == NULL)
+ goto err;
+ goto start;
+ }
- xi->enc_data=NULL;
- xi->enc_len=0;
+ xi->enc_data = NULL;
+ xi->enc_len = 0;
- xi->x_pkey=X509_PKEY_new();
- ptype=EVP_PKEY_RSA;
- pp=&xi->x_pkey->dec_pkey;
- if ((int)strlen(header) > 10) /* assume encrypted */
- raw=1;
- }
- else
+ xi->x_pkey = X509_PKEY_new();
+ ptype = EVP_PKEY_RSA;
+ pp = &xi->x_pkey->dec_pkey;
+ if ((int)strlen(header) > 10) /* assume encrypted */
+ raw = 1;
+ } else
#ifndef OPENSSL_NO_DSA
- if (strcmp(name,PEM_STRING_DSA) == 0)
- {
- d2i=(D2I_OF(void))d2i_DSAPrivateKey;
- if (xi->x_pkey != NULL)
- {
- if (!sk_X509_INFO_push(ret,xi)) goto err;
- if ((xi=X509_INFO_new()) == NULL) goto err;
- goto start;
- }
+ if (strcmp(name, PEM_STRING_DSA) == 0) {
+ d2i = (D2I_OF(void)) d2i_DSAPrivateKey;
+ if (xi->x_pkey != NULL) {
+ if (!sk_X509_INFO_push(ret, xi))
+ goto err;
+ if ((xi = X509_INFO_new()) == NULL)
+ goto err;
+ goto start;
+ }
- xi->enc_data=NULL;
- xi->enc_len=0;
+ xi->enc_data = NULL;
+ xi->enc_len = 0;
- xi->x_pkey=X509_PKEY_new();
- ptype = EVP_PKEY_DSA;
- pp=&xi->x_pkey->dec_pkey;
- if ((int)strlen(header) > 10) /* assume encrypted */
- raw=1;
- }
- else
+ xi->x_pkey = X509_PKEY_new();
+ ptype = EVP_PKEY_DSA;
+ pp = &xi->x_pkey->dec_pkey;
+ if ((int)strlen(header) > 10) /* assume encrypted */
+ raw = 1;
+ } else
#endif
- if (strcmp(name,PEM_STRING_ECPRIVATEKEY) == 0)
- {
- d2i=(D2I_OF(void))d2i_ECPrivateKey;
- if (xi->x_pkey != NULL)
- {
- if (!sk_X509_INFO_push(ret,xi)) goto err;
- if ((xi=X509_INFO_new()) == NULL) goto err;
- goto start;
- }
-
- xi->enc_data=NULL;
- xi->enc_len=0;
-
- xi->x_pkey=X509_PKEY_new();
- ptype = EVP_PKEY_EC;
- pp=&xi->x_pkey->dec_pkey;
- if ((int)strlen(header) > 10) /* assume encrypted */
- raw=1;
- }
- else
- {
- d2i=NULL;
- pp=NULL;
- }
+ if (strcmp(name, PEM_STRING_ECPRIVATEKEY) == 0) {
+ d2i = (D2I_OF(void)) d2i_ECPrivateKey;
+ if (xi->x_pkey != NULL) {
+ if (!sk_X509_INFO_push(ret, xi))
+ goto err;
+ if ((xi = X509_INFO_new()) == NULL)
+ goto err;
+ goto start;
+ }
+
+ xi->enc_data = NULL;
+ xi->enc_len = 0;
- if (d2i != NULL)
- {
- if (!raw)
- {
- EVP_CIPHER_INFO cipher;
+ xi->x_pkey = X509_PKEY_new();
+ ptype = EVP_PKEY_EC;
+ pp = &xi->x_pkey->dec_pkey;
+ if ((int)strlen(header) > 10) /* assume encrypted */
+ raw = 1;
+ } else {
+ d2i = NULL;
+ pp = NULL;
+ }
- if (!PEM_get_EVP_CIPHER_INFO(header,&cipher))
- goto err;
- if (!PEM_do_header(&cipher,data,&len,cb,u))
- goto err;
- p=data;
- if (ptype)
- {
- if (!d2i_PrivateKey(ptype, pp, &p, len))
- {
- OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB);
- goto err;
- }
- }
- else if (d2i(pp,&p,len) == NULL)
- {
- OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB);
- goto err;
- }
- }
- else
- { /* encrypted RSA data */
- if (!PEM_get_EVP_CIPHER_INFO(header,
- &xi->enc_cipher)) goto err;
- xi->enc_data=(char *)data;
- xi->enc_len=(int)len;
- data=NULL;
- }
- }
- else {
- /* unknown */
- }
- if (name != NULL) OPENSSL_free(name);
- if (header != NULL) OPENSSL_free(header);
- if (data != NULL) OPENSSL_free(data);
- name=NULL;
- header=NULL;
- data=NULL;
- }
+ if (d2i != NULL) {
+ if (!raw) {
+ EVP_CIPHER_INFO cipher;
- /* if the last one hasn't been pushed yet and there is anything
- * in it then add it to the stack ...
- */
- if ((xi->x509 != NULL) || (xi->crl != NULL) ||
- (xi->x_pkey != NULL) || (xi->enc_data != NULL))
- {
- if (!sk_X509_INFO_push(ret,xi)) goto err;
- xi=NULL;
- }
- ok=1;
-err:
- if (xi != NULL) X509_INFO_free(xi);
- if (!ok)
- {
- for (i=0; i<sk_X509_INFO_num(ret); i++)
- {
- xi=sk_X509_INFO_value(ret,i);
- X509_INFO_free(xi);
- }
- if (ret != sk) sk_X509_INFO_free(ret);
- ret=NULL;
- }
-
- if (name != NULL) OPENSSL_free(name);
- if (header != NULL) OPENSSL_free(header);
- if (data != NULL) OPENSSL_free(data);
- return(ret);
- }
+ if (!PEM_get_EVP_CIPHER_INFO(header, &cipher))
+ goto err;
+ if (!PEM_do_header(&cipher, data, &len, cb, u))
+ goto err;
+ p = data;
+ if (ptype) {
+ if (!d2i_PrivateKey(ptype, pp, &p, len)) {
+ OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB);
+ goto err;
+ }
+ } else if (d2i(pp, &p, len) == NULL) {
+ OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB);
+ goto err;
+ }
+ } else { /* encrypted RSA data */
+ if (!PEM_get_EVP_CIPHER_INFO(header, &xi->enc_cipher))
+ goto err;
+ xi->enc_data = (char *)data;
+ xi->enc_len = (int)len;
+ data = NULL;
+ }
+ } else {
+ /* unknown */
+ }
+ if (name != NULL)
+ OPENSSL_free(name);
+ if (header != NULL)
+ OPENSSL_free(header);
+ if (data != NULL)
+ OPENSSL_free(data);
+ name = NULL;
+ header = NULL;
+ data = NULL;
+ }
+ /*
+ * if the last one hasn't been pushed yet and there is anything in it
+ * then add it to the stack ...
+ */
+ if ((xi->x509 != NULL) || (xi->crl != NULL) ||
+ (xi->x_pkey != NULL) || (xi->enc_data != NULL)) {
+ if (!sk_X509_INFO_push(ret, xi))
+ goto err;
+ xi = NULL;
+ }
+ ok = 1;
+ err:
+ if (xi != NULL)
+ X509_INFO_free(xi);
+ if (!ok) {
+ for (i = 0; i < sk_X509_INFO_num(ret); i++) {
+ xi = sk_X509_INFO_value(ret, i);
+ X509_INFO_free(xi);
+ }
+ if (ret != sk)
+ sk_X509_INFO_free(ret);
+ ret = NULL;
+ }
+
+ if (name != NULL)
+ OPENSSL_free(name);
+ if (header != NULL)
+ OPENSSL_free(header);
+ if (data != NULL)
+ OPENSSL_free(data);
+ return (ret);
+}
/* A TJH addition */
int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc,
- unsigned char *kstr, int klen, pem_password_cb *cb, void *u)
- {
- EVP_CIPHER_CTX ctx;
- int i,ret=0;
- unsigned char *data=NULL;
- const char *objstr=NULL;
- char buf[PEM_BUFSIZE];
- unsigned char *iv=NULL;
- unsigned iv_len = 0;
-
- if (enc != NULL)
- {
- iv_len = EVP_CIPHER_iv_length(enc);
- objstr=OBJ_nid2sn(EVP_CIPHER_nid(enc));
- if (objstr == NULL)
- {
- OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_CIPHER);
- goto err;
- }
- }
+ unsigned char *kstr, int klen,
+ pem_password_cb *cb, void *u)
+{
+ EVP_CIPHER_CTX ctx;
+ int i, ret = 0;
+ unsigned char *data = NULL;
+ const char *objstr = NULL;
+ char buf[PEM_BUFSIZE];
+ unsigned char *iv = NULL;
+ unsigned iv_len = 0;
+
+ if (enc != NULL) {
+ iv_len = EVP_CIPHER_iv_length(enc);
+ objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc));
+ if (objstr == NULL) {
+ OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_CIPHER);
+ goto err;
+ }
+ }
- /* now for the fun part ... if we have a private key then
- * we have to be able to handle a not-yet-decrypted key
- * being written out correctly ... if it is decrypted or
- * it is non-encrypted then we use the base code
- */
- if (xi->x_pkey!=NULL)
- {
- if ( (xi->enc_data!=NULL) && (xi->enc_len>0) )
- {
- if (enc == NULL)
- {
- OPENSSL_PUT_ERROR(PEM, PEM_R_CIPHER_IS_NULL);
- goto err;
- }
+ /*
+ * now for the fun part ... if we have a private key then we have to be
+ * able to handle a not-yet-decrypted key being written out correctly ...
+ * if it is decrypted or it is non-encrypted then we use the base code
+ */
+ if (xi->x_pkey != NULL) {
+ if ((xi->enc_data != NULL) && (xi->enc_len > 0)) {
+ if (enc == NULL) {
+ OPENSSL_PUT_ERROR(PEM, PEM_R_CIPHER_IS_NULL);
+ goto err;
+ }
- /* copy from weirdo names into more normal things */
- iv=xi->enc_cipher.iv;
- data=(unsigned char *)xi->enc_data;
- i=xi->enc_len;
+ /* copy from weirdo names into more normal things */
+ iv = xi->enc_cipher.iv;
+ data = (unsigned char *)xi->enc_data;
+ i = xi->enc_len;
- /* we take the encryption data from the
- * internal stuff rather than what the
- * user has passed us ... as we have to
- * match exactly for some strange reason
- */
- objstr=OBJ_nid2sn(
- EVP_CIPHER_nid(xi->enc_cipher.cipher));
- if (objstr == NULL)
- {
- OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_CIPHER);
- goto err;
- }
+ /*
+ * we take the encryption data from the internal stuff rather
+ * than what the user has passed us ... as we have to match
+ * exactly for some strange reason
+ */
+ objstr = OBJ_nid2sn(EVP_CIPHER_nid(xi->enc_cipher.cipher));
+ if (objstr == NULL) {
+ OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_CIPHER);
+ goto err;
+ }
- /* create the right magic header stuff */
- assert(strlen(objstr)+23+2*iv_len+13 <= sizeof buf);
- buf[0]='\0';
- PEM_proc_type(buf,PEM_TYPE_ENCRYPTED);
- PEM_dek_info(buf,objstr,iv_len,(char *)iv);
+ /* create the right magic header stuff */
+ assert(strlen(objstr) + 23 + 2 * iv_len + 13 <= sizeof buf);
+ buf[0] = '\0';
+ PEM_proc_type(buf, PEM_TYPE_ENCRYPTED);
+ PEM_dek_info(buf, objstr, iv_len, (char *)iv);
- /* use the normal code to write things out */
- i=PEM_write_bio(bp,PEM_STRING_RSA,buf,data,i);
- if (i <= 0) goto err;
- }
- else
- {
- /* Add DSA/DH */
- /* normal optionally encrypted stuff */
- if (PEM_write_bio_RSAPrivateKey(bp,
- xi->x_pkey->dec_pkey->pkey.rsa,
- enc,kstr,klen,cb,u)<=0)
- goto err;
- }
- }
+ /* use the normal code to write things out */
+ i = PEM_write_bio(bp, PEM_STRING_RSA, buf, data, i);
+ if (i <= 0)
+ goto err;
+ } else {
+ /* Add DSA/DH */
+ /* normal optionally encrypted stuff */
+ if (PEM_write_bio_RSAPrivateKey(bp,
+ xi->x_pkey->dec_pkey->pkey.rsa,
+ enc, kstr, klen, cb, u) <= 0)
+ goto err;
+ }
+ }
- /* if we have a certificate then write it out now */
- if ((xi->x509 != NULL) && (PEM_write_bio_X509(bp,xi->x509) <= 0))
- goto err;
+ /* if we have a certificate then write it out now */
+ if ((xi->x509 != NULL) && (PEM_write_bio_X509(bp, xi->x509) <= 0))
+ goto err;
- /* we are ignoring anything else that is loaded into the X509_INFO
- * structure for the moment ... as I don't need it so I'm not
- * coding it here and Eric can do it when this makes it into the
- * base library --tjh
- */
+ /*
+ * we are ignoring anything else that is loaded into the X509_INFO
+ * structure for the moment ... as I don't need it so I'm not coding it
+ * here and Eric can do it when this makes it into the base library --tjh
+ */
- ret=1;
+ ret = 1;
-err:
- OPENSSL_cleanse((char *)&ctx,sizeof(ctx));
- OPENSSL_cleanse(buf,PEM_BUFSIZE);
- return(ret);
- }
+ err:
+ OPENSSL_cleanse((char *)&ctx, sizeof(ctx));
+ OPENSSL_cleanse(buf, PEM_BUFSIZE);
+ return (ret);
+}
diff --git a/src/crypto/pem/pem_lib.c b/src/crypto/pem/pem_lib.c
index 12d96744..6e928a65 100644
--- a/src/crypto/pem/pem_lib.c
+++ b/src/crypto/pem/pem_lib.c
@@ -71,761 +71,708 @@
#include <openssl/rand.h>
#include <openssl/x509.h>
-#include "../evp/internal.h"
+#define MIN_LENGTH 4
-
-#define MIN_LENGTH 4
-
-static int load_iv(char **fromp,unsigned char *to, int num);
+static int load_iv(char **fromp, unsigned char *to, int num);
static int check_pem(const char *nm, const char *name);
-int pem_check_suffix(const char *pem_str, const char *suffix);
void PEM_proc_type(char *buf, int type)
- {
- const char *str;
-
- if (type == PEM_TYPE_ENCRYPTED)
- str="ENCRYPTED";
- else if (type == PEM_TYPE_MIC_CLEAR)
- str="MIC-CLEAR";
- else if (type == PEM_TYPE_MIC_ONLY)
- str="MIC-ONLY";
- else
- str="BAD-TYPE";
-
- BUF_strlcat(buf,"Proc-Type: 4,",PEM_BUFSIZE);
- BUF_strlcat(buf,str,PEM_BUFSIZE);
- BUF_strlcat(buf,"\n",PEM_BUFSIZE);
- }
+{
+ const char *str;
+
+ if (type == PEM_TYPE_ENCRYPTED)
+ str = "ENCRYPTED";
+ else if (type == PEM_TYPE_MIC_CLEAR)
+ str = "MIC-CLEAR";
+ else if (type == PEM_TYPE_MIC_ONLY)
+ str = "MIC-ONLY";
+ else
+ str = "BAD-TYPE";
+
+ BUF_strlcat(buf, "Proc-Type: 4,", PEM_BUFSIZE);
+ BUF_strlcat(buf, str, PEM_BUFSIZE);
+ BUF_strlcat(buf, "\n", PEM_BUFSIZE);
+}
void PEM_dek_info(char *buf, const char *type, int len, char *str)
- {
- static const unsigned char map[17]="0123456789ABCDEF";
- long i;
- int j;
-
- BUF_strlcat(buf,"DEK-Info: ",PEM_BUFSIZE);
- BUF_strlcat(buf,type,PEM_BUFSIZE);
- BUF_strlcat(buf,",",PEM_BUFSIZE);
- j=strlen(buf);
- if (j + (len * 2) + 1 > PEM_BUFSIZE)
- return;
- for (i=0; i<len; i++)
- {
- buf[j+i*2] =map[(str[i]>>4)&0x0f];
- buf[j+i*2+1]=map[(str[i] )&0x0f];
- }
- buf[j+i*2]='\n';
- buf[j+i*2+1]='\0';
- }
+{
+ static const unsigned char map[17] = "0123456789ABCDEF";
+ long i;
+ int j;
+
+ BUF_strlcat(buf, "DEK-Info: ", PEM_BUFSIZE);
+ BUF_strlcat(buf, type, PEM_BUFSIZE);
+ BUF_strlcat(buf, ",", PEM_BUFSIZE);
+ j = strlen(buf);
+ if (j + (len * 2) + 1 > PEM_BUFSIZE)
+ return;
+ for (i = 0; i < len; i++) {
+ buf[j + i * 2] = map[(str[i] >> 4) & 0x0f];
+ buf[j + i * 2 + 1] = map[(str[i]) & 0x0f];
+ }
+ buf[j + i * 2] = '\n';
+ buf[j + i * 2 + 1] = '\0';
+}
#ifndef OPENSSL_NO_FP_API
void *PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x,
- pem_password_cb *cb, void *u)
- {
- BIO *b;
- void *ret;
-
- if ((b=BIO_new(BIO_s_file())) == NULL)
- {
- OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
- return(0);
- }
- BIO_set_fp(b,fp,BIO_NOCLOSE);
- ret=PEM_ASN1_read_bio(d2i,name,b,x,cb,u);
- BIO_free(b);
- return(ret);
- }
+ pem_password_cb *cb, void *u)
+{
+ BIO *b;
+ void *ret;
+
+ if ((b = BIO_new(BIO_s_file())) == NULL) {
+ OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
+ return (0);
+ }
+ BIO_set_fp(b, fp, BIO_NOCLOSE);
+ ret = PEM_ASN1_read_bio(d2i, name, b, x, cb, u);
+ BIO_free(b);
+ return (ret);
+}
#endif
static int check_pem(const char *nm, const char *name)
{
- /* Normal matching nm and name */
- if (!strcmp(nm,name)) return 1;
-
- /* Make PEM_STRING_EVP_PKEY match any private key */
-
- if(!strcmp(name,PEM_STRING_EVP_PKEY))
- {
- int slen;
- const EVP_PKEY_ASN1_METHOD *ameth;
- if(!strcmp(nm,PEM_STRING_PKCS8))
- return 1;
- if(!strcmp(nm,PEM_STRING_PKCS8INF))
- return 1;
- slen = pem_check_suffix(nm, "PRIVATE KEY");
- if (slen > 0)
- {
- /* NB: ENGINE implementations wont contain
- * a deprecated old private key decode function
- * so don't look for them.
- */
- ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen);
- if (ameth && ameth->old_priv_decode)
- return 1;
- }
- return 0;
- }
-
- if(!strcmp(name,PEM_STRING_PARAMETERS))
- {
- int slen;
- const EVP_PKEY_ASN1_METHOD *ameth;
- slen = pem_check_suffix(nm, "PARAMETERS");
- if (slen > 0)
- {
- ENGINE *e;
- ameth = EVP_PKEY_asn1_find_str(&e, nm, slen);
- if (ameth)
- {
- int r;
- if (ameth->param_decode)
- r = 1;
- else
- r = 0;
- return r;
- }
- }
- return 0;
- }
- /* Permit older strings */
-
- if(!strcmp(nm,PEM_STRING_X509_OLD) &&
- !strcmp(name,PEM_STRING_X509)) return 1;
-
- if(!strcmp(nm,PEM_STRING_X509_REQ_OLD) &&
- !strcmp(name,PEM_STRING_X509_REQ)) return 1;
-
- /* Allow normal certs to be read as trusted certs */
- if(!strcmp(nm,PEM_STRING_X509) &&
- !strcmp(name,PEM_STRING_X509_TRUSTED)) return 1;
-
- if(!strcmp(nm,PEM_STRING_X509_OLD) &&
- !strcmp(name,PEM_STRING_X509_TRUSTED)) return 1;
-
- /* Some CAs use PKCS#7 with CERTIFICATE headers */
- if(!strcmp(nm, PEM_STRING_X509) &&
- !strcmp(name, PEM_STRING_PKCS7)) return 1;
-
- if(!strcmp(nm, PEM_STRING_PKCS7_SIGNED) &&
- !strcmp(name, PEM_STRING_PKCS7)) return 1;
+ /* Normal matching nm and name */
+ if (!strcmp(nm, name))
+ return 1;
+
+ /* Make PEM_STRING_EVP_PKEY match any private key */
+
+ if (!strcmp(name, PEM_STRING_EVP_PKEY)) {
+ return !strcmp(nm, PEM_STRING_PKCS8) ||
+ !strcmp(nm, PEM_STRING_PKCS8INF) ||
+ !strcmp(nm, PEM_STRING_RSA) ||
+ !strcmp(nm, PEM_STRING_EC) ||
+ !strcmp(nm, PEM_STRING_DSA);
+ }
+
+ /* Permit older strings */
+
+ if (!strcmp(nm, PEM_STRING_X509_OLD) && !strcmp(name, PEM_STRING_X509))
+ return 1;
+
+ if (!strcmp(nm, PEM_STRING_X509_REQ_OLD) &&
+ !strcmp(name, PEM_STRING_X509_REQ))
+ return 1;
+
+ /* Allow normal certs to be read as trusted certs */
+ if (!strcmp(nm, PEM_STRING_X509) &&
+ !strcmp(name, PEM_STRING_X509_TRUSTED))
+ return 1;
+
+ if (!strcmp(nm, PEM_STRING_X509_OLD) &&
+ !strcmp(name, PEM_STRING_X509_TRUSTED))
+ return 1;
+
+ /* Some CAs use PKCS#7 with CERTIFICATE headers */
+ if (!strcmp(nm, PEM_STRING_X509) && !strcmp(name, PEM_STRING_PKCS7))
+ return 1;
+
+ if (!strcmp(nm, PEM_STRING_PKCS7_SIGNED) &&
+ !strcmp(name, PEM_STRING_PKCS7))
+ return 1;
#ifndef OPENSSL_NO_CMS
- if(!strcmp(nm, PEM_STRING_X509) &&
- !strcmp(name, PEM_STRING_CMS)) return 1;
- /* Allow CMS to be read from PKCS#7 headers */
- if(!strcmp(nm, PEM_STRING_PKCS7) &&
- !strcmp(name, PEM_STRING_CMS)) return 1;
+ if (!strcmp(nm, PEM_STRING_X509) && !strcmp(name, PEM_STRING_CMS))
+ return 1;
+ /* Allow CMS to be read from PKCS#7 headers */
+ if (!strcmp(nm, PEM_STRING_PKCS7) && !strcmp(name, PEM_STRING_CMS))
+ return 1;
#endif
- return 0;
+ return 0;
}
-int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, const char *name, BIO *bp,
- pem_password_cb *cb, void *u)
- {
- EVP_CIPHER_INFO cipher;
- char *nm=NULL,*header=NULL;
- unsigned char *data=NULL;
- long len;
- int ret = 0;
-
- for (;;)
- {
- if (!PEM_read_bio(bp,&nm,&header,&data,&len)) {
- if(ERR_GET_REASON(ERR_peek_error()) ==
- PEM_R_NO_START_LINE)
- ERR_add_error_data(2, "Expecting: ", name);
- return 0;
- }
- if(check_pem(nm, name)) break;
- OPENSSL_free(nm);
- OPENSSL_free(header);
- OPENSSL_free(data);
- }
- if (!PEM_get_EVP_CIPHER_INFO(header,&cipher)) goto err;
- if (!PEM_do_header(&cipher,data,&len,cb,u)) goto err;
-
- *pdata = data;
- *plen = len;
-
- if (pnm)
- *pnm = nm;
-
- ret = 1;
-
-err:
- if (!ret || !pnm) OPENSSL_free(nm);
- OPENSSL_free(header);
- if (!ret) OPENSSL_free(data);
- return ret;
- }
+int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm,
+ const char *name, BIO *bp, pem_password_cb *cb,
+ void *u)
+{
+ EVP_CIPHER_INFO cipher;
+ char *nm = NULL, *header = NULL;
+ unsigned char *data = NULL;
+ long len;
+ int ret = 0;
+
+ for (;;) {
+ if (!PEM_read_bio(bp, &nm, &header, &data, &len)) {
+ if (ERR_GET_REASON(ERR_peek_error()) == PEM_R_NO_START_LINE)
+ ERR_add_error_data(2, "Expecting: ", name);
+ return 0;
+ }
+ if (check_pem(nm, name))
+ break;
+ OPENSSL_free(nm);
+ OPENSSL_free(header);
+ OPENSSL_free(data);
+ }
+ if (!PEM_get_EVP_CIPHER_INFO(header, &cipher))
+ goto err;
+ if (!PEM_do_header(&cipher, data, &len, cb, u))
+ goto err;
+
+ *pdata = data;
+ *plen = len;
+
+ if (pnm)
+ *pnm = nm;
+
+ ret = 1;
+
+ err:
+ if (!ret || !pnm)
+ OPENSSL_free(nm);
+ OPENSSL_free(header);
+ if (!ret)
+ OPENSSL_free(data);
+ return ret;
+}
#ifndef OPENSSL_NO_FP_API
int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp,
- void *x, const EVP_CIPHER *enc, unsigned char *kstr,
- int klen, pem_password_cb *callback, void *u)
- {
- BIO *b;
- int ret;
-
- if ((b=BIO_new(BIO_s_file())) == NULL)
- {
- OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
- return(0);
- }
- BIO_set_fp(b,fp,BIO_NOCLOSE);
- ret=PEM_ASN1_write_bio(i2d,name,b,x,enc,kstr,klen,callback,u);
- BIO_free(b);
- return(ret);
- }
+ void *x, const EVP_CIPHER *enc, unsigned char *kstr,
+ int klen, pem_password_cb *callback, void *u)
+{
+ BIO *b;
+ int ret;
+
+ if ((b = BIO_new(BIO_s_file())) == NULL) {
+ OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
+ return (0);
+ }
+ BIO_set_fp(b, fp, BIO_NOCLOSE);
+ ret = PEM_ASN1_write_bio(i2d, name, b, x, enc, kstr, klen, callback, u);
+ BIO_free(b);
+ return (ret);
+}
#endif
int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp,
- void *x, const EVP_CIPHER *enc, unsigned char *kstr,
- int klen, pem_password_cb *callback, void *u)
- {
- EVP_CIPHER_CTX ctx;
- int dsize=0,i,j,ret=0;
- unsigned char *p,*data=NULL;
- const char *objstr=NULL;
- char buf[PEM_BUFSIZE];
- unsigned char key[EVP_MAX_KEY_LENGTH];
- unsigned char iv[EVP_MAX_IV_LENGTH];
-
- if (enc != NULL)
- {
- objstr=OBJ_nid2sn(EVP_CIPHER_nid(enc));
- if (objstr == NULL)
- {
- OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_CIPHER);
- goto err;
- }
- }
-
- if ((dsize=i2d(x,NULL)) < 0)
- {
- OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB);
- dsize=0;
- goto err;
- }
- /* dzise + 8 bytes are needed */
- /* actually it needs the cipher block size extra... */
- data=(unsigned char *)OPENSSL_malloc((unsigned int)dsize+20);
- if (data == NULL)
- {
- OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- p=data;
- i=i2d(x,&p);
-
- if (enc != NULL)
- {
- const unsigned iv_len = EVP_CIPHER_iv_length(enc);
-
- if (kstr == NULL)
- {
- klen = 0;
- if (!callback)
- callback = PEM_def_callback;
- klen=(*callback)(buf,PEM_BUFSIZE,1,u);
- if (klen <= 0)
- {
- OPENSSL_PUT_ERROR(PEM, PEM_R_READ_KEY);
- goto err;
- }
- kstr=(unsigned char *)buf;
- }
- assert(iv_len <= (int)sizeof(iv));
- if (!RAND_bytes(iv, iv_len)) /* Generate a salt */
- goto err;
- /* The 'iv' is used as the iv and as a salt. It is
- * NOT taken from the BytesToKey function */
- if (!EVP_BytesToKey(enc,EVP_md5(),iv,kstr,klen,1,key,NULL))
- goto err;
-
- if (kstr == (unsigned char *)buf) OPENSSL_cleanse(buf,PEM_BUFSIZE);
-
- assert(strlen(objstr)+23+2*iv_len+13 <= sizeof buf);
-
- buf[0]='\0';
- PEM_proc_type(buf,PEM_TYPE_ENCRYPTED);
- PEM_dek_info(buf,objstr,iv_len,(char *)iv);
- /* k=strlen(buf); */
-
- EVP_CIPHER_CTX_init(&ctx);
- ret = 1;
- if (!EVP_EncryptInit_ex(&ctx,enc,NULL,key,iv)
- || !EVP_EncryptUpdate(&ctx,data,&j,data,i)
- || !EVP_EncryptFinal_ex(&ctx,&(data[j]),&i))
- ret = 0;
- else
- i += j;
- EVP_CIPHER_CTX_cleanup(&ctx);
- if (ret == 0)
- goto err;
- }
- else
- {
- ret=1;
- buf[0]='\0';
- }
- i=PEM_write_bio(bp,name,buf,data,i);
- if (i <= 0) ret=0;
-err:
- OPENSSL_cleanse(key,sizeof(key));
- OPENSSL_cleanse(iv,sizeof(iv));
- OPENSSL_cleanse((char *)&ctx,sizeof(ctx));
- OPENSSL_cleanse(buf,PEM_BUFSIZE);
- if (data != NULL)
- {
- OPENSSL_cleanse(data,(unsigned int)dsize);
- OPENSSL_free(data);
- }
- return(ret);
- }
+ void *x, const EVP_CIPHER *enc, unsigned char *kstr,
+ int klen, pem_password_cb *callback, void *u)
+{
+ EVP_CIPHER_CTX ctx;
+ int dsize = 0, i, j, ret = 0;
+ unsigned char *p, *data = NULL;
+ const char *objstr = NULL;
+ char buf[PEM_BUFSIZE];
+ unsigned char key[EVP_MAX_KEY_LENGTH];
+ unsigned char iv[EVP_MAX_IV_LENGTH];
+
+ if (enc != NULL) {
+ objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc));
+ if (objstr == NULL) {
+ OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_CIPHER);
+ goto err;
+ }
+ }
+
+ if ((dsize = i2d(x, NULL)) < 0) {
+ OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB);
+ dsize = 0;
+ goto err;
+ }
+ /* dzise + 8 bytes are needed */
+ /* actually it needs the cipher block size extra... */
+ data = (unsigned char *)OPENSSL_malloc((unsigned int)dsize + 20);
+ if (data == NULL) {
+ OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ p = data;
+ i = i2d(x, &p);
+
+ if (enc != NULL) {
+ const unsigned iv_len = EVP_CIPHER_iv_length(enc);
+
+ if (kstr == NULL) {
+ klen = 0;
+ if (!callback)
+ callback = PEM_def_callback;
+ klen = (*callback) (buf, PEM_BUFSIZE, 1, u);
+ if (klen <= 0) {
+ OPENSSL_PUT_ERROR(PEM, PEM_R_READ_KEY);
+ goto err;
+ }
+ kstr = (unsigned char *)buf;
+ }
+ assert(iv_len <= (int)sizeof(iv));
+ if (!RAND_bytes(iv, iv_len)) /* Generate a salt */
+ goto err;
+ /*
+ * The 'iv' is used as the iv and as a salt. It is NOT taken from
+ * the BytesToKey function
+ */
+ if (!EVP_BytesToKey(enc, EVP_md5(), iv, kstr, klen, 1, key, NULL))
+ goto err;
+
+ if (kstr == (unsigned char *)buf)
+ OPENSSL_cleanse(buf, PEM_BUFSIZE);
+
+ assert(strlen(objstr) + 23 + 2 * iv_len + 13 <= sizeof buf);
+
+ buf[0] = '\0';
+ PEM_proc_type(buf, PEM_TYPE_ENCRYPTED);
+ PEM_dek_info(buf, objstr, iv_len, (char *)iv);
+ /* k=strlen(buf); */
+
+ EVP_CIPHER_CTX_init(&ctx);
+ ret = 1;
+ if (!EVP_EncryptInit_ex(&ctx, enc, NULL, key, iv)
+ || !EVP_EncryptUpdate(&ctx, data, &j, data, i)
+ || !EVP_EncryptFinal_ex(&ctx, &(data[j]), &i))
+ ret = 0;
+ else
+ i += j;
+ EVP_CIPHER_CTX_cleanup(&ctx);
+ if (ret == 0)
+ goto err;
+ } else {
+ ret = 1;
+ buf[0] = '\0';
+ }
+ i = PEM_write_bio(bp, name, buf, data, i);
+ if (i <= 0)
+ ret = 0;
+ err:
+ OPENSSL_cleanse(key, sizeof(key));
+ OPENSSL_cleanse(iv, sizeof(iv));
+ OPENSSL_cleanse((char *)&ctx, sizeof(ctx));
+ OPENSSL_cleanse(buf, PEM_BUFSIZE);
+ if (data != NULL) {
+ OPENSSL_cleanse(data, (unsigned int)dsize);
+ OPENSSL_free(data);
+ }
+ return (ret);
+}
int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *plen,
- pem_password_cb *callback,void *u)
- {
- int i=0,j,o,klen;
- long len;
- EVP_CIPHER_CTX ctx;
- unsigned char key[EVP_MAX_KEY_LENGTH];
- char buf[PEM_BUFSIZE];
-
- len= *plen;
-
- if (cipher->cipher == NULL) return(1);
-
- klen = 0;
- if (!callback) callback = PEM_def_callback;
- klen=callback(buf,PEM_BUFSIZE,0,u);
- if (klen <= 0)
- {
- OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_PASSWORD_READ);
- return(0);
- }
-
- if (!EVP_BytesToKey(cipher->cipher,EVP_md5(),&(cipher->iv[0]),
- (unsigned char *)buf,klen,1,key,NULL))
- return 0;
-
- j=(int)len;
- EVP_CIPHER_CTX_init(&ctx);
- o = EVP_DecryptInit_ex(&ctx,cipher->cipher,NULL, key,&(cipher->iv[0]));
- if (o)
- o = EVP_DecryptUpdate(&ctx,data,&i,data,j);
- if (o)
- o = EVP_DecryptFinal_ex(&ctx,&(data[i]),&j);
- EVP_CIPHER_CTX_cleanup(&ctx);
- OPENSSL_cleanse((char *)buf,sizeof(buf));
- OPENSSL_cleanse((char *)key,sizeof(key));
- if (!o)
- {
- OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_DECRYPT);
- return(0);
- }
- j+=i;
- *plen=j;
- return(1);
- }
-
-static const EVP_CIPHER* cipher_by_name(const char *name) {
- /* 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 (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 (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;
- }
+ pem_password_cb *callback, void *u)
+{
+ int i = 0, j, o, klen;
+ long len;
+ EVP_CIPHER_CTX ctx;
+ unsigned char key[EVP_MAX_KEY_LENGTH];
+ char buf[PEM_BUFSIZE];
+
+ len = *plen;
+
+ if (cipher->cipher == NULL)
+ return (1);
+
+ klen = 0;
+ if (!callback)
+ callback = PEM_def_callback;
+ klen = callback(buf, PEM_BUFSIZE, 0, u);
+ if (klen <= 0) {
+ OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_PASSWORD_READ);
+ return (0);
+ }
+
+ if (!EVP_BytesToKey(cipher->cipher, EVP_md5(), &(cipher->iv[0]),
+ (unsigned char *)buf, klen, 1, key, NULL))
+ return 0;
+
+ j = (int)len;
+ EVP_CIPHER_CTX_init(&ctx);
+ o = EVP_DecryptInit_ex(&ctx, cipher->cipher, NULL, key, &(cipher->iv[0]));
+ if (o)
+ o = EVP_DecryptUpdate(&ctx, data, &i, data, j);
+ if (o)
+ o = EVP_DecryptFinal_ex(&ctx, &(data[i]), &j);
+ EVP_CIPHER_CTX_cleanup(&ctx);
+ OPENSSL_cleanse((char *)buf, sizeof(buf));
+ OPENSSL_cleanse((char *)key, sizeof(key));
+ if (!o) {
+ OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_DECRYPT);
+ return (0);
+ }
+ j += i;
+ *plen = j;
+ return (1);
+}
+
+static const EVP_CIPHER *cipher_by_name(const char *name)
+{
+ /* 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 (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 (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;
+ }
}
int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher)
- {
- const EVP_CIPHER *enc=NULL;
- char *p,c;
- char **header_pp = &header;
-
- cipher->cipher=NULL;
- if ((header == NULL) || (*header == '\0') || (*header == '\n'))
- return(1);
- if (strncmp(header,"Proc-Type: ",11) != 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_R_NOT_ENCRYPTED); return(0); }
- for (; (*header != '\n') && (*header != '\0'); header++)
- ;
- if (*header == '\0')
- { OPENSSL_PUT_ERROR(PEM, PEM_R_SHORT_HEADER); return(0); }
- header++;
- if (strncmp(header,"DEK-Info: ",10) != 0)
- { OPENSSL_PUT_ERROR(PEM, PEM_R_NOT_DEK_INFO); return(0); }
- header+=10;
-
- p=header;
- for (;;)
- {
- c= *header;
- if (!( ((c >= 'A') && (c <= 'Z')) || (c == '-') ||
- ((c >= '0') && (c <= '9'))))
- break;
- header++;
- }
- *header='\0';
- cipher->cipher=enc=cipher_by_name(p);
- *header=c;
- header++;
-
- if (enc == NULL)
- {
- OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_ENCRYPTION);
- return(0);
- }
- if (!load_iv(header_pp,&(cipher->iv[0]),EVP_CIPHER_iv_length(enc)))
- return(0);
-
- return(1);
- }
+{
+ const EVP_CIPHER *enc = NULL;
+ char *p, c;
+ char **header_pp = &header;
+
+ cipher->cipher = NULL;
+ if ((header == NULL) || (*header == '\0') || (*header == '\n'))
+ return (1);
+ if (strncmp(header, "Proc-Type: ", 11) != 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_R_NOT_ENCRYPTED);
+ return (0);
+ }
+ for (; (*header != '\n') && (*header != '\0'); header++) ;
+ if (*header == '\0') {
+ OPENSSL_PUT_ERROR(PEM, PEM_R_SHORT_HEADER);
+ return (0);
+ }
+ header++;
+ if (strncmp(header, "DEK-Info: ", 10) != 0) {
+ OPENSSL_PUT_ERROR(PEM, PEM_R_NOT_DEK_INFO);
+ return (0);
+ }
+ header += 10;
+
+ p = header;
+ for (;;) {
+ c = *header;
+ if (!(((c >= 'A') && (c <= 'Z')) || (c == '-') ||
+ ((c >= '0') && (c <= '9'))))
+ break;
+ header++;
+ }
+ *header = '\0';
+ cipher->cipher = enc = cipher_by_name(p);
+ *header = c;
+ header++;
+
+ if (enc == NULL) {
+ OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_ENCRYPTION);
+ return (0);
+ }
+ if (!load_iv(header_pp, &(cipher->iv[0]), EVP_CIPHER_iv_length(enc)))
+ return (0);
+
+ return (1);
+}
static int load_iv(char **fromp, unsigned char *to, int num)
- {
- int v,i;
- char *from;
-
- from= *fromp;
- for (i=0; i<num; i++) to[i]=0;
- num*=2;
- for (i=0; i<num; i++)
- {
- if ((*from >= '0') && (*from <= '9'))
- v= *from-'0';
- else if ((*from >= 'A') && (*from <= 'F'))
- v= *from-'A'+10;
- else if ((*from >= 'a') && (*from <= 'f'))
- v= *from-'a'+10;
- else
- {
- OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_IV_CHARS);
- return(0);
- }
- from++;
- to[i/2]|=v<<(long)((!(i&1))*4);
- }
-
- *fromp=from;
- return(1);
- }
+{
+ int v, i;
+ char *from;
+
+ from = *fromp;
+ for (i = 0; i < num; i++)
+ to[i] = 0;
+ num *= 2;
+ for (i = 0; i < num; i++) {
+ if ((*from >= '0') && (*from <= '9'))
+ v = *from - '0';
+ else if ((*from >= 'A') && (*from <= 'F'))
+ v = *from - 'A' + 10;
+ else if ((*from >= 'a') && (*from <= 'f'))
+ v = *from - 'a' + 10;
+ else {
+ OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_IV_CHARS);
+ return (0);
+ }
+ from++;
+ to[i / 2] |= v << (long)((!(i & 1)) * 4);
+ }
+
+ *fromp = from;
+ return (1);
+}
#ifndef OPENSSL_NO_FP_API
int PEM_write(FILE *fp, const char *name, const char *header,
- const unsigned char *data, long len)
- {
- BIO *b;
- int ret;
-
- if ((b=BIO_new(BIO_s_file())) == NULL)
- {
- OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
- return(0);
- }
- BIO_set_fp(b,fp,BIO_NOCLOSE);
- ret=PEM_write_bio(b, name, header, data,len);
- BIO_free(b);
- return(ret);
- }
+ const unsigned char *data, long len)
+{
+ BIO *b;
+ int ret;
+
+ if ((b = BIO_new(BIO_s_file())) == NULL) {
+ OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
+ return (0);
+ }
+ BIO_set_fp(b, fp, BIO_NOCLOSE);
+ ret = PEM_write_bio(b, name, header, data, len);
+ BIO_free(b);
+ return (ret);
+}
#endif
int PEM_write_bio(BIO *bp, const char *name, const char *header,
- const unsigned char *data, long len)
- {
- int nlen,n,i,j,outl;
- unsigned char *buf = NULL;
- EVP_ENCODE_CTX ctx;
- int reason=ERR_R_BUF_LIB;
-
- EVP_EncodeInit(&ctx);
- nlen=strlen(name);
-
- if ( (BIO_write(bp,"-----BEGIN ",11) != 11) ||
- (BIO_write(bp,name,nlen) != nlen) ||
- (BIO_write(bp,"-----\n",6) != 6))
- goto err;
-
- i=strlen(header);
- if (i > 0)
- {
- if ( (BIO_write(bp,header,i) != i) ||
- (BIO_write(bp,"\n",1) != 1))
- goto err;
- }
-
- buf = OPENSSL_malloc(PEM_BUFSIZE*8);
- if (buf == NULL)
- {
- reason=ERR_R_MALLOC_FAILURE;
- goto err;
- }
-
- i=j=0;
- while (len > 0)
- {
- n=(int)((len>(PEM_BUFSIZE*5))?(PEM_BUFSIZE*5):len);
- EVP_EncodeUpdate(&ctx,buf,&outl,&(data[j]),n);
- if ((outl) && (BIO_write(bp,(char *)buf,outl) != outl))
- goto err;
- i+=outl;
- len-=n;
- j+=n;
- }
- EVP_EncodeFinal(&ctx,buf,&outl);
- if ((outl > 0) && (BIO_write(bp,(char *)buf,outl) != outl)) goto err;
- OPENSSL_cleanse(buf, PEM_BUFSIZE*8);
- OPENSSL_free(buf);
- buf = NULL;
- if ( (BIO_write(bp,"-----END ",9) != 9) ||
- (BIO_write(bp,name,nlen) != nlen) ||
- (BIO_write(bp,"-----\n",6) != 6))
- goto err;
- return(i+outl);
-err:
- if (buf) {
- OPENSSL_cleanse(buf, PEM_BUFSIZE*8);
- OPENSSL_free(buf);
- }
- OPENSSL_PUT_ERROR(PEM, reason);
- return(0);
- }
+ const unsigned char *data, long len)
+{
+ int nlen, n, i, j, outl;
+ unsigned char *buf = NULL;
+ EVP_ENCODE_CTX ctx;
+ int reason = ERR_R_BUF_LIB;
+
+ EVP_EncodeInit(&ctx);
+ nlen = strlen(name);
+
+ if ((BIO_write(bp, "-----BEGIN ", 11) != 11) ||
+ (BIO_write(bp, name, nlen) != nlen) ||
+ (BIO_write(bp, "-----\n", 6) != 6))
+ goto err;
+
+ i = strlen(header);
+ if (i > 0) {
+ if ((BIO_write(bp, header, i) != i) || (BIO_write(bp, "\n", 1) != 1))
+ goto err;
+ }
+
+ buf = OPENSSL_malloc(PEM_BUFSIZE * 8);
+ if (buf == NULL) {
+ reason = ERR_R_MALLOC_FAILURE;
+ goto err;
+ }
+
+ i = j = 0;
+ while (len > 0) {
+ n = (int)((len > (PEM_BUFSIZE * 5)) ? (PEM_BUFSIZE * 5) : len);
+ EVP_EncodeUpdate(&ctx, buf, &outl, &(data[j]), n);
+ if ((outl) && (BIO_write(bp, (char *)buf, outl) != outl))
+ goto err;
+ i += outl;
+ len -= n;
+ j += n;
+ }
+ EVP_EncodeFinal(&ctx, buf, &outl);
+ if ((outl > 0) && (BIO_write(bp, (char *)buf, outl) != outl))
+ goto err;
+ OPENSSL_cleanse(buf, PEM_BUFSIZE * 8);
+ OPENSSL_free(buf);
+ buf = NULL;
+ if ((BIO_write(bp, "-----END ", 9) != 9) ||
+ (BIO_write(bp, name, nlen) != nlen) ||
+ (BIO_write(bp, "-----\n", 6) != 6))
+ goto err;
+ return (i + outl);
+ err:
+ if (buf) {
+ OPENSSL_cleanse(buf, PEM_BUFSIZE * 8);
+ OPENSSL_free(buf);
+ }
+ OPENSSL_PUT_ERROR(PEM, reason);
+ return (0);
+}
#ifndef OPENSSL_NO_FP_API
int PEM_read(FILE *fp, char **name, char **header, unsigned char **data,
- long *len)
- {
- BIO *b;
- int ret;
-
- if ((b=BIO_new(BIO_s_file())) == NULL)
- {
- OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
- return(0);
- }
- BIO_set_fp(b,fp,BIO_NOCLOSE);
- ret=PEM_read_bio(b, name, header, data,len);
- BIO_free(b);
- return(ret);
- }
+ long *len)
+{
+ BIO *b;
+ int ret;
+
+ if ((b = BIO_new(BIO_s_file())) == NULL) {
+ OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
+ return (0);
+ }
+ BIO_set_fp(b, fp, BIO_NOCLOSE);
+ ret = PEM_read_bio(b, name, header, data, len);
+ BIO_free(b);
+ return (ret);
+}
#endif
int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data,
- long *len)
- {
- EVP_ENCODE_CTX ctx;
- int end=0,i,k,bl=0,hl=0,nohead=0;
- char buf[256];
- BUF_MEM *nameB;
- BUF_MEM *headerB;
- BUF_MEM *dataB,*tmpB;
-
- nameB=BUF_MEM_new();
- headerB=BUF_MEM_new();
- dataB=BUF_MEM_new();
- if ((nameB == NULL) || (headerB == NULL) || (dataB == NULL))
- {
- BUF_MEM_free(nameB);
- BUF_MEM_free(headerB);
- BUF_MEM_free(dataB);
- OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE);
- return(0);
- }
-
- buf[254]='\0';
- for (;;)
- {
- i=BIO_gets(bp,buf,254);
-
- if (i <= 0)
- {
- OPENSSL_PUT_ERROR(PEM, PEM_R_NO_START_LINE);
- goto err;
- }
-
- while ((i >= 0) && (buf[i] <= ' ')) i--;
- buf[++i]='\n'; buf[++i]='\0';
-
- if (strncmp(buf,"-----BEGIN ",11) == 0)
- {
- i=strlen(&(buf[11]));
-
- if (strncmp(&(buf[11+i-6]),"-----\n",6) != 0)
- continue;
- if (!BUF_MEM_grow(nameB,i+9))
- {
- OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- memcpy(nameB->data,&(buf[11]),i-6);
- nameB->data[i-6]='\0';
- break;
- }
- }
- hl=0;
- if (!BUF_MEM_grow(headerB,256))
- { OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); goto err; }
- headerB->data[0]='\0';
- for (;;)
- {
- i=BIO_gets(bp,buf,254);
- if (i <= 0) break;
-
- while ((i >= 0) && (buf[i] <= ' ')) i--;
- buf[++i]='\n'; buf[++i]='\0';
-
- if (buf[0] == '\n') break;
- if (!BUF_MEM_grow(headerB,hl+i+9))
- { OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); goto err; }
- if (strncmp(buf,"-----END ",9) == 0)
- {
- nohead=1;
- break;
- }
- memcpy(&(headerB->data[hl]),buf,i);
- headerB->data[hl+i]='\0';
- hl+=i;
- }
-
- bl=0;
- if (!BUF_MEM_grow(dataB,1024))
- { OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); goto err; }
- dataB->data[0]='\0';
- if (!nohead)
- {
- for (;;)
- {
- i=BIO_gets(bp,buf,254);
- if (i <= 0) break;
-
- while ((i >= 0) && (buf[i] <= ' ')) i--;
- buf[++i]='\n'; buf[++i]='\0';
-
- if (i != 65) end=1;
- if (strncmp(buf,"-----END ",9) == 0)
- break;
- if (i > 65) break;
- if (!BUF_MEM_grow_clean(dataB,i+bl+9))
- {
- OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- memcpy(&(dataB->data[bl]),buf,i);
- dataB->data[bl+i]='\0';
- bl+=i;
- if (end)
- {
- buf[0]='\0';
- i=BIO_gets(bp,buf,254);
- if (i <= 0) break;
-
- while ((i >= 0) && (buf[i] <= ' ')) i--;
- buf[++i]='\n'; buf[++i]='\0';
-
- break;
- }
- }
- }
- else
- {
- tmpB=headerB;
- headerB=dataB;
- dataB=tmpB;
- bl=hl;
- }
- i=strlen(nameB->data);
- if ( (strncmp(buf,"-----END ",9) != 0) ||
- (strncmp(nameB->data,&(buf[9]),i) != 0) ||
- (strncmp(&(buf[9+i]),"-----\n",6) != 0))
- {
- OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_END_LINE);
- goto err;
- }
-
- EVP_DecodeInit(&ctx);
- i=EVP_DecodeUpdate(&ctx,
- (unsigned char *)dataB->data,&bl,
- (unsigned char *)dataB->data,bl);
- if (i < 0)
- {
- 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_R_BAD_BASE64_DECODE);
- goto err;
- }
- bl+=k;
-
- if (bl == 0) goto err;
- *name=nameB->data;
- *header=headerB->data;
- *data=(unsigned char *)dataB->data;
- *len=bl;
- OPENSSL_free(nameB);
- OPENSSL_free(headerB);
- OPENSSL_free(dataB);
- return(1);
-err:
- BUF_MEM_free(nameB);
- BUF_MEM_free(headerB);
- BUF_MEM_free(dataB);
- return(0);
- }
-
-/* Check pem string and return prefix length.
- * If for example the pem_str == "RSA PRIVATE KEY" and suffix = "PRIVATE KEY"
- * the return value is 3 for the string "RSA".
- */
-
-int pem_check_suffix(const char *pem_str, const char *suffix)
- {
- int pem_len = strlen(pem_str);
- int suffix_len = strlen(suffix);
- const char *p;
- if (suffix_len + 1 >= pem_len)
- return 0;
- p = pem_str + pem_len - suffix_len;
- if (strcmp(p, suffix))
- return 0;
- p--;
- if (*p != ' ')
- return 0;
- return p - pem_str;
- }
+ long *len)
+{
+ EVP_ENCODE_CTX ctx;
+ int end = 0, i, k, bl = 0, hl = 0, nohead = 0;
+ char buf[256];
+ BUF_MEM *nameB;
+ BUF_MEM *headerB;
+ BUF_MEM *dataB, *tmpB;
+
+ nameB = BUF_MEM_new();
+ headerB = BUF_MEM_new();
+ dataB = BUF_MEM_new();
+ if ((nameB == NULL) || (headerB == NULL) || (dataB == NULL)) {
+ BUF_MEM_free(nameB);
+ BUF_MEM_free(headerB);
+ BUF_MEM_free(dataB);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE);
+ return (0);
+ }
+
+ buf[254] = '\0';
+ for (;;) {
+ i = BIO_gets(bp, buf, 254);
+
+ if (i <= 0) {
+ OPENSSL_PUT_ERROR(PEM, PEM_R_NO_START_LINE);
+ goto err;
+ }
+
+ while ((i >= 0) && (buf[i] <= ' '))
+ i--;
+ buf[++i] = '\n';
+ buf[++i] = '\0';
+
+ if (strncmp(buf, "-----BEGIN ", 11) == 0) {
+ i = strlen(&(buf[11]));
+
+ if (strncmp(&(buf[11 + i - 6]), "-----\n", 6) != 0)
+ continue;
+ if (!BUF_MEM_grow(nameB, i + 9)) {
+ OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ memcpy(nameB->data, &(buf[11]), i - 6);
+ nameB->data[i - 6] = '\0';
+ break;
+ }
+ }
+ hl = 0;
+ if (!BUF_MEM_grow(headerB, 256)) {
+ OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ headerB->data[0] = '\0';
+ for (;;) {
+ i = BIO_gets(bp, buf, 254);
+ if (i <= 0)
+ break;
+
+ while ((i >= 0) && (buf[i] <= ' '))
+ i--;
+ buf[++i] = '\n';
+ buf[++i] = '\0';
+
+ if (buf[0] == '\n')
+ break;
+ if (!BUF_MEM_grow(headerB, hl + i + 9)) {
+ OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if (strncmp(buf, "-----END ", 9) == 0) {
+ nohead = 1;
+ break;
+ }
+ memcpy(&(headerB->data[hl]), buf, i);
+ headerB->data[hl + i] = '\0';
+ hl += i;
+ }
+
+ bl = 0;
+ if (!BUF_MEM_grow(dataB, 1024)) {
+ OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ dataB->data[0] = '\0';
+ if (!nohead) {
+ for (;;) {
+ i = BIO_gets(bp, buf, 254);
+ if (i <= 0)
+ break;
+
+ while ((i >= 0) && (buf[i] <= ' '))
+ i--;
+ buf[++i] = '\n';
+ buf[++i] = '\0';
+
+ if (i != 65)
+ end = 1;
+ if (strncmp(buf, "-----END ", 9) == 0)
+ break;
+ if (i > 65)
+ break;
+ if (!BUF_MEM_grow_clean(dataB, i + bl + 9)) {
+ OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ memcpy(&(dataB->data[bl]), buf, i);
+ dataB->data[bl + i] = '\0';
+ bl += i;
+ if (end) {
+ buf[0] = '\0';
+ i = BIO_gets(bp, buf, 254);
+ if (i <= 0)
+ break;
+
+ while ((i >= 0) && (buf[i] <= ' '))
+ i--;
+ buf[++i] = '\n';
+ buf[++i] = '\0';
+
+ break;
+ }
+ }
+ } else {
+ tmpB = headerB;
+ headerB = dataB;
+ dataB = tmpB;
+ bl = hl;
+ }
+ i = strlen(nameB->data);
+ if ((strncmp(buf, "-----END ", 9) != 0) ||
+ (strncmp(nameB->data, &(buf[9]), i) != 0) ||
+ (strncmp(&(buf[9 + i]), "-----\n", 6) != 0)) {
+ OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_END_LINE);
+ goto err;
+ }
+
+ EVP_DecodeInit(&ctx);
+ i = EVP_DecodeUpdate(&ctx,
+ (unsigned char *)dataB->data, &bl,
+ (unsigned char *)dataB->data, bl);
+ if (i < 0) {
+ 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_R_BAD_BASE64_DECODE);
+ goto err;
+ }
+ bl += k;
+
+ if (bl == 0)
+ goto err;
+ *name = nameB->data;
+ *header = headerB->data;
+ *data = (unsigned char *)dataB->data;
+ *len = bl;
+ OPENSSL_free(nameB);
+ OPENSSL_free(headerB);
+ OPENSSL_free(dataB);
+ return (1);
+ err:
+ BUF_MEM_free(nameB);
+ BUF_MEM_free(headerB);
+ BUF_MEM_free(dataB);
+ return (0);
+}
int PEM_def_callback(char *buf, int size, int rwflag, void *userdata)
- {
- if (!buf || !userdata)
- {
- return 0;
- }
- size_t len = strlen((char *) userdata);
- if (len >= (size_t) size)
- {
- return 0;
- }
- strcpy(buf, (char *) userdata);
- return len;
- }
+{
+ if (!buf || !userdata) {
+ return 0;
+ }
+ size_t len = strlen((char *)userdata);
+ if (len >= (size_t)size) {
+ return 0;
+ }
+ strcpy(buf, (char *)userdata);
+ return len;
+}
diff --git a/src/crypto/pem/pem_oth.c b/src/crypto/pem/pem_oth.c
index 3e8f6bda..8530c567 100644
--- a/src/crypto/pem/pem_oth.c
+++ b/src/crypto/pem/pem_oth.c
@@ -67,23 +67,22 @@
#include <openssl/rand.h>
#include <openssl/x509.h>
-
/* Handle 'other' PEMs: not private keys */
void *PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp, void **x,
- pem_password_cb *cb, void *u)
- {
- const unsigned char *p=NULL;
- unsigned char *data=NULL;
- long len;
- char *ret=NULL;
+ pem_password_cb *cb, void *u)
+{
+ const unsigned char *p = NULL;
+ unsigned char *data = NULL;
+ long len;
+ char *ret = NULL;
- if (!PEM_bytes_read_bio(&data, &len, NULL, name, bp, cb, u))
- return NULL;
- p = data;
- ret=d2i(x,&p,len);
- if (ret == NULL)
- OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB);
- OPENSSL_free(data);
- return ret;
- }
+ if (!PEM_bytes_read_bio(&data, &len, NULL, name, bp, cb, u))
+ return NULL;
+ p = data;
+ ret = d2i(x, &p, len);
+ if (ret == NULL)
+ 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 08244772..550661d6 100644
--- a/src/crypto/pem/pem_pk8.c
+++ b/src/crypto/pem/pem_pk8.c
@@ -65,180 +65,193 @@
#include <openssl/rand.h>
#include <openssl/x509.h>
-
static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder,
- int nid, const EVP_CIPHER *enc,
- char *kstr, int klen,
- pem_password_cb *cb, void *u);
+ int nid, const EVP_CIPHER *enc,
+ char *kstr, int klen, pem_password_cb *cb, void *u);
static int do_pk8pkey_fp(FILE *bp, EVP_PKEY *x, int isder,
- int nid, const EVP_CIPHER *enc,
- char *kstr, int klen,
- pem_password_cb *cb, void *u);
+ int nid, const EVP_CIPHER *enc,
+ char *kstr, int klen, pem_password_cb *cb, void *u);
-/* These functions write a private key in PKCS#8 format: it is a "drop in"
+/*
+ * These functions write a private key in PKCS#8 format: it is a "drop in"
* replacement for PEM_write_bio_PrivateKey() and friends. As usual if 'enc'
* is NULL then it uses the unencrypted private key form. The 'nid' versions
* uses PKCS#5 v1.5 PBE algorithms whereas the others use PKCS#5 v2.0.
*/
int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid,
- char *kstr, int klen,
- pem_password_cb *cb, void *u)
+ char *kstr, int klen,
+ pem_password_cb *cb, void *u)
{
- return do_pk8pkey(bp, x, 0, nid, NULL, kstr, klen, cb, u);
+ return do_pk8pkey(bp, x, 0, nid, NULL, kstr, klen, cb, u);
}
int PEM_write_bio_PKCS8PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
- char *kstr, int klen,
- pem_password_cb *cb, void *u)
+ char *kstr, int klen,
+ pem_password_cb *cb, void *u)
{
- return do_pk8pkey(bp, x, 0, -1, enc, kstr, klen, cb, u);
+ return do_pk8pkey(bp, x, 0, -1, enc, kstr, klen, cb, u);
}
int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
- char *kstr, int klen,
- pem_password_cb *cb, void *u)
+ char *kstr, int klen,
+ pem_password_cb *cb, void *u)
{
- return do_pk8pkey(bp, x, 1, -1, enc, kstr, klen, cb, u);
+ return do_pk8pkey(bp, x, 1, -1, enc, kstr, klen, cb, u);
}
int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid,
- char *kstr, int klen,
- pem_password_cb *cb, void *u)
+ char *kstr, int klen,
+ pem_password_cb *cb, void *u)
{
- return do_pk8pkey(bp, x, 1, nid, NULL, kstr, klen, cb, u);
+ return do_pk8pkey(bp, x, 1, nid, NULL, kstr, klen, cb, u);
}
-static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, int nid, const EVP_CIPHER *enc,
- char *kstr, int klen,
- pem_password_cb *cb, void *u)
+static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, int nid,
+ const EVP_CIPHER *enc, char *kstr, int klen,
+ pem_password_cb *cb, void *u)
{
- X509_SIG *p8;
- PKCS8_PRIV_KEY_INFO *p8inf;
- char buf[PEM_BUFSIZE];
- int ret;
- if(!(p8inf = EVP_PKEY2PKCS8(x))) {
- OPENSSL_PUT_ERROR(PEM, PEM_R_ERROR_CONVERTING_PRIVATE_KEY);
- return 0;
- }
- if(enc || (nid != -1)) {
- if(!kstr) {
- klen = 0;
- if (!cb) cb = PEM_def_callback;
- klen = cb(buf, PEM_BUFSIZE, 1, u);
- if(klen <= 0) {
- OPENSSL_PUT_ERROR(PEM, PEM_R_READ_KEY);
- PKCS8_PRIV_KEY_INFO_free(p8inf);
- return 0;
- }
-
- kstr = buf;
- }
- p8 = PKCS8_encrypt(nid, enc, kstr, klen, NULL, 0, 0, p8inf);
- if(kstr == buf) OPENSSL_cleanse(buf, klen);
- PKCS8_PRIV_KEY_INFO_free(p8inf);
- if(isder) ret = i2d_PKCS8_bio(bp, p8);
- else ret = PEM_write_bio_PKCS8(bp, p8);
- X509_SIG_free(p8);
- return ret;
- } else {
- if(isder) ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf);
- else ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(bp, p8inf);
- PKCS8_PRIV_KEY_INFO_free(p8inf);
- return ret;
- }
+ X509_SIG *p8;
+ PKCS8_PRIV_KEY_INFO *p8inf;
+ char buf[PEM_BUFSIZE];
+ int ret;
+ if (!(p8inf = EVP_PKEY2PKCS8(x))) {
+ OPENSSL_PUT_ERROR(PEM, PEM_R_ERROR_CONVERTING_PRIVATE_KEY);
+ return 0;
+ }
+ if (enc || (nid != -1)) {
+ if (!kstr) {
+ klen = 0;
+ if (!cb)
+ cb = PEM_def_callback;
+ klen = cb(buf, PEM_BUFSIZE, 1, u);
+ if (klen <= 0) {
+ OPENSSL_PUT_ERROR(PEM, PEM_R_READ_KEY);
+ PKCS8_PRIV_KEY_INFO_free(p8inf);
+ return 0;
+ }
+
+ kstr = buf;
+ }
+ p8 = PKCS8_encrypt(nid, enc, kstr, klen, NULL, 0, 0, p8inf);
+ if (kstr == buf)
+ OPENSSL_cleanse(buf, klen);
+ PKCS8_PRIV_KEY_INFO_free(p8inf);
+ if (isder)
+ ret = i2d_PKCS8_bio(bp, p8);
+ else
+ ret = PEM_write_bio_PKCS8(bp, p8);
+ X509_SIG_free(p8);
+ return ret;
+ } else {
+ if (isder)
+ ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf);
+ else
+ ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(bp, p8inf);
+ PKCS8_PRIV_KEY_INFO_free(p8inf);
+ return ret;
+ }
}
-EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u)
+EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb,
+ void *u)
{
- PKCS8_PRIV_KEY_INFO *p8inf = NULL;
- X509_SIG *p8 = NULL;
- int klen;
- EVP_PKEY *ret;
- char psbuf[PEM_BUFSIZE];
- p8 = d2i_PKCS8_bio(bp, NULL);
- if(!p8) return NULL;
-
- klen = 0;
- if (!cb) cb = PEM_def_callback;
- klen=cb(psbuf,PEM_BUFSIZE,0,u);
- if (klen <= 0) {
- OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_PASSWORD_READ);
- X509_SIG_free(p8);
- return NULL;
- }
- p8inf = PKCS8_decrypt(p8, psbuf, klen);
- X509_SIG_free(p8);
- if(!p8inf) return NULL;
- ret = EVP_PKCS82PKEY(p8inf);
- PKCS8_PRIV_KEY_INFO_free(p8inf);
- if(!ret) return NULL;
- if(x) {
- if(*x) EVP_PKEY_free(*x);
- *x = ret;
- }
- return ret;
+ PKCS8_PRIV_KEY_INFO *p8inf = NULL;
+ X509_SIG *p8 = NULL;
+ int klen;
+ EVP_PKEY *ret;
+ char psbuf[PEM_BUFSIZE];
+ p8 = d2i_PKCS8_bio(bp, NULL);
+ if (!p8)
+ return NULL;
+
+ klen = 0;
+ if (!cb)
+ cb = PEM_def_callback;
+ klen = cb(psbuf, PEM_BUFSIZE, 0, u);
+ if (klen <= 0) {
+ OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_PASSWORD_READ);
+ X509_SIG_free(p8);
+ return NULL;
+ }
+ p8inf = PKCS8_decrypt(p8, psbuf, klen);
+ X509_SIG_free(p8);
+ if (!p8inf)
+ return NULL;
+ ret = EVP_PKCS82PKEY(p8inf);
+ PKCS8_PRIV_KEY_INFO_free(p8inf);
+ if (!ret)
+ return NULL;
+ if (x) {
+ if (*x)
+ EVP_PKEY_free(*x);
+ *x = ret;
+ }
+ return ret;
}
#ifndef OPENSSL_NO_FP_API
int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
- char *kstr, int klen,
- pem_password_cb *cb, void *u)
+ char *kstr, int klen, pem_password_cb *cb, void *u)
{
- return do_pk8pkey_fp(fp, x, 1, -1, enc, kstr, klen, cb, u);
+ return do_pk8pkey_fp(fp, x, 1, -1, enc, kstr, klen, cb, u);
}
int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid,
- char *kstr, int klen,
- pem_password_cb *cb, void *u)
+ char *kstr, int klen,
+ pem_password_cb *cb, void *u)
{
- return do_pk8pkey_fp(fp, x, 1, nid, NULL, kstr, klen, cb, u);
+ return do_pk8pkey_fp(fp, x, 1, nid, NULL, kstr, klen, cb, u);
}
int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid,
- char *kstr, int klen,
- pem_password_cb *cb, void *u)
+ char *kstr, int klen,
+ pem_password_cb *cb, void *u)
{
- return do_pk8pkey_fp(fp, x, 0, nid, NULL, kstr, klen, cb, u);
+ return do_pk8pkey_fp(fp, x, 0, nid, NULL, kstr, klen, cb, u);
}
int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
- char *kstr, int klen, pem_password_cb *cb, void *u)
+ char *kstr, int klen, pem_password_cb *cb,
+ void *u)
{
- return do_pk8pkey_fp(fp, x, 0, -1, enc, kstr, klen, cb, u);
+ return do_pk8pkey_fp(fp, x, 0, -1, enc, kstr, klen, cb, u);
}
-static int do_pk8pkey_fp(FILE *fp, EVP_PKEY *x, int isder, int nid, const EVP_CIPHER *enc,
- char *kstr, int klen,
- pem_password_cb *cb, void *u)
+static int do_pk8pkey_fp(FILE *fp, EVP_PKEY *x, int isder, int nid,
+ const EVP_CIPHER *enc, char *kstr, int klen,
+ pem_password_cb *cb, void *u)
{
- BIO *bp;
- int ret;
- if(!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) {
- OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
- return(0);
- }
- ret = do_pk8pkey(bp, x, isder, nid, enc, kstr, klen, cb, u);
- BIO_free(bp);
- return ret;
+ BIO *bp;
+ int ret;
+ if (!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) {
+ OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
+ return (0);
+ }
+ ret = do_pk8pkey(bp, x, isder, nid, enc, kstr, klen, cb, u);
+ BIO_free(bp);
+ return ret;
}
-EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u)
+EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb,
+ void *u)
{
- BIO *bp;
- EVP_PKEY *ret;
- if(!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) {
- OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
- return NULL;
- }
- ret = d2i_PKCS8PrivateKey_bio(bp, x, cb, u);
- BIO_free(bp);
- return ret;
+ BIO *bp;
+ EVP_PKEY *ret;
+ if (!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) {
+ OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
+ return NULL;
+ }
+ ret = d2i_PKCS8PrivateKey_bio(bp, x, cb, u);
+ BIO_free(bp);
+ return ret;
}
#endif
IMPLEMENT_PEM_rw(PKCS8, X509_SIG, PEM_STRING_PKCS8, X509_SIG)
+
+
IMPLEMENT_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO, PEM_STRING_PKCS8INF,
- PKCS8_PRIV_KEY_INFO)
+ PKCS8_PRIV_KEY_INFO)
diff --git a/src/crypto/pem/pem_pkey.c b/src/crypto/pem/pem_pkey.c
index cd334b4d..058c0311 100644
--- a/src/crypto/pem/pem_pkey.c
+++ b/src/crypto/pem/pem_pkey.c
@@ -69,240 +69,159 @@
#include <openssl/rand.h>
#include <openssl/x509.h>
-#include "../evp/internal.h"
-
-
-int pem_check_suffix(const char *pem_str, const char *suffix);
-
-EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u)
- {
- char *nm=NULL;
- const unsigned char *p=NULL;
- unsigned char *data=NULL;
- long len;
- int slen;
- EVP_PKEY *ret=NULL;
-
- if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_EVP_PKEY, bp, cb, u))
- return NULL;
- p = data;
-
- if (strcmp(nm,PEM_STRING_PKCS8INF) == 0) {
- PKCS8_PRIV_KEY_INFO *p8inf;
- p8inf=d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len);
- if(!p8inf) goto p8err;
- ret = EVP_PKCS82PKEY(p8inf);
- if(x) {
- if(*x) EVP_PKEY_free((EVP_PKEY *)*x);
- *x = ret;
- }
- PKCS8_PRIV_KEY_INFO_free(p8inf);
- } else if (strcmp(nm,PEM_STRING_PKCS8) == 0) {
- PKCS8_PRIV_KEY_INFO *p8inf;
- X509_SIG *p8;
- int klen;
- char psbuf[PEM_BUFSIZE];
- p8 = d2i_X509_SIG(NULL, &p, len);
- if(!p8) goto p8err;
-
- klen = 0;
- if (!cb) cb = PEM_def_callback;
- klen=cb(psbuf,PEM_BUFSIZE,0,u);
- if (klen <= 0) {
- OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_PASSWORD_READ);
- X509_SIG_free(p8);
- goto err;
- }
- p8inf = PKCS8_decrypt(p8, psbuf, klen);
- X509_SIG_free(p8);
- if(!p8inf) goto p8err;
- ret = EVP_PKCS82PKEY(p8inf);
- if(x) {
- if(*x) EVP_PKEY_free((EVP_PKEY *)*x);
- *x = ret;
- }
- PKCS8_PRIV_KEY_INFO_free(p8inf);
- } else if ((slen = pem_check_suffix(nm, "PRIVATE KEY")) > 0)
- {
- const EVP_PKEY_ASN1_METHOD *ameth;
- ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen);
- if (!ameth || !ameth->old_priv_decode)
- goto p8err;
- ret=d2i_PrivateKey(ameth->pkey_id,x,&p,len);
- }
-p8err:
- if (ret == NULL)
- OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB);
-
-err:
- OPENSSL_free(nm);
- OPENSSL_cleanse(data, len);
- OPENSSL_free(data);
- return(ret);
- }
-
-int PEM_write_bio_PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
- unsigned char *kstr, int klen,
- pem_password_cb *cb, void *u)
- {
- char pem_str[80];
- if (!x->ameth || x->ameth->priv_encode)
- return PEM_write_bio_PKCS8PrivateKey(bp, x, enc,
- (char *)kstr, klen,
- cb, u);
-
- BIO_snprintf(pem_str, 80, "%s PRIVATE KEY", x->ameth->pem_str);
- return PEM_ASN1_write_bio((i2d_of_void *)i2d_PrivateKey,
- pem_str,bp,x,enc,kstr,klen,cb,u);
- }
-
-static int public_key_type_from_str(const char *name, size_t len) {
- if (len == 3 && memcmp(name, "RSA", 3) == 0) {
- return EVP_PKEY_RSA;
- } else if (len == 2 && memcmp(name, "DH", 2) == 0) {
- return EVP_PKEY_DH;
- } else if (len == 2 && memcmp(name, "EC", 2) == 0) {
- return EVP_PKEY_EC;
- }
- return NID_undef;
+EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb,
+ void *u)
+{
+ char *nm = NULL;
+ const unsigned char *p = NULL;
+ unsigned char *data = NULL;
+ long len;
+ EVP_PKEY *ret = NULL;
+
+ if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_EVP_PKEY, bp, cb, u))
+ return NULL;
+ p = data;
+
+ if (strcmp(nm, PEM_STRING_PKCS8INF) == 0) {
+ PKCS8_PRIV_KEY_INFO *p8inf;
+ p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len);
+ if (!p8inf)
+ goto p8err;
+ ret = EVP_PKCS82PKEY(p8inf);
+ if (x) {
+ if (*x)
+ EVP_PKEY_free((EVP_PKEY *)*x);
+ *x = ret;
+ }
+ PKCS8_PRIV_KEY_INFO_free(p8inf);
+ } else if (strcmp(nm, PEM_STRING_PKCS8) == 0) {
+ PKCS8_PRIV_KEY_INFO *p8inf;
+ X509_SIG *p8;
+ int klen;
+ char psbuf[PEM_BUFSIZE];
+ p8 = d2i_X509_SIG(NULL, &p, len);
+ if (!p8)
+ goto p8err;
+
+ klen = 0;
+ if (!cb)
+ cb = PEM_def_callback;
+ klen = cb(psbuf, PEM_BUFSIZE, 0, u);
+ if (klen <= 0) {
+ OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_PASSWORD_READ);
+ X509_SIG_free(p8);
+ goto err;
+ }
+ p8inf = PKCS8_decrypt(p8, psbuf, klen);
+ X509_SIG_free(p8);
+ if (!p8inf)
+ goto p8err;
+ ret = EVP_PKCS82PKEY(p8inf);
+ if (x) {
+ if (*x)
+ EVP_PKEY_free((EVP_PKEY *)*x);
+ *x = ret;
+ }
+ PKCS8_PRIV_KEY_INFO_free(p8inf);
+ } else if (strcmp(nm, PEM_STRING_RSA) == 0) {
+ /* TODO(davidben): d2i_PrivateKey parses PKCS#8 along with the
+ * standalone format. This and the cases below probably should not
+ * accept PKCS#8. */
+ ret = d2i_PrivateKey(EVP_PKEY_RSA, x, &p, len);
+ } else if (strcmp(nm, PEM_STRING_EC) == 0) {
+ ret = d2i_PrivateKey(EVP_PKEY_EC, x, &p, len);
+ } else if (strcmp(nm, PEM_STRING_DSA) == 0) {
+ ret = d2i_PrivateKey(EVP_PKEY_DSA, x, &p, len);
+ }
+ p8err:
+ if (ret == NULL)
+ OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB);
+
+ err:
+ OPENSSL_free(nm);
+ OPENSSL_cleanse(data, len);
+ OPENSSL_free(data);
+ return (ret);
}
-static int set_pkey_type_from_str(EVP_PKEY *pkey, const char *name, size_t len) {
- int nid = public_key_type_from_str(name, len);
- if (nid == NID_undef) {
- return 0;
- }
- return EVP_PKEY_set_type(pkey, nid);
+int PEM_write_bio_PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
+ unsigned char *kstr, int klen,
+ pem_password_cb *cb, void *u)
+{
+ return PEM_write_bio_PKCS8PrivateKey(bp, x, enc, (char *)kstr, klen, cb, u);
}
-EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x)
- {
- char *nm=NULL;
- const unsigned char *p=NULL;
- unsigned char *data=NULL;
- long len;
- int slen;
- EVP_PKEY *ret=NULL;
-
- if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_PARAMETERS,
- bp, 0, NULL))
- return NULL;
- p = data;
-
- if ((slen = pem_check_suffix(nm, "PARAMETERS")) > 0)
- {
- ret = EVP_PKEY_new();
- if (!ret)
- goto err;
- if (!set_pkey_type_from_str(ret, nm, slen)
- || !ret->ameth->param_decode
- || !ret->ameth->param_decode(ret, &p, len))
- {
- EVP_PKEY_free(ret);
- ret = NULL;
- goto err;
- }
- if(x)
- {
- if(*x) EVP_PKEY_free((EVP_PKEY *)*x);
- *x = ret;
- }
- }
-err:
- if (ret == NULL)
- OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB);
- OPENSSL_free(nm);
- OPENSSL_free(data);
- return(ret);
- }
-
-int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x)
- {
- char pem_str[80];
- if (!x->ameth || !x->ameth->param_encode)
- return 0;
-
- BIO_snprintf(pem_str, 80, "%s PARAMETERS", x->ameth->pem_str);
- return PEM_ASN1_write_bio(
- (i2d_of_void *)x->ameth->param_encode,
- pem_str,bp,x,NULL,NULL,0,0,NULL);
- }
-
#ifndef OPENSSL_NO_FP_API
-EVP_PKEY *PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u)
- {
- BIO *b;
- EVP_PKEY *ret;
-
- if ((b=BIO_new(BIO_s_file())) == NULL)
- {
- OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
- return(0);
- }
- BIO_set_fp(b,fp,BIO_NOCLOSE);
- ret=PEM_read_bio_PrivateKey(b,x,cb,u);
- BIO_free(b);
- return(ret);
- }
+EVP_PKEY *PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x, pem_password_cb *cb,
+ void *u)
+{
+ BIO *b;
+ EVP_PKEY *ret;
+
+ if ((b = BIO_new(BIO_s_file())) == NULL) {
+ OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
+ return (0);
+ }
+ BIO_set_fp(b, fp, BIO_NOCLOSE);
+ ret = PEM_read_bio_PrivateKey(b, x, cb, u);
+ BIO_free(b);
+ return (ret);
+}
int PEM_write_PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
- unsigned char *kstr, int klen,
- pem_password_cb *cb, void *u)
- {
- BIO *b;
- int ret;
-
- if ((b=BIO_new_fp(fp, BIO_NOCLOSE)) == NULL)
- {
- OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
- return 0;
- }
- ret=PEM_write_bio_PrivateKey(b, x, enc, kstr, klen, cb, u);
- BIO_free(b);
- return ret;
- }
+ unsigned char *kstr, int klen,
+ pem_password_cb *cb, void *u)
+{
+ BIO *b;
+ int ret;
+
+ if ((b = BIO_new_fp(fp, BIO_NOCLOSE)) == NULL) {
+ OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
+ return 0;
+ }
+ ret = PEM_write_bio_PrivateKey(b, x, enc, kstr, klen, cb, u);
+ BIO_free(b);
+ return ret;
+}
#endif
-
/* Transparently read in PKCS#3 or X9.42 DH parameters */
DH *PEM_read_bio_DHparams(BIO *bp, DH **x, pem_password_cb *cb, void *u)
- {
- char *nm=NULL;
- const unsigned char *p=NULL;
- unsigned char *data=NULL;
- long len;
- DH *ret=NULL;
-
- if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_DHPARAMS,
- bp, cb, u))
- return NULL;
- p = data;
-
- ret = d2i_DHparams(x, &p, len);
-
- if (ret == NULL)
- OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB);
- OPENSSL_free(nm);
- OPENSSL_free(data);
- return ret;
- }
+{
+ char *nm = NULL;
+ const unsigned char *p = NULL;
+ unsigned char *data = NULL;
+ long len;
+ DH *ret = NULL;
+
+ if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_DHPARAMS, bp, cb, u))
+ return NULL;
+ p = data;
+
+ ret = d2i_DHparams(x, &p, len);
+
+ if (ret == NULL)
+ OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB);
+ OPENSSL_free(nm);
+ OPENSSL_free(data);
+ return ret;
+}
#ifndef OPENSSL_NO_FP_API
DH *PEM_read_DHparams(FILE *fp, DH **x, pem_password_cb *cb, void *u)
- {
- BIO *b;
- DH *ret;
-
- if ((b=BIO_new(BIO_s_file())) == NULL)
- {
- OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
- return(0);
- }
- BIO_set_fp(b,fp,BIO_NOCLOSE);
- ret=PEM_read_bio_DHparams(b,x,cb,u);
- BIO_free(b);
- return(ret);
- }
+{
+ BIO *b;
+ DH *ret;
+
+ if ((b = BIO_new(BIO_s_file())) == NULL) {
+ OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
+ return (0);
+ }
+ BIO_set_fp(b, fp, BIO_NOCLOSE);
+ ret = PEM_read_bio_DHparams(b, x, cb, u);
+ BIO_free(b);
+ return (ret);
+}
#endif
diff --git a/src/crypto/pem/pem_x509.c b/src/crypto/pem/pem_x509.c
index f4630472..97f814db 100644
--- a/src/crypto/pem/pem_x509.c
+++ b/src/crypto/pem/pem_x509.c
@@ -1,6 +1,7 @@
/* pem_x509.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2001.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2001.
*/
/* ====================================================================
* Copyright (c) 2001 The OpenSSL Project. All rights reserved.
@@ -61,5 +62,4 @@
#include <openssl/pem.h>
#include <openssl/x509.h>
-
IMPLEMENT_PEM_rw(X509, X509, PEM_STRING_X509, X509)
diff --git a/src/crypto/pem/pem_xaux.c b/src/crypto/pem/pem_xaux.c
index 8dabd41e..386dd60d 100644
--- a/src/crypto/pem/pem_xaux.c
+++ b/src/crypto/pem/pem_xaux.c
@@ -1,6 +1,7 @@
/* pem_xaux.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2001.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2001.
*/
/* ====================================================================
* Copyright (c) 2001 The OpenSSL Project. All rights reserved.
@@ -61,6 +62,6 @@
#include <openssl/pem.h>
#include <openssl/x509.h>
-
IMPLEMENT_PEM_rw(X509_AUX, X509, PEM_STRING_X509_TRUSTED, X509_AUX)
-IMPLEMENT_PEM_rw(X509_CERT_PAIR, X509_CERT_PAIR, PEM_STRING_X509_PAIR, X509_CERT_PAIR)
+IMPLEMENT_PEM_rw(X509_CERT_PAIR, X509_CERT_PAIR, PEM_STRING_X509_PAIR,
+ X509_CERT_PAIR)
diff --git a/src/crypto/perlasm/arm-xlate.pl b/src/crypto/perlasm/arm-xlate.pl
index 706fa708..6e9b0199 100755
--- a/src/crypto/perlasm/arm-xlate.pl
+++ b/src/crypto/perlasm/arm-xlate.pl
@@ -55,7 +55,9 @@ my $globl = sub {
};
}
- $ret = ".globl $name" if (!$ret);
+ $ret = ".globl $name\n";
+ # All symbols in assembly files are hidden.
+ $ret .= &$hidden($name);
$$global = $name;
$ret;
};
@@ -165,6 +167,6 @@ while($line=<>) {
print "\n";
}
-print "#endif" if ($flavour eq "linux32" || $flavour eq "linux64");
+print "#endif\n" 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 3ebb0184..4965985d 100755
--- a/src/crypto/perlasm/x86_64-xlate.pl
+++ b/src/crypto/perlasm/x86_64-xlate.pl
@@ -190,14 +190,17 @@ my %globals;
sub out {
my $self = shift;
+ $self->{value} =~ s/\b(0b[0-1]+)/oct($1)/eig;
if ($gas) {
# Solaris /usr/ccs/bin/as can't handle multiplications
# in $self->{value}
- $self->{value} =~ s/(?<![\w\$\.])(0x?[0-9a-f]+)/oct($1)/egi;
- $self->{value} =~ s/([0-9]+\s*[\*\/\%]\s*[0-9]+)/eval($1)/eg;
+ my $value = $self->{value};
+ $value =~ s/(?<![\w\$\.])(0x?[0-9a-f]+)/oct($1)/egi;
+ if ($value =~ s/([0-9]+\s*[\*\/\%]\s*[0-9]+)/eval($1)/eg) {
+ $self->{value} = $value;
+ }
sprintf "\$%s",$self->{value};
} else {
- $self->{value} =~ s/(0b[0-1]+)/oct($1)/eig;
$self->{value} =~ s/0x([0-9a-f]+)/0$1h/ig if ($masm);
sprintf "%s",$self->{value};
}
diff --git a/src/crypto/perlasm/x86gas.pl b/src/crypto/perlasm/x86gas.pl
index 99d7c1bd..55d09d8b 100644
--- a/src/crypto/perlasm/x86gas.pl
+++ b/src/crypto/perlasm/x86gas.pl
@@ -17,7 +17,7 @@ sub opsize()
{ my $reg=shift;
if ($reg =~ m/^%e/o) { "l"; }
elsif ($reg =~ m/^%[a-d][hl]$/o) { "b"; }
- elsif ($reg =~ m/^%[xm]/o) { undef; }
+ elsif ($reg =~ m/^%[yxm]/o) { undef; }
else { "w"; }
}
diff --git a/src/crypto/pkcs8/CMakeLists.txt b/src/crypto/pkcs8/CMakeLists.txt
index 95501099..ffb38218 100644
--- a/src/crypto/pkcs8/CMakeLists.txt
+++ b/src/crypto/pkcs8/CMakeLists.txt
@@ -1,7 +1,7 @@
include_directories(../../include)
add_library(
- pkcs8
+ pkcs8_lib
OBJECT
diff --git a/src/crypto/pkcs8/p5_pbe.c b/src/crypto/pkcs8/p5_pbe.c
index 653cabf3..8e56d41b 100644
--- a/src/crypto/pkcs8/p5_pbe.c
+++ b/src/crypto/pkcs8/p5_pbe.c
@@ -57,6 +57,7 @@
#include <openssl/asn1t.h>
#include <openssl/err.h>
+#include <openssl/obj.h>
#include <openssl/pkcs8.h>
#include <openssl/rand.h>
#include <openssl/x509.h>
diff --git a/src/crypto/pkcs8/p5_pbev2.c b/src/crypto/pkcs8/p5_pbev2.c
index fec0d86d..3799b39b 100644
--- a/src/crypto/pkcs8/p5_pbev2.c
+++ b/src/crypto/pkcs8/p5_pbev2.c
@@ -61,6 +61,7 @@
#include <openssl/cipher.h>
#include <openssl/err.h>
#include <openssl/mem.h>
+#include <openssl/obj.h>
#include <openssl/pkcs8.h>
#include <openssl/rand.h>
#include <openssl/x509.h>
diff --git a/src/crypto/pkcs8/pkcs12_test.cc b/src/crypto/pkcs8/pkcs12_test.cc
index 55006b4d..17bcd273 100644
--- a/src/crypto/pkcs8/pkcs12_test.cc
+++ b/src/crypto/pkcs8/pkcs12_test.cc
@@ -708,7 +708,7 @@ static bool Test(const char *name, const uint8_t *der, size_t der_len) {
}
static bool TestCompat(const uint8_t *der, size_t der_len) {
- ScopedBIO bio(BIO_new_mem_buf((void*) der, der_len));
+ ScopedBIO bio(BIO_new_mem_buf(der, der_len));
if (!bio) {
return false;
}
@@ -757,7 +757,6 @@ static bool TestCompat(const uint8_t *der, size_t der_len) {
int main(int argc, char **argv) {
CRYPTO_library_init();
- ERR_load_crypto_strings();
if (!Test("OpenSSL", kOpenSSL, sizeof(kOpenSSL)) ||
!Test("NSS", kNSS, sizeof(kNSS)) ||
diff --git a/src/crypto/pkcs8/pkcs8.c b/src/crypto/pkcs8/pkcs8.c
index 31a34a7c..4ecf17f8 100644
--- a/src/crypto/pkcs8/pkcs8.c
+++ b/src/crypto/pkcs8/pkcs8.c
@@ -60,18 +60,18 @@
#include <string.h>
#include <openssl/asn1.h>
-#include <openssl/bn.h>
#include <openssl/buf.h>
+#include <openssl/bytestring.h>
#include <openssl/cipher.h>
#include <openssl/digest.h>
#include <openssl/err.h>
#include <openssl/hmac.h>
#include <openssl/mem.h>
+#include <openssl/obj.h>
#include <openssl/x509.h>
#include "internal.h"
#include "../bytestring/internal.h"
-#include "../evp/internal.h"
#define PKCS12_KEY_ID 1
@@ -106,112 +106,122 @@ static int ascii_to_ucs2(const char *ascii, size_t ascii_len,
static int pkcs12_key_gen_raw(const uint8_t *pass_raw, size_t pass_raw_len,
const uint8_t *salt, size_t salt_len,
- int id, int iterations,
+ uint8_t id, int iterations,
size_t out_len, uint8_t *out,
- const EVP_MD *md_type) {
- uint8_t *B, *D, *I, *p, *Ai;
- int Slen, Plen, Ilen, Ijlen;
- int i, j, v;
- size_t u;
- int ret = 0;
- BIGNUM *Ij, *Bpl1; /* These hold Ij and B + 1 */
- EVP_MD_CTX ctx;
+ const EVP_MD *md) {
+ /* See https://tools.ietf.org/html/rfc7292#appendix-B. Quoted parts of the
+ * specification have errata applied and other typos fixed. */
- EVP_MD_CTX_init(&ctx);
- v = EVP_MD_block_size(md_type);
- u = EVP_MD_size(md_type);
- D = OPENSSL_malloc(v);
- Ai = OPENSSL_malloc(u);
- B = OPENSSL_malloc(v + 1);
- Slen = v * ((salt_len + v - 1) / v);
- if (pass_raw_len) {
- Plen = v * ((pass_raw_len + v - 1) / v);
- } else {
- Plen = 0;
+ if (iterations < 1) {
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_ITERATION_COUNT);
+ return 0;
}
- Ilen = Slen + Plen;
- I = OPENSSL_malloc(Ilen);
- Ij = BN_new();
- Bpl1 = BN_new();
- if (!D || !Ai || !B || !I || !Ij || !Bpl1) {
- goto err;
+
+ /* In the spec, |block_size| is called "v", but measured in bits. */
+ size_t block_size = EVP_MD_block_size(md);
+
+ /* 1. Construct a string, D (the "diversifier"), by concatenating v/8 copies
+ * of ID. */
+ uint8_t D[EVP_MAX_MD_BLOCK_SIZE];
+ memset(D, id, block_size);
+
+ /* 2. Concatenate copies of the salt together to create a string S of length
+ * v(ceiling(s/v)) bits (the final copy of the salt may be truncated to
+ * create S). Note that if the salt is the empty string, then so is S.
+ *
+ * 3. Concatenate copies of the password together to create a string P of
+ * length v(ceiling(p/v)) bits (the final copy of the password may be
+ * truncated to create P). Note that if the password is the empty string,
+ * then so is P.
+ *
+ * 4. Set I=S||P to be the concatenation of S and P. */
+ if (salt_len + block_size - 1 < salt_len ||
+ pass_raw_len + block_size - 1 < pass_raw_len) {
+ OPENSSL_PUT_ERROR(PKCS8, ERR_R_OVERFLOW);
+ return 0;
}
- for (i = 0; i < v; i++) {
- D[i] = id;
+ size_t S_len = block_size * ((salt_len + block_size - 1) / block_size);
+ size_t P_len = block_size * ((pass_raw_len + block_size - 1) / block_size);
+ size_t I_len = S_len + P_len;
+ if (I_len < S_len) {
+ OPENSSL_PUT_ERROR(PKCS8, ERR_R_OVERFLOW);
+ return 0;
}
- p = I;
- for (i = 0; i < Slen; i++) {
- *p++ = salt[i % salt_len];
+
+ uint8_t *I = OPENSSL_malloc(I_len);
+ if (I_len != 0 && I == NULL) {
+ OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE);
+ return 0;
}
- for (i = 0; i < Plen; i++) {
- *p++ = pass_raw[i % pass_raw_len];
+
+ size_t i;
+ for (i = 0; i < S_len; i++) {
+ I[i] = salt[i % salt_len];
}
- for (;;) {
- if (!EVP_DigestInit_ex(&ctx, md_type, NULL) ||
- !EVP_DigestUpdate(&ctx, D, v) ||
- !EVP_DigestUpdate(&ctx, I, Ilen) ||
- !EVP_DigestFinal_ex(&ctx, Ai, NULL)) {
+ for (i = 0; i < P_len; i++) {
+ I[i + S_len] = pass_raw[i % pass_raw_len];
+ }
+
+ int ret = 0;
+ EVP_MD_CTX ctx;
+ EVP_MD_CTX_init(&ctx);
+
+ while (out_len != 0) {
+ /* A. Set A_i=H^r(D||I). (i.e., the r-th hash of D||I,
+ * H(H(H(... H(D||I)))) */
+ uint8_t A[EVP_MAX_MD_SIZE];
+ unsigned A_len;
+ if (!EVP_DigestInit_ex(&ctx, md, NULL) ||
+ !EVP_DigestUpdate(&ctx, D, block_size) ||
+ !EVP_DigestUpdate(&ctx, I, I_len) ||
+ !EVP_DigestFinal_ex(&ctx, A, &A_len)) {
goto err;
}
- for (j = 1; j < iterations; j++) {
- if (!EVP_DigestInit_ex(&ctx, md_type, NULL) ||
- !EVP_DigestUpdate(&ctx, Ai, u) ||
- !EVP_DigestFinal_ex(&ctx, Ai, NULL)) {
+ int iter;
+ for (iter = 1; iter < iterations; iter++) {
+ if (!EVP_DigestInit_ex(&ctx, md, NULL) ||
+ !EVP_DigestUpdate(&ctx, A, A_len) ||
+ !EVP_DigestFinal_ex(&ctx, A, &A_len)) {
goto err;
}
}
- memcpy(out, Ai, out_len < u ? out_len : u);
- if (u >= out_len) {
- ret = 1;
- goto end;
- }
- out_len -= u;
- out += u;
- for (j = 0; j < v; j++) {
- B[j] = Ai[j % u];
+
+ size_t todo = out_len < A_len ? out_len : A_len;
+ memcpy(out, A, todo);
+ out += todo;
+ out_len -= todo;
+ if (out_len == 0) {
+ break;
}
- /* Work out B + 1 first then can use B as tmp space */
- if (!BN_bin2bn(B, v, Bpl1) ||
- !BN_add_word(Bpl1, 1)) {
- goto err;
+
+ /* B. Concatenate copies of A_i to create a string B of length v bits (the
+ * final copy of A_i may be truncated to create B). */
+ uint8_t B[EVP_MAX_MD_BLOCK_SIZE];
+ for (i = 0; i < block_size; i++) {
+ B[i] = A[i % A_len];
}
- for (j = 0; j < Ilen; j += v) {
- if (!BN_bin2bn(I + j, v, Ij) ||
- !BN_add(Ij, Ij, Bpl1) ||
- !BN_bn2bin(Ij, B)) {
- goto err;
- }
- Ijlen = BN_num_bytes(Ij);
- /* If more than 2^(v*8) - 1 cut off MSB */
- if (Ijlen > v) {
- if (!BN_bn2bin(Ij, B)) {
- goto err;
- }
- memcpy(I + j, B + 1, v);
- /* If less than v bytes pad with zeroes */
- } else if (Ijlen < v) {
- memset(I + j, 0, v - Ijlen);
- if (!BN_bn2bin(Ij, I + j + v - Ijlen)) {
- goto err;
- }
- } else if (!BN_bn2bin(Ij, I + j)) {
- goto err;
+
+ /* C. Treating I as a concatenation I_0, I_1, ..., I_(k-1) of v-bit blocks,
+ * where k=ceiling(s/v)+ceiling(p/v), modify I by setting I_j=(I_j+B+1) mod
+ * 2^v for each j. */
+ assert(I_len % block_size == 0);
+ for (i = 0; i < I_len; i += block_size) {
+ unsigned carry = 1;
+ size_t j;
+ for (j = block_size - 1; j < block_size; j--) {
+ carry += I[i + j] + B[j];
+ I[i + j] = (uint8_t)carry;
+ carry >>= 8;
}
}
}
-err:
- OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE);
+ ret = 1;
-end:
- OPENSSL_free(Ai);
- OPENSSL_free(B);
- OPENSSL_free(D);
+err:
+ OPENSSL_cleanse(I, I_len);
OPENSSL_free(I);
- BN_free(Ij);
- BN_free(Bpl1);
EVP_MD_CTX_cleanup(&ctx);
-
return ret;
}
@@ -591,72 +601,52 @@ err:
}
EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8) {
- EVP_PKEY *pkey = NULL;
- ASN1_OBJECT *algoid;
- char obj_tmp[80];
-
- if (!PKCS8_pkey_get0(&algoid, NULL, NULL, NULL, p8)) {
+ uint8_t *der = NULL;
+ int der_len = i2d_PKCS8_PRIV_KEY_INFO(p8, &der);
+ if (der_len < 0) {
return NULL;
}
- pkey = EVP_PKEY_new();
- if (pkey == NULL) {
- OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE);
+ CBS cbs;
+ CBS_init(&cbs, der, (size_t)der_len);
+ EVP_PKEY *ret = EVP_parse_private_key(&cbs);
+ if (ret == NULL || CBS_len(&cbs) != 0) {
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR);
+ EVP_PKEY_free(ret);
+ OPENSSL_free(der);
return NULL;
}
- if (!EVP_PKEY_set_type(pkey, OBJ_obj2nid(algoid))) {
- 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;
- }
-
- if (pkey->ameth->priv_decode) {
- if (!pkey->ameth->priv_decode(pkey, p8)) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_PRIVATE_KEY_DECODE_ERROR);
- goto error;
- }
- } else {
- OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_METHOD_NOT_SUPPORTED);
- goto error;
- }
-
- return pkey;
-
-error:
- EVP_PKEY_free(pkey);
- return NULL;
+ OPENSSL_free(der);
+ return ret;
}
PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey) {
- PKCS8_PRIV_KEY_INFO *p8;
-
- p8 = PKCS8_PRIV_KEY_INFO_new();
- if (p8 == NULL) {
- OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE);
- return NULL;
+ CBB cbb;
+ uint8_t *der = NULL;
+ size_t der_len;
+ if (!CBB_init(&cbb, 0) ||
+ !EVP_marshal_private_key(&cbb, pkey) ||
+ !CBB_finish(&cbb, &der, &der_len) ||
+ der_len > LONG_MAX) {
+ CBB_cleanup(&cbb);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_ENCODE_ERROR);
+ goto err;
}
- p8->broken = PKCS8_OK;
- if (pkey->ameth) {
- if (pkey->ameth->priv_encode) {
- if (!pkey->ameth->priv_encode(p8, pkey)) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_PRIVATE_KEY_ENCODE_ERROR);
- goto error;
- }
- } else {
- OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_METHOD_NOT_SUPPORTED);
- goto error;
- }
- } else {
- OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
- goto error;
+ const uint8_t *p = der;
+ PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, (long)der_len);
+ if (p8 == NULL || p != der + der_len) {
+ PKCS8_PRIV_KEY_INFO_free(p8);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR);
+ goto err;
}
+
+ OPENSSL_free(der);
return p8;
-error:
- PKCS8_PRIV_KEY_INFO_free(p8);
+err:
+ OPENSSL_free(der);
return NULL;
}
@@ -737,6 +727,7 @@ static int PKCS12_handle_content_info(CBS *content_info, unsigned depth,
struct pkcs12_context *ctx) {
CBS content_type, wrapped_contents, contents, content_infos;
int nid, ret = 0;
+ uint8_t *storage = NULL;
if (!CBS_get_asn1(content_info, &content_type, CBS_ASN1_OBJECT) ||
!CBS_get_asn1(content_info, &wrapped_contents,
@@ -767,8 +758,9 @@ static int PKCS12_handle_content_info(CBS *content_info, unsigned depth,
/* AlgorithmIdentifier, see
* https://tools.ietf.org/html/rfc5280#section-4.1.1.2 */
!CBS_get_asn1_element(&eci, &ai, CBS_ASN1_SEQUENCE) ||
- !CBS_get_asn1(&eci, &encrypted_contents,
- CBS_ASN1_CONTEXT_SPECIFIC | 0)) {
+ !CBS_get_asn1_implicit_string(
+ &eci, &encrypted_contents, &storage,
+ CBS_ASN1_CONTEXT_SPECIFIC | 0, CBS_ASN1_OCTETSTRING)) {
OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
}
@@ -895,6 +887,7 @@ static int PKCS12_handle_content_info(CBS *content_info, unsigned depth,
}
err:
+ OPENSSL_free(storage);
return ret;
}
@@ -975,7 +968,7 @@ int PKCS12_get_key_and_certs(EVP_PKEY **out_key, STACK_OF(X509) *out_certs,
ctx.out_key = out_key;
ctx.out_certs = out_certs;
- if (!ascii_to_ucs2(password, strlen(password), &ctx.password,
+ if (!ascii_to_ucs2(password, password ? strlen(password) : 0, &ctx.password,
&ctx.password_len)) {
OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR);
goto err;
@@ -1066,9 +1059,6 @@ struct pkcs12_st {
PKCS12* d2i_PKCS12(PKCS12 **out_p12, const uint8_t **ber_bytes, size_t ber_len) {
PKCS12 *p12;
- /* out_p12 must be NULL because we don't export the PKCS12 structure. */
- assert(out_p12 == NULL);
-
p12 = OPENSSL_malloc(sizeof(PKCS12));
if (!p12) {
return NULL;
@@ -1084,6 +1074,12 @@ PKCS12* d2i_PKCS12(PKCS12 **out_p12, const uint8_t **ber_bytes, size_t ber_len)
p12->ber_len = ber_len;
*ber_bytes += ber_len;
+ if (out_p12) {
+ PKCS12_free(*out_p12);
+
+ *out_p12 = p12;
+ }
+
return p12;
}
@@ -1105,7 +1101,12 @@ PKCS12* d2i_PKCS12_bio(BIO *bio, PKCS12 **out_p12) {
for (;;) {
int n = BIO_read(bio, &buf->data[used], buf->length - used);
if (n < 0) {
- goto out;
+ if (used == 0) {
+ goto out;
+ }
+ /* Workaround a bug in node.js. It uses a memory BIO for this in the wrong
+ * mode. */
+ n = 0;
}
if (n == 0) {
@@ -1212,6 +1213,9 @@ int PKCS12_verify_mac(const PKCS12 *p12, const char *password,
}
void PKCS12_free(PKCS12 *p12) {
+ if (p12 == NULL) {
+ return;
+ }
OPENSSL_free(p12->ber_bytes);
OPENSSL_free(p12);
}
diff --git a/src/crypto/poly1305/asm/poly1305-armv4.pl b/src/crypto/poly1305/asm/poly1305-armv4.pl
new file mode 100755
index 00000000..9b765cec
--- /dev/null
+++ b/src/crypto/poly1305/asm/poly1305-armv4.pl
@@ -0,0 +1,1216 @@
+#!/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/.
+# ====================================================================
+#
+# IALU(*)/gcc-4.4 NEON
+#
+# ARM11xx(ARMv6) 7.78/+100% -
+# Cortex-A5 6.30/+130% 2.96
+# Cortex-A8 6.25/+115% 2.36
+# Cortex-A9 5.10/+95% 2.55
+# Cortex-A15 3.79/+85% 1.25(**)
+# Snapdragon S4 5.70/+100% 1.48(**)
+#
+# (*) this is for -march=armv6, i.e. with bunch of ldrb loading data;
+# (**) these are trade-off results, they can be improved by ~8% but at
+# the cost of 15/12% regression on Cortex-A5/A7, it's even possible
+# to improve Cortex-A9 result, but then A5/A7 loose more than 20%;
+
+$flavour = shift;
+if ($flavour=~/^\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; }
+else { while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {} }
+
+if ($flavour && $flavour ne "void") {
+ $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 STDOUT,"| \"$^X\" $xlate $flavour $output";
+} else {
+ open STDOUT,">$output";
+}
+
+($ctx,$inp,$len,$padbit)=map("r$_",(0..3));
+
+$code.=<<___;
+#include <openssl/arm_arch.h>
+
+.text
+#if defined(__thumb2__)
+.syntax unified
+.thumb
+#else
+.code 32
+#endif
+
+.globl poly1305_emit
+.globl poly1305_blocks
+.globl poly1305_init
+.type poly1305_init,%function
+.align 5
+poly1305_init:
+.Lpoly1305_init:
+ stmdb sp!,{r4-r11}
+
+ eor r3,r3,r3
+ cmp $inp,#0
+ str r3,[$ctx,#0] @ zero hash value
+ str r3,[$ctx,#4]
+ str r3,[$ctx,#8]
+ str r3,[$ctx,#12]
+ str r3,[$ctx,#16]
+ str r3,[$ctx,#36] @ is_base2_26
+ add $ctx,$ctx,#20
+
+#ifdef __thumb2__
+ it eq
+#endif
+ moveq r0,#0
+ beq .Lno_key
+
+#if __ARM_MAX_ARCH__>=7
+ adr r11,.Lpoly1305_init
+ ldr r12,.LOPENSSL_armcap
+#endif
+ ldrb r4,[$inp,#0]
+ mov r10,#0x0fffffff
+ ldrb r5,[$inp,#1]
+ and r3,r10,#-4 @ 0x0ffffffc
+ ldrb r6,[$inp,#2]
+ ldrb r7,[$inp,#3]
+ orr r4,r4,r5,lsl#8
+ ldrb r5,[$inp,#4]
+ orr r4,r4,r6,lsl#16
+ ldrb r6,[$inp,#5]
+ orr r4,r4,r7,lsl#24
+ ldrb r7,[$inp,#6]
+ and r4,r4,r10
+
+#if __ARM_MAX_ARCH__>=7
+ ldr r12,[r11,r12] @ OPENSSL_armcap_P
+# ifdef __APPLE__
+ ldr r12,[r12]
+# endif
+#endif
+ ldrb r8,[$inp,#7]
+ orr r5,r5,r6,lsl#8
+ ldrb r6,[$inp,#8]
+ orr r5,r5,r7,lsl#16
+ ldrb r7,[$inp,#9]
+ orr r5,r5,r8,lsl#24
+ ldrb r8,[$inp,#10]
+ and r5,r5,r3
+
+#if __ARM_MAX_ARCH__>=7
+ tst r12,#ARMV7_NEON @ check for NEON
+# ifdef __APPLE__
+ adr r9,poly1305_blocks_neon
+ adr r11,poly1305_blocks
+# ifdef __thumb2__
+ it ne
+# endif
+ movne r11,r9
+ adr r12,poly1305_emit
+ adr r10,poly1305_emit_neon
+# ifdef __thumb2__
+ it ne
+# endif
+ movne r12,r10
+# else
+# ifdef __thumb2__
+ itete eq
+# endif
+ addeq r12,r11,#(poly1305_emit-.Lpoly1305_init)
+ addne r12,r11,#(poly1305_emit_neon-.Lpoly1305_init)
+ addeq r11,r11,#(poly1305_blocks-.Lpoly1305_init)
+ addne r11,r11,#(poly1305_blocks_neon-.Lpoly1305_init)
+# endif
+# ifdef __thumb2__
+ orr r12,r12,#1 @ thumb-ify address
+ orr r11,r11,#1
+# endif
+#endif
+ ldrb r9,[$inp,#11]
+ orr r6,r6,r7,lsl#8
+ ldrb r7,[$inp,#12]
+ orr r6,r6,r8,lsl#16
+ ldrb r8,[$inp,#13]
+ orr r6,r6,r9,lsl#24
+ ldrb r9,[$inp,#14]
+ and r6,r6,r3
+
+ ldrb r10,[$inp,#15]
+ orr r7,r7,r8,lsl#8
+ str r4,[$ctx,#0]
+ orr r7,r7,r9,lsl#16
+ str r5,[$ctx,#4]
+ orr r7,r7,r10,lsl#24
+ str r6,[$ctx,#8]
+ and r7,r7,r3
+ str r7,[$ctx,#12]
+#if __ARM_MAX_ARCH__>=7
+ stmia r2,{r11,r12} @ fill functions table
+ mov r0,#1
+#else
+ mov r0,#0
+#endif
+.Lno_key:
+ ldmia sp!,{r4-r11}
+#if __ARM_ARCH__>=5
+ ret @ bx lr
+#else
+ tst lr,#1
+ moveq pc,lr @ be binary compatible with V4, yet
+ bx lr @ interoperable with Thumb ISA:-)
+#endif
+.size poly1305_init,.-poly1305_init
+___
+{
+my ($h0,$h1,$h2,$h3,$h4,$r0,$r1,$r2,$r3)=map("r$_",(4..12));
+my ($s1,$s2,$s3)=($r1,$r2,$r3);
+
+$code.=<<___;
+.type poly1305_blocks,%function
+.align 5
+poly1305_blocks:
+ stmdb sp!,{r3-r11,lr}
+
+ ands $len,$len,#-16
+ beq .Lno_data
+
+ cmp $padbit,#0
+ add $len,$len,$inp @ end pointer
+ sub sp,sp,#32
+
+ ldmia $ctx,{$h0-$r3} @ load context
+
+ str $ctx,[sp,#12] @ offload stuff
+ mov lr,$inp
+ str $len,[sp,#16]
+ str $r1,[sp,#20]
+ str $r2,[sp,#24]
+ str $r3,[sp,#28]
+ b .Loop
+
+.Loop:
+#if __ARM_ARCH__<7
+ ldrb r0,[lr],#16 @ load input
+# ifdef __thumb2__
+ it hi
+# endif
+ addhi $h4,$h4,#1 @ 1<<128
+ ldrb r1,[lr,#-15]
+ ldrb r2,[lr,#-14]
+ ldrb r3,[lr,#-13]
+ orr r1,r0,r1,lsl#8
+ ldrb r0,[lr,#-12]
+ orr r2,r1,r2,lsl#16
+ ldrb r1,[lr,#-11]
+ orr r3,r2,r3,lsl#24
+ ldrb r2,[lr,#-10]
+ adds $h0,$h0,r3 @ accumulate input
+
+ ldrb r3,[lr,#-9]
+ orr r1,r0,r1,lsl#8
+ ldrb r0,[lr,#-8]
+ orr r2,r1,r2,lsl#16
+ ldrb r1,[lr,#-7]
+ orr r3,r2,r3,lsl#24
+ ldrb r2,[lr,#-6]
+ adcs $h1,$h1,r3
+
+ ldrb r3,[lr,#-5]
+ orr r1,r0,r1,lsl#8
+ ldrb r0,[lr,#-4]
+ orr r2,r1,r2,lsl#16
+ ldrb r1,[lr,#-3]
+ orr r3,r2,r3,lsl#24
+ ldrb r2,[lr,#-2]
+ adcs $h2,$h2,r3
+
+ ldrb r3,[lr,#-1]
+ orr r1,r0,r1,lsl#8
+ str lr,[sp,#8] @ offload input pointer
+ orr r2,r1,r2,lsl#16
+ add $s1,$r1,$r1,lsr#2
+ orr r3,r2,r3,lsl#24
+#else
+ ldr r0,[lr],#16 @ load input
+# ifdef __thumb2__
+ it hi
+# endif
+ addhi $h4,$h4,#1 @ padbit
+ ldr r1,[lr,#-12]
+ ldr r2,[lr,#-8]
+ ldr r3,[lr,#-4]
+# ifdef __ARMEB__
+ rev r0,r0
+ rev r1,r1
+ rev r2,r2
+ rev r3,r3
+# endif
+ adds $h0,$h0,r0 @ accumulate input
+ str lr,[sp,#8] @ offload input pointer
+ adcs $h1,$h1,r1
+ add $s1,$r1,$r1,lsr#2
+ adcs $h2,$h2,r2
+#endif
+ add $s2,$r2,$r2,lsr#2
+ adcs $h3,$h3,r3
+ add $s3,$r3,$r3,lsr#2
+
+ umull r2,r3,$h1,$r0
+ adc $h4,$h4,#0
+ umull r0,r1,$h0,$r0
+ umlal r2,r3,$h4,$s1
+ umlal r0,r1,$h3,$s1
+ ldr $r1,[sp,#20] @ reload $r1
+ umlal r2,r3,$h2,$s3
+ umlal r0,r1,$h1,$s3
+ umlal r2,r3,$h3,$s2
+ umlal r0,r1,$h2,$s2
+ umlal r2,r3,$h0,$r1
+ str r0,[sp,#0] @ future $h0
+ mul r0,$s2,$h4
+ ldr $r2,[sp,#24] @ reload $r2
+ adds r2,r2,r1 @ d1+=d0>>32
+ eor r1,r1,r1
+ adc lr,r3,#0 @ future $h2
+ str r2,[sp,#4] @ future $h1
+
+ mul r2,$s3,$h4
+ eor r3,r3,r3
+ umlal r0,r1,$h3,$s3
+ ldr $r3,[sp,#28] @ reload $r3
+ umlal r2,r3,$h3,$r0
+ umlal r0,r1,$h2,$r0
+ umlal r2,r3,$h2,$r1
+ umlal r0,r1,$h1,$r1
+ umlal r2,r3,$h1,$r2
+ umlal r0,r1,$h0,$r2
+ umlal r2,r3,$h0,$r3
+ ldr $h0,[sp,#0]
+ mul $h4,$r0,$h4
+ ldr $h1,[sp,#4]
+
+ adds $h2,lr,r0 @ d2+=d1>>32
+ ldr lr,[sp,#8] @ reload input pointer
+ adc r1,r1,#0
+ adds $h3,r2,r1 @ d3+=d2>>32
+ ldr r0,[sp,#16] @ reload end pointer
+ adc r3,r3,#0
+ add $h4,$h4,r3 @ h4+=d3>>32
+
+ and r1,$h4,#-4
+ and $h4,$h4,#3
+ add r1,r1,r1,lsr#2 @ *=5
+ adds $h0,$h0,r1
+ adcs $h1,$h1,#0
+ adcs $h2,$h2,#0
+ adc $h3,$h3,#0
+
+ cmp r0,lr @ done yet?
+ bhi .Loop
+
+ ldr $ctx,[sp,#12]
+ add sp,sp,#32
+ stmia $ctx,{$h0-$h4} @ store the result
+
+.Lno_data:
+#if __ARM_ARCH__>=5
+ ldmia sp!,{r3-r11,pc}
+#else
+ ldmia sp!,{r3-r11,lr}
+ tst lr,#1
+ moveq pc,lr @ be binary compatible with V4, yet
+ bx lr @ interoperable with Thumb ISA:-)
+#endif
+.size poly1305_blocks,.-poly1305_blocks
+___
+}
+{
+my ($ctx,$mac,$nonce)=map("r$_",(0..2));
+my ($h0,$h1,$h2,$h3,$h4,$g0,$g1,$g2,$g3)=map("r$_",(3..11));
+my $g4=$h4;
+
+$code.=<<___;
+.type poly1305_emit,%function
+.align 5
+poly1305_emit:
+ stmdb sp!,{r4-r11}
+.Lpoly1305_emit_enter:
+
+ ldmia $ctx,{$h0-$h4}
+ adds $g0,$h0,#5 @ compare to modulus
+ adcs $g1,$h1,#0
+ adcs $g2,$h2,#0
+ adcs $g3,$h3,#0
+ adc $g4,$h4,#0
+ tst $g4,#4 @ did it carry/borrow?
+
+#ifdef __thumb2__
+ it ne
+#endif
+ movne $h0,$g0
+ ldr $g0,[$nonce,#0]
+#ifdef __thumb2__
+ it ne
+#endif
+ movne $h1,$g1
+ ldr $g1,[$nonce,#4]
+#ifdef __thumb2__
+ it ne
+#endif
+ movne $h2,$g2
+ ldr $g2,[$nonce,#8]
+#ifdef __thumb2__
+ it ne
+#endif
+ movne $h3,$g3
+ ldr $g3,[$nonce,#12]
+
+ adds $h0,$h0,$g0
+ adcs $h1,$h1,$g1
+ adcs $h2,$h2,$g2
+ adc $h3,$h3,$g3
+
+#if __ARM_ARCH__>=7
+# ifdef __ARMEB__
+ rev $h0,$h0
+ rev $h1,$h1
+ rev $h2,$h2
+ rev $h3,$h3
+# endif
+ str $h0,[$mac,#0]
+ str $h1,[$mac,#4]
+ str $h2,[$mac,#8]
+ str $h3,[$mac,#12]
+#else
+ strb $h0,[$mac,#0]
+ mov $h0,$h0,lsr#8
+ strb $h1,[$mac,#4]
+ mov $h1,$h1,lsr#8
+ strb $h2,[$mac,#8]
+ mov $h2,$h2,lsr#8
+ strb $h3,[$mac,#12]
+ mov $h3,$h3,lsr#8
+
+ strb $h0,[$mac,#1]
+ mov $h0,$h0,lsr#8
+ strb $h1,[$mac,#5]
+ mov $h1,$h1,lsr#8
+ strb $h2,[$mac,#9]
+ mov $h2,$h2,lsr#8
+ strb $h3,[$mac,#13]
+ mov $h3,$h3,lsr#8
+
+ strb $h0,[$mac,#2]
+ mov $h0,$h0,lsr#8
+ strb $h1,[$mac,#6]
+ mov $h1,$h1,lsr#8
+ strb $h2,[$mac,#10]
+ mov $h2,$h2,lsr#8
+ strb $h3,[$mac,#14]
+ mov $h3,$h3,lsr#8
+
+ strb $h0,[$mac,#3]
+ strb $h1,[$mac,#7]
+ strb $h2,[$mac,#11]
+ strb $h3,[$mac,#15]
+#endif
+ ldmia sp!,{r4-r11}
+#if __ARM_ARCH__>=5
+ ret @ bx lr
+#else
+ tst lr,#1
+ moveq pc,lr @ be binary compatible with V4, yet
+ bx lr @ interoperable with Thumb ISA:-)
+#endif
+.size poly1305_emit,.-poly1305_emit
+___
+{
+my ($R0,$R1,$S1,$R2,$S2,$R3,$S3,$R4,$S4) = map("d$_",(0..9));
+my ($D0,$D1,$D2,$D3,$D4, $H0,$H1,$H2,$H3,$H4) = map("q$_",(5..14));
+my ($T0,$T1,$MASK) = map("q$_",(15,4,0));
+
+my ($in2,$zeros,$tbl0,$tbl1) = map("r$_",(4..7));
+
+$code.=<<___;
+#if __ARM_MAX_ARCH__>=7
+.fpu neon
+
+.type poly1305_init_neon,%function
+.align 5
+poly1305_init_neon:
+ ldr r4,[$ctx,#20] @ load key base 2^32
+ ldr r5,[$ctx,#24]
+ ldr r6,[$ctx,#28]
+ ldr r7,[$ctx,#32]
+
+ and r2,r4,#0x03ffffff @ base 2^32 -> base 2^26
+ mov r3,r4,lsr#26
+ mov r4,r5,lsr#20
+ orr r3,r3,r5,lsl#6
+ mov r5,r6,lsr#14
+ orr r4,r4,r6,lsl#12
+ mov r6,r7,lsr#8
+ orr r5,r5,r7,lsl#18
+ and r3,r3,#0x03ffffff
+ and r4,r4,#0x03ffffff
+ and r5,r5,#0x03ffffff
+
+ vdup.32 $R0,r2 @ r^1 in both lanes
+ add r2,r3,r3,lsl#2 @ *5
+ vdup.32 $R1,r3
+ add r3,r4,r4,lsl#2
+ vdup.32 $S1,r2
+ vdup.32 $R2,r4
+ add r4,r5,r5,lsl#2
+ vdup.32 $S2,r3
+ vdup.32 $R3,r5
+ add r5,r6,r6,lsl#2
+ vdup.32 $S3,r4
+ vdup.32 $R4,r6
+ vdup.32 $S4,r5
+
+ mov $zeros,#2 @ counter
+
+.Lsquare_neon:
+ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+ @ d0 = h0*r0 + h4*5*r1 + h3*5*r2 + h2*5*r3 + h1*5*r4
+ @ d1 = h1*r0 + h0*r1 + h4*5*r2 + h3*5*r3 + h2*5*r4
+ @ d2 = h2*r0 + h1*r1 + h0*r2 + h4*5*r3 + h3*5*r4
+ @ d3 = h3*r0 + h2*r1 + h1*r2 + h0*r3 + h4*5*r4
+ @ d4 = h4*r0 + h3*r1 + h2*r2 + h1*r3 + h0*r4
+
+ vmull.u32 $D0,$R0,${R0}[1]
+ vmull.u32 $D1,$R1,${R0}[1]
+ vmull.u32 $D2,$R2,${R0}[1]
+ vmull.u32 $D3,$R3,${R0}[1]
+ vmull.u32 $D4,$R4,${R0}[1]
+
+ vmlal.u32 $D0,$R4,${S1}[1]
+ vmlal.u32 $D1,$R0,${R1}[1]
+ vmlal.u32 $D2,$R1,${R1}[1]
+ vmlal.u32 $D3,$R2,${R1}[1]
+ vmlal.u32 $D4,$R3,${R1}[1]
+
+ vmlal.u32 $D0,$R3,${S2}[1]
+ vmlal.u32 $D1,$R4,${S2}[1]
+ vmlal.u32 $D3,$R1,${R2}[1]
+ vmlal.u32 $D2,$R0,${R2}[1]
+ vmlal.u32 $D4,$R2,${R2}[1]
+
+ vmlal.u32 $D0,$R2,${S3}[1]
+ vmlal.u32 $D3,$R0,${R3}[1]
+ vmlal.u32 $D1,$R3,${S3}[1]
+ vmlal.u32 $D2,$R4,${S3}[1]
+ vmlal.u32 $D4,$R1,${R3}[1]
+
+ vmlal.u32 $D3,$R4,${S4}[1]
+ vmlal.u32 $D0,$R1,${S4}[1]
+ vmlal.u32 $D1,$R2,${S4}[1]
+ vmlal.u32 $D2,$R3,${S4}[1]
+ vmlal.u32 $D4,$R0,${R4}[1]
+
+ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+ @ lazy reduction as discussed in "NEON crypto" by D.J. Bernstein
+ @ and P. Schwabe
+
+ vshr.u64 $T0,$D3,#26
+ vmovn.i64 $D3#lo,$D3
+ vshr.u64 $T1,$D0,#26
+ vmovn.i64 $D0#lo,$D0
+ vadd.i64 $D4,$D4,$T0 @ h3 -> h4
+ vbic.i32 $D3#lo,#0xfc000000 @ &=0x03ffffff
+ vadd.i64 $D1,$D1,$T1 @ h0 -> h1
+ vbic.i32 $D0#lo,#0xfc000000
+
+ vshrn.u64 $T0#lo,$D4,#26
+ vmovn.i64 $D4#lo,$D4
+ vshr.u64 $T1,$D1,#26
+ vmovn.i64 $D1#lo,$D1
+ vadd.i64 $D2,$D2,$T1 @ h1 -> h2
+ vbic.i32 $D4#lo,#0xfc000000
+ vbic.i32 $D1#lo,#0xfc000000
+
+ vadd.i32 $D0#lo,$D0#lo,$T0#lo
+ vshl.u32 $T0#lo,$T0#lo,#2
+ vshrn.u64 $T1#lo,$D2,#26
+ vmovn.i64 $D2#lo,$D2
+ vadd.i32 $D0#lo,$D0#lo,$T0#lo @ h4 -> h0
+ vadd.i32 $D3#lo,$D3#lo,$T1#lo @ h2 -> h3
+ vbic.i32 $D2#lo,#0xfc000000
+
+ vshr.u32 $T0#lo,$D0#lo,#26
+ vbic.i32 $D0#lo,#0xfc000000
+ vshr.u32 $T1#lo,$D3#lo,#26
+ vbic.i32 $D3#lo,#0xfc000000
+ vadd.i32 $D1#lo,$D1#lo,$T0#lo @ h0 -> h1
+ vadd.i32 $D4#lo,$D4#lo,$T1#lo @ h3 -> h4
+
+ subs $zeros,$zeros,#1
+ beq .Lsquare_break_neon
+
+ add $tbl0,$ctx,#(48+0*9*4)
+ add $tbl1,$ctx,#(48+1*9*4)
+
+ vtrn.32 $R0,$D0#lo @ r^2:r^1
+ vtrn.32 $R2,$D2#lo
+ vtrn.32 $R3,$D3#lo
+ vtrn.32 $R1,$D1#lo
+ vtrn.32 $R4,$D4#lo
+
+ vshl.u32 $S2,$R2,#2 @ *5
+ vshl.u32 $S3,$R3,#2
+ vshl.u32 $S1,$R1,#2
+ vshl.u32 $S4,$R4,#2
+ vadd.i32 $S2,$S2,$R2
+ vadd.i32 $S1,$S1,$R1
+ vadd.i32 $S3,$S3,$R3
+ vadd.i32 $S4,$S4,$R4
+
+ vst4.32 {${R0}[0],${R1}[0],${S1}[0],${R2}[0]},[$tbl0]!
+ vst4.32 {${R0}[1],${R1}[1],${S1}[1],${R2}[1]},[$tbl1]!
+ vst4.32 {${S2}[0],${R3}[0],${S3}[0],${R4}[0]},[$tbl0]!
+ vst4.32 {${S2}[1],${R3}[1],${S3}[1],${R4}[1]},[$tbl1]!
+ vst1.32 {${S4}[0]},[$tbl0,:32]
+ vst1.32 {${S4}[1]},[$tbl1,:32]
+
+ b .Lsquare_neon
+
+.align 4
+.Lsquare_break_neon:
+ add $tbl0,$ctx,#(48+2*4*9)
+ add $tbl1,$ctx,#(48+3*4*9)
+
+ vmov $R0,$D0#lo @ r^4:r^3
+ vshl.u32 $S1,$D1#lo,#2 @ *5
+ vmov $R1,$D1#lo
+ vshl.u32 $S2,$D2#lo,#2
+ vmov $R2,$D2#lo
+ vshl.u32 $S3,$D3#lo,#2
+ vmov $R3,$D3#lo
+ vshl.u32 $S4,$D4#lo,#2
+ vmov $R4,$D4#lo
+ vadd.i32 $S1,$S1,$D1#lo
+ vadd.i32 $S2,$S2,$D2#lo
+ vadd.i32 $S3,$S3,$D3#lo
+ vadd.i32 $S4,$S4,$D4#lo
+
+ vst4.32 {${R0}[0],${R1}[0],${S1}[0],${R2}[0]},[$tbl0]!
+ vst4.32 {${R0}[1],${R1}[1],${S1}[1],${R2}[1]},[$tbl1]!
+ vst4.32 {${S2}[0],${R3}[0],${S3}[0],${R4}[0]},[$tbl0]!
+ vst4.32 {${S2}[1],${R3}[1],${S3}[1],${R4}[1]},[$tbl1]!
+ vst1.32 {${S4}[0]},[$tbl0]
+ vst1.32 {${S4}[1]},[$tbl1]
+
+ ret @ bx lr
+.size poly1305_init_neon,.-poly1305_init_neon
+
+.type poly1305_blocks_neon,%function
+.align 5
+poly1305_blocks_neon:
+ ldr ip,[$ctx,#36] @ is_base2_26
+ ands $len,$len,#-16
+ beq .Lno_data_neon
+
+ cmp $len,#64
+ bhs .Lenter_neon
+ tst ip,ip @ is_base2_26?
+ beq poly1305_blocks
+
+.Lenter_neon:
+ stmdb sp!,{r4-r7}
+ vstmdb sp!,{d8-d15} @ ABI specification says so
+
+ tst ip,ip @ is_base2_26?
+ bne .Lbase2_26_neon
+
+ stmdb sp!,{r1-r3,lr}
+ bl poly1305_init_neon
+
+ ldr r4,[$ctx,#0] @ load hash value base 2^32
+ ldr r5,[$ctx,#4]
+ ldr r6,[$ctx,#8]
+ ldr r7,[$ctx,#12]
+ ldr ip,[$ctx,#16]
+
+ and r2,r4,#0x03ffffff @ base 2^32 -> base 2^26
+ mov r3,r4,lsr#26
+ veor $D0#lo,$D0#lo,$D0#lo
+ mov r4,r5,lsr#20
+ orr r3,r3,r5,lsl#6
+ veor $D1#lo,$D1#lo,$D1#lo
+ mov r5,r6,lsr#14
+ orr r4,r4,r6,lsl#12
+ veor $D2#lo,$D2#lo,$D2#lo
+ mov r6,r7,lsr#8
+ orr r5,r5,r7,lsl#18
+ veor $D3#lo,$D3#lo,$D3#lo
+ and r3,r3,#0x03ffffff
+ orr r6,r6,ip,lsl#24
+ veor $D4#lo,$D4#lo,$D4#lo
+ and r4,r4,#0x03ffffff
+ mov r1,#1
+ and r5,r5,#0x03ffffff
+ str r1,[$ctx,#36] @ is_base2_26
+
+ vmov.32 $D0#lo[0],r2
+ vmov.32 $D1#lo[0],r3
+ vmov.32 $D2#lo[0],r4
+ vmov.32 $D3#lo[0],r5
+ vmov.32 $D4#lo[0],r6
+ adr $zeros,.Lzeros
+
+ ldmia sp!,{r1-r3,lr}
+ b .Lbase2_32_neon
+
+.align 4
+.Lbase2_26_neon:
+ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+ @ load hash value
+
+ veor $D0#lo,$D0#lo,$D0#lo
+ veor $D1#lo,$D1#lo,$D1#lo
+ veor $D2#lo,$D2#lo,$D2#lo
+ veor $D3#lo,$D3#lo,$D3#lo
+ veor $D4#lo,$D4#lo,$D4#lo
+ vld4.32 {$D0#lo[0],$D1#lo[0],$D2#lo[0],$D3#lo[0]},[$ctx]!
+ adr $zeros,.Lzeros
+ vld1.32 {$D4#lo[0]},[$ctx]
+ sub $ctx,$ctx,#16 @ rewind
+
+.Lbase2_32_neon:
+ add $in2,$inp,#32
+ mov $padbit,$padbit,lsl#24
+ tst $len,#31
+ beq .Leven
+
+ vld4.32 {$H0#lo[0],$H1#lo[0],$H2#lo[0],$H3#lo[0]},[$inp]!
+ vmov.32 $H4#lo[0],$padbit
+ sub $len,$len,#16
+ add $in2,$inp,#32
+
+# ifdef __ARMEB__
+ vrev32.8 $H0,$H0
+ vrev32.8 $H3,$H3
+ vrev32.8 $H1,$H1
+ vrev32.8 $H2,$H2
+# endif
+ vsri.u32 $H4#lo,$H3#lo,#8 @ base 2^32 -> base 2^26
+ vshl.u32 $H3#lo,$H3#lo,#18
+
+ vsri.u32 $H3#lo,$H2#lo,#14
+ vshl.u32 $H2#lo,$H2#lo,#12
+ vadd.i32 $H4#hi,$H4#lo,$D4#lo @ add hash value and move to #hi
+
+ vbic.i32 $H3#lo,#0xfc000000
+ vsri.u32 $H2#lo,$H1#lo,#20
+ vshl.u32 $H1#lo,$H1#lo,#6
+
+ vbic.i32 $H2#lo,#0xfc000000
+ vsri.u32 $H1#lo,$H0#lo,#26
+ vadd.i32 $H3#hi,$H3#lo,$D3#lo
+
+ vbic.i32 $H0#lo,#0xfc000000
+ vbic.i32 $H1#lo,#0xfc000000
+ vadd.i32 $H2#hi,$H2#lo,$D2#lo
+
+ vadd.i32 $H0#hi,$H0#lo,$D0#lo
+ vadd.i32 $H1#hi,$H1#lo,$D1#lo
+
+ mov $tbl1,$zeros
+ add $tbl0,$ctx,#48
+
+ cmp $len,$len
+ b .Long_tail
+
+.align 4
+.Leven:
+ subs $len,$len,#64
+# ifdef __thumb2__
+ it lo
+# endif
+ movlo $in2,$zeros
+
+ vmov.i32 $H4,#1<<24 @ padbit, yes, always
+ vld4.32 {$H0#lo,$H1#lo,$H2#lo,$H3#lo},[$inp] @ inp[0:1]
+ add $inp,$inp,#64
+ vld4.32 {$H0#hi,$H1#hi,$H2#hi,$H3#hi},[$in2] @ inp[2:3] (or 0)
+ add $in2,$in2,#64
+# ifdef __thumb2__
+ itt hi
+# endif
+ addhi $tbl1,$ctx,#(48+1*9*4)
+ addhi $tbl0,$ctx,#(48+3*9*4)
+
+# ifdef __ARMEB__
+ vrev32.8 $H0,$H0
+ vrev32.8 $H3,$H3
+ vrev32.8 $H1,$H1
+ vrev32.8 $H2,$H2
+# endif
+ vsri.u32 $H4,$H3,#8 @ base 2^32 -> base 2^26
+ vshl.u32 $H3,$H3,#18
+
+ vsri.u32 $H3,$H2,#14
+ vshl.u32 $H2,$H2,#12
+
+ vbic.i32 $H3,#0xfc000000
+ vsri.u32 $H2,$H1,#20
+ vshl.u32 $H1,$H1,#6
+
+ vbic.i32 $H2,#0xfc000000
+ vsri.u32 $H1,$H0,#26
+
+ vbic.i32 $H0,#0xfc000000
+ vbic.i32 $H1,#0xfc000000
+
+ bls .Lskip_loop
+
+ vld4.32 {${R0}[1],${R1}[1],${S1}[1],${R2}[1]},[$tbl1]! @ load r^2
+ vld4.32 {${R0}[0],${R1}[0],${S1}[0],${R2}[0]},[$tbl0]! @ load r^4
+ vld4.32 {${S2}[1],${R3}[1],${S3}[1],${R4}[1]},[$tbl1]!
+ vld4.32 {${S2}[0],${R3}[0],${S3}[0],${R4}[0]},[$tbl0]!
+ b .Loop_neon
+
+.align 5
+.Loop_neon:
+ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+ @ ((inp[0]*r^4+inp[2]*r^2+inp[4])*r^4+inp[6]*r^2
+ @ ((inp[1]*r^4+inp[3]*r^2+inp[5])*r^3+inp[7]*r
+ @ \___________________/
+ @ ((inp[0]*r^4+inp[2]*r^2+inp[4])*r^4+inp[6]*r^2+inp[8])*r^2
+ @ ((inp[1]*r^4+inp[3]*r^2+inp[5])*r^4+inp[7]*r^2+inp[9])*r
+ @ \___________________/ \____________________/
+ @
+ @ Note that we start with inp[2:3]*r^2. This is because it
+ @ doesn't depend on reduction in previous iteration.
+ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+ @ d4 = h4*r0 + h3*r1 + h2*r2 + h1*r3 + h0*r4
+ @ d3 = h3*r0 + h2*r1 + h1*r2 + h0*r3 + h4*5*r4
+ @ d2 = h2*r0 + h1*r1 + h0*r2 + h4*5*r3 + h3*5*r4
+ @ d1 = h1*r0 + h0*r1 + h4*5*r2 + h3*5*r3 + h2*5*r4
+ @ d0 = h0*r0 + h4*5*r1 + h3*5*r2 + h2*5*r3 + h1*5*r4
+
+ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+ @ inp[2:3]*r^2
+
+ vadd.i32 $H2#lo,$H2#lo,$D2#lo @ accumulate inp[0:1]
+ vmull.u32 $D2,$H2#hi,${R0}[1]
+ vadd.i32 $H0#lo,$H0#lo,$D0#lo
+ vmull.u32 $D0,$H0#hi,${R0}[1]
+ vadd.i32 $H3#lo,$H3#lo,$D3#lo
+ vmull.u32 $D3,$H3#hi,${R0}[1]
+ vmlal.u32 $D2,$H1#hi,${R1}[1]
+ vadd.i32 $H1#lo,$H1#lo,$D1#lo
+ vmull.u32 $D1,$H1#hi,${R0}[1]
+
+ vadd.i32 $H4#lo,$H4#lo,$D4#lo
+ vmull.u32 $D4,$H4#hi,${R0}[1]
+ subs $len,$len,#64
+ vmlal.u32 $D0,$H4#hi,${S1}[1]
+# ifdef __thumb2__
+ it lo
+# endif
+ movlo $in2,$zeros
+ vmlal.u32 $D3,$H2#hi,${R1}[1]
+ vld1.32 ${S4}[1],[$tbl1,:32]
+ vmlal.u32 $D1,$H0#hi,${R1}[1]
+ vmlal.u32 $D4,$H3#hi,${R1}[1]
+
+ vmlal.u32 $D0,$H3#hi,${S2}[1]
+ vmlal.u32 $D3,$H1#hi,${R2}[1]
+ vmlal.u32 $D4,$H2#hi,${R2}[1]
+ vmlal.u32 $D1,$H4#hi,${S2}[1]
+ vmlal.u32 $D2,$H0#hi,${R2}[1]
+
+ vmlal.u32 $D3,$H0#hi,${R3}[1]
+ vmlal.u32 $D0,$H2#hi,${S3}[1]
+ vmlal.u32 $D4,$H1#hi,${R3}[1]
+ vmlal.u32 $D1,$H3#hi,${S3}[1]
+ vmlal.u32 $D2,$H4#hi,${S3}[1]
+
+ vmlal.u32 $D3,$H4#hi,${S4}[1]
+ vmlal.u32 $D0,$H1#hi,${S4}[1]
+ vmlal.u32 $D4,$H0#hi,${R4}[1]
+ vmlal.u32 $D1,$H2#hi,${S4}[1]
+ vmlal.u32 $D2,$H3#hi,${S4}[1]
+
+ vld4.32 {$H0#hi,$H1#hi,$H2#hi,$H3#hi},[$in2] @ inp[2:3] (or 0)
+ add $in2,$in2,#64
+
+ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+ @ (hash+inp[0:1])*r^4 and accumulate
+
+ vmlal.u32 $D3,$H3#lo,${R0}[0]
+ vmlal.u32 $D0,$H0#lo,${R0}[0]
+ vmlal.u32 $D4,$H4#lo,${R0}[0]
+ vmlal.u32 $D1,$H1#lo,${R0}[0]
+ vmlal.u32 $D2,$H2#lo,${R0}[0]
+ vld1.32 ${S4}[0],[$tbl0,:32]
+
+ vmlal.u32 $D3,$H2#lo,${R1}[0]
+ vmlal.u32 $D0,$H4#lo,${S1}[0]
+ vmlal.u32 $D4,$H3#lo,${R1}[0]
+ vmlal.u32 $D1,$H0#lo,${R1}[0]
+ vmlal.u32 $D2,$H1#lo,${R1}[0]
+
+ vmlal.u32 $D3,$H1#lo,${R2}[0]
+ vmlal.u32 $D0,$H3#lo,${S2}[0]
+ vmlal.u32 $D4,$H2#lo,${R2}[0]
+ vmlal.u32 $D1,$H4#lo,${S2}[0]
+ vmlal.u32 $D2,$H0#lo,${R2}[0]
+
+ vmlal.u32 $D3,$H0#lo,${R3}[0]
+ vmlal.u32 $D0,$H2#lo,${S3}[0]
+ vmlal.u32 $D4,$H1#lo,${R3}[0]
+ vmlal.u32 $D1,$H3#lo,${S3}[0]
+ vmlal.u32 $D3,$H4#lo,${S4}[0]
+
+ vmlal.u32 $D2,$H4#lo,${S3}[0]
+ vmlal.u32 $D0,$H1#lo,${S4}[0]
+ vmlal.u32 $D4,$H0#lo,${R4}[0]
+ vmov.i32 $H4,#1<<24 @ padbit, yes, always
+ vmlal.u32 $D1,$H2#lo,${S4}[0]
+ vmlal.u32 $D2,$H3#lo,${S4}[0]
+
+ vld4.32 {$H0#lo,$H1#lo,$H2#lo,$H3#lo},[$inp] @ inp[0:1]
+ add $inp,$inp,#64
+# ifdef __ARMEB__
+ vrev32.8 $H0,$H0
+ vrev32.8 $H1,$H1
+ vrev32.8 $H2,$H2
+ vrev32.8 $H3,$H3
+# endif
+
+ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+ @ lazy reduction interleaved with base 2^32 -> base 2^26
+
+ vshr.u64 $T0,$D3,#26
+ vmovn.i64 $D3#lo,$D3
+ vshr.u64 $T1,$D0,#26
+ vmovn.i64 $D0#lo,$D0
+ vadd.i64 $D4,$D4,$T0 @ h3 -> h4
+ vbic.i32 $D3#lo,#0xfc000000
+ vsri.u32 $H4,$H3,#8 @ base 2^32 -> base 2^26
+ vadd.i64 $D1,$D1,$T1 @ h0 -> h1
+ vshl.u32 $H3,$H3,#18
+ vbic.i32 $D0#lo,#0xfc000000
+
+ vshrn.u64 $T0#lo,$D4,#26
+ vmovn.i64 $D4#lo,$D4
+ vshr.u64 $T1,$D1,#26
+ vmovn.i64 $D1#lo,$D1
+ vadd.i64 $D2,$D2,$T1 @ h1 -> h2
+ vsri.u32 $H3,$H2,#14
+ vbic.i32 $D4#lo,#0xfc000000
+ vshl.u32 $H2,$H2,#12
+ vbic.i32 $D1#lo,#0xfc000000
+
+ vadd.i32 $D0#lo,$D0#lo,$T0#lo
+ vshl.u32 $T0#lo,$T0#lo,#2
+ vbic.i32 $H3,#0xfc000000
+ vshrn.u64 $T1#lo,$D2,#26
+ vmovn.i64 $D2#lo,$D2
+ vadd.i32 $D0#lo,$D0#lo,$T0#lo @ h4 -> h0
+ vsri.u32 $H2,$H1,#20
+ vadd.i32 $D3#lo,$D3#lo,$T1#lo @ h2 -> h3
+ vshl.u32 $H1,$H1,#6
+ vbic.i32 $D2#lo,#0xfc000000
+ vbic.i32 $H2,#0xfc000000
+
+ vshr.u32 $T0#lo,$D0#lo,#26
+ vbic.i32 $D0#lo,#0xfc000000
+ vsri.u32 $H1,$H0,#26
+ vbic.i32 $H0,#0xfc000000
+ vshr.u32 $T1#lo,$D3#lo,#26
+ vbic.i32 $D3#lo,#0xfc000000
+ vadd.i32 $D1#lo,$D1#lo,$T0#lo @ h0 -> h1
+ vadd.i32 $D4#lo,$D4#lo,$T1#lo @ h3 -> h4
+ vbic.i32 $H1,#0xfc000000
+
+ bhi .Loop_neon
+
+.Lskip_loop:
+ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+ @ multiply (inp[0:1]+hash) or inp[2:3] by r^2:r^1
+
+ add $tbl1,$ctx,#(48+0*9*4)
+ add $tbl0,$ctx,#(48+1*9*4)
+ adds $len,$len,#32
+# ifdef __thumb2__
+ it ne
+# endif
+ movne $len,#0
+ bne .Long_tail
+
+ vadd.i32 $H2#hi,$H2#lo,$D2#lo @ add hash value and move to #hi
+ vadd.i32 $H0#hi,$H0#lo,$D0#lo
+ vadd.i32 $H3#hi,$H3#lo,$D3#lo
+ vadd.i32 $H1#hi,$H1#lo,$D1#lo
+ vadd.i32 $H4#hi,$H4#lo,$D4#lo
+
+.Long_tail:
+ vld4.32 {${R0}[1],${R1}[1],${S1}[1],${R2}[1]},[$tbl1]! @ load r^1
+ vld4.32 {${R0}[0],${R1}[0],${S1}[0],${R2}[0]},[$tbl0]! @ load r^2
+
+ vadd.i32 $H2#lo,$H2#lo,$D2#lo @ can be redundant
+ vmull.u32 $D2,$H2#hi,$R0
+ vadd.i32 $H0#lo,$H0#lo,$D0#lo
+ vmull.u32 $D0,$H0#hi,$R0
+ vadd.i32 $H3#lo,$H3#lo,$D3#lo
+ vmull.u32 $D3,$H3#hi,$R0
+ vadd.i32 $H1#lo,$H1#lo,$D1#lo
+ vmull.u32 $D1,$H1#hi,$R0
+ vadd.i32 $H4#lo,$H4#lo,$D4#lo
+ vmull.u32 $D4,$H4#hi,$R0
+
+ vmlal.u32 $D0,$H4#hi,$S1
+ vld4.32 {${S2}[1],${R3}[1],${S3}[1],${R4}[1]},[$tbl1]!
+ vmlal.u32 $D3,$H2#hi,$R1
+ vld4.32 {${S2}[0],${R3}[0],${S3}[0],${R4}[0]},[$tbl0]!
+ vmlal.u32 $D1,$H0#hi,$R1
+ vmlal.u32 $D4,$H3#hi,$R1
+ vmlal.u32 $D2,$H1#hi,$R1
+
+ vmlal.u32 $D3,$H1#hi,$R2
+ vld1.32 ${S4}[1],[$tbl1,:32]
+ vmlal.u32 $D0,$H3#hi,$S2
+ vld1.32 ${S4}[0],[$tbl0,:32]
+ vmlal.u32 $D4,$H2#hi,$R2
+ vmlal.u32 $D1,$H4#hi,$S2
+ vmlal.u32 $D2,$H0#hi,$R2
+
+ vmlal.u32 $D3,$H0#hi,$R3
+# ifdef __thumb2__
+ it ne
+# endif
+ addne $tbl1,$ctx,#(48+2*9*4)
+ vmlal.u32 $D0,$H2#hi,$S3
+# ifdef __thumb2__
+ it ne
+# endif
+ addne $tbl0,$ctx,#(48+3*9*4)
+ vmlal.u32 $D4,$H1#hi,$R3
+ vmlal.u32 $D1,$H3#hi,$S3
+ vmlal.u32 $D2,$H4#hi,$S3
+
+ vmlal.u32 $D3,$H4#hi,$S4
+ vorn $MASK,$MASK,$MASK @ all-ones, can be redundant
+ vmlal.u32 $D0,$H1#hi,$S4
+ vshr.u64 $MASK,$MASK,#38
+ vmlal.u32 $D4,$H0#hi,$R4
+ vmlal.u32 $D1,$H2#hi,$S4
+ vmlal.u32 $D2,$H3#hi,$S4
+
+ beq .Lshort_tail
+
+ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+ @ (hash+inp[0:1])*r^4:r^3 and accumulate
+
+ vld4.32 {${R0}[1],${R1}[1],${S1}[1],${R2}[1]},[$tbl1]! @ load r^3
+ vld4.32 {${R0}[0],${R1}[0],${S1}[0],${R2}[0]},[$tbl0]! @ load r^4
+
+ vmlal.u32 $D2,$H2#lo,$R0
+ vmlal.u32 $D0,$H0#lo,$R0
+ vmlal.u32 $D3,$H3#lo,$R0
+ vmlal.u32 $D1,$H1#lo,$R0
+ vmlal.u32 $D4,$H4#lo,$R0
+
+ vmlal.u32 $D0,$H4#lo,$S1
+ vld4.32 {${S2}[1],${R3}[1],${S3}[1],${R4}[1]},[$tbl1]!
+ vmlal.u32 $D3,$H2#lo,$R1
+ vld4.32 {${S2}[0],${R3}[0],${S3}[0],${R4}[0]},[$tbl0]!
+ vmlal.u32 $D1,$H0#lo,$R1
+ vmlal.u32 $D4,$H3#lo,$R1
+ vmlal.u32 $D2,$H1#lo,$R1
+
+ vmlal.u32 $D3,$H1#lo,$R2
+ vld1.32 ${S4}[1],[$tbl1,:32]
+ vmlal.u32 $D0,$H3#lo,$S2
+ vld1.32 ${S4}[0],[$tbl0,:32]
+ vmlal.u32 $D4,$H2#lo,$R2
+ vmlal.u32 $D1,$H4#lo,$S2
+ vmlal.u32 $D2,$H0#lo,$R2
+
+ vmlal.u32 $D3,$H0#lo,$R3
+ vmlal.u32 $D0,$H2#lo,$S3
+ vmlal.u32 $D4,$H1#lo,$R3
+ vmlal.u32 $D1,$H3#lo,$S3
+ vmlal.u32 $D2,$H4#lo,$S3
+
+ vmlal.u32 $D3,$H4#lo,$S4
+ vorn $MASK,$MASK,$MASK @ all-ones
+ vmlal.u32 $D0,$H1#lo,$S4
+ vshr.u64 $MASK,$MASK,#38
+ vmlal.u32 $D4,$H0#lo,$R4
+ vmlal.u32 $D1,$H2#lo,$S4
+ vmlal.u32 $D2,$H3#lo,$S4
+
+.Lshort_tail:
+ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+ @ horizontal addition
+
+ vadd.i64 $D3#lo,$D3#lo,$D3#hi
+ vadd.i64 $D0#lo,$D0#lo,$D0#hi
+ vadd.i64 $D4#lo,$D4#lo,$D4#hi
+ vadd.i64 $D1#lo,$D1#lo,$D1#hi
+ vadd.i64 $D2#lo,$D2#lo,$D2#hi
+
+ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+ @ lazy reduction, but without narrowing
+
+ vshr.u64 $T0,$D3,#26
+ vand.i64 $D3,$D3,$MASK
+ vshr.u64 $T1,$D0,#26
+ vand.i64 $D0,$D0,$MASK
+ vadd.i64 $D4,$D4,$T0 @ h3 -> h4
+ vadd.i64 $D1,$D1,$T1 @ h0 -> h1
+
+ vshr.u64 $T0,$D4,#26
+ vand.i64 $D4,$D4,$MASK
+ vshr.u64 $T1,$D1,#26
+ vand.i64 $D1,$D1,$MASK
+ vadd.i64 $D2,$D2,$T1 @ h1 -> h2
+
+ vadd.i64 $D0,$D0,$T0
+ vshl.u64 $T0,$T0,#2
+ vshr.u64 $T1,$D2,#26
+ vand.i64 $D2,$D2,$MASK
+ vadd.i64 $D0,$D0,$T0 @ h4 -> h0
+ vadd.i64 $D3,$D3,$T1 @ h2 -> h3
+
+ vshr.u64 $T0,$D0,#26
+ vand.i64 $D0,$D0,$MASK
+ vshr.u64 $T1,$D3,#26
+ vand.i64 $D3,$D3,$MASK
+ vadd.i64 $D1,$D1,$T0 @ h0 -> h1
+ vadd.i64 $D4,$D4,$T1 @ h3 -> h4
+
+ cmp $len,#0
+ bne .Leven
+
+ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+ @ store hash value
+
+ vst4.32 {$D0#lo[0],$D1#lo[0],$D2#lo[0],$D3#lo[0]},[$ctx]!
+ vst1.32 {$D4#lo[0]},[$ctx]
+
+ vldmia sp!,{d8-d15} @ epilogue
+ ldmia sp!,{r4-r7}
+.Lno_data_neon:
+ ret @ bx lr
+.size poly1305_blocks_neon,.-poly1305_blocks_neon
+
+.type poly1305_emit_neon,%function
+.align 5
+poly1305_emit_neon:
+ ldr ip,[$ctx,#36] @ is_base2_26
+
+ stmdb sp!,{r4-r11}
+
+ tst ip,ip
+ beq .Lpoly1305_emit_enter
+
+ ldmia $ctx,{$h0-$h4}
+ eor $g0,$g0,$g0
+
+ adds $h0,$h0,$h1,lsl#26 @ base 2^26 -> base 2^32
+ mov $h1,$h1,lsr#6
+ adcs $h1,$h1,$h2,lsl#20
+ mov $h2,$h2,lsr#12
+ adcs $h2,$h2,$h3,lsl#14
+ mov $h3,$h3,lsr#18
+ adcs $h3,$h3,$h4,lsl#8
+ adc $h4,$g0,$h4,lsr#24 @ can be partially reduced ...
+
+ and $g0,$h4,#-4 @ ... so reduce
+ and $h4,$h3,#3
+ add $g0,$g0,$g0,lsr#2 @ *= 5
+ adds $h0,$h0,$g0
+ adcs $h1,$h1,#0
+ adcs $h2,$h2,#0
+ adc $h3,$h3,#0
+
+ adds $g0,$h0,#5 @ compare to modulus
+ adcs $g1,$h1,#0
+ adcs $g2,$h2,#0
+ adcs $g3,$h3,#0
+ adc $g4,$h4,#0
+ tst $g4,#4 @ did it carry/borrow?
+
+# ifdef __thumb2__
+ it ne
+# endif
+ movne $h0,$g0
+ ldr $g0,[$nonce,#0]
+# ifdef __thumb2__
+ it ne
+# endif
+ movne $h1,$g1
+ ldr $g1,[$nonce,#4]
+# ifdef __thumb2__
+ it ne
+# endif
+ movne $h2,$g2
+ ldr $g2,[$nonce,#8]
+# ifdef __thumb2__
+ it ne
+# endif
+ movne $h3,$g3
+ ldr $g3,[$nonce,#12]
+
+ adds $h0,$h0,$g0 @ accumulate nonce
+ adcs $h1,$h1,$g1
+ adcs $h2,$h2,$g2
+ adc $h3,$h3,$g3
+
+# ifdef __ARMEB__
+ rev $h0,$h0
+ rev $h1,$h1
+ rev $h2,$h2
+ rev $h3,$h3
+# endif
+ str $h0,[$mac,#0] @ store the result
+ str $h1,[$mac,#4]
+ str $h2,[$mac,#8]
+ str $h3,[$mac,#12]
+
+ ldmia sp!,{r4-r11}
+ ret @ bx lr
+.size poly1305_emit_neon,.-poly1305_emit_neon
+
+.align 5
+.Lzeros:
+.long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+.LOPENSSL_armcap:
+.word OPENSSL_armcap_P-.Lpoly1305_init
+#endif
+___
+} }
+$code.=<<___;
+.asciz "Poly1305 for ARMv4/NEON, CRYPTOGAMS by <appro\@openssl.org>"
+.align 2
+#if __ARM_MAX_ARCH__>=7
+.comm OPENSSL_armcap_P,4,4
+#endif
+___
+
+foreach (split("\n",$code)) {
+ s/\`([^\`]*)\`/eval $1/geo;
+
+ s/\bq([0-9]+)#(lo|hi)/sprintf "d%d",2*$1+($2 eq "hi")/geo or
+ s/\bret\b/bx lr/go or
+ s/\bbx\s+lr\b/.word\t0xe12fff1e/go; # make it possible to compile with -march=armv4
+
+ print $_,"\n";
+}
+close STDOUT; # enforce flush
diff --git a/src/crypto/poly1305/asm/poly1305-armv8.pl b/src/crypto/poly1305/asm/poly1305-armv8.pl
new file mode 100755
index 00000000..1d9a81b8
--- /dev/null
+++ b/src/crypto/poly1305/asm/poly1305-armv8.pl
@@ -0,0 +1,925 @@
+#!/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/.
+# ====================================================================
+#
+# This module implements Poly1305 hash for ARMv8.
+#
+# June 2015
+#
+# Numbers are cycles per processed byte with poly1305_blocks alone.
+#
+# IALU/gcc-4.9 NEON
+#
+# Apple A7 1.86/+5% 0.72
+# Cortex-A53 2.63/+58% 1.47
+# Cortex-A57 2.70/+7% 1.14
+# Denver 1.39/+50% 1.18(*)
+# X-Gene 2.00/+68% 2.19
+#
+# (*) estimate based on resources availability is less than 1.0,
+# i.e. measured result is worse than expected, presumably binary
+# translator is not almighty;
+
+$flavour=shift;
+$output=shift;
+
+$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;
+
+my ($ctx,$inp,$len,$padbit) = map("x$_",(0..3));
+my ($mac,$nonce)=($inp,$len);
+
+my ($h0,$h1,$h2,$r0,$r1,$s1,$t0,$t1,$d0,$d1,$d2) = map("x$_",(4..14));
+
+$code.=<<___;
+#include <openssl/arm_arch.h>
+
+.text
+
+// forward "declarations" are required for Apple
+.extern OPENSSL_armcap_P
+.globl poly1305_blocks
+.globl poly1305_emit
+
+.globl poly1305_init
+.type poly1305_init,%function
+.align 5
+poly1305_init:
+ cmp $inp,xzr
+ stp xzr,xzr,[$ctx] // zero hash value
+ stp xzr,xzr,[$ctx,#16] // [along with is_base2_26]
+
+ csel x0,xzr,x0,eq
+ b.eq .Lno_key
+
+#ifdef __ILP32__
+ ldrsw $t1,.LOPENSSL_armcap_P
+#else
+ ldr $t1,.LOPENSSL_armcap_P
+#endif
+ adr $t0,.LOPENSSL_armcap_P
+
+ ldp $r0,$r1,[$inp] // load key
+ mov $s1,#0xfffffffc0fffffff
+ movk $s1,#0x0fff,lsl#48
+ ldr w17,[$t0,$t1]
+#ifdef __ARMEB__
+ rev $r0,$r0 // flip bytes
+ rev $r1,$r1
+#endif
+ and $r0,$r0,$s1 // &=0ffffffc0fffffff
+ and $s1,$s1,#-4
+ and $r1,$r1,$s1 // &=0ffffffc0ffffffc
+ stp $r0,$r1,[$ctx,#32] // save key value
+
+ tst w17,#ARMV7_NEON
+
+ adr $d0,poly1305_blocks
+ adr $r0,poly1305_blocks_neon
+ adr $d1,poly1305_emit
+ adr $r1,poly1305_emit_neon
+
+ csel $d0,$d0,$r0,eq
+ csel $d1,$d1,$r1,eq
+
+ stp $d0,$d1,[$len]
+
+ mov x0,#1
+.Lno_key:
+ ret
+.size poly1305_init,.-poly1305_init
+
+.type poly1305_blocks,%function
+.align 5
+poly1305_blocks:
+ ands $len,$len,#-16
+ b.eq .Lno_data
+
+ ldp $h0,$h1,[$ctx] // load hash value
+ ldp $r0,$r1,[$ctx,#32] // load key value
+ ldr $h2,[$ctx,#16]
+ add $s1,$r1,$r1,lsr#2 // s1 = r1 + (r1 >> 2)
+ b .Loop
+
+.align 5
+.Loop:
+ ldp $t0,$t1,[$inp],#16 // load input
+ sub $len,$len,#16
+#ifdef __ARMEB__
+ rev $t0,$t0
+ rev $t1,$t1
+#endif
+ adds $h0,$h0,$t0 // accumulate input
+ adcs $h1,$h1,$t1
+
+ mul $d0,$h0,$r0 // h0*r0
+ adc $h2,$h2,$padbit
+ umulh $d1,$h0,$r0
+
+ mul $t0,$h1,$s1 // h1*5*r1
+ umulh $t1,$h1,$s1
+
+ adds $d0,$d0,$t0
+ mul $t0,$h0,$r1 // h0*r1
+ adc $d1,$d1,$t1
+ umulh $d2,$h0,$r1
+
+ adds $d1,$d1,$t0
+ mul $t0,$h1,$r0 // h1*r0
+ adc $d2,$d2,xzr
+ umulh $t1,$h1,$r0
+
+ adds $d1,$d1,$t0
+ mul $t0,$h2,$s1 // h2*5*r1
+ adc $d2,$d2,$t1
+ mul $t1,$h2,$r0 // h2*r0
+
+ adds $d1,$d1,$t0
+ adc $d2,$d2,$t1
+
+ and $t0,$d2,#-4 // final reduction
+ and $h2,$d2,#3
+ add $t0,$t0,$d2,lsr#2
+ adds $h0,$d0,$t0
+ adc $h1,$d1,xzr
+
+ cbnz $len,.Loop
+
+ stp $h0,$h1,[$ctx] // store hash value
+ str $h2,[$ctx,#16]
+
+.Lno_data:
+ ret
+.size poly1305_blocks,.-poly1305_blocks
+
+.type poly1305_emit,%function
+.align 5
+poly1305_emit:
+ ldp $h0,$h1,[$ctx] // load hash base 2^64
+ ldr $h2,[$ctx,#16]
+ ldp $t0,$t1,[$nonce] // load nonce
+
+ adds $d0,$h0,#5 // compare to modulus
+ adcs $d1,$h1,xzr
+ adc $d2,$h2,xzr
+
+ tst $d2,#-4 // see if it's carried/borrowed
+
+ csel $h0,$h0,$d0,eq
+ csel $h1,$h1,$d1,eq
+
+#ifdef __ARMEB__
+ ror $t0,$t0,#32 // flip nonce words
+ ror $t1,$t1,#32
+#endif
+ adds $h0,$h0,$t0 // accumulate nonce
+ adc $h1,$h1,$t1
+#ifdef __ARMEB__
+ rev $h0,$h0 // flip output bytes
+ rev $h1,$h1
+#endif
+ stp $h0,$h1,[$mac] // write result
+
+ ret
+.size poly1305_emit,.-poly1305_emit
+___
+my ($R0,$R1,$S1,$R2,$S2,$R3,$S3,$R4,$S4) = map("v$_.4s",(0..8));
+my ($IN01_0,$IN01_1,$IN01_2,$IN01_3,$IN01_4) = map("v$_.2s",(9..13));
+my ($IN23_0,$IN23_1,$IN23_2,$IN23_3,$IN23_4) = map("v$_.2s",(14..18));
+my ($ACC0,$ACC1,$ACC2,$ACC3,$ACC4) = map("v$_.2d",(19..23));
+my ($H0,$H1,$H2,$H3,$H4) = map("v$_.2s",(24..28));
+my ($T0,$T1,$MASK) = map("v$_",(29..31));
+
+my ($in2,$zeros)=("x16","x17");
+my $is_base2_26 = $zeros; # borrow
+
+$code.=<<___;
+.type poly1305_mult,%function
+.align 5
+poly1305_mult:
+ mul $d0,$h0,$r0 // h0*r0
+ umulh $d1,$h0,$r0
+
+ mul $t0,$h1,$s1 // h1*5*r1
+ umulh $t1,$h1,$s1
+
+ adds $d0,$d0,$t0
+ mul $t0,$h0,$r1 // h0*r1
+ adc $d1,$d1,$t1
+ umulh $d2,$h0,$r1
+
+ adds $d1,$d1,$t0
+ mul $t0,$h1,$r0 // h1*r0
+ adc $d2,$d2,xzr
+ umulh $t1,$h1,$r0
+
+ adds $d1,$d1,$t0
+ mul $t0,$h2,$s1 // h2*5*r1
+ adc $d2,$d2,$t1
+ mul $t1,$h2,$r0 // h2*r0
+
+ adds $d1,$d1,$t0
+ adc $d2,$d2,$t1
+
+ and $t0,$d2,#-4 // final reduction
+ and $h2,$d2,#3
+ add $t0,$t0,$d2,lsr#2
+ adds $h0,$d0,$t0
+ adc $h1,$d1,xzr
+
+ ret
+.size poly1305_mult,.-poly1305_mult
+
+.type poly1305_splat,%function
+.align 5
+poly1305_splat:
+ and x12,$h0,#0x03ffffff // base 2^64 -> base 2^26
+ ubfx x13,$h0,#26,#26
+ extr x14,$h1,$h0,#52
+ and x14,x14,#0x03ffffff
+ ubfx x15,$h1,#14,#26
+ extr x16,$h2,$h1,#40
+
+ str w12,[$ctx,#16*0] // r0
+ add w12,w13,w13,lsl#2 // r1*5
+ str w13,[$ctx,#16*1] // r1
+ add w13,w14,w14,lsl#2 // r2*5
+ str w12,[$ctx,#16*2] // s1
+ str w14,[$ctx,#16*3] // r2
+ add w14,w15,w15,lsl#2 // r3*5
+ str w13,[$ctx,#16*4] // s2
+ str w15,[$ctx,#16*5] // r3
+ add w15,w16,w16,lsl#2 // r4*5
+ str w14,[$ctx,#16*6] // s3
+ str w16,[$ctx,#16*7] // r4
+ str w15,[$ctx,#16*8] // s4
+
+ ret
+.size poly1305_splat,.-poly1305_splat
+
+.type poly1305_blocks_neon,%function
+.align 5
+poly1305_blocks_neon:
+ ldr $is_base2_26,[$ctx,#24]
+ cmp $len,#128
+ b.hs .Lblocks_neon
+ cbz $is_base2_26,poly1305_blocks
+
+.Lblocks_neon:
+ stp x29,x30,[sp,#-80]!
+ add x29,sp,#0
+
+ ands $len,$len,#-16
+ b.eq .Lno_data_neon
+
+ cbz $is_base2_26,.Lbase2_64_neon
+
+ ldp w10,w11,[$ctx] // load hash value base 2^26
+ ldp w12,w13,[$ctx,#8]
+ ldr w14,[$ctx,#16]
+
+ tst $len,#31
+ b.eq .Leven_neon
+
+ ldp $r0,$r1,[$ctx,#32] // load key value
+
+ add $h0,x10,x11,lsl#26 // base 2^26 -> base 2^64
+ lsr $h1,x12,#12
+ adds $h0,$h0,x12,lsl#52
+ add $h1,$h1,x13,lsl#14
+ adc $h1,$h1,xzr
+ lsr $h2,x14,#24
+ adds $h1,$h1,x14,lsl#40
+ adc $d2,$h2,xzr // can be partially reduced...
+
+ ldp $d0,$d1,[$inp],#16 // load input
+ sub $len,$len,#16
+ add $s1,$r1,$r1,lsr#2 // s1 = r1 + (r1 >> 2)
+
+ and $t0,$d2,#-4 // ... so reduce
+ and $h2,$d2,#3
+ add $t0,$t0,$d2,lsr#2
+ adds $h0,$h0,$t0
+ adc $h1,$h1,xzr
+
+#ifdef __ARMEB__
+ rev $d0,$d0
+ rev $d1,$d1
+#endif
+ adds $h0,$h0,$d0 // accumulate input
+ adcs $h1,$h1,$d1
+ adc $h2,$h2,$padbit
+
+ bl poly1305_mult
+ ldr x30,[sp,#8]
+
+ cbz $padbit,.Lstore_base2_64_neon
+
+ and x10,$h0,#0x03ffffff // base 2^64 -> base 2^26
+ ubfx x11,$h0,#26,#26
+ extr x12,$h1,$h0,#52
+ and x12,x12,#0x03ffffff
+ ubfx x13,$h1,#14,#26
+ extr x14,$h2,$h1,#40
+
+ cbnz $len,.Leven_neon
+
+ stp w10,w11,[$ctx] // store hash value base 2^26
+ stp w12,w13,[$ctx,#8]
+ str w14,[$ctx,#16]
+ b .Lno_data_neon
+
+.align 4
+.Lstore_base2_64_neon:
+ stp $h0,$h1,[$ctx] // store hash value base 2^64
+ stp $h2,xzr,[$ctx,#16] // note that is_base2_26 is zeroed
+ b .Lno_data_neon
+
+.align 4
+.Lbase2_64_neon:
+ ldp $r0,$r1,[$ctx,#32] // load key value
+
+ ldp $h0,$h1,[$ctx] // load hash value base 2^64
+ ldr $h2,[$ctx,#16]
+
+ tst $len,#31
+ b.eq .Linit_neon
+
+ ldp $d0,$d1,[$inp],#16 // load input
+ sub $len,$len,#16
+ add $s1,$r1,$r1,lsr#2 // s1 = r1 + (r1 >> 2)
+#ifdef __ARMEB__
+ rev $d0,$d0
+ rev $d1,$d1
+#endif
+ adds $h0,$h0,$d0 // accumulate input
+ adcs $h1,$h1,$d1
+ adc $h2,$h2,$padbit
+
+ bl poly1305_mult
+
+.Linit_neon:
+ and x10,$h0,#0x03ffffff // base 2^64 -> base 2^26
+ ubfx x11,$h0,#26,#26
+ extr x12,$h1,$h0,#52
+ and x12,x12,#0x03ffffff
+ ubfx x13,$h1,#14,#26
+ extr x14,$h2,$h1,#40
+
+ stp d8,d9,[sp,#16] // meet ABI requirements
+ stp d10,d11,[sp,#32]
+ stp d12,d13,[sp,#48]
+ stp d14,d15,[sp,#64]
+
+ fmov ${H0},x10
+ fmov ${H1},x11
+ fmov ${H2},x12
+ fmov ${H3},x13
+ fmov ${H4},x14
+
+ ////////////////////////////////// initialize r^n table
+ mov $h0,$r0 // r^1
+ add $s1,$r1,$r1,lsr#2 // s1 = r1 + (r1 >> 2)
+ mov $h1,$r1
+ mov $h2,xzr
+ add $ctx,$ctx,#48+12
+ bl poly1305_splat
+
+ bl poly1305_mult // r^2
+ sub $ctx,$ctx,#4
+ bl poly1305_splat
+
+ bl poly1305_mult // r^3
+ sub $ctx,$ctx,#4
+ bl poly1305_splat
+
+ bl poly1305_mult // r^4
+ sub $ctx,$ctx,#4
+ bl poly1305_splat
+ ldr x30,[sp,#8]
+
+ add $in2,$inp,#32
+ adr $zeros,.Lzeros
+ subs $len,$len,#64
+ csel $in2,$zeros,$in2,lo
+
+ mov x4,#1
+ str x4,[$ctx,#-24] // set is_base2_26
+ sub $ctx,$ctx,#48 // restore original $ctx
+ b .Ldo_neon
+
+.align 4
+.Leven_neon:
+ add $in2,$inp,#32
+ adr $zeros,.Lzeros
+ subs $len,$len,#64
+ csel $in2,$zeros,$in2,lo
+
+ stp d8,d9,[sp,#16] // meet ABI requirements
+ stp d10,d11,[sp,#32]
+ stp d12,d13,[sp,#48]
+ stp d14,d15,[sp,#64]
+
+ fmov ${H0},x10
+ fmov ${H1},x11
+ fmov ${H2},x12
+ fmov ${H3},x13
+ fmov ${H4},x14
+
+.Ldo_neon:
+ ldp x8,x12,[$in2],#16 // inp[2:3] (or zero)
+ ldp x9,x13,[$in2],#48
+
+ lsl $padbit,$padbit,#24
+ add x15,$ctx,#48
+
+#ifdef __ARMEB__
+ rev x8,x8
+ rev x12,x12
+ rev x9,x9
+ rev x13,x13
+#endif
+ and x4,x8,#0x03ffffff // base 2^64 -> base 2^26
+ and x5,x9,#0x03ffffff
+ ubfx x6,x8,#26,#26
+ ubfx x7,x9,#26,#26
+ add x4,x4,x5,lsl#32 // bfi x4,x5,#32,#32
+ extr x8,x12,x8,#52
+ extr x9,x13,x9,#52
+ add x6,x6,x7,lsl#32 // bfi x6,x7,#32,#32
+ fmov $IN23_0,x4
+ and x8,x8,#0x03ffffff
+ and x9,x9,#0x03ffffff
+ ubfx x10,x12,#14,#26
+ ubfx x11,x13,#14,#26
+ add x12,$padbit,x12,lsr#40
+ add x13,$padbit,x13,lsr#40
+ add x8,x8,x9,lsl#32 // bfi x8,x9,#32,#32
+ fmov $IN23_1,x6
+ add x10,x10,x11,lsl#32 // bfi x10,x11,#32,#32
+ add x12,x12,x13,lsl#32 // bfi x12,x13,#32,#32
+ fmov $IN23_2,x8
+ fmov $IN23_3,x10
+ fmov $IN23_4,x12
+
+ ldp x8,x12,[$inp],#16 // inp[0:1]
+ ldp x9,x13,[$inp],#48
+
+ ld1 {$R0,$R1,$S1,$R2},[x15],#64
+ ld1 {$S2,$R3,$S3,$R4},[x15],#64
+ ld1 {$S4},[x15]
+
+#ifdef __ARMEB__
+ rev x8,x8
+ rev x12,x12
+ rev x9,x9
+ rev x13,x13
+#endif
+ and x4,x8,#0x03ffffff // base 2^64 -> base 2^26
+ and x5,x9,#0x03ffffff
+ ubfx x6,x8,#26,#26
+ ubfx x7,x9,#26,#26
+ add x4,x4,x5,lsl#32 // bfi x4,x5,#32,#32
+ extr x8,x12,x8,#52
+ extr x9,x13,x9,#52
+ add x6,x6,x7,lsl#32 // bfi x6,x7,#32,#32
+ fmov $IN01_0,x4
+ and x8,x8,#0x03ffffff
+ and x9,x9,#0x03ffffff
+ ubfx x10,x12,#14,#26
+ ubfx x11,x13,#14,#26
+ add x12,$padbit,x12,lsr#40
+ add x13,$padbit,x13,lsr#40
+ add x8,x8,x9,lsl#32 // bfi x8,x9,#32,#32
+ fmov $IN01_1,x6
+ add x10,x10,x11,lsl#32 // bfi x10,x11,#32,#32
+ add x12,x12,x13,lsl#32 // bfi x12,x13,#32,#32
+ fmov $IN01_2,x8
+ fmov $IN01_3,x10
+ fmov $IN01_4,x12
+
+ b.ls .Lskip_loop
+
+.align 4
+.Loop_neon:
+ ////////////////////////////////////////////////////////////////
+ // ((inp[0]*r^4+inp[2]*r^2+inp[4])*r^4+inp[6]*r^2
+ // ((inp[1]*r^4+inp[3]*r^2+inp[5])*r^3+inp[7]*r
+ // \___________________/
+ // ((inp[0]*r^4+inp[2]*r^2+inp[4])*r^4+inp[6]*r^2+inp[8])*r^2
+ // ((inp[1]*r^4+inp[3]*r^2+inp[5])*r^4+inp[7]*r^2+inp[9])*r
+ // \___________________/ \____________________/
+ //
+ // Note that we start with inp[2:3]*r^2. This is because it
+ // doesn't depend on reduction in previous iteration.
+ ////////////////////////////////////////////////////////////////
+ // d4 = h0*r4 + h1*r3 + h2*r2 + h3*r1 + h4*r0
+ // d3 = h0*r3 + h1*r2 + h2*r1 + h3*r0 + h4*5*r4
+ // d2 = h0*r2 + h1*r1 + h2*r0 + h3*5*r4 + h4*5*r3
+ // d1 = h0*r1 + h1*r0 + h2*5*r4 + h3*5*r3 + h4*5*r2
+ // d0 = h0*r0 + h1*5*r4 + h2*5*r3 + h3*5*r2 + h4*5*r1
+
+ subs $len,$len,#64
+ umull $ACC4,$IN23_0,${R4}[2]
+ csel $in2,$zeros,$in2,lo
+ umull $ACC3,$IN23_0,${R3}[2]
+ umull $ACC2,$IN23_0,${R2}[2]
+ ldp x8,x12,[$in2],#16 // inp[2:3] (or zero)
+ umull $ACC1,$IN23_0,${R1}[2]
+ ldp x9,x13,[$in2],#48
+ umull $ACC0,$IN23_0,${R0}[2]
+#ifdef __ARMEB__
+ rev x8,x8
+ rev x12,x12
+ rev x9,x9
+ rev x13,x13
+#endif
+
+ umlal $ACC4,$IN23_1,${R3}[2]
+ and x4,x8,#0x03ffffff // base 2^64 -> base 2^26
+ umlal $ACC3,$IN23_1,${R2}[2]
+ and x5,x9,#0x03ffffff
+ umlal $ACC2,$IN23_1,${R1}[2]
+ ubfx x6,x8,#26,#26
+ umlal $ACC1,$IN23_1,${R0}[2]
+ ubfx x7,x9,#26,#26
+ umlal $ACC0,$IN23_1,${S4}[2]
+ add x4,x4,x5,lsl#32 // bfi x4,x5,#32,#32
+
+ umlal $ACC4,$IN23_2,${R2}[2]
+ extr x8,x12,x8,#52
+ umlal $ACC3,$IN23_2,${R1}[2]
+ extr x9,x13,x9,#52
+ umlal $ACC2,$IN23_2,${R0}[2]
+ add x6,x6,x7,lsl#32 // bfi x6,x7,#32,#32
+ umlal $ACC1,$IN23_2,${S4}[2]
+ fmov $IN23_0,x4
+ umlal $ACC0,$IN23_2,${S3}[2]
+ and x8,x8,#0x03ffffff
+
+ umlal $ACC4,$IN23_3,${R1}[2]
+ and x9,x9,#0x03ffffff
+ umlal $ACC3,$IN23_3,${R0}[2]
+ ubfx x10,x12,#14,#26
+ umlal $ACC2,$IN23_3,${S4}[2]
+ ubfx x11,x13,#14,#26
+ umlal $ACC1,$IN23_3,${S3}[2]
+ add x8,x8,x9,lsl#32 // bfi x8,x9,#32,#32
+ umlal $ACC0,$IN23_3,${S2}[2]
+ fmov $IN23_1,x6
+
+ add $IN01_2,$IN01_2,$H2
+ add x12,$padbit,x12,lsr#40
+ umlal $ACC4,$IN23_4,${R0}[2]
+ add x13,$padbit,x13,lsr#40
+ umlal $ACC3,$IN23_4,${S4}[2]
+ add x10,x10,x11,lsl#32 // bfi x10,x11,#32,#32
+ umlal $ACC2,$IN23_4,${S3}[2]
+ add x12,x12,x13,lsl#32 // bfi x12,x13,#32,#32
+ umlal $ACC1,$IN23_4,${S2}[2]
+ fmov $IN23_2,x8
+ umlal $ACC0,$IN23_4,${S1}[2]
+ fmov $IN23_3,x10
+
+ ////////////////////////////////////////////////////////////////
+ // (hash+inp[0:1])*r^4 and accumulate
+
+ add $IN01_0,$IN01_0,$H0
+ fmov $IN23_4,x12
+ umlal $ACC3,$IN01_2,${R1}[0]
+ ldp x8,x12,[$inp],#16 // inp[0:1]
+ umlal $ACC0,$IN01_2,${S3}[0]
+ ldp x9,x13,[$inp],#48
+ umlal $ACC4,$IN01_2,${R2}[0]
+ umlal $ACC1,$IN01_2,${S4}[0]
+ umlal $ACC2,$IN01_2,${R0}[0]
+#ifdef __ARMEB__
+ rev x8,x8
+ rev x12,x12
+ rev x9,x9
+ rev x13,x13
+#endif
+
+ add $IN01_1,$IN01_1,$H1
+ umlal $ACC3,$IN01_0,${R3}[0]
+ umlal $ACC4,$IN01_0,${R4}[0]
+ and x4,x8,#0x03ffffff // base 2^64 -> base 2^26
+ umlal $ACC2,$IN01_0,${R2}[0]
+ and x5,x9,#0x03ffffff
+ umlal $ACC0,$IN01_0,${R0}[0]
+ ubfx x6,x8,#26,#26
+ umlal $ACC1,$IN01_0,${R1}[0]
+ ubfx x7,x9,#26,#26
+
+ add $IN01_3,$IN01_3,$H3
+ add x4,x4,x5,lsl#32 // bfi x4,x5,#32,#32
+ umlal $ACC3,$IN01_1,${R2}[0]
+ extr x8,x12,x8,#52
+ umlal $ACC4,$IN01_1,${R3}[0]
+ extr x9,x13,x9,#52
+ umlal $ACC0,$IN01_1,${S4}[0]
+ add x6,x6,x7,lsl#32 // bfi x6,x7,#32,#32
+ umlal $ACC2,$IN01_1,${R1}[0]
+ fmov $IN01_0,x4
+ umlal $ACC1,$IN01_1,${R0}[0]
+ and x8,x8,#0x03ffffff
+
+ add $IN01_4,$IN01_4,$H4
+ and x9,x9,#0x03ffffff
+ umlal $ACC3,$IN01_3,${R0}[0]
+ ubfx x10,x12,#14,#26
+ umlal $ACC0,$IN01_3,${S2}[0]
+ ubfx x11,x13,#14,#26
+ umlal $ACC4,$IN01_3,${R1}[0]
+ add x8,x8,x9,lsl#32 // bfi x8,x9,#32,#32
+ umlal $ACC1,$IN01_3,${S3}[0]
+ fmov $IN01_1,x6
+ umlal $ACC2,$IN01_3,${S4}[0]
+ add x12,$padbit,x12,lsr#40
+
+ umlal $ACC3,$IN01_4,${S4}[0]
+ add x13,$padbit,x13,lsr#40
+ umlal $ACC0,$IN01_4,${S1}[0]
+ add x10,x10,x11,lsl#32 // bfi x10,x11,#32,#32
+ umlal $ACC4,$IN01_4,${R0}[0]
+ add x12,x12,x13,lsl#32 // bfi x12,x13,#32,#32
+ umlal $ACC1,$IN01_4,${S2}[0]
+ fmov $IN01_2,x8
+ umlal $ACC2,$IN01_4,${S3}[0]
+ fmov $IN01_3,x10
+
+ /////////////////////////////////////////////////////////////////
+ // lazy reduction as discussed in "NEON crypto" by D.J. Bernstein
+ // and P. Schwabe
+
+ ushr $T0.2d,$ACC3,#26
+ fmov $IN01_4,x12
+ xtn $H3,$ACC3
+ ushr $T1.2d,$ACC0,#26
+ xtn $H0,$ACC0
+ add $ACC4,$ACC4,$T0.2d // h3 -> h4
+ bic $H3,#0xfc,lsl#24 // &=0x03ffffff
+ add $ACC1,$ACC1,$T1.2d // h0 -> h1
+ bic $H0,#0xfc,lsl#24
+
+ shrn $T0.2s,$ACC4,#26
+ xtn $H4,$ACC4
+ ushr $T1.2d,$ACC1,#26
+ xtn $H1,$ACC1
+ add $ACC2,$ACC2,$T1.2d // h1 -> h2
+ bic $H4,#0xfc,lsl#24
+ bic $H1,#0xfc,lsl#24
+
+ add $H0,$H0,$T0.2s
+ shl $T0.2s,$T0.2s,#2
+ shrn $T1.2s,$ACC2,#26
+ xtn $H2,$ACC2
+ add $H0,$H0,$T0.2s // h4 -> h0
+ add $H3,$H3,$T1.2s // h2 -> h3
+ bic $H2,#0xfc,lsl#24
+
+ ushr $T0.2s,$H0,#26
+ bic $H0,#0xfc,lsl#24
+ ushr $T1.2s,$H3,#26
+ bic $H3,#0xfc,lsl#24
+ add $H1,$H1,$T0.2s // h0 -> h1
+ add $H4,$H4,$T1.2s // h3 -> h4
+
+ b.hi .Loop_neon
+
+.Lskip_loop:
+ dup $IN23_2,${IN23_2}[0]
+ movi $MASK.2d,#-1
+ add $IN01_2,$IN01_2,$H2
+ ushr $MASK.2d,$MASK.2d,#38
+
+ ////////////////////////////////////////////////////////////////
+ // multiply (inp[0:1]+hash) or inp[2:3] by r^2:r^1
+
+ adds $len,$len,#32
+ b.ne .Long_tail
+
+ dup $IN23_2,${IN01_2}[0]
+ add $IN23_0,$IN01_0,$H0
+ add $IN23_3,$IN01_3,$H3
+ add $IN23_1,$IN01_1,$H1
+ add $IN23_4,$IN01_4,$H4
+
+.Long_tail:
+ dup $IN23_0,${IN23_0}[0]
+ umull2 $ACC0,$IN23_2,${S3}
+ umull2 $ACC3,$IN23_2,${R1}
+ umull2 $ACC4,$IN23_2,${R2}
+ umull2 $ACC2,$IN23_2,${R0}
+ umull2 $ACC1,$IN23_2,${S4}
+
+ dup $IN23_1,${IN23_1}[0]
+ umlal2 $ACC0,$IN23_0,${R0}
+ umlal2 $ACC2,$IN23_0,${R2}
+ umlal2 $ACC3,$IN23_0,${R3}
+ umlal2 $ACC4,$IN23_0,${R4}
+ umlal2 $ACC1,$IN23_0,${R1}
+
+ dup $IN23_3,${IN23_3}[0]
+ umlal2 $ACC0,$IN23_1,${S4}
+ umlal2 $ACC3,$IN23_1,${R2}
+ umlal2 $ACC2,$IN23_1,${R1}
+ umlal2 $ACC4,$IN23_1,${R3}
+ umlal2 $ACC1,$IN23_1,${R0}
+
+ dup $IN23_4,${IN23_4}[0]
+ umlal2 $ACC3,$IN23_3,${R0}
+ umlal2 $ACC4,$IN23_3,${R1}
+ umlal2 $ACC0,$IN23_3,${S2}
+ umlal2 $ACC1,$IN23_3,${S3}
+ umlal2 $ACC2,$IN23_3,${S4}
+
+ umlal2 $ACC3,$IN23_4,${S4}
+ umlal2 $ACC0,$IN23_4,${S1}
+ umlal2 $ACC4,$IN23_4,${R0}
+ umlal2 $ACC1,$IN23_4,${S2}
+ umlal2 $ACC2,$IN23_4,${S3}
+
+ b.eq .Lshort_tail
+
+ ////////////////////////////////////////////////////////////////
+ // (hash+inp[0:1])*r^4:r^3 and accumulate
+
+ add $IN01_0,$IN01_0,$H0
+ umlal $ACC3,$IN01_2,${R1}
+ umlal $ACC0,$IN01_2,${S3}
+ umlal $ACC4,$IN01_2,${R2}
+ umlal $ACC1,$IN01_2,${S4}
+ umlal $ACC2,$IN01_2,${R0}
+
+ add $IN01_1,$IN01_1,$H1
+ umlal $ACC3,$IN01_0,${R3}
+ umlal $ACC0,$IN01_0,${R0}
+ umlal $ACC4,$IN01_0,${R4}
+ umlal $ACC1,$IN01_0,${R1}
+ umlal $ACC2,$IN01_0,${R2}
+
+ add $IN01_3,$IN01_3,$H3
+ umlal $ACC3,$IN01_1,${R2}
+ umlal $ACC0,$IN01_1,${S4}
+ umlal $ACC4,$IN01_1,${R3}
+ umlal $ACC1,$IN01_1,${R0}
+ umlal $ACC2,$IN01_1,${R1}
+
+ add $IN01_4,$IN01_4,$H4
+ umlal $ACC3,$IN01_3,${R0}
+ umlal $ACC0,$IN01_3,${S2}
+ umlal $ACC4,$IN01_3,${R1}
+ umlal $ACC1,$IN01_3,${S3}
+ umlal $ACC2,$IN01_3,${S4}
+
+ umlal $ACC3,$IN01_4,${S4}
+ umlal $ACC0,$IN01_4,${S1}
+ umlal $ACC4,$IN01_4,${R0}
+ umlal $ACC1,$IN01_4,${S2}
+ umlal $ACC2,$IN01_4,${S3}
+
+.Lshort_tail:
+ ////////////////////////////////////////////////////////////////
+ // horizontal add
+
+ addp $ACC3,$ACC3,$ACC3
+ ldp d8,d9,[sp,#16] // meet ABI requirements
+ addp $ACC0,$ACC0,$ACC0
+ ldp d10,d11,[sp,#32]
+ addp $ACC4,$ACC4,$ACC4
+ ldp d12,d13,[sp,#48]
+ addp $ACC1,$ACC1,$ACC1
+ ldp d14,d15,[sp,#64]
+ addp $ACC2,$ACC2,$ACC2
+
+ ////////////////////////////////////////////////////////////////
+ // lazy reduction, but without narrowing
+
+ ushr $T0.2d,$ACC3,#26
+ and $ACC3,$ACC3,$MASK.2d
+ ushr $T1.2d,$ACC0,#26
+ and $ACC0,$ACC0,$MASK.2d
+
+ add $ACC4,$ACC4,$T0.2d // h3 -> h4
+ add $ACC1,$ACC1,$T1.2d // h0 -> h1
+
+ ushr $T0.2d,$ACC4,#26
+ and $ACC4,$ACC4,$MASK.2d
+ ushr $T1.2d,$ACC1,#26
+ and $ACC1,$ACC1,$MASK.2d
+ add $ACC2,$ACC2,$T1.2d // h1 -> h2
+
+ add $ACC0,$ACC0,$T0.2d
+ shl $T0.2d,$T0.2d,#2
+ ushr $T1.2d,$ACC2,#26
+ and $ACC2,$ACC2,$MASK.2d
+ add $ACC0,$ACC0,$T0.2d // h4 -> h0
+ add $ACC3,$ACC3,$T1.2d // h2 -> h3
+
+ ushr $T0.2d,$ACC0,#26
+ and $ACC0,$ACC0,$MASK.2d
+ ushr $T1.2d,$ACC3,#26
+ and $ACC3,$ACC3,$MASK.2d
+ add $ACC1,$ACC1,$T0.2d // h0 -> h1
+ add $ACC4,$ACC4,$T1.2d // h3 -> h4
+
+ ////////////////////////////////////////////////////////////////
+ // write the result, can be partially reduced
+
+ st4 {$ACC0,$ACC1,$ACC2,$ACC3}[0],[$ctx],#16
+ st1 {$ACC4}[0],[$ctx]
+
+.Lno_data_neon:
+ ldr x29,[sp],#80
+ ret
+.size poly1305_blocks_neon,.-poly1305_blocks_neon
+
+.type poly1305_emit_neon,%function
+.align 5
+poly1305_emit_neon:
+ ldr $is_base2_26,[$ctx,#24]
+ cbz $is_base2_26,poly1305_emit
+
+ ldp w10,w11,[$ctx] // load hash value base 2^26
+ ldp w12,w13,[$ctx,#8]
+ ldr w14,[$ctx,#16]
+
+ add $h0,x10,x11,lsl#26 // base 2^26 -> base 2^64
+ lsr $h1,x12,#12
+ adds $h0,$h0,x12,lsl#52
+ add $h1,$h1,x13,lsl#14
+ adc $h1,$h1,xzr
+ lsr $h2,x14,#24
+ adds $h1,$h1,x14,lsl#40
+ adc $h2,$h2,xzr // can be partially reduced...
+
+ ldp $t0,$t1,[$nonce] // load nonce
+
+ and $d0,$h2,#-4 // ... so reduce
+ add $d0,$d0,$h2,lsr#2
+ and $h2,$h2,#3
+ adds $h0,$h0,$d0
+ adc $h1,$h1,xzr
+
+ adds $d0,$h0,#5 // compare to modulus
+ adcs $d1,$h1,xzr
+ adc $d2,$h2,xzr
+
+ tst $d2,#-4 // see if it's carried/borrowed
+
+ csel $h0,$h0,$d0,eq
+ csel $h1,$h1,$d1,eq
+
+#ifdef __ARMEB__
+ ror $t0,$t0,#32 // flip nonce words
+ ror $t1,$t1,#32
+#endif
+ adds $h0,$h0,$t0 // accumulate nonce
+ adc $h1,$h1,$t1
+#ifdef __ARMEB__
+ rev $h0,$h0 // flip output bytes
+ rev $h1,$h1
+#endif
+ stp $h0,$h1,[$mac] // write result
+
+ ret
+.size poly1305_emit_neon,.-poly1305_emit_neon
+
+.align 5
+.Lzeros:
+.long 0,0,0,0,0,0,0,0
+.LOPENSSL_armcap_P:
+#ifdef __ILP32__
+.long OPENSSL_armcap_P-.
+#else
+.quad OPENSSL_armcap_P-.
+#endif
+.asciz "Poly1305 for ARMv8, CRYPTOGAMS by <appro\@openssl.org>"
+.align 2
+___
+
+foreach (split("\n",$code)) {
+ s/\b(shrn\s+v[0-9]+)\.[24]d/$1.2s/ or
+ s/\b(fmov\s+)v([0-9]+)[^,]*,\s*x([0-9]+)/$1d$2,x$3/ or
+ (m/\bdup\b/ and (s/\.[24]s/.2d/g or 1)) or
+ (m/\b(eor|and)/ and (s/\.[248][sdh]/.16b/g or 1)) or
+ (m/\bum(ul|la)l\b/ and (s/\.4s/.2s/g or 1)) or
+ (m/\bum(ul|la)l2\b/ and (s/\.2s/.4s/g or 1)) or
+ (m/\bst[1-4]\s+{[^}]+}\[/ and (s/\.[24]d/.s/g or 1));
+
+ s/\.[124]([sd])\[/.$1\[/;
+
+ print $_,"\n";
+}
+close STDOUT;
diff --git a/src/crypto/poly1305/asm/poly1305-x86.pl b/src/crypto/poly1305/asm/poly1305-x86.pl
new file mode 100755
index 00000000..4ad2289e
--- /dev/null
+++ b/src/crypto/poly1305/asm/poly1305-x86.pl
@@ -0,0 +1,1788 @@
+#!/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/.
+# ====================================================================
+#
+# This module implements Poly1305 hash for x86.
+#
+# April 2015
+#
+# Numbers are cycles per processed byte with poly1305_blocks alone,
+# measured with rdtsc at fixed clock frequency.
+#
+# IALU/gcc-3.4(*) SSE2(**) AVX2
+# Pentium 15.7/+80% -
+# PIII 6.21/+90% -
+# P4 19.8/+40% 3.24
+# Core 2 4.85/+90% 1.80
+# Westmere 4.58/+100% 1.43
+# Sandy Bridge 3.90/+100% 1.36
+# Haswell 3.88/+70% 1.18 0.72
+# Silvermont 11.0/+40% 4.80
+# VIA Nano 6.71/+90% 2.47
+# Sledgehammer 3.51/+180% 4.27
+# Bulldozer 4.53/+140% 1.31
+#
+# (*) gcc 4.8 for some reason generated worse code;
+# (**) besides SSE2 there are floating-point and AVX options; FP
+# is deemed unnecessary, because pre-SSE2 processor are too
+# old to care about, while it's not the fastest option on
+# SSE2-capable ones; AVX is omitted, because it doesn't give
+# a lot of improvement, 5-10% depending on processor;
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC,"${dir}","${dir}../../perlasm");
+require "x86asm.pl";
+
+&asm_init($ARGV[0],"poly1305-x86.pl",$ARGV[$#ARGV] eq "386");
+
+$sse2=$avx=0;
+for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
+
+if ($sse2) {
+ &static_label("const_sse2");
+ &static_label("enter_blocks");
+ &static_label("enter_emit");
+ &external_label("OPENSSL_ia32cap_P");
+
+ # This may be set to 2, but valgrind can't do AVX2 on 32-bit. Without a
+ # way to verify test coverage, keep it disabled.
+ $avx = 0;
+}
+
+########################################################################
+# Layout of opaque area is following.
+#
+# unsigned __int32 h[5]; # current hash value base 2^32
+# unsigned __int32 pad; # is_base2_26 in vector context
+# unsigned __int32 r[4]; # key value base 2^32
+
+&align(64);
+&function_begin("poly1305_init");
+ &mov ("edi",&wparam(0)); # context
+ &mov ("esi",&wparam(1)); # key
+ &mov ("ebp",&wparam(2)); # function table
+
+ &xor ("eax","eax");
+ &mov (&DWP(4*0,"edi"),"eax"); # zero hash value
+ &mov (&DWP(4*1,"edi"),"eax");
+ &mov (&DWP(4*2,"edi"),"eax");
+ &mov (&DWP(4*3,"edi"),"eax");
+ &mov (&DWP(4*4,"edi"),"eax");
+ &mov (&DWP(4*5,"edi"),"eax"); # is_base2_26
+
+ &cmp ("esi",0);
+ &je (&label("nokey"));
+
+ if ($sse2) {
+ &call (&label("pic_point"));
+ &set_label("pic_point");
+ &blindpop("ebx");
+
+ &lea ("eax",&DWP("poly1305_blocks-".&label("pic_point"),"ebx"));
+ &lea ("edx",&DWP("poly1305_emit-".&label("pic_point"),"ebx"));
+
+ &picmeup("edi","OPENSSL_ia32cap_P","ebx",&label("pic_point"));
+ &mov ("ecx",&DWP(0,"edi"));
+ &and ("ecx",1<<26|1<<24);
+ &cmp ("ecx",1<<26|1<<24); # SSE2 and XMM?
+ &jne (&label("no_sse2"));
+
+ &lea ("eax",&DWP("_poly1305_blocks_sse2-".&label("pic_point"),"ebx"));
+ &lea ("edx",&DWP("_poly1305_emit_sse2-".&label("pic_point"),"ebx"));
+
+ if ($avx>1) {
+ &mov ("ecx",&DWP(8,"edi"));
+ &test ("ecx",1<<5); # AVX2?
+ &jz (&label("no_sse2"));
+
+ &lea ("eax",&DWP("_poly1305_blocks_avx2-".&label("pic_point"),"ebx"));
+ }
+ &set_label("no_sse2");
+ &mov ("edi",&wparam(0)); # reload context
+ &mov (&DWP(0,"ebp"),"eax"); # fill function table
+ &mov (&DWP(4,"ebp"),"edx");
+ }
+
+ &mov ("eax",&DWP(4*0,"esi")); # load input key
+ &mov ("ebx",&DWP(4*1,"esi"));
+ &mov ("ecx",&DWP(4*2,"esi"));
+ &mov ("edx",&DWP(4*3,"esi"));
+ &and ("eax",0x0fffffff);
+ &and ("ebx",0x0ffffffc);
+ &and ("ecx",0x0ffffffc);
+ &and ("edx",0x0ffffffc);
+ &mov (&DWP(4*6,"edi"),"eax");
+ &mov (&DWP(4*7,"edi"),"ebx");
+ &mov (&DWP(4*8,"edi"),"ecx");
+ &mov (&DWP(4*9,"edi"),"edx");
+
+ &mov ("eax",$sse2);
+&set_label("nokey");
+&function_end("poly1305_init");
+
+($h0,$h1,$h2,$h3,$h4,
+ $d0,$d1,$d2,$d3,
+ $r0,$r1,$r2,$r3,
+ $s1,$s2,$s3)=map(4*$_,(0..15));
+
+&function_begin("poly1305_blocks");
+ &mov ("edi",&wparam(0)); # ctx
+ &mov ("esi",&wparam(1)); # inp
+ &mov ("ecx",&wparam(2)); # len
+&set_label("enter_blocks");
+ &and ("ecx",-15);
+ &jz (&label("nodata"));
+
+ &stack_push(16);
+ &mov ("eax",&DWP(4*6,"edi")); # r0
+ &mov ("ebx",&DWP(4*7,"edi")); # r1
+ &lea ("ebp",&DWP(0,"esi","ecx")); # end of input
+ &mov ("ecx",&DWP(4*8,"edi")); # r2
+ &mov ("edx",&DWP(4*9,"edi")); # r3
+
+ &mov (&wparam(2),"ebp");
+ &mov ("ebp","esi");
+
+ &mov (&DWP($r0,"esp"),"eax"); # r0
+ &mov ("eax","ebx");
+ &shr ("eax",2);
+ &mov (&DWP($r1,"esp"),"ebx"); # r1
+ &add ("eax","ebx"); # s1
+ &mov ("ebx","ecx");
+ &shr ("ebx",2);
+ &mov (&DWP($r2,"esp"),"ecx"); # r2
+ &add ("ebx","ecx"); # s2
+ &mov ("ecx","edx");
+ &shr ("ecx",2);
+ &mov (&DWP($r3,"esp"),"edx"); # r3
+ &add ("ecx","edx"); # s3
+ &mov (&DWP($s1,"esp"),"eax"); # s1
+ &mov (&DWP($s2,"esp"),"ebx"); # s2
+ &mov (&DWP($s3,"esp"),"ecx"); # s3
+
+ &mov ("eax",&DWP(4*0,"edi")); # load hash value
+ &mov ("ebx",&DWP(4*1,"edi"));
+ &mov ("ecx",&DWP(4*2,"edi"));
+ &mov ("esi",&DWP(4*3,"edi"));
+ &mov ("edi",&DWP(4*4,"edi"));
+ &jmp (&label("loop"));
+
+&set_label("loop",32);
+ &add ("eax",&DWP(4*0,"ebp")); # accumulate input
+ &adc ("ebx",&DWP(4*1,"ebp"));
+ &adc ("ecx",&DWP(4*2,"ebp"));
+ &adc ("esi",&DWP(4*3,"ebp"));
+ &lea ("ebp",&DWP(4*4,"ebp"));
+ &adc ("edi",&wparam(3)); # padbit
+
+ &mov (&DWP($h0,"esp"),"eax"); # put aside hash[+inp]
+ &mov (&DWP($h3,"esp"),"esi");
+
+ &mul (&DWP($r0,"esp")); # h0*r0
+ &mov (&DWP($h4,"esp"),"edi");
+ &mov ("edi","eax");
+ &mov ("eax","ebx"); # h1
+ &mov ("esi","edx");
+ &mul (&DWP($s3,"esp")); # h1*s3
+ &add ("edi","eax");
+ &mov ("eax","ecx"); # h2
+ &adc ("esi","edx");
+ &mul (&DWP($s2,"esp")); # h2*s2
+ &add ("edi","eax");
+ &mov ("eax",&DWP($h3,"esp"));
+ &adc ("esi","edx");
+ &mul (&DWP($s1,"esp")); # h3*s1
+ &add ("edi","eax");
+ &mov ("eax",&DWP($h0,"esp"));
+ &adc ("esi","edx");
+
+ &mul (&DWP($r1,"esp")); # h0*r1
+ &mov (&DWP($d0,"esp"),"edi");
+ &xor ("edi","edi");
+ &add ("esi","eax");
+ &mov ("eax","ebx"); # h1
+ &adc ("edi","edx");
+ &mul (&DWP($r0,"esp")); # h1*r0
+ &add ("esi","eax");
+ &mov ("eax","ecx"); # h2
+ &adc ("edi","edx");
+ &mul (&DWP($s3,"esp")); # h2*s3
+ &add ("esi","eax");
+ &mov ("eax",&DWP($h3,"esp"));
+ &adc ("edi","edx");
+ &mul (&DWP($s2,"esp")); # h3*s2
+ &add ("esi","eax");
+ &mov ("eax",&DWP($h4,"esp"));
+ &adc ("edi","edx");
+ &imul ("eax",&DWP($s1,"esp")); # h4*s1
+ &add ("esi","eax");
+ &mov ("eax",&DWP($h0,"esp"));
+ &adc ("edi",0);
+
+ &mul (&DWP($r2,"esp")); # h0*r2
+ &mov (&DWP($d1,"esp"),"esi");
+ &xor ("esi","esi");
+ &add ("edi","eax");
+ &mov ("eax","ebx"); # h1
+ &adc ("esi","edx");
+ &mul (&DWP($r1,"esp")); # h1*r1
+ &add ("edi","eax");
+ &mov ("eax","ecx"); # h2
+ &adc ("esi","edx");
+ &mul (&DWP($r0,"esp")); # h2*r0
+ &add ("edi","eax");
+ &mov ("eax",&DWP($h3,"esp"));
+ &adc ("esi","edx");
+ &mul (&DWP($s3,"esp")); # h3*s3
+ &add ("edi","eax");
+ &mov ("eax",&DWP($h4,"esp"));
+ &adc ("esi","edx");
+ &imul ("eax",&DWP($s2,"esp")); # h4*s2
+ &add ("edi","eax");
+ &mov ("eax",&DWP($h0,"esp"));
+ &adc ("esi",0);
+
+ &mul (&DWP($r3,"esp")); # h0*r3
+ &mov (&DWP($d2,"esp"),"edi");
+ &xor ("edi","edi");
+ &add ("esi","eax");
+ &mov ("eax","ebx"); # h1
+ &adc ("edi","edx");
+ &mul (&DWP($r2,"esp")); # h1*r2
+ &add ("esi","eax");
+ &mov ("eax","ecx"); # h2
+ &adc ("edi","edx");
+ &mul (&DWP($r1,"esp")); # h2*r1
+ &add ("esi","eax");
+ &mov ("eax",&DWP($h3,"esp"));
+ &adc ("edi","edx");
+ &mul (&DWP($r0,"esp")); # h3*r0
+ &add ("esi","eax");
+ &mov ("ecx",&DWP($h4,"esp"));
+ &adc ("edi","edx");
+
+ &mov ("edx","ecx");
+ &imul ("ecx",&DWP($s3,"esp")); # h4*s3
+ &add ("esi","ecx");
+ &mov ("eax",&DWP($d0,"esp"));
+ &adc ("edi",0);
+
+ &imul ("edx",&DWP($r0,"esp")); # h4*r0
+ &add ("edx","edi");
+
+ &mov ("ebx",&DWP($d1,"esp"));
+ &mov ("ecx",&DWP($d2,"esp"));
+
+ &mov ("edi","edx"); # last reduction step
+ &shr ("edx",2);
+ &and ("edi",3);
+ &lea ("edx",&DWP(0,"edx","edx",4)); # *5
+ &add ("eax","edx");
+ &adc ("ebx",0);
+ &adc ("ecx",0);
+ &adc ("esi",0);
+
+ &cmp ("ebp",&wparam(2)); # done yet?
+ &jne (&label("loop"));
+
+ &mov ("edx",&wparam(0)); # ctx
+ &stack_pop(16);
+ &mov (&DWP(4*0,"edx"),"eax"); # store hash value
+ &mov (&DWP(4*1,"edx"),"ebx");
+ &mov (&DWP(4*2,"edx"),"ecx");
+ &mov (&DWP(4*3,"edx"),"esi");
+ &mov (&DWP(4*4,"edx"),"edi");
+&set_label("nodata");
+&function_end("poly1305_blocks");
+
+&function_begin("poly1305_emit");
+ &mov ("ebp",&wparam(0)); # context
+&set_label("enter_emit");
+ &mov ("edi",&wparam(1)); # output
+ &mov ("eax",&DWP(4*0,"ebp")); # load hash value
+ &mov ("ebx",&DWP(4*1,"ebp"));
+ &mov ("ecx",&DWP(4*2,"ebp"));
+ &mov ("edx",&DWP(4*3,"ebp"));
+ &mov ("esi",&DWP(4*4,"ebp"));
+
+ &add ("eax",5); # compare to modulus
+ &adc ("ebx",0);
+ &adc ("ecx",0);
+ &adc ("edx",0);
+ &adc ("esi",0);
+ &shr ("esi",2); # did it carry/borrow?
+ &neg ("esi"); # do we choose hash-modulus?
+
+ &and ("eax","esi");
+ &and ("ebx","esi");
+ &and ("ecx","esi");
+ &and ("edx","esi");
+ &mov (&DWP(4*0,"edi"),"eax");
+ &mov (&DWP(4*1,"edi"),"ebx");
+ &mov (&DWP(4*2,"edi"),"ecx");
+ &mov (&DWP(4*3,"edi"),"edx");
+
+ &not ("esi"); # or original hash value?
+ &mov ("eax",&DWP(4*0,"ebp"));
+ &mov ("ebx",&DWP(4*1,"ebp"));
+ &mov ("ecx",&DWP(4*2,"ebp"));
+ &mov ("edx",&DWP(4*3,"ebp"));
+ &mov ("ebp",&wparam(2));
+ &and ("eax","esi");
+ &and ("ebx","esi");
+ &and ("ecx","esi");
+ &and ("edx","esi");
+ &or ("eax",&DWP(4*0,"edi"));
+ &or ("ebx",&DWP(4*1,"edi"));
+ &or ("ecx",&DWP(4*2,"edi"));
+ &or ("edx",&DWP(4*3,"edi"));
+
+ &add ("eax",&DWP(4*0,"ebp")); # accumulate key
+ &adc ("ebx",&DWP(4*1,"ebp"));
+ &adc ("ecx",&DWP(4*2,"ebp"));
+ &adc ("edx",&DWP(4*3,"ebp"));
+
+ &mov (&DWP(4*0,"edi"),"eax");
+ &mov (&DWP(4*1,"edi"),"ebx");
+ &mov (&DWP(4*2,"edi"),"ecx");
+ &mov (&DWP(4*3,"edi"),"edx");
+&function_end("poly1305_emit");
+
+if ($sse2) {
+########################################################################
+# Layout of opaque area is following.
+#
+# unsigned __int32 h[5]; # current hash value base 2^26
+# unsigned __int32 is_base2_26;
+# unsigned __int32 r[4]; # key value base 2^32
+# unsigned __int32 pad[2];
+# struct { unsigned __int32 r^4, r^3, r^2, r^1; } r[9];
+#
+# where r^n are base 2^26 digits of degrees of multiplier key. There are
+# 5 digits, but last four are interleaved with multiples of 5, totalling
+# in 9 elements: r0, r1, 5*r1, r2, 5*r2, r3, 5*r3, r4, 5*r4.
+
+my ($D0,$D1,$D2,$D3,$D4,$T0,$T1,$T2)=map("xmm$_",(0..7));
+my $MASK=$T2; # borrow and keep in mind
+
+&align (32);
+&function_begin_B("_poly1305_init_sse2");
+ &movdqu ($D4,&QWP(4*6,"edi")); # key base 2^32
+ &lea ("edi",&DWP(16*3,"edi")); # size optimization
+ &mov ("ebp","esp");
+ &sub ("esp",16*(9+5));
+ &and ("esp",-16);
+
+ #&pand ($D4,&QWP(96,"ebx")); # magic mask
+ &movq ($MASK,&QWP(64,"ebx"));
+
+ &movdqa ($D0,$D4);
+ &movdqa ($D1,$D4);
+ &movdqa ($D2,$D4);
+
+ &pand ($D0,$MASK); # -> base 2^26
+ &psrlq ($D1,26);
+ &psrldq ($D2,6);
+ &pand ($D1,$MASK);
+ &movdqa ($D3,$D2);
+ &psrlq ($D2,4)
+ &psrlq ($D3,30);
+ &pand ($D2,$MASK);
+ &pand ($D3,$MASK);
+ &psrldq ($D4,13);
+
+ &lea ("edx",&DWP(16*9,"esp")); # size optimization
+ &mov ("ecx",2);
+&set_label("square");
+ &movdqa (&QWP(16*0,"esp"),$D0);
+ &movdqa (&QWP(16*1,"esp"),$D1);
+ &movdqa (&QWP(16*2,"esp"),$D2);
+ &movdqa (&QWP(16*3,"esp"),$D3);
+ &movdqa (&QWP(16*4,"esp"),$D4);
+
+ &movdqa ($T1,$D1);
+ &movdqa ($T0,$D2);
+ &pslld ($T1,2);
+ &pslld ($T0,2);
+ &paddd ($T1,$D1); # *5
+ &paddd ($T0,$D2); # *5
+ &movdqa (&QWP(16*5,"esp"),$T1);
+ &movdqa (&QWP(16*6,"esp"),$T0);
+ &movdqa ($T1,$D3);
+ &movdqa ($T0,$D4);
+ &pslld ($T1,2);
+ &pslld ($T0,2);
+ &paddd ($T1,$D3); # *5
+ &paddd ($T0,$D4); # *5
+ &movdqa (&QWP(16*7,"esp"),$T1);
+ &movdqa (&QWP(16*8,"esp"),$T0);
+
+ &pshufd ($T1,$D0,0b01000100);
+ &movdqa ($T0,$D1);
+ &pshufd ($D1,$D1,0b01000100);
+ &pshufd ($D2,$D2,0b01000100);
+ &pshufd ($D3,$D3,0b01000100);
+ &pshufd ($D4,$D4,0b01000100);
+ &movdqa (&QWP(16*0,"edx"),$T1);
+ &movdqa (&QWP(16*1,"edx"),$D1);
+ &movdqa (&QWP(16*2,"edx"),$D2);
+ &movdqa (&QWP(16*3,"edx"),$D3);
+ &movdqa (&QWP(16*4,"edx"),$D4);
+
+ ################################################################
+ # d4 = h4*r0 + h3*r1 + h2*r2 + h1*r3 + h0*r4
+ # d3 = h3*r0 + h2*r1 + h1*r2 + h0*r3 + h4*5*r4
+ # d2 = h2*r0 + h1*r1 + h0*r2 + h4*5*r3 + h3*5*r4
+ # d1 = h1*r0 + h0*r1 + h4*5*r2 + h3*5*r3 + h2*5*r4
+ # d0 = h0*r0 + h4*5*r1 + h3*5*r2 + h2*5*r3 + h1*5*r4
+
+ &pmuludq ($D4,$D0); # h4*r0
+ &pmuludq ($D3,$D0); # h3*r0
+ &pmuludq ($D2,$D0); # h2*r0
+ &pmuludq ($D1,$D0); # h1*r0
+ &pmuludq ($D0,$T1); # h0*r0
+
+sub pmuladd {
+my $load = shift;
+my $base = shift; $base = "esp" if (!defined($base));
+
+ ################################################################
+ # As for choice to "rotate" $T0-$T2 in order to move paddq
+ # past next multiplication. While it makes code harder to read
+ # and doesn't have significant effect on most processors, it
+ # makes a lot of difference on Atom, up to 30% improvement.
+
+ &movdqa ($T1,$T0);
+ &pmuludq ($T0,&QWP(16*3,$base)); # r1*h3
+ &movdqa ($T2,$T1);
+ &pmuludq ($T1,&QWP(16*2,$base)); # r1*h2
+ &paddq ($D4,$T0);
+ &movdqa ($T0,$T2);
+ &pmuludq ($T2,&QWP(16*1,$base)); # r1*h1
+ &paddq ($D3,$T1);
+ &$load ($T1,5); # s1
+ &pmuludq ($T0,&QWP(16*0,$base)); # r1*h0
+ &paddq ($D2,$T2);
+ &pmuludq ($T1,&QWP(16*4,$base)); # s1*h4
+ &$load ($T2,2); # r2^n
+ &paddq ($D1,$T0);
+
+ &movdqa ($T0,$T2);
+ &pmuludq ($T2,&QWP(16*2,$base)); # r2*h2
+ &paddq ($D0,$T1);
+ &movdqa ($T1,$T0);
+ &pmuludq ($T0,&QWP(16*1,$base)); # r2*h1
+ &paddq ($D4,$T2);
+ &$load ($T2,6); # s2^n
+ &pmuludq ($T1,&QWP(16*0,$base)); # r2*h0
+ &paddq ($D3,$T0);
+ &movdqa ($T0,$T2);
+ &pmuludq ($T2,&QWP(16*4,$base)); # s2*h4
+ &paddq ($D2,$T1);
+ &pmuludq ($T0,&QWP(16*3,$base)); # s2*h3
+ &$load ($T1,3); # r3^n
+ &paddq ($D1,$T2);
+
+ &movdqa ($T2,$T1);
+ &pmuludq ($T1,&QWP(16*1,$base)); # r3*h1
+ &paddq ($D0,$T0);
+ &$load ($T0,7); # s3^n
+ &pmuludq ($T2,&QWP(16*0,$base)); # r3*h0
+ &paddq ($D4,$T1);
+ &movdqa ($T1,$T0);
+ &pmuludq ($T0,&QWP(16*4,$base)); # s3*h4
+ &paddq ($D3,$T2);
+ &movdqa ($T2,$T1);
+ &pmuludq ($T1,&QWP(16*3,$base)); # s3*h3
+ &paddq ($D2,$T0);
+ &pmuludq ($T2,&QWP(16*2,$base)); # s3*h2
+ &$load ($T0,4); # r4^n
+ &paddq ($D1,$T1);
+
+ &$load ($T1,8); # s4^n
+ &pmuludq ($T0,&QWP(16*0,$base)); # r4*h0
+ &paddq ($D0,$T2);
+ &movdqa ($T2,$T1);
+ &pmuludq ($T1,&QWP(16*4,$base)); # s4*h4
+ &paddq ($D4,$T0);
+ &movdqa ($T0,$T2);
+ &pmuludq ($T2,&QWP(16*1,$base)); # s4*h1
+ &paddq ($D3,$T1);
+ &movdqa ($T1,$T0);
+ &pmuludq ($T0,&QWP(16*2,$base)); # s4*h2
+ &paddq ($D0,$T2);
+ &pmuludq ($T1,&QWP(16*3,$base)); # s4*h3
+ &movdqa ($MASK,&QWP(64,"ebx"));
+ &paddq ($D1,$T0);
+ &paddq ($D2,$T1);
+}
+ &pmuladd (sub { my ($reg,$i)=@_;
+ &movdqa ($reg,&QWP(16*$i,"esp"));
+ },"edx");
+
+sub lazy_reduction {
+my $extra = shift;
+my $paddx = defined($extra) ? paddq : paddd;
+
+ ################################################################
+ # lazy reduction as discussed in "NEON crypto" by D.J. Bernstein
+ # and P. Schwabe
+
+ &movdqa ($T0,$D3);
+ &pand ($D3,$MASK);
+ &psrlq ($T0,26);
+ &$extra () if (defined($extra));
+ &paddq ($T0,$D4); # h3 -> h4
+ &movdqa ($T1,$D0);
+ &pand ($D0,$MASK);
+ &psrlq ($T1,26);
+ &movdqa ($D4,$T0);
+ &paddq ($T1,$D1); # h0 -> h1
+ &psrlq ($T0,26);
+ &pand ($D4,$MASK);
+ &movdqa ($D1,$T1);
+ &psrlq ($T1,26);
+ &paddd ($D0,$T0); # favour paddd when
+ # possible, because
+ # paddq is "broken"
+ # on Atom
+ &psllq ($T0,2);
+ &paddq ($T1,$D2); # h1 -> h2
+ &$paddx ($T0,$D0); # h4 -> h0
+ &pand ($D1,$MASK);
+ &movdqa ($D2,$T1);
+ &psrlq ($T1,26);
+ &pand ($D2,$MASK);
+ &paddd ($T1,$D3); # h2 -> h3
+ &movdqa ($D0,$T0);
+ &psrlq ($T0,26);
+ &movdqa ($D3,$T1);
+ &psrlq ($T1,26);
+ &pand ($D0,$MASK);
+ &paddd ($D1,$T0); # h0 -> h1
+ &pand ($D3,$MASK);
+ &paddd ($D4,$T1); # h3 -> h4
+}
+ &lazy_reduction ();
+
+ &dec ("ecx");
+ &jz (&label("square_break"));
+
+ &punpcklqdq ($D0,&QWP(16*0,"esp")); # 0:r^1:0:r^2
+ &punpcklqdq ($D1,&QWP(16*1,"esp"));
+ &punpcklqdq ($D2,&QWP(16*2,"esp"));
+ &punpcklqdq ($D3,&QWP(16*3,"esp"));
+ &punpcklqdq ($D4,&QWP(16*4,"esp"));
+ &jmp (&label("square"));
+
+&set_label("square_break");
+ &psllq ($D0,32); # -> r^3:0:r^4:0
+ &psllq ($D1,32);
+ &psllq ($D2,32);
+ &psllq ($D3,32);
+ &psllq ($D4,32);
+ &por ($D0,&QWP(16*0,"esp")); # r^3:r^1:r^4:r^2
+ &por ($D1,&QWP(16*1,"esp"));
+ &por ($D2,&QWP(16*2,"esp"));
+ &por ($D3,&QWP(16*3,"esp"));
+ &por ($D4,&QWP(16*4,"esp"));
+
+ &pshufd ($D0,$D0,0b10001101); # -> r^1:r^2:r^3:r^4
+ &pshufd ($D1,$D1,0b10001101);
+ &pshufd ($D2,$D2,0b10001101);
+ &pshufd ($D3,$D3,0b10001101);
+ &pshufd ($D4,$D4,0b10001101);
+
+ &movdqu (&QWP(16*0,"edi"),$D0); # save the table
+ &movdqu (&QWP(16*1,"edi"),$D1);
+ &movdqu (&QWP(16*2,"edi"),$D2);
+ &movdqu (&QWP(16*3,"edi"),$D3);
+ &movdqu (&QWP(16*4,"edi"),$D4);
+
+ &movdqa ($T1,$D1);
+ &movdqa ($T0,$D2);
+ &pslld ($T1,2);
+ &pslld ($T0,2);
+ &paddd ($T1,$D1); # *5
+ &paddd ($T0,$D2); # *5
+ &movdqu (&QWP(16*5,"edi"),$T1);
+ &movdqu (&QWP(16*6,"edi"),$T0);
+ &movdqa ($T1,$D3);
+ &movdqa ($T0,$D4);
+ &pslld ($T1,2);
+ &pslld ($T0,2);
+ &paddd ($T1,$D3); # *5
+ &paddd ($T0,$D4); # *5
+ &movdqu (&QWP(16*7,"edi"),$T1);
+ &movdqu (&QWP(16*8,"edi"),$T0);
+
+ &mov ("esp","ebp");
+ &lea ("edi",&DWP(-16*3,"edi")); # size de-optimization
+ &ret ();
+&function_end_B("_poly1305_init_sse2");
+
+&align (32);
+&function_begin("_poly1305_blocks_sse2");
+ &mov ("edi",&wparam(0)); # ctx
+ &mov ("esi",&wparam(1)); # inp
+ &mov ("ecx",&wparam(2)); # len
+
+ &mov ("eax",&DWP(4*5,"edi")); # is_base2_26
+ &and ("ecx",-16);
+ &jz (&label("nodata"));
+ &cmp ("ecx",64);
+ &jae (&label("enter_sse2"));
+ &test ("eax","eax"); # is_base2_26?
+ &jz (&label("enter_blocks"));
+
+&set_label("enter_sse2",16);
+ &call (&label("pic_point"));
+&set_label("pic_point");
+ &blindpop("ebx");
+ &lea ("ebx",&DWP(&label("const_sse2")."-".&label("pic_point"),"ebx"));
+
+ &test ("eax","eax"); # is_base2_26?
+ &jnz (&label("base2_26"));
+
+ &call ("_poly1305_init_sse2");
+
+ ################################################# base 2^32 -> base 2^26
+ &mov ("eax",&DWP(0,"edi"));
+ &mov ("ecx",&DWP(3,"edi"));
+ &mov ("edx",&DWP(6,"edi"));
+ &mov ("esi",&DWP(9,"edi"));
+ &mov ("ebp",&DWP(13,"edi"));
+ &mov (&DWP(4*5,"edi"),1); # is_base2_26
+
+ &shr ("ecx",2);
+ &and ("eax",0x3ffffff);
+ &shr ("edx",4);
+ &and ("ecx",0x3ffffff);
+ &shr ("esi",6);
+ &and ("edx",0x3ffffff);
+
+ &movd ($D0,"eax");
+ &movd ($D1,"ecx");
+ &movd ($D2,"edx");
+ &movd ($D3,"esi");
+ &movd ($D4,"ebp");
+
+ &mov ("esi",&wparam(1)); # [reload] inp
+ &mov ("ecx",&wparam(2)); # [reload] len
+ &jmp (&label("base2_32"));
+
+&set_label("base2_26",16);
+ &movd ($D0,&DWP(4*0,"edi")); # load hash value
+ &movd ($D1,&DWP(4*1,"edi"));
+ &movd ($D2,&DWP(4*2,"edi"));
+ &movd ($D3,&DWP(4*3,"edi"));
+ &movd ($D4,&DWP(4*4,"edi"));
+ &movdqa ($MASK,&QWP(64,"ebx"));
+
+&set_label("base2_32");
+ &mov ("eax",&wparam(3)); # padbit
+ &mov ("ebp","esp");
+
+ &sub ("esp",16*(5+5+5+9+9));
+ &and ("esp",-16);
+
+ &lea ("edi",&DWP(16*3,"edi")); # size optimization
+ &shl ("eax",24); # padbit
+
+ &test ("ecx",31);
+ &jz (&label("even"));
+
+ ################################################################
+ # process single block, with SSE2, because it's still faster
+ # even though half of result is discarded
+
+ &movdqu ($T1,&QWP(0,"esi")); # input
+ &lea ("esi",&DWP(16,"esi"));
+
+ &movdqa ($T0,$T1); # -> base 2^26 ...
+ &pand ($T1,$MASK);
+ &paddd ($D0,$T1); # ... and accumuate
+
+ &movdqa ($T1,$T0);
+ &psrlq ($T0,26);
+ &psrldq ($T1,6);
+ &pand ($T0,$MASK);
+ &paddd ($D1,$T0);
+
+ &movdqa ($T0,$T1);
+ &psrlq ($T1,4);
+ &pand ($T1,$MASK);
+ &paddd ($D2,$T1);
+
+ &movdqa ($T1,$T0);
+ &psrlq ($T0,30);
+ &pand ($T0,$MASK);
+ &psrldq ($T1,7);
+ &paddd ($D3,$T0);
+
+ &movd ($T0,"eax"); # padbit
+ &paddd ($D4,$T1);
+ &movd ($T1,&DWP(16*0+12,"edi")); # r0
+ &paddd ($D4,$T0);
+
+ &movdqa (&QWP(16*0,"esp"),$D0);
+ &movdqa (&QWP(16*1,"esp"),$D1);
+ &movdqa (&QWP(16*2,"esp"),$D2);
+ &movdqa (&QWP(16*3,"esp"),$D3);
+ &movdqa (&QWP(16*4,"esp"),$D4);
+
+ ################################################################
+ # d4 = h4*r0 + h3*r1 + h2*r2 + h1*r3 + h0*r4
+ # d3 = h3*r0 + h2*r1 + h1*r2 + h0*r3 + h4*5*r4
+ # d2 = h2*r0 + h1*r1 + h0*r2 + h4*5*r3 + h3*5*r4
+ # d1 = h1*r0 + h0*r1 + h4*5*r2 + h3*5*r3 + h2*5*r4
+ # d0 = h0*r0 + h4*5*r1 + h3*5*r2 + h2*5*r3 + h1*5*r4
+
+ &pmuludq ($D0,$T1); # h4*r0
+ &pmuludq ($D1,$T1); # h3*r0
+ &pmuludq ($D2,$T1); # h2*r0
+ &movd ($T0,&DWP(16*1+12,"edi")); # r1
+ &pmuludq ($D3,$T1); # h1*r0
+ &pmuludq ($D4,$T1); # h0*r0
+
+ &pmuladd (sub { my ($reg,$i)=@_;
+ &movd ($reg,&DWP(16*$i+12,"edi"));
+ });
+
+ &lazy_reduction ();
+
+ &sub ("ecx",16);
+ &jz (&label("done"));
+
+&set_label("even");
+ &lea ("edx",&DWP(16*(5+5+5+9),"esp"));# size optimization
+ &lea ("eax",&DWP(-16*2,"esi"));
+ &sub ("ecx",64);
+
+ ################################################################
+ # expand and copy pre-calculated table to stack
+
+ &movdqu ($T0,&QWP(16*0,"edi")); # r^1:r^2:r^3:r^4
+ &pshufd ($T1,$T0,0b01000100); # duplicate r^3:r^4
+ &cmovb ("esi","eax");
+ &pshufd ($T0,$T0,0b11101110); # duplicate r^1:r^2
+ &movdqa (&QWP(16*0,"edx"),$T1);
+ &lea ("eax",&DWP(16*10,"esp"));
+ &movdqu ($T1,&QWP(16*1,"edi"));
+ &movdqa (&QWP(16*(0-9),"edx"),$T0);
+ &pshufd ($T0,$T1,0b01000100);
+ &pshufd ($T1,$T1,0b11101110);
+ &movdqa (&QWP(16*1,"edx"),$T0);
+ &movdqu ($T0,&QWP(16*2,"edi"));
+ &movdqa (&QWP(16*(1-9),"edx"),$T1);
+ &pshufd ($T1,$T0,0b01000100);
+ &pshufd ($T0,$T0,0b11101110);
+ &movdqa (&QWP(16*2,"edx"),$T1);
+ &movdqu ($T1,&QWP(16*3,"edi"));
+ &movdqa (&QWP(16*(2-9),"edx"),$T0);
+ &pshufd ($T0,$T1,0b01000100);
+ &pshufd ($T1,$T1,0b11101110);
+ &movdqa (&QWP(16*3,"edx"),$T0);
+ &movdqu ($T0,&QWP(16*4,"edi"));
+ &movdqa (&QWP(16*(3-9),"edx"),$T1);
+ &pshufd ($T1,$T0,0b01000100);
+ &pshufd ($T0,$T0,0b11101110);
+ &movdqa (&QWP(16*4,"edx"),$T1);
+ &movdqu ($T1,&QWP(16*5,"edi"));
+ &movdqa (&QWP(16*(4-9),"edx"),$T0);
+ &pshufd ($T0,$T1,0b01000100);
+ &pshufd ($T1,$T1,0b11101110);
+ &movdqa (&QWP(16*5,"edx"),$T0);
+ &movdqu ($T0,&QWP(16*6,"edi"));
+ &movdqa (&QWP(16*(5-9),"edx"),$T1);
+ &pshufd ($T1,$T0,0b01000100);
+ &pshufd ($T0,$T0,0b11101110);
+ &movdqa (&QWP(16*6,"edx"),$T1);
+ &movdqu ($T1,&QWP(16*7,"edi"));
+ &movdqa (&QWP(16*(6-9),"edx"),$T0);
+ &pshufd ($T0,$T1,0b01000100);
+ &pshufd ($T1,$T1,0b11101110);
+ &movdqa (&QWP(16*7,"edx"),$T0);
+ &movdqu ($T0,&QWP(16*8,"edi"));
+ &movdqa (&QWP(16*(7-9),"edx"),$T1);
+ &pshufd ($T1,$T0,0b01000100);
+ &pshufd ($T0,$T0,0b11101110);
+ &movdqa (&QWP(16*8,"edx"),$T1);
+ &movdqa (&QWP(16*(8-9),"edx"),$T0);
+
+sub load_input {
+my ($inpbase,$offbase)=@_;
+
+ &movdqu ($T0,&QWP($inpbase+0,"esi")); # load input
+ &movdqu ($T1,&QWP($inpbase+16,"esi"));
+ &lea ("esi",&DWP(16*2,"esi"));
+
+ &movdqa (&QWP($offbase+16*2,"esp"),$D2);
+ &movdqa (&QWP($offbase+16*3,"esp"),$D3);
+ &movdqa (&QWP($offbase+16*4,"esp"),$D4);
+
+ &movdqa ($D2,$T0); # splat input
+ &movdqa ($D3,$T1);
+ &psrldq ($D2,6);
+ &psrldq ($D3,6);
+ &movdqa ($D4,$T0);
+ &punpcklqdq ($D2,$D3); # 2:3
+ &punpckhqdq ($D4,$T1); # 4
+ &punpcklqdq ($T0,$T1); # 0:1
+
+ &movdqa ($D3,$D2);
+ &psrlq ($D2,4);
+ &psrlq ($D3,30);
+ &movdqa ($T1,$T0);
+ &psrlq ($D4,40); # 4
+ &psrlq ($T1,26);
+ &pand ($T0,$MASK); # 0
+ &pand ($T1,$MASK); # 1
+ &pand ($D2,$MASK); # 2
+ &pand ($D3,$MASK); # 3
+ &por ($D4,&QWP(0,"ebx")); # padbit, yes, always
+
+ &movdqa (&QWP($offbase+16*0,"esp"),$D0) if ($offbase);
+ &movdqa (&QWP($offbase+16*1,"esp"),$D1) if ($offbase);
+}
+ &load_input (16*2,16*5);
+
+ &jbe (&label("skip_loop"));
+ &jmp (&label("loop"));
+
+&set_label("loop",32);
+ ################################################################
+ # ((inp[0]*r^4+inp[2]*r^2+inp[4])*r^4+inp[6]*r^2
+ # ((inp[1]*r^4+inp[3]*r^2+inp[5])*r^3+inp[7]*r
+ # \___________________/
+ # ((inp[0]*r^4+inp[2]*r^2+inp[4])*r^4+inp[6]*r^2+inp[8])*r^2
+ # ((inp[1]*r^4+inp[3]*r^2+inp[5])*r^4+inp[7]*r^2+inp[9])*r
+ # \___________________/ \____________________/
+ ################################################################
+
+ &movdqa ($T2,&QWP(16*(0-9),"edx")); # r0^2
+ &movdqa (&QWP(16*1,"eax"),$T1);
+ &movdqa (&QWP(16*2,"eax"),$D2);
+ &movdqa (&QWP(16*3,"eax"),$D3);
+ &movdqa (&QWP(16*4,"eax"),$D4);
+
+ ################################################################
+ # d4 = h4*r0 + h0*r4 + h1*r3 + h2*r2 + h3*r1
+ # d3 = h3*r0 + h0*r3 + h1*r2 + h2*r1 + h4*5*r4
+ # d2 = h2*r0 + h0*r2 + h1*r1 + h3*5*r4 + h4*5*r3
+ # d1 = h1*r0 + h0*r1 + h2*5*r4 + h3*5*r3 + h4*5*r2
+ # d0 = h0*r0 + h1*5*r4 + h2*5*r3 + h3*5*r2 + h4*5*r1
+
+ &movdqa ($D1,$T0);
+ &pmuludq ($T0,$T2); # h0*r0
+ &movdqa ($D0,$T1);
+ &pmuludq ($T1,$T2); # h1*r0
+ &pmuludq ($D2,$T2); # h2*r0
+ &pmuludq ($D3,$T2); # h3*r0
+ &pmuludq ($D4,$T2); # h4*r0
+
+sub pmuladd_alt {
+my $addr = shift;
+
+ &pmuludq ($D0,&$addr(8)); # h1*s4
+ &movdqa ($T2,$D1);
+ &pmuludq ($D1,&$addr(1)); # h0*r1
+ &paddq ($D0,$T0);
+ &movdqa ($T0,$T2);
+ &pmuludq ($T2,&$addr(2)); # h0*r2
+ &paddq ($D1,$T1);
+ &movdqa ($T1,$T0);
+ &pmuludq ($T0,&$addr(3)); # h0*r3
+ &paddq ($D2,$T2);
+ &movdqa ($T2,&QWP(16*1,"eax")); # pull h1
+ &pmuludq ($T1,&$addr(4)); # h0*r4
+ &paddq ($D3,$T0);
+
+ &movdqa ($T0,$T2);
+ &pmuludq ($T2,&$addr(1)); # h1*r1
+ &paddq ($D4,$T1);
+ &movdqa ($T1,$T0);
+ &pmuludq ($T0,&$addr(2)); # h1*r2
+ &paddq ($D2,$T2);
+ &movdqa ($T2,&QWP(16*2,"eax")); # pull h2
+ &pmuludq ($T1,&$addr(3)); # h1*r3
+ &paddq ($D3,$T0);
+ &movdqa ($T0,$T2);
+ &pmuludq ($T2,&$addr(7)); # h2*s3
+ &paddq ($D4,$T1);
+ &movdqa ($T1,$T0);
+ &pmuludq ($T0,&$addr(8)); # h2*s4
+ &paddq ($D0,$T2);
+
+ &movdqa ($T2,$T1);
+ &pmuludq ($T1,&$addr(1)); # h2*r1
+ &paddq ($D1,$T0);
+ &movdqa ($T0,&QWP(16*3,"eax")); # pull h3
+ &pmuludq ($T2,&$addr(2)); # h2*r2
+ &paddq ($D3,$T1);
+ &movdqa ($T1,$T0);
+ &pmuludq ($T0,&$addr(6)); # h3*s2
+ &paddq ($D4,$T2);
+ &movdqa ($T2,$T1);
+ &pmuludq ($T1,&$addr(7)); # h3*s3
+ &paddq ($D0,$T0);
+ &movdqa ($T0,$T2);
+ &pmuludq ($T2,&$addr(8)); # h3*s4
+ &paddq ($D1,$T1);
+
+ &movdqa ($T1,&QWP(16*4,"eax")); # pull h4
+ &pmuludq ($T0,&$addr(1)); # h3*r1
+ &paddq ($D2,$T2);
+ &movdqa ($T2,$T1);
+ &pmuludq ($T1,&$addr(8)); # h4*s4
+ &paddq ($D4,$T0);
+ &movdqa ($T0,$T2);
+ &pmuludq ($T2,&$addr(5)); # h4*s1
+ &paddq ($D3,$T1);
+ &movdqa ($T1,$T0);
+ &pmuludq ($T0,&$addr(6)); # h4*s2
+ &paddq ($D0,$T2);
+ &movdqa ($MASK,&QWP(64,"ebx"));
+ &pmuludq ($T1,&$addr(7)); # h4*s3
+ &paddq ($D1,$T0);
+ &paddq ($D2,$T1);
+}
+ &pmuladd_alt (sub { my $i=shift; &QWP(16*($i-9),"edx"); });
+
+ &load_input (-16*2,0);
+ &lea ("eax",&DWP(-16*2,"esi"));
+ &sub ("ecx",64);
+
+ &paddd ($T0,&QWP(16*(5+0),"esp")); # add hash value
+ &paddd ($T1,&QWP(16*(5+1),"esp"));
+ &paddd ($D2,&QWP(16*(5+2),"esp"));
+ &paddd ($D3,&QWP(16*(5+3),"esp"));
+ &paddd ($D4,&QWP(16*(5+4),"esp"));
+
+ &cmovb ("esi","eax");
+ &lea ("eax",&DWP(16*10,"esp"));
+
+ &movdqa ($T2,&QWP(16*0,"edx")); # r0^4
+ &movdqa (&QWP(16*1,"esp"),$D1);
+ &movdqa (&QWP(16*1,"eax"),$T1);
+ &movdqa (&QWP(16*2,"eax"),$D2);
+ &movdqa (&QWP(16*3,"eax"),$D3);
+ &movdqa (&QWP(16*4,"eax"),$D4);
+
+ ################################################################
+ # d4 += h4*r0 + h0*r4 + h1*r3 + h2*r2 + h3*r1
+ # d3 += h3*r0 + h0*r3 + h1*r2 + h2*r1 + h4*5*r4
+ # d2 += h2*r0 + h0*r2 + h1*r1 + h3*5*r4 + h4*5*r3
+ # d1 += h1*r0 + h0*r1 + h2*5*r4 + h3*5*r3 + h4*5*r2
+ # d0 += h0*r0 + h1*5*r4 + h2*5*r3 + h3*5*r2 + h4*5*r1
+
+ &movdqa ($D1,$T0);
+ &pmuludq ($T0,$T2); # h0*r0
+ &paddq ($T0,$D0);
+ &movdqa ($D0,$T1);
+ &pmuludq ($T1,$T2); # h1*r0
+ &pmuludq ($D2,$T2); # h2*r0
+ &pmuludq ($D3,$T2); # h3*r0
+ &pmuludq ($D4,$T2); # h4*r0
+
+ &paddq ($T1,&QWP(16*1,"esp"));
+ &paddq ($D2,&QWP(16*2,"esp"));
+ &paddq ($D3,&QWP(16*3,"esp"));
+ &paddq ($D4,&QWP(16*4,"esp"));
+
+ &pmuladd_alt (sub { my $i=shift; &QWP(16*$i,"edx"); });
+
+ &lazy_reduction ();
+
+ &load_input (16*2,16*5);
+
+ &ja (&label("loop"));
+
+&set_label("skip_loop");
+ ################################################################
+ # multiply (inp[0:1]+hash) or inp[2:3] by r^2:r^1
+
+ &pshufd ($T2,&QWP(16*(0-9),"edx"),0x10);# r0^n
+ &add ("ecx",32);
+ &jnz (&label("long_tail"));
+
+ &paddd ($T0,$D0); # add hash value
+ &paddd ($T1,$D1);
+ &paddd ($D2,&QWP(16*7,"esp"));
+ &paddd ($D3,&QWP(16*8,"esp"));
+ &paddd ($D4,&QWP(16*9,"esp"));
+
+&set_label("long_tail");
+
+ &movdqa (&QWP(16*0,"eax"),$T0);
+ &movdqa (&QWP(16*1,"eax"),$T1);
+ &movdqa (&QWP(16*2,"eax"),$D2);
+ &movdqa (&QWP(16*3,"eax"),$D3);
+ &movdqa (&QWP(16*4,"eax"),$D4);
+
+ ################################################################
+ # d4 = h4*r0 + h3*r1 + h2*r2 + h1*r3 + h0*r4
+ # d3 = h3*r0 + h2*r1 + h1*r2 + h0*r3 + h4*5*r4
+ # d2 = h2*r0 + h1*r1 + h0*r2 + h4*5*r3 + h3*5*r4
+ # d1 = h1*r0 + h0*r1 + h4*5*r2 + h3*5*r3 + h2*5*r4
+ # d0 = h0*r0 + h4*5*r1 + h3*5*r2 + h2*5*r3 + h1*5*r4
+
+ &pmuludq ($T0,$T2); # h0*r0
+ &pmuludq ($T1,$T2); # h1*r0
+ &pmuludq ($D2,$T2); # h2*r0
+ &movdqa ($D0,$T0);
+ &pshufd ($T0,&QWP(16*(1-9),"edx"),0x10);# r1^n
+ &pmuludq ($D3,$T2); # h3*r0
+ &movdqa ($D1,$T1);
+ &pmuludq ($D4,$T2); # h4*r0
+
+ &pmuladd (sub { my ($reg,$i)=@_;
+ &pshufd ($reg,&QWP(16*($i-9),"edx"),0x10);
+ },"eax");
+
+ &jz (&label("short_tail"));
+
+ &load_input (-16*2,0);
+
+ &pshufd ($T2,&QWP(16*0,"edx"),0x10); # r0^n
+ &paddd ($T0,&QWP(16*5,"esp")); # add hash value
+ &paddd ($T1,&QWP(16*6,"esp"));
+ &paddd ($D2,&QWP(16*7,"esp"));
+ &paddd ($D3,&QWP(16*8,"esp"));
+ &paddd ($D4,&QWP(16*9,"esp"));
+
+ ################################################################
+ # multiply inp[0:1] by r^4:r^3 and accumulate
+
+ &movdqa (&QWP(16*0,"esp"),$T0);
+ &pmuludq ($T0,$T2); # h0*r0
+ &movdqa (&QWP(16*1,"esp"),$T1);
+ &pmuludq ($T1,$T2); # h1*r0
+ &paddq ($D0,$T0);
+ &movdqa ($T0,$D2);
+ &pmuludq ($D2,$T2); # h2*r0
+ &paddq ($D1,$T1);
+ &movdqa ($T1,$D3);
+ &pmuludq ($D3,$T2); # h3*r0
+ &paddq ($D2,&QWP(16*2,"esp"));
+ &movdqa (&QWP(16*2,"esp"),$T0);
+ &pshufd ($T0,&QWP(16*1,"edx"),0x10); # r1^n
+ &paddq ($D3,&QWP(16*3,"esp"));
+ &movdqa (&QWP(16*3,"esp"),$T1);
+ &movdqa ($T1,$D4);
+ &pmuludq ($D4,$T2); # h4*r0
+ &paddq ($D4,&QWP(16*4,"esp"));
+ &movdqa (&QWP(16*4,"esp"),$T1);
+
+ &pmuladd (sub { my ($reg,$i)=@_;
+ &pshufd ($reg,&QWP(16*$i,"edx"),0x10);
+ });
+
+&set_label("short_tail");
+
+ ################################################################
+ # horizontal addition
+
+ &pshufd ($T1,$D4,0b01001110);
+ &pshufd ($T0,$D3,0b01001110);
+ &paddq ($D4,$T1);
+ &paddq ($D3,$T0);
+ &pshufd ($T1,$D0,0b01001110);
+ &pshufd ($T0,$D1,0b01001110);
+ &paddq ($D0,$T1);
+ &paddq ($D1,$T0);
+ &pshufd ($T1,$D2,0b01001110);
+ #&paddq ($D2,$T1);
+
+ &lazy_reduction (sub { &paddq ($D2,$T1) });
+
+&set_label("done");
+ &movd (&DWP(-16*3+4*0,"edi"),$D0); # store hash value
+ &movd (&DWP(-16*3+4*1,"edi"),$D1);
+ &movd (&DWP(-16*3+4*2,"edi"),$D2);
+ &movd (&DWP(-16*3+4*3,"edi"),$D3);
+ &movd (&DWP(-16*3+4*4,"edi"),$D4);
+ &mov ("esp","ebp");
+&set_label("nodata");
+&function_end("_poly1305_blocks_sse2");
+
+&align (32);
+&function_begin("_poly1305_emit_sse2");
+ &mov ("ebp",&wparam(0)); # context
+
+ &cmp (&DWP(4*5,"ebp"),0); # is_base2_26?
+ &je (&label("enter_emit"));
+
+ &mov ("eax",&DWP(4*0,"ebp")); # load hash value
+ &mov ("edi",&DWP(4*1,"ebp"));
+ &mov ("ecx",&DWP(4*2,"ebp"));
+ &mov ("edx",&DWP(4*3,"ebp"));
+ &mov ("esi",&DWP(4*4,"ebp"));
+
+ &mov ("ebx","edi"); # base 2^26 -> base 2^32
+ &shl ("edi",26);
+ &shr ("ebx",6);
+ &add ("eax","edi");
+ &mov ("edi","ecx");
+ &adc ("ebx",0);
+
+ &shl ("edi",20);
+ &shr ("ecx",12);
+ &add ("ebx","edi");
+ &mov ("edi","edx");
+ &adc ("ecx",0);
+
+ &shl ("edi",14);
+ &shr ("edx",18);
+ &add ("ecx","edi");
+ &mov ("edi","esi");
+ &adc ("edx",0);
+
+ &shl ("edi",8);
+ &shr ("esi",24);
+ &add ("edx","edi");
+ &adc ("esi",0); # can be partially reduced
+
+ &mov ("edi","esi"); # final reduction
+ &and ("esi",3);
+ &shr ("edi",2);
+ &lea ("ebp",&DWP(0,"edi","edi",4)); # *5
+ &mov ("edi",&wparam(1)); # output
+ add ("eax","ebp");
+ &mov ("ebp",&wparam(2)); # key
+ adc ("ebx",0);
+ adc ("ecx",0);
+ adc ("edx",0);
+
+ &movd ($D0,"eax"); # offload original hash value
+ &add ("eax",5); # compare to modulus
+ &movd ($D1,"ebx");
+ &adc ("ebx",0);
+ &movd ($D2,"ecx");
+ &adc ("ecx",0);
+ &movd ($D3,"edx");
+ &adc ("edx",0);
+ &adc ("esi",0);
+ &shr ("esi",2); # did it carry/borrow?
+
+ &neg ("esi"); # do we choose (hash-modulus) ...
+ &and ("eax","esi");
+ &and ("ebx","esi");
+ &and ("ecx","esi");
+ &and ("edx","esi");
+ &mov (&DWP(4*0,"edi"),"eax");
+ &movd ("eax",$D0);
+ &mov (&DWP(4*1,"edi"),"ebx");
+ &movd ("ebx",$D1);
+ &mov (&DWP(4*2,"edi"),"ecx");
+ &movd ("ecx",$D2);
+ &mov (&DWP(4*3,"edi"),"edx");
+ &movd ("edx",$D3);
+
+ &not ("esi"); # ... or original hash value?
+ &and ("eax","esi");
+ &and ("ebx","esi");
+ &or ("eax",&DWP(4*0,"edi"));
+ &and ("ecx","esi");
+ &or ("ebx",&DWP(4*1,"edi"));
+ &and ("edx","esi");
+ &or ("ecx",&DWP(4*2,"edi"));
+ &or ("edx",&DWP(4*3,"edi"));
+
+ &add ("eax",&DWP(4*0,"ebp")); # accumulate key
+ &adc ("ebx",&DWP(4*1,"ebp"));
+ &mov (&DWP(4*0,"edi"),"eax");
+ &adc ("ecx",&DWP(4*2,"ebp"));
+ &mov (&DWP(4*1,"edi"),"ebx");
+ &adc ("edx",&DWP(4*3,"ebp"));
+ &mov (&DWP(4*2,"edi"),"ecx");
+ &mov (&DWP(4*3,"edi"),"edx");
+&function_end("_poly1305_emit_sse2");
+
+if ($avx>1) {
+########################################################################
+# Note that poly1305_init_avx2 operates on %xmm, I could have used
+# poly1305_init_sse2...
+
+&align (32);
+&function_begin_B("_poly1305_init_avx2");
+ &vmovdqu ($D4,&QWP(4*6,"edi")); # key base 2^32
+ &lea ("edi",&DWP(16*3,"edi")); # size optimization
+ &mov ("ebp","esp");
+ &sub ("esp",16*(9+5));
+ &and ("esp",-16);
+
+ #&vpand ($D4,$D4,&QWP(96,"ebx")); # magic mask
+ &vmovdqa ($MASK,&QWP(64,"ebx"));
+
+ &vpand ($D0,$D4,$MASK); # -> base 2^26
+ &vpsrlq ($D1,$D4,26);
+ &vpsrldq ($D3,$D4,6);
+ &vpand ($D1,$D1,$MASK);
+ &vpsrlq ($D2,$D3,4)
+ &vpsrlq ($D3,$D3,30);
+ &vpand ($D2,$D2,$MASK);
+ &vpand ($D3,$D3,$MASK);
+ &vpsrldq ($D4,$D4,13);
+
+ &lea ("edx",&DWP(16*9,"esp")); # size optimization
+ &mov ("ecx",2);
+&set_label("square");
+ &vmovdqa (&QWP(16*0,"esp"),$D0);
+ &vmovdqa (&QWP(16*1,"esp"),$D1);
+ &vmovdqa (&QWP(16*2,"esp"),$D2);
+ &vmovdqa (&QWP(16*3,"esp"),$D3);
+ &vmovdqa (&QWP(16*4,"esp"),$D4);
+
+ &vpslld ($T1,$D1,2);
+ &vpslld ($T0,$D2,2);
+ &vpaddd ($T1,$T1,$D1); # *5
+ &vpaddd ($T0,$T0,$D2); # *5
+ &vmovdqa (&QWP(16*5,"esp"),$T1);
+ &vmovdqa (&QWP(16*6,"esp"),$T0);
+ &vpslld ($T1,$D3,2);
+ &vpslld ($T0,$D4,2);
+ &vpaddd ($T1,$T1,$D3); # *5
+ &vpaddd ($T0,$T0,$D4); # *5
+ &vmovdqa (&QWP(16*7,"esp"),$T1);
+ &vmovdqa (&QWP(16*8,"esp"),$T0);
+
+ &vpshufd ($T0,$D0,0b01000100);
+ &vmovdqa ($T1,$D1);
+ &vpshufd ($D1,$D1,0b01000100);
+ &vpshufd ($D2,$D2,0b01000100);
+ &vpshufd ($D3,$D3,0b01000100);
+ &vpshufd ($D4,$D4,0b01000100);
+ &vmovdqa (&QWP(16*0,"edx"),$T0);
+ &vmovdqa (&QWP(16*1,"edx"),$D1);
+ &vmovdqa (&QWP(16*2,"edx"),$D2);
+ &vmovdqa (&QWP(16*3,"edx"),$D3);
+ &vmovdqa (&QWP(16*4,"edx"),$D4);
+
+ ################################################################
+ # d4 = h4*r0 + h3*r1 + h2*r2 + h1*r3 + h0*r4
+ # d3 = h3*r0 + h2*r1 + h1*r2 + h0*r3 + h4*5*r4
+ # d2 = h2*r0 + h1*r1 + h0*r2 + h4*5*r3 + h3*5*r4
+ # d1 = h1*r0 + h0*r1 + h4*5*r2 + h3*5*r3 + h2*5*r4
+ # d0 = h0*r0 + h4*5*r1 + h3*5*r2 + h2*5*r3 + h1*5*r4
+
+ &vpmuludq ($D4,$D4,$D0); # h4*r0
+ &vpmuludq ($D3,$D3,$D0); # h3*r0
+ &vpmuludq ($D2,$D2,$D0); # h2*r0
+ &vpmuludq ($D1,$D1,$D0); # h1*r0
+ &vpmuludq ($D0,$T0,$D0); # h0*r0
+
+ &vpmuludq ($T0,$T1,&QWP(16*3,"edx")); # r1*h3
+ &vpaddq ($D4,$D4,$T0);
+ &vpmuludq ($T2,$T1,&QWP(16*2,"edx")); # r1*h2
+ &vpaddq ($D3,$D3,$T2);
+ &vpmuludq ($T0,$T1,&QWP(16*1,"edx")); # r1*h1
+ &vpaddq ($D2,$D2,$T0);
+ &vmovdqa ($T2,&QWP(16*5,"esp")); # s1
+ &vpmuludq ($T1,$T1,&QWP(16*0,"edx")); # r1*h0
+ &vpaddq ($D1,$D1,$T1);
+ &vmovdqa ($T0,&QWP(16*2,"esp")); # r2
+ &vpmuludq ($T2,$T2,&QWP(16*4,"edx")); # s1*h4
+ &vpaddq ($D0,$D0,$T2);
+
+ &vpmuludq ($T1,$T0,&QWP(16*2,"edx")); # r2*h2
+ &vpaddq ($D4,$D4,$T1);
+ &vpmuludq ($T2,$T0,&QWP(16*1,"edx")); # r2*h1
+ &vpaddq ($D3,$D3,$T2);
+ &vmovdqa ($T1,&QWP(16*6,"esp")); # s2
+ &vpmuludq ($T0,$T0,&QWP(16*0,"edx")); # r2*h0
+ &vpaddq ($D2,$D2,$T0);
+ &vpmuludq ($T2,$T1,&QWP(16*4,"edx")); # s2*h4
+ &vpaddq ($D1,$D1,$T2);
+ &vmovdqa ($T0,&QWP(16*3,"esp")); # r3
+ &vpmuludq ($T1,$T1,&QWP(16*3,"edx")); # s2*h3
+ &vpaddq ($D0,$D0,$T1);
+
+ &vpmuludq ($T2,$T0,&QWP(16*1,"edx")); # r3*h1
+ &vpaddq ($D4,$D4,$T2);
+ &vmovdqa ($T1,&QWP(16*7,"esp")); # s3
+ &vpmuludq ($T0,$T0,&QWP(16*0,"edx")); # r3*h0
+ &vpaddq ($D3,$D3,$T0);
+ &vpmuludq ($T2,$T1,&QWP(16*4,"edx")); # s3*h4
+ &vpaddq ($D2,$D2,$T2);
+ &vpmuludq ($T0,$T1,&QWP(16*3,"edx")); # s3*h3
+ &vpaddq ($D1,$D1,$T0);
+ &vmovdqa ($T2,&QWP(16*4,"esp")); # r4
+ &vpmuludq ($T1,$T1,&QWP(16*2,"edx")); # s3*h2
+ &vpaddq ($D0,$D0,$T1);
+
+ &vmovdqa ($T0,&QWP(16*8,"esp")); # s4
+ &vpmuludq ($T2,$T2,&QWP(16*0,"edx")); # r4*h0
+ &vpaddq ($D4,$D4,$T2);
+ &vpmuludq ($T1,$T0,&QWP(16*4,"edx")); # s4*h4
+ &vpaddq ($D3,$D3,$T1);
+ &vpmuludq ($T2,$T0,&QWP(16*1,"edx")); # s4*h1
+ &vpaddq ($D0,$D0,$T2);
+ &vpmuludq ($T1,$T0,&QWP(16*2,"edx")); # s4*h2
+ &vpaddq ($D1,$D1,$T1);
+ &vmovdqa ($MASK,&QWP(64,"ebx"));
+ &vpmuludq ($T0,$T0,&QWP(16*3,"edx")); # s4*h3
+ &vpaddq ($D2,$D2,$T0);
+
+ ################################################################
+ # lazy reduction
+ &vpsrlq ($T0,$D3,26);
+ &vpand ($D3,$D3,$MASK);
+ &vpsrlq ($T1,$D0,26);
+ &vpand ($D0,$D0,$MASK);
+ &vpaddq ($D4,$D4,$T0); # h3 -> h4
+ &vpaddq ($D1,$D1,$T1); # h0 -> h1
+ &vpsrlq ($T0,$D4,26);
+ &vpand ($D4,$D4,$MASK);
+ &vpsrlq ($T1,$D1,26);
+ &vpand ($D1,$D1,$MASK);
+ &vpaddq ($D2,$D2,$T1); # h1 -> h2
+ &vpaddd ($D0,$D0,$T0);
+ &vpsllq ($T0,$T0,2);
+ &vpsrlq ($T1,$D2,26);
+ &vpand ($D2,$D2,$MASK);
+ &vpaddd ($D0,$D0,$T0); # h4 -> h0
+ &vpaddd ($D3,$D3,$T1); # h2 -> h3
+ &vpsrlq ($T1,$D3,26);
+ &vpsrlq ($T0,$D0,26);
+ &vpand ($D0,$D0,$MASK);
+ &vpand ($D3,$D3,$MASK);
+ &vpaddd ($D1,$D1,$T0); # h0 -> h1
+ &vpaddd ($D4,$D4,$T1); # h3 -> h4
+
+ &dec ("ecx");
+ &jz (&label("square_break"));
+
+ &vpunpcklqdq ($D0,$D0,&QWP(16*0,"esp")); # 0:r^1:0:r^2
+ &vpunpcklqdq ($D1,$D1,&QWP(16*1,"esp"));
+ &vpunpcklqdq ($D2,$D2,&QWP(16*2,"esp"));
+ &vpunpcklqdq ($D3,$D3,&QWP(16*3,"esp"));
+ &vpunpcklqdq ($D4,$D4,&QWP(16*4,"esp"));
+ &jmp (&label("square"));
+
+&set_label("square_break");
+ &vpsllq ($D0,$D0,32); # -> r^3:0:r^4:0
+ &vpsllq ($D1,$D1,32);
+ &vpsllq ($D2,$D2,32);
+ &vpsllq ($D3,$D3,32);
+ &vpsllq ($D4,$D4,32);
+ &vpor ($D0,$D0,&QWP(16*0,"esp")); # r^3:r^1:r^4:r^2
+ &vpor ($D1,$D1,&QWP(16*1,"esp"));
+ &vpor ($D2,$D2,&QWP(16*2,"esp"));
+ &vpor ($D3,$D3,&QWP(16*3,"esp"));
+ &vpor ($D4,$D4,&QWP(16*4,"esp"));
+
+ &vpshufd ($D0,$D0,0b10001101); # -> r^1:r^2:r^3:r^4
+ &vpshufd ($D1,$D1,0b10001101);
+ &vpshufd ($D2,$D2,0b10001101);
+ &vpshufd ($D3,$D3,0b10001101);
+ &vpshufd ($D4,$D4,0b10001101);
+
+ &vmovdqu (&QWP(16*0,"edi"),$D0); # save the table
+ &vmovdqu (&QWP(16*1,"edi"),$D1);
+ &vmovdqu (&QWP(16*2,"edi"),$D2);
+ &vmovdqu (&QWP(16*3,"edi"),$D3);
+ &vmovdqu (&QWP(16*4,"edi"),$D4);
+
+ &vpslld ($T1,$D1,2);
+ &vpslld ($T0,$D2,2);
+ &vpaddd ($T1,$T1,$D1); # *5
+ &vpaddd ($T0,$T0,$D2); # *5
+ &vmovdqu (&QWP(16*5,"edi"),$T1);
+ &vmovdqu (&QWP(16*6,"edi"),$T0);
+ &vpslld ($T1,$D3,2);
+ &vpslld ($T0,$D4,2);
+ &vpaddd ($T1,$T1,$D3); # *5
+ &vpaddd ($T0,$T0,$D4); # *5
+ &vmovdqu (&QWP(16*7,"edi"),$T1);
+ &vmovdqu (&QWP(16*8,"edi"),$T0);
+
+ &mov ("esp","ebp");
+ &lea ("edi",&DWP(-16*3,"edi")); # size de-optimization
+ &ret ();
+&function_end_B("_poly1305_init_avx2");
+
+########################################################################
+# now it's time to switch to %ymm
+
+my ($D0,$D1,$D2,$D3,$D4,$T0,$T1,$T2)=map("ymm$_",(0..7));
+my $MASK=$T2;
+
+sub X { my $reg=shift; $reg=~s/^ymm/xmm/; $reg; }
+
+&align (32);
+&function_begin("_poly1305_blocks_avx2");
+ &mov ("edi",&wparam(0)); # ctx
+ &mov ("esi",&wparam(1)); # inp
+ &mov ("ecx",&wparam(2)); # len
+
+ &mov ("eax",&DWP(4*5,"edi")); # is_base2_26
+ &and ("ecx",-16);
+ &jz (&label("nodata"));
+ &cmp ("ecx",64);
+ &jae (&label("enter_avx2"));
+ &test ("eax","eax"); # is_base2_26?
+ &jz (&label("enter_blocks"));
+
+&set_label("enter_avx2");
+ &vzeroupper ();
+
+ &call (&label("pic_point"));
+&set_label("pic_point");
+ &blindpop("ebx");
+ &lea ("ebx",&DWP(&label("const_sse2")."-".&label("pic_point"),"ebx"));
+
+ &test ("eax","eax"); # is_base2_26?
+ &jnz (&label("base2_26"));
+
+ &call ("_poly1305_init_avx2");
+
+ ################################################# base 2^32 -> base 2^26
+ &mov ("eax",&DWP(0,"edi"));
+ &mov ("ecx",&DWP(3,"edi"));
+ &mov ("edx",&DWP(6,"edi"));
+ &mov ("esi",&DWP(9,"edi"));
+ &mov ("ebp",&DWP(13,"edi"));
+
+ &shr ("ecx",2);
+ &and ("eax",0x3ffffff);
+ &shr ("edx",4);
+ &and ("ecx",0x3ffffff);
+ &shr ("esi",6);
+ &and ("edx",0x3ffffff);
+
+ &mov (&DWP(4*0,"edi"),"eax");
+ &mov (&DWP(4*1,"edi"),"ecx");
+ &mov (&DWP(4*2,"edi"),"edx");
+ &mov (&DWP(4*3,"edi"),"esi");
+ &mov (&DWP(4*4,"edi"),"ebp");
+ &mov (&DWP(4*5,"edi"),1); # is_base2_26
+
+ &mov ("esi",&wparam(1)); # [reload] inp
+ &mov ("ecx",&wparam(2)); # [reload] len
+
+&set_label("base2_26");
+ &mov ("eax",&wparam(3)); # padbit
+ &mov ("ebp","esp");
+
+ &sub ("esp",32*(5+9));
+ &and ("esp",-512); # ensure that frame
+ # doesn't cross page
+ # boundary, which is
+ # essential for
+ # misaligned 32-byte
+ # loads
+
+ ################################################################
+ # expand and copy pre-calculated table to stack
+
+ &vmovdqu (&X($D0),&QWP(16*(3+0),"edi"));
+ &lea ("edx",&DWP(32*5+128,"esp")); # +128 size optimization
+ &vmovdqu (&X($D1),&QWP(16*(3+1),"edi"));
+ &vmovdqu (&X($D2),&QWP(16*(3+2),"edi"));
+ &vmovdqu (&X($D3),&QWP(16*(3+3),"edi"));
+ &vmovdqu (&X($D4),&QWP(16*(3+4),"edi"));
+ &lea ("edi",&DWP(16*3,"edi")); # size optimization
+ &vpermq ($D0,$D0,0b01000000); # 00001234 -> 12343434
+ &vpermq ($D1,$D1,0b01000000);
+ &vpermq ($D2,$D2,0b01000000);
+ &vpermq ($D3,$D3,0b01000000);
+ &vpermq ($D4,$D4,0b01000000);
+ &vpshufd ($D0,$D0,0b11001000); # 12343434 -> 14243444
+ &vpshufd ($D1,$D1,0b11001000);
+ &vpshufd ($D2,$D2,0b11001000);
+ &vpshufd ($D3,$D3,0b11001000);
+ &vpshufd ($D4,$D4,0b11001000);
+ &vmovdqa (&QWP(32*0-128,"edx"),$D0);
+ &vmovdqu (&X($D0),&QWP(16*5,"edi"));
+ &vmovdqa (&QWP(32*1-128,"edx"),$D1);
+ &vmovdqu (&X($D1),&QWP(16*6,"edi"));
+ &vmovdqa (&QWP(32*2-128,"edx"),$D2);
+ &vmovdqu (&X($D2),&QWP(16*7,"edi"));
+ &vmovdqa (&QWP(32*3-128,"edx"),$D3);
+ &vmovdqu (&X($D3),&QWP(16*8,"edi"));
+ &vmovdqa (&QWP(32*4-128,"edx"),$D4);
+ &vpermq ($D0,$D0,0b01000000);
+ &vpermq ($D1,$D1,0b01000000);
+ &vpermq ($D2,$D2,0b01000000);
+ &vpermq ($D3,$D3,0b01000000);
+ &vpshufd ($D0,$D0,0b11001000);
+ &vpshufd ($D1,$D1,0b11001000);
+ &vpshufd ($D2,$D2,0b11001000);
+ &vpshufd ($D3,$D3,0b11001000);
+ &vmovdqa (&QWP(32*5-128,"edx"),$D0);
+ &vmovd (&X($D0),&DWP(-16*3+4*0,"edi"));# load hash value
+ &vmovdqa (&QWP(32*6-128,"edx"),$D1);
+ &vmovd (&X($D1),&DWP(-16*3+4*1,"edi"));
+ &vmovdqa (&QWP(32*7-128,"edx"),$D2);
+ &vmovd (&X($D2),&DWP(-16*3+4*2,"edi"));
+ &vmovdqa (&QWP(32*8-128,"edx"),$D3);
+ &vmovd (&X($D3),&DWP(-16*3+4*3,"edi"));
+ &vmovd (&X($D4),&DWP(-16*3+4*4,"edi"));
+ &vmovdqa ($MASK,&QWP(64,"ebx"));
+ &neg ("eax"); # padbit
+
+ &test ("ecx",63);
+ &jz (&label("even"));
+
+ &mov ("edx","ecx");
+ &and ("ecx",-64);
+ &and ("edx",63);
+
+ &vmovdqu (&X($T0),&QWP(16*0,"esi"));
+ &cmp ("edx",32);
+ &jb (&label("one"));
+
+ &vmovdqu (&X($T1),&QWP(16*1,"esi"));
+ &je (&label("two"));
+
+ &vinserti128 ($T0,$T0,&QWP(16*2,"esi"),1);
+ &lea ("esi",&DWP(16*3,"esi"));
+ &lea ("ebx",&DWP(8,"ebx")); # three padbits
+ &lea ("edx",&DWP(32*5+128+8,"esp")); # --:r^1:r^2:r^3 (*)
+ &jmp (&label("tail"));
+
+&set_label("two");
+ &lea ("esi",&DWP(16*2,"esi"));
+ &lea ("ebx",&DWP(16,"ebx")); # two padbits
+ &lea ("edx",&DWP(32*5+128+16,"esp"));# --:--:r^1:r^2 (*)
+ &jmp (&label("tail"));
+
+&set_label("one");
+ &lea ("esi",&DWP(16*1,"esi"));
+ &vpxor ($T1,$T1,$T1);
+ &lea ("ebx",&DWP(32,"ebx","eax",8)); # one or no padbits
+ &lea ("edx",&DWP(32*5+128+24,"esp"));# --:--:--:r^1 (*)
+ &jmp (&label("tail"));
+
+# (*) spots marked with '--' are data from next table entry, but they
+# are multiplied by 0 and therefore rendered insignificant
+
+&set_label("even",32);
+ &vmovdqu (&X($T0),&QWP(16*0,"esi")); # load input
+ &vmovdqu (&X($T1),&QWP(16*1,"esi"));
+ &vinserti128 ($T0,$T0,&QWP(16*2,"esi"),1);
+ &vinserti128 ($T1,$T1,&QWP(16*3,"esi"),1);
+ &lea ("esi",&DWP(16*4,"esi"));
+ &sub ("ecx",64);
+ &jz (&label("tail"));
+
+&set_label("loop");
+ ################################################################
+ # ((inp[0]*r^4+r[4])*r^4+r[8])*r^4
+ # ((inp[1]*r^4+r[5])*r^4+r[9])*r^3
+ # ((inp[2]*r^4+r[6])*r^4+r[10])*r^2
+ # ((inp[3]*r^4+r[7])*r^4+r[11])*r^1
+ # \________/ \_______/
+ ################################################################
+
+sub vsplat_input {
+ &vmovdqa (&QWP(32*2,"esp"),$D2);
+ &vpsrldq ($D2,$T0,6); # splat input
+ &vmovdqa (&QWP(32*0,"esp"),$D0);
+ &vpsrldq ($D0,$T1,6);
+ &vmovdqa (&QWP(32*1,"esp"),$D1);
+ &vpunpckhqdq ($D1,$T0,$T1); # 4
+ &vpunpcklqdq ($T0,$T0,$T1); # 0:1
+ &vpunpcklqdq ($D2,$D2,$D0); # 2:3
+
+ &vpsrlq ($D0,$D2,30);
+ &vpsrlq ($D2,$D2,4);
+ &vpsrlq ($T1,$T0,26);
+ &vpsrlq ($D1,$D1,40); # 4
+ &vpand ($D2,$D2,$MASK); # 2
+ &vpand ($T0,$T0,$MASK); # 0
+ &vpand ($T1,$T1,$MASK); # 1
+ &vpand ($D0,$D0,$MASK); # 3 (*)
+ &vpor ($D1,$D1,&QWP(0,"ebx")); # padbit, yes, always
+
+ # (*) note that output is counterintuitive, inp[3:4] is
+ # returned in $D1-2, while $D3-4 are preserved;
+}
+ &vsplat_input ();
+
+sub vpmuladd {
+my $addr = shift;
+
+ &vpaddq ($D2,$D2,&QWP(32*2,"esp")); # add hash value
+ &vpaddq ($T0,$T0,&QWP(32*0,"esp"));
+ &vpaddq ($T1,$T1,&QWP(32*1,"esp"));
+ &vpaddq ($D0,$D0,$D3);
+ &vpaddq ($D1,$D1,$D4);
+
+ ################################################################
+ # d3 = h2*r1 + h0*r3 + h1*r2 + h3*r0 + h4*5*r4
+ # d4 = h2*r2 + h0*r4 + h1*r3 + h3*r1 + h4*r0
+ # d0 = h2*5*r3 + h0*r0 + h1*5*r4 + h3*5*r2 + h4*5*r1
+ # d1 = h2*5*r4 + h0*r1 + h1*r0 + h3*5*r3 + h4*5*r2
+ # d2 = h2*r0 + h0*r2 + h1*r1 + h3*5*r4 + h4*5*r3
+
+ &vpmuludq ($D3,$D2,&$addr(1)); # d3 = h2*r1
+ &vmovdqa (QWP(32*1,"esp"),$T1);
+ &vpmuludq ($D4,$D2,&$addr(2)); # d4 = h2*r2
+ &vmovdqa (QWP(32*3,"esp"),$D0);
+ &vpmuludq ($D0,$D2,&$addr(7)); # d0 = h2*s3
+ &vmovdqa (QWP(32*4,"esp"),$D1);
+ &vpmuludq ($D1,$D2,&$addr(8)); # d1 = h2*s4
+ &vpmuludq ($D2,$D2,&$addr(0)); # d2 = h2*r0
+
+ &vpmuludq ($T2,$T0,&$addr(3)); # h0*r3
+ &vpaddq ($D3,$D3,$T2); # d3 += h0*r3
+ &vpmuludq ($T1,$T0,&$addr(4)); # h0*r4
+ &vpaddq ($D4,$D4,$T1); # d4 + h0*r4
+ &vpmuludq ($T2,$T0,&$addr(0)); # h0*r0
+ &vpaddq ($D0,$D0,$T2); # d0 + h0*r0
+ &vmovdqa ($T2,&QWP(32*1,"esp")); # h1
+ &vpmuludq ($T1,$T0,&$addr(1)); # h0*r1
+ &vpaddq ($D1,$D1,$T1); # d1 += h0*r1
+ &vpmuludq ($T0,$T0,&$addr(2)); # h0*r2
+ &vpaddq ($D2,$D2,$T0); # d2 += h0*r2
+
+ &vpmuludq ($T1,$T2,&$addr(2)); # h1*r2
+ &vpaddq ($D3,$D3,$T1); # d3 += h1*r2
+ &vpmuludq ($T0,$T2,&$addr(3)); # h1*r3
+ &vpaddq ($D4,$D4,$T0); # d4 += h1*r3
+ &vpmuludq ($T1,$T2,&$addr(8)); # h1*s4
+ &vpaddq ($D0,$D0,$T1); # d0 += h1*s4
+ &vmovdqa ($T1,&QWP(32*3,"esp")); # h3
+ &vpmuludq ($T0,$T2,&$addr(0)); # h1*r0
+ &vpaddq ($D1,$D1,$T0); # d1 += h1*r0
+ &vpmuludq ($T2,$T2,&$addr(1)); # h1*r1
+ &vpaddq ($D2,$D2,$T2); # d2 += h1*r1
+
+ &vpmuludq ($T0,$T1,&$addr(0)); # h3*r0
+ &vpaddq ($D3,$D3,$T0); # d3 += h3*r0
+ &vpmuludq ($T2,$T1,&$addr(1)); # h3*r1
+ &vpaddq ($D4,$D4,$T2); # d4 += h3*r1
+ &vpmuludq ($T0,$T1,&$addr(6)); # h3*s2
+ &vpaddq ($D0,$D0,$T0); # d0 += h3*s2
+ &vmovdqa ($T0,&QWP(32*4,"esp")); # h4
+ &vpmuludq ($T2,$T1,&$addr(7)); # h3*s3
+ &vpaddq ($D1,$D1,$T2); # d1+= h3*s3
+ &vpmuludq ($T1,$T1,&$addr(8)); # h3*s4
+ &vpaddq ($D2,$D2,$T1); # d2 += h3*s4
+
+ &vpmuludq ($T2,$T0,&$addr(8)); # h4*s4
+ &vpaddq ($D3,$D3,$T2); # d3 += h4*s4
+ &vpmuludq ($T1,$T0,&$addr(5)); # h4*s1
+ &vpaddq ($D0,$D0,$T1); # d0 += h4*s1
+ &vpmuludq ($T2,$T0,&$addr(0)); # h4*r0
+ &vpaddq ($D4,$D4,$T2); # d4 += h4*r0
+ &vmovdqa ($MASK,&QWP(64,"ebx"));
+ &vpmuludq ($T1,$T0,&$addr(6)); # h4*s2
+ &vpaddq ($D1,$D1,$T1); # d1 += h4*s2
+ &vpmuludq ($T0,$T0,&$addr(7)); # h4*s3
+ &vpaddq ($D2,$D2,$T0); # d2 += h4*s3
+}
+ &vpmuladd (sub { my $i=shift; &QWP(32*$i-128,"edx"); });
+
+sub vlazy_reduction {
+ ################################################################
+ # lazy reduction
+
+ &vpsrlq ($T0,$D3,26);
+ &vpand ($D3,$D3,$MASK);
+ &vpsrlq ($T1,$D0,26);
+ &vpand ($D0,$D0,$MASK);
+ &vpaddq ($D4,$D4,$T0); # h3 -> h4
+ &vpaddq ($D1,$D1,$T1); # h0 -> h1
+ &vpsrlq ($T0,$D4,26);
+ &vpand ($D4,$D4,$MASK);
+ &vpsrlq ($T1,$D1,26);
+ &vpand ($D1,$D1,$MASK);
+ &vpaddq ($D2,$D2,$T1); # h1 -> h2
+ &vpaddq ($D0,$D0,$T0);
+ &vpsllq ($T0,$T0,2);
+ &vpsrlq ($T1,$D2,26);
+ &vpand ($D2,$D2,$MASK);
+ &vpaddq ($D0,$D0,$T0); # h4 -> h0
+ &vpaddq ($D3,$D3,$T1); # h2 -> h3
+ &vpsrlq ($T1,$D3,26);
+ &vpsrlq ($T0,$D0,26);
+ &vpand ($D0,$D0,$MASK);
+ &vpand ($D3,$D3,$MASK);
+ &vpaddq ($D1,$D1,$T0); # h0 -> h1
+ &vpaddq ($D4,$D4,$T1); # h3 -> h4
+}
+ &vlazy_reduction();
+
+ &vmovdqu (&X($T0),&QWP(16*0,"esi")); # load input
+ &vmovdqu (&X($T1),&QWP(16*1,"esi"));
+ &vinserti128 ($T0,$T0,&QWP(16*2,"esi"),1);
+ &vinserti128 ($T1,$T1,&QWP(16*3,"esi"),1);
+ &lea ("esi",&DWP(16*4,"esi"));
+ &sub ("ecx",64);
+ &jnz (&label("loop"));
+
+&set_label("tail");
+ &vsplat_input ();
+ &and ("ebx",-64); # restore pointer
+
+ &vpmuladd (sub { my $i=shift; &QWP(4+32*$i-128,"edx"); });
+
+ ################################################################
+ # horizontal addition
+
+ &vpsrldq ($T0,$D4,8);
+ &vpsrldq ($T1,$D3,8);
+ &vpaddq ($D4,$D4,$T0);
+ &vpsrldq ($T0,$D0,8);
+ &vpaddq ($D3,$D3,$T1);
+ &vpsrldq ($T1,$D1,8);
+ &vpaddq ($D0,$D0,$T0);
+ &vpsrldq ($T0,$D2,8);
+ &vpaddq ($D1,$D1,$T1);
+ &vpermq ($T1,$D4,2); # keep folding
+ &vpaddq ($D2,$D2,$T0);
+ &vpermq ($T0,$D3,2);
+ &vpaddq ($D4,$D4,$T1);
+ &vpermq ($T1,$D0,2);
+ &vpaddq ($D3,$D3,$T0);
+ &vpermq ($T0,$D1,2);
+ &vpaddq ($D0,$D0,$T1);
+ &vpermq ($T1,$D2,2);
+ &vpaddq ($D1,$D1,$T0);
+ &vpaddq ($D2,$D2,$T1);
+
+ &vlazy_reduction();
+
+ &cmp ("ecx",0);
+ &je (&label("done"));
+
+ ################################################################
+ # clear all but single word
+
+ &vpshufd (&X($D0),&X($D0),0b11111100);
+ &lea ("edx",&DWP(32*5+128,"esp")); # restore pointer
+ &vpshufd (&X($D1),&X($D1),0b11111100);
+ &vpshufd (&X($D2),&X($D2),0b11111100);
+ &vpshufd (&X($D3),&X($D3),0b11111100);
+ &vpshufd (&X($D4),&X($D4),0b11111100);
+ &jmp (&label("even"));
+
+&set_label("done",16);
+ &vmovd (&DWP(-16*3+4*0,"edi"),&X($D0));# store hash value
+ &vmovd (&DWP(-16*3+4*1,"edi"),&X($D1));
+ &vmovd (&DWP(-16*3+4*2,"edi"),&X($D2));
+ &vmovd (&DWP(-16*3+4*3,"edi"),&X($D3));
+ &vmovd (&DWP(-16*3+4*4,"edi"),&X($D4));
+ &vzeroupper ();
+ &mov ("esp","ebp");
+&set_label("nodata");
+&function_end("_poly1305_blocks_avx2");
+}
+&set_label("const_sse2",64);
+ &data_word(1<<24,0, 1<<24,0, 1<<24,0, 1<<24,0);
+ &data_word(0,0, 0,0, 0,0, 0,0);
+ &data_word(0x03ffffff,0,0x03ffffff,0, 0x03ffffff,0, 0x03ffffff,0);
+ &data_word(0x0fffffff,0x0ffffffc,0x0ffffffc,0x0ffffffc);
+}
+&asciz ("Poly1305 for x86, CRYPTOGAMS by <appro\@openssl.org>");
+&align (4);
+
+&asm_finish();
diff --git a/src/crypto/poly1305/asm/poly1305-x86_64.pl b/src/crypto/poly1305/asm/poly1305-x86_64.pl
new file mode 100755
index 00000000..3c810c5a
--- /dev/null
+++ b/src/crypto/poly1305/asm/poly1305-x86_64.pl
@@ -0,0 +1,2235 @@
+#!/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/.
+# ====================================================================
+#
+# This module implements Poly1305 hash for x86_64.
+#
+# March 2015
+#
+# Numbers are cycles per processed byte with poly1305_blocks alone,
+# measured with rdtsc at fixed clock frequency.
+#
+# IALU/gcc-4.8(*) AVX(**) AVX2
+# P4 4.90/+120% -
+# Core 2 2.39/+90% -
+# Westmere 1.86/+120% -
+# Sandy Bridge 1.39/+140% 1.10
+# Haswell 1.10/+175% 1.11 0.65
+# Skylake 1.12/+120% 0.96 0.51
+# Silvermont 2.83/+95% -
+# VIA Nano 1.82/+150% -
+# Sledgehammer 1.38/+160% -
+# Bulldozer 2.21/+130% 0.97
+#
+# (*) improvement coefficients relative to clang are more modest and
+# are ~50% on most processors, in both cases we are comparing to
+# __int128 code;
+# (**) SSE2 implementation was attempted, but among non-AVX processors
+# it was faster than integer-only code only on older Intel P4 and
+# Core processors, 50-30%, less newer processor is, but slower on
+# contemporary ones, for example almost 2x slower on Atom, and as
+# former are naturally disappearing, SSE2 is deemed unnecessary;
+
+$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";
+
+$avx = 2;
+
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
+
+my ($ctx,$inp,$len,$padbit)=("%rdi","%rsi","%rdx","%rcx");
+my ($mac,$nonce)=($inp,$len); # *_emit arguments
+my ($d1,$d2,$d3, $r0,$r1,$s1)=map("%r$_",(8..13));
+my ($h0,$h1,$h2)=("%r14","%rbx","%rbp");
+
+sub poly1305_iteration {
+# input: copy of $r1 in %rax, $h0-$h2, $r0-$r1
+# output: $h0-$h2 *= $r0-$r1
+$code.=<<___;
+ mulq $h0 # h0*r1
+ mov %rax,$d2
+ mov $r0,%rax
+ mov %rdx,$d3
+
+ mulq $h0 # h0*r0
+ mov %rax,$h0 # future $h0
+ mov $r0,%rax
+ mov %rdx,$d1
+
+ mulq $h1 # h1*r0
+ add %rax,$d2
+ mov $s1,%rax
+ adc %rdx,$d3
+
+ mulq $h1 # h1*s1
+ mov $h2,$h1 # borrow $h1
+ add %rax,$h0
+ adc %rdx,$d1
+
+ imulq $s1,$h1 # h2*s1
+ add $h1,$d2
+ mov $d1,$h1
+ adc \$0,$d3
+
+ imulq $r0,$h2 # h2*r0
+ add $d2,$h1
+ mov \$-4,%rax # mask value
+ adc $h2,$d3
+
+ and $d3,%rax # last reduction step
+ mov $d3,$h2
+ shr \$2,$d3
+ and \$3,$h2
+ add $d3,%rax
+ add %rax,$h0
+ adc \$0,$h1
+___
+}
+
+########################################################################
+# Layout of opaque area is following.
+#
+# unsigned __int64 h[3]; # current hash value base 2^64
+# unsigned __int64 r[2]; # key value base 2^64
+
+$code.=<<___;
+.text
+
+.extern OPENSSL_ia32cap_P
+
+.globl poly1305_init
+.globl poly1305_blocks
+.globl poly1305_emit
+.type poly1305_init,\@function,3
+.align 32
+poly1305_init:
+ xor %rax,%rax
+ mov %rax,0($ctx) # initialize hash value
+ mov %rax,8($ctx)
+ mov %rax,16($ctx)
+
+ cmp \$0,$inp
+ je .Lno_key
+
+ lea poly1305_blocks(%rip),%r10
+ lea poly1305_emit(%rip),%r11
+___
+$code.=<<___ if ($avx);
+ mov OPENSSL_ia32cap_P+4(%rip),%r9
+ lea poly1305_blocks_avx(%rip),%rax
+ lea poly1305_emit_avx(%rip),%rcx
+ bt \$`60-32`,%r9 # AVX?
+ cmovc %rax,%r10
+ cmovc %rcx,%r11
+___
+$code.=<<___ if ($avx>1);
+ lea poly1305_blocks_avx2(%rip),%rax
+ bt \$`5+32`,%r9 # AVX2?
+ cmovc %rax,%r10
+___
+$code.=<<___;
+ mov \$0x0ffffffc0fffffff,%rax
+ mov \$0x0ffffffc0ffffffc,%rcx
+ and 0($inp),%rax
+ and 8($inp),%rcx
+ mov %rax,24($ctx)
+ mov %rcx,32($ctx)
+___
+$code.=<<___ if ($flavour !~ /elf32/);
+ mov %r10,0(%rdx)
+ mov %r11,8(%rdx)
+___
+$code.=<<___ if ($flavour =~ /elf32/);
+ mov %r10d,0(%rdx)
+ mov %r11d,4(%rdx)
+___
+$code.=<<___;
+ mov \$1,%eax
+.Lno_key:
+ ret
+.size poly1305_init,.-poly1305_init
+
+.type poly1305_blocks,\@function,4
+.align 32
+poly1305_blocks:
+.Lblocks:
+ sub \$16,$len # too short?
+ jc .Lno_data
+
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+.Lblocks_body:
+
+ mov $len,%r15 # reassign $len
+
+ mov 24($ctx),$r0 # load r
+ mov 32($ctx),$s1
+
+ mov 0($ctx),$h0 # load hash value
+ mov 8($ctx),$h1
+ mov 16($ctx),$h2
+
+ mov $s1,$r1
+ shr \$2,$s1
+ mov $r1,%rax
+ add $r1,$s1 # s1 = r1 + (r1 >> 2)
+ jmp .Loop
+
+.align 32
+.Loop:
+ add 0($inp),$h0 # accumulate input
+ adc 8($inp),$h1
+ lea 16($inp),$inp
+ adc $padbit,$h2
+___
+ &poly1305_iteration();
+$code.=<<___;
+ mov $r1,%rax
+ sub \$16,%r15 # len-=16
+ jnc .Loop
+
+ mov $h0,0($ctx) # store hash value
+ mov $h1,8($ctx)
+ mov $h2,16($ctx)
+
+ mov 0(%rsp),%r15
+ mov 8(%rsp),%r14
+ mov 16(%rsp),%r13
+ mov 24(%rsp),%r12
+ mov 32(%rsp),%rbp
+ mov 40(%rsp),%rbx
+ lea 48(%rsp),%rsp
+.Lno_data:
+.Lblocks_epilogue:
+ ret
+.size poly1305_blocks,.-poly1305_blocks
+
+.type poly1305_emit,\@function,3
+.align 32
+poly1305_emit:
+.Lemit:
+ mov 0($ctx),%r8 # load hash value
+ mov 8($ctx),%r9
+ mov 16($ctx),%r10
+
+ mov %r8,%rax
+ add \$5,%r8 # compare to modulus
+ mov %r9,%rcx
+ adc \$0,%r9
+ adc \$0,%r10
+ shr \$2,%r10 # did 130-bit value overfow?
+ cmovnz %r8,%rax
+ cmovnz %r9,%rcx
+
+ add 0($nonce),%rax # accumulate nonce
+ adc 8($nonce),%rcx
+ mov %rax,0($mac) # write result
+ mov %rcx,8($mac)
+
+ ret
+.size poly1305_emit,.-poly1305_emit
+___
+if ($avx) {
+
+########################################################################
+# Layout of opaque area is following.
+#
+# unsigned __int32 h[5]; # current hash value base 2^26
+# unsigned __int32 is_base2_26;
+# unsigned __int64 r[2]; # key value base 2^64
+# unsigned __int64 pad;
+# struct { unsigned __int32 r^2, r^1, r^4, r^3; } r[9];
+#
+# where r^n are base 2^26 digits of degrees of multiplier key. There are
+# 5 digits, but last four are interleaved with multiples of 5, totalling
+# in 9 elements: r0, r1, 5*r1, r2, 5*r2, r3, 5*r3, r4, 5*r4.
+
+my ($H0,$H1,$H2,$H3,$H4, $T0,$T1,$T2,$T3,$T4, $D0,$D1,$D2,$D3,$D4, $MASK) =
+ map("%xmm$_",(0..15));
+
+$code.=<<___;
+.type __poly1305_block,\@abi-omnipotent
+.align 32
+__poly1305_block:
+___
+ &poly1305_iteration();
+$code.=<<___;
+ ret
+.size __poly1305_block,.-__poly1305_block
+
+.type __poly1305_init_avx,\@abi-omnipotent
+.align 32
+__poly1305_init_avx:
+ mov $r0,$h0
+ mov $r1,$h1
+ xor $h2,$h2
+
+ lea 48+64($ctx),$ctx # size optimization
+
+ mov $r1,%rax
+ call __poly1305_block # r^2
+
+ mov \$0x3ffffff,%eax # save interleaved r^2 and r base 2^26
+ mov \$0x3ffffff,%edx
+ mov $h0,$d1
+ and $h0#d,%eax
+ mov $r0,$d2
+ and $r0#d,%edx
+ mov %eax,`16*0+0-64`($ctx)
+ shr \$26,$d1
+ mov %edx,`16*0+4-64`($ctx)
+ shr \$26,$d2
+
+ mov \$0x3ffffff,%eax
+ mov \$0x3ffffff,%edx
+ and $d1#d,%eax
+ and $d2#d,%edx
+ mov %eax,`16*1+0-64`($ctx)
+ lea (%rax,%rax,4),%eax # *5
+ mov %edx,`16*1+4-64`($ctx)
+ lea (%rdx,%rdx,4),%edx # *5
+ mov %eax,`16*2+0-64`($ctx)
+ shr \$26,$d1
+ mov %edx,`16*2+4-64`($ctx)
+ shr \$26,$d2
+
+ mov $h1,%rax
+ mov $r1,%rdx
+ shl \$12,%rax
+ shl \$12,%rdx
+ or $d1,%rax
+ or $d2,%rdx
+ and \$0x3ffffff,%eax
+ and \$0x3ffffff,%edx
+ mov %eax,`16*3+0-64`($ctx)
+ lea (%rax,%rax,4),%eax # *5
+ mov %edx,`16*3+4-64`($ctx)
+ lea (%rdx,%rdx,4),%edx # *5
+ mov %eax,`16*4+0-64`($ctx)
+ mov $h1,$d1
+ mov %edx,`16*4+4-64`($ctx)
+ mov $r1,$d2
+
+ mov \$0x3ffffff,%eax
+ mov \$0x3ffffff,%edx
+ shr \$14,$d1
+ shr \$14,$d2
+ and $d1#d,%eax
+ and $d2#d,%edx
+ mov %eax,`16*5+0-64`($ctx)
+ lea (%rax,%rax,4),%eax # *5
+ mov %edx,`16*5+4-64`($ctx)
+ lea (%rdx,%rdx,4),%edx # *5
+ mov %eax,`16*6+0-64`($ctx)
+ shr \$26,$d1
+ mov %edx,`16*6+4-64`($ctx)
+ shr \$26,$d2
+
+ mov $h2,%rax
+ shl \$24,%rax
+ or %rax,$d1
+ mov $d1#d,`16*7+0-64`($ctx)
+ lea ($d1,$d1,4),$d1 # *5
+ mov $d2#d,`16*7+4-64`($ctx)
+ lea ($d2,$d2,4),$d2 # *5
+ mov $d1#d,`16*8+0-64`($ctx)
+ mov $d2#d,`16*8+4-64`($ctx)
+
+ mov $r1,%rax
+ call __poly1305_block # r^3
+
+ mov \$0x3ffffff,%eax # save r^3 base 2^26
+ mov $h0,$d1
+ and $h0#d,%eax
+ shr \$26,$d1
+ mov %eax,`16*0+12-64`($ctx)
+
+ mov \$0x3ffffff,%edx
+ and $d1#d,%edx
+ mov %edx,`16*1+12-64`($ctx)
+ lea (%rdx,%rdx,4),%edx # *5
+ shr \$26,$d1
+ mov %edx,`16*2+12-64`($ctx)
+
+ mov $h1,%rax
+ shl \$12,%rax
+ or $d1,%rax
+ and \$0x3ffffff,%eax
+ mov %eax,`16*3+12-64`($ctx)
+ lea (%rax,%rax,4),%eax # *5
+ mov $h1,$d1
+ mov %eax,`16*4+12-64`($ctx)
+
+ mov \$0x3ffffff,%edx
+ shr \$14,$d1
+ and $d1#d,%edx
+ mov %edx,`16*5+12-64`($ctx)
+ lea (%rdx,%rdx,4),%edx # *5
+ shr \$26,$d1
+ mov %edx,`16*6+12-64`($ctx)
+
+ mov $h2,%rax
+ shl \$24,%rax
+ or %rax,$d1
+ mov $d1#d,`16*7+12-64`($ctx)
+ lea ($d1,$d1,4),$d1 # *5
+ mov $d1#d,`16*8+12-64`($ctx)
+
+ mov $r1,%rax
+ call __poly1305_block # r^4
+
+ mov \$0x3ffffff,%eax # save r^4 base 2^26
+ mov $h0,$d1
+ and $h0#d,%eax
+ shr \$26,$d1
+ mov %eax,`16*0+8-64`($ctx)
+
+ mov \$0x3ffffff,%edx
+ and $d1#d,%edx
+ mov %edx,`16*1+8-64`($ctx)
+ lea (%rdx,%rdx,4),%edx # *5
+ shr \$26,$d1
+ mov %edx,`16*2+8-64`($ctx)
+
+ mov $h1,%rax
+ shl \$12,%rax
+ or $d1,%rax
+ and \$0x3ffffff,%eax
+ mov %eax,`16*3+8-64`($ctx)
+ lea (%rax,%rax,4),%eax # *5
+ mov $h1,$d1
+ mov %eax,`16*4+8-64`($ctx)
+
+ mov \$0x3ffffff,%edx
+ shr \$14,$d1
+ and $d1#d,%edx
+ mov %edx,`16*5+8-64`($ctx)
+ lea (%rdx,%rdx,4),%edx # *5
+ shr \$26,$d1
+ mov %edx,`16*6+8-64`($ctx)
+
+ mov $h2,%rax
+ shl \$24,%rax
+ or %rax,$d1
+ mov $d1#d,`16*7+8-64`($ctx)
+ lea ($d1,$d1,4),$d1 # *5
+ mov $d1#d,`16*8+8-64`($ctx)
+
+ lea -48-64($ctx),$ctx # size [de-]optimization
+ ret
+.size __poly1305_init_avx,.-__poly1305_init_avx
+
+.type poly1305_blocks_avx,\@function,4
+.align 32
+poly1305_blocks_avx:
+ mov 20($ctx),%r8d # is_base2_26
+ cmp \$128,$len
+ jae .Lblocks_avx
+ test %r8d,%r8d
+ jz .Lblocks
+
+.Lblocks_avx:
+ and \$-16,$len
+ jz .Lno_data_avx
+
+ vzeroupper
+
+ test %r8d,%r8d
+ jz .Lbase2_64_avx
+
+ test \$31,$len
+ jz .Leven_avx
+
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+.Lblocks_avx_body:
+
+ mov $len,%r15 # reassign $len
+
+ mov 0($ctx),$d1 # load hash value
+ mov 8($ctx),$d2
+ mov 16($ctx),$h2#d
+
+ mov 24($ctx),$r0 # load r
+ mov 32($ctx),$s1
+
+ ################################# base 2^26 -> base 2^64
+ mov $d1#d,$h0#d
+ and \$-1<<31,$d1
+ mov $d2,$r1 # borrow $r1
+ mov $d2#d,$h1#d
+ and \$-1<<31,$d2
+
+ shr \$6,$d1
+ shl \$52,$r1
+ add $d1,$h0
+ shr \$12,$h1
+ shr \$18,$d2
+ add $r1,$h0
+ adc $d2,$h1
+
+ mov $h2,$d1
+ shl \$40,$d1
+ shr \$24,$h2
+ add $d1,$h1
+ adc \$0,$h2 # can be partially reduced...
+
+ mov \$-4,$d2 # ... so reduce
+ mov $h2,$d1
+ and $h2,$d2
+ shr \$2,$d1
+ and \$3,$h2
+ add $d2,$d1 # =*5
+ add $d1,$h0
+ adc \$0,$h1
+
+ mov $s1,$r1
+ mov $s1,%rax
+ shr \$2,$s1
+ add $r1,$s1 # s1 = r1 + (r1 >> 2)
+
+ add 0($inp),$h0 # accumulate input
+ adc 8($inp),$h1
+ lea 16($inp),$inp
+ adc $padbit,$h2
+
+ call __poly1305_block
+
+ test $padbit,$padbit # if $padbit is zero,
+ jz .Lstore_base2_64_avx # store hash in base 2^64 format
+
+ ################################# base 2^64 -> base 2^26
+ mov $h0,%rax
+ mov $h0,%rdx
+ shr \$52,$h0
+ mov $h1,$r0
+ mov $h1,$r1
+ shr \$26,%rdx
+ and \$0x3ffffff,%rax # h[0]
+ shl \$12,$r0
+ and \$0x3ffffff,%rdx # h[1]
+ shr \$14,$h1
+ or $r0,$h0
+ shl \$24,$h2
+ and \$0x3ffffff,$h0 # h[2]
+ shr \$40,$r1
+ and \$0x3ffffff,$h1 # h[3]
+ or $r1,$h2 # h[4]
+
+ sub \$16,%r15
+ jz .Lstore_base2_26_avx
+
+ vmovd %rax#d,$H0
+ vmovd %rdx#d,$H1
+ vmovd $h0#d,$H2
+ vmovd $h1#d,$H3
+ vmovd $h2#d,$H4
+ jmp .Lproceed_avx
+
+.align 32
+.Lstore_base2_64_avx:
+ mov $h0,0($ctx)
+ mov $h1,8($ctx)
+ mov $h2,16($ctx) # note that is_base2_26 is zeroed
+ jmp .Ldone_avx
+
+.align 16
+.Lstore_base2_26_avx:
+ mov %rax#d,0($ctx) # store hash value base 2^26
+ mov %rdx#d,4($ctx)
+ mov $h0#d,8($ctx)
+ mov $h1#d,12($ctx)
+ mov $h2#d,16($ctx)
+.align 16
+.Ldone_avx:
+ mov 0(%rsp),%r15
+ mov 8(%rsp),%r14
+ mov 16(%rsp),%r13
+ mov 24(%rsp),%r12
+ mov 32(%rsp),%rbp
+ mov 40(%rsp),%rbx
+ lea 48(%rsp),%rsp
+.Lno_data_avx:
+.Lblocks_avx_epilogue:
+ ret
+
+.align 32
+.Lbase2_64_avx:
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+.Lbase2_64_avx_body:
+
+ mov $len,%r15 # reassign $len
+
+ mov 24($ctx),$r0 # load r
+ mov 32($ctx),$s1
+
+ mov 0($ctx),$h0 # load hash value
+ mov 8($ctx),$h1
+ mov 16($ctx),$h2#d
+
+ mov $s1,$r1
+ mov $s1,%rax
+ shr \$2,$s1
+ add $r1,$s1 # s1 = r1 + (r1 >> 2)
+
+ test \$31,$len
+ jz .Linit_avx
+
+ add 0($inp),$h0 # accumulate input
+ adc 8($inp),$h1
+ lea 16($inp),$inp
+ adc $padbit,$h2
+ sub \$16,%r15
+
+ call __poly1305_block
+
+.Linit_avx:
+ ################################# base 2^64 -> base 2^26
+ mov $h0,%rax
+ mov $h0,%rdx
+ shr \$52,$h0
+ mov $h1,$d1
+ mov $h1,$d2
+ shr \$26,%rdx
+ and \$0x3ffffff,%rax # h[0]
+ shl \$12,$d1
+ and \$0x3ffffff,%rdx # h[1]
+ shr \$14,$h1
+ or $d1,$h0
+ shl \$24,$h2
+ and \$0x3ffffff,$h0 # h[2]
+ shr \$40,$d2
+ and \$0x3ffffff,$h1 # h[3]
+ or $d2,$h2 # h[4]
+
+ vmovd %rax#d,$H0
+ vmovd %rdx#d,$H1
+ vmovd $h0#d,$H2
+ vmovd $h1#d,$H3
+ vmovd $h2#d,$H4
+ movl \$1,20($ctx) # set is_base2_26
+
+ call __poly1305_init_avx
+
+.Lproceed_avx:
+ mov %r15,$len
+
+ mov 0(%rsp),%r15
+ mov 8(%rsp),%r14
+ mov 16(%rsp),%r13
+ mov 24(%rsp),%r12
+ mov 32(%rsp),%rbp
+ mov 40(%rsp),%rbx
+ lea 48(%rsp),%rax
+ lea 48(%rsp),%rsp
+.Lbase2_64_avx_epilogue:
+ jmp .Ldo_avx
+
+.align 32
+.Leven_avx:
+ vmovd 4*0($ctx),$H0 # load hash value
+ vmovd 4*1($ctx),$H1
+ vmovd 4*2($ctx),$H2
+ vmovd 4*3($ctx),$H3
+ vmovd 4*4($ctx),$H4
+
+.Ldo_avx:
+___
+$code.=<<___ if (!$win64);
+ lea -0x58(%rsp),%r11
+ sub \$0x178,%rsp
+___
+$code.=<<___ if ($win64);
+ lea -0xf8(%rsp),%r11
+ sub \$0x218,%rsp
+ vmovdqa %xmm6,0x50(%r11)
+ vmovdqa %xmm7,0x60(%r11)
+ vmovdqa %xmm8,0x70(%r11)
+ vmovdqa %xmm9,0x80(%r11)
+ vmovdqa %xmm10,0x90(%r11)
+ vmovdqa %xmm11,0xa0(%r11)
+ vmovdqa %xmm12,0xb0(%r11)
+ vmovdqa %xmm13,0xc0(%r11)
+ vmovdqa %xmm14,0xd0(%r11)
+ vmovdqa %xmm15,0xe0(%r11)
+.Ldo_avx_body:
+___
+$code.=<<___;
+ sub \$64,$len
+ lea -32($inp),%rax
+ cmovc %rax,$inp
+
+ vmovdqu `16*3`($ctx),$D4 # preload r0^2
+ lea `16*3+64`($ctx),$ctx # size optimization
+ lea .Lconst(%rip),%rcx
+
+ ################################################################
+ # load input
+ vmovdqu 16*2($inp),$T0
+ vmovdqu 16*3($inp),$T1
+ vmovdqa 64(%rcx),$MASK # .Lmask26
+
+ vpsrldq \$6,$T0,$T2 # splat input
+ vpsrldq \$6,$T1,$T3
+ vpunpckhqdq $T1,$T0,$T4 # 4
+ vpunpcklqdq $T1,$T0,$T0 # 0:1
+ vpunpcklqdq $T3,$T2,$T3 # 2:3
+
+ vpsrlq \$40,$T4,$T4 # 4
+ vpsrlq \$26,$T0,$T1
+ vpand $MASK,$T0,$T0 # 0
+ vpsrlq \$4,$T3,$T2
+ vpand $MASK,$T1,$T1 # 1
+ vpsrlq \$30,$T3,$T3
+ vpand $MASK,$T2,$T2 # 2
+ vpand $MASK,$T3,$T3 # 3
+ vpor 32(%rcx),$T4,$T4 # padbit, yes, always
+
+ jbe .Lskip_loop_avx
+
+ # expand and copy pre-calculated table to stack
+ vmovdqu `16*1-64`($ctx),$D1
+ vmovdqu `16*2-64`($ctx),$D2
+ vpshufd \$0xEE,$D4,$D3 # 34xx -> 3434
+ vpshufd \$0x44,$D4,$D0 # xx12 -> 1212
+ vmovdqa $D3,-0x90(%r11)
+ vmovdqa $D0,0x00(%rsp)
+ vpshufd \$0xEE,$D1,$D4
+ vmovdqu `16*3-64`($ctx),$D0
+ vpshufd \$0x44,$D1,$D1
+ vmovdqa $D4,-0x80(%r11)
+ vmovdqa $D1,0x10(%rsp)
+ vpshufd \$0xEE,$D2,$D3
+ vmovdqu `16*4-64`($ctx),$D1
+ vpshufd \$0x44,$D2,$D2
+ vmovdqa $D3,-0x70(%r11)
+ vmovdqa $D2,0x20(%rsp)
+ vpshufd \$0xEE,$D0,$D4
+ vmovdqu `16*5-64`($ctx),$D2
+ vpshufd \$0x44,$D0,$D0
+ vmovdqa $D4,-0x60(%r11)
+ vmovdqa $D0,0x30(%rsp)
+ vpshufd \$0xEE,$D1,$D3
+ vmovdqu `16*6-64`($ctx),$D0
+ vpshufd \$0x44,$D1,$D1
+ vmovdqa $D3,-0x50(%r11)
+ vmovdqa $D1,0x40(%rsp)
+ vpshufd \$0xEE,$D2,$D4
+ vmovdqu `16*7-64`($ctx),$D1
+ vpshufd \$0x44,$D2,$D2
+ vmovdqa $D4,-0x40(%r11)
+ vmovdqa $D2,0x50(%rsp)
+ vpshufd \$0xEE,$D0,$D3
+ vmovdqu `16*8-64`($ctx),$D2
+ vpshufd \$0x44,$D0,$D0
+ vmovdqa $D3,-0x30(%r11)
+ vmovdqa $D0,0x60(%rsp)
+ vpshufd \$0xEE,$D1,$D4
+ vpshufd \$0x44,$D1,$D1
+ vmovdqa $D4,-0x20(%r11)
+ vmovdqa $D1,0x70(%rsp)
+ vpshufd \$0xEE,$D2,$D3
+ vmovdqa 0x00(%rsp),$D4 # preload r0^2
+ vpshufd \$0x44,$D2,$D2
+ vmovdqa $D3,-0x10(%r11)
+ vmovdqa $D2,0x80(%rsp)
+
+ jmp .Loop_avx
+
+.align 32
+.Loop_avx:
+ ################################################################
+ # ((inp[0]*r^4+inp[2]*r^2+inp[4])*r^4+inp[6]*r^2
+ # ((inp[1]*r^4+inp[3]*r^2+inp[5])*r^3+inp[7]*r
+ # \___________________/
+ # ((inp[0]*r^4+inp[2]*r^2+inp[4])*r^4+inp[6]*r^2+inp[8])*r^2
+ # ((inp[1]*r^4+inp[3]*r^2+inp[5])*r^4+inp[7]*r^2+inp[9])*r
+ # \___________________/ \____________________/
+ #
+ # Note that we start with inp[2:3]*r^2. This is because it
+ # doesn't depend on reduction in previous iteration.
+ ################################################################
+ # d4 = h4*r0 + h3*r1 + h2*r2 + h1*r3 + h0*r4
+ # d3 = h3*r0 + h2*r1 + h1*r2 + h0*r3 + h4*5*r4
+ # d2 = h2*r0 + h1*r1 + h0*r2 + h4*5*r3 + h3*5*r4
+ # d1 = h1*r0 + h0*r1 + h4*5*r2 + h3*5*r3 + h2*5*r4
+ # d0 = h0*r0 + h4*5*r1 + h3*5*r2 + h2*5*r3 + h1*5*r4
+ #
+ # though note that $Tx and $Hx are "reversed" in this section,
+ # and $D4 is preloaded with r0^2...
+
+ vpmuludq $T0,$D4,$D0 # d0 = h0*r0
+ vpmuludq $T1,$D4,$D1 # d1 = h1*r0
+ vmovdqa $H2,0x20(%r11) # offload hash
+ vpmuludq $T2,$D4,$D2 # d3 = h2*r0
+ vmovdqa 0x10(%rsp),$H2 # r1^2
+ vpmuludq $T3,$D4,$D3 # d3 = h3*r0
+ vpmuludq $T4,$D4,$D4 # d4 = h4*r0
+
+ vmovdqa $H0,0x00(%r11) #
+ vpmuludq 0x20(%rsp),$T4,$H0 # h4*s1
+ vmovdqa $H1,0x10(%r11) #
+ vpmuludq $T3,$H2,$H1 # h3*r1
+ vpaddq $H0,$D0,$D0 # d0 += h4*s1
+ vpaddq $H1,$D4,$D4 # d4 += h3*r1
+ vmovdqa $H3,0x30(%r11) #
+ vpmuludq $T2,$H2,$H0 # h2*r1
+ vpmuludq $T1,$H2,$H1 # h1*r1
+ vpaddq $H0,$D3,$D3 # d3 += h2*r1
+ vmovdqa 0x30(%rsp),$H3 # r2^2
+ vpaddq $H1,$D2,$D2 # d2 += h1*r1
+ vmovdqa $H4,0x40(%r11) #
+ vpmuludq $T0,$H2,$H2 # h0*r1
+ vpmuludq $T2,$H3,$H0 # h2*r2
+ vpaddq $H2,$D1,$D1 # d1 += h0*r1
+
+ vmovdqa 0x40(%rsp),$H4 # s2^2
+ vpaddq $H0,$D4,$D4 # d4 += h2*r2
+ vpmuludq $T1,$H3,$H1 # h1*r2
+ vpmuludq $T0,$H3,$H3 # h0*r2
+ vpaddq $H1,$D3,$D3 # d3 += h1*r2
+ vmovdqa 0x50(%rsp),$H2 # r3^2
+ vpaddq $H3,$D2,$D2 # d2 += h0*r2
+ vpmuludq $T4,$H4,$H0 # h4*s2
+ vpmuludq $T3,$H4,$H4 # h3*s2
+ vpaddq $H0,$D1,$D1 # d1 += h4*s2
+ vmovdqa 0x60(%rsp),$H3 # s3^2
+ vpaddq $H4,$D0,$D0 # d0 += h3*s2
+
+ vmovdqa 0x80(%rsp),$H4 # s4^2
+ vpmuludq $T1,$H2,$H1 # h1*r3
+ vpmuludq $T0,$H2,$H2 # h0*r3
+ vpaddq $H1,$D4,$D4 # d4 += h1*r3
+ vpaddq $H2,$D3,$D3 # d3 += h0*r3
+ vpmuludq $T4,$H3,$H0 # h4*s3
+ vpmuludq $T3,$H3,$H1 # h3*s3
+ vpaddq $H0,$D2,$D2 # d2 += h4*s3
+ vmovdqu 16*0($inp),$H0 # load input
+ vpaddq $H1,$D1,$D1 # d1 += h3*s3
+ vpmuludq $T2,$H3,$H3 # h2*s3
+ vpmuludq $T2,$H4,$T2 # h2*s4
+ vpaddq $H3,$D0,$D0 # d0 += h2*s3
+
+ vmovdqu 16*1($inp),$H1 #
+ vpaddq $T2,$D1,$D1 # d1 += h2*s4
+ vpmuludq $T3,$H4,$T3 # h3*s4
+ vpmuludq $T4,$H4,$T4 # h4*s4
+ vpsrldq \$6,$H0,$H2 # splat input
+ vpaddq $T3,$D2,$D2 # d2 += h3*s4
+ vpaddq $T4,$D3,$D3 # d3 += h4*s4
+ vpsrldq \$6,$H1,$H3 #
+ vpmuludq 0x70(%rsp),$T0,$T4 # h0*r4
+ vpmuludq $T1,$H4,$T0 # h1*s4
+ vpunpckhqdq $H1,$H0,$H4 # 4
+ vpaddq $T4,$D4,$D4 # d4 += h0*r4
+ vmovdqa -0x90(%r11),$T4 # r0^4
+ vpaddq $T0,$D0,$D0 # d0 += h1*s4
+
+ vpunpcklqdq $H1,$H0,$H0 # 0:1
+ vpunpcklqdq $H3,$H2,$H3 # 2:3
+
+ #vpsrlq \$40,$H4,$H4 # 4
+ vpsrldq \$`40/8`,$H4,$H4 # 4
+ vpsrlq \$26,$H0,$H1
+ vpand $MASK,$H0,$H0 # 0
+ vpsrlq \$4,$H3,$H2
+ vpand $MASK,$H1,$H1 # 1
+ vpand 0(%rcx),$H4,$H4 # .Lmask24
+ vpsrlq \$30,$H3,$H3
+ vpand $MASK,$H2,$H2 # 2
+ vpand $MASK,$H3,$H3 # 3
+ vpor 32(%rcx),$H4,$H4 # padbit, yes, always
+
+ vpaddq 0x00(%r11),$H0,$H0 # add hash value
+ vpaddq 0x10(%r11),$H1,$H1
+ vpaddq 0x20(%r11),$H2,$H2
+ vpaddq 0x30(%r11),$H3,$H3
+ vpaddq 0x40(%r11),$H4,$H4
+
+ lea 16*2($inp),%rax
+ lea 16*4($inp),$inp
+ sub \$64,$len
+ cmovc %rax,$inp
+
+ ################################################################
+ # Now we accumulate (inp[0:1]+hash)*r^4
+ ################################################################
+ # d4 = h4*r0 + h3*r1 + h2*r2 + h1*r3 + h0*r4
+ # d3 = h3*r0 + h2*r1 + h1*r2 + h0*r3 + h4*5*r4
+ # d2 = h2*r0 + h1*r1 + h0*r2 + h4*5*r3 + h3*5*r4
+ # d1 = h1*r0 + h0*r1 + h4*5*r2 + h3*5*r3 + h2*5*r4
+ # d0 = h0*r0 + h4*5*r1 + h3*5*r2 + h2*5*r3 + h1*5*r4
+
+ vpmuludq $H0,$T4,$T0 # h0*r0
+ vpmuludq $H1,$T4,$T1 # h1*r0
+ vpaddq $T0,$D0,$D0
+ vpaddq $T1,$D1,$D1
+ vmovdqa -0x80(%r11),$T2 # r1^4
+ vpmuludq $H2,$T4,$T0 # h2*r0
+ vpmuludq $H3,$T4,$T1 # h3*r0
+ vpaddq $T0,$D2,$D2
+ vpaddq $T1,$D3,$D3
+ vpmuludq $H4,$T4,$T4 # h4*r0
+ vpmuludq -0x70(%r11),$H4,$T0 # h4*s1
+ vpaddq $T4,$D4,$D4
+
+ vpaddq $T0,$D0,$D0 # d0 += h4*s1
+ vpmuludq $H2,$T2,$T1 # h2*r1
+ vpmuludq $H3,$T2,$T0 # h3*r1
+ vpaddq $T1,$D3,$D3 # d3 += h2*r1
+ vmovdqa -0x60(%r11),$T3 # r2^4
+ vpaddq $T0,$D4,$D4 # d4 += h3*r1
+ vpmuludq $H1,$T2,$T1 # h1*r1
+ vpmuludq $H0,$T2,$T2 # h0*r1
+ vpaddq $T1,$D2,$D2 # d2 += h1*r1
+ vpaddq $T2,$D1,$D1 # d1 += h0*r1
+
+ vmovdqa -0x50(%r11),$T4 # s2^4
+ vpmuludq $H2,$T3,$T0 # h2*r2
+ vpmuludq $H1,$T3,$T1 # h1*r2
+ vpaddq $T0,$D4,$D4 # d4 += h2*r2
+ vpaddq $T1,$D3,$D3 # d3 += h1*r2
+ vmovdqa -0x40(%r11),$T2 # r3^4
+ vpmuludq $H0,$T3,$T3 # h0*r2
+ vpmuludq $H4,$T4,$T0 # h4*s2
+ vpaddq $T3,$D2,$D2 # d2 += h0*r2
+ vpaddq $T0,$D1,$D1 # d1 += h4*s2
+ vmovdqa -0x30(%r11),$T3 # s3^4
+ vpmuludq $H3,$T4,$T4 # h3*s2
+ vpmuludq $H1,$T2,$T1 # h1*r3
+ vpaddq $T4,$D0,$D0 # d0 += h3*s2
+
+ vmovdqa -0x10(%r11),$T4 # s4^4
+ vpaddq $T1,$D4,$D4 # d4 += h1*r3
+ vpmuludq $H0,$T2,$T2 # h0*r3
+ vpmuludq $H4,$T3,$T0 # h4*s3
+ vpaddq $T2,$D3,$D3 # d3 += h0*r3
+ vpaddq $T0,$D2,$D2 # d2 += h4*s3
+ vmovdqu 16*2($inp),$T0 # load input
+ vpmuludq $H3,$T3,$T2 # h3*s3
+ vpmuludq $H2,$T3,$T3 # h2*s3
+ vpaddq $T2,$D1,$D1 # d1 += h3*s3
+ vmovdqu 16*3($inp),$T1 #
+ vpaddq $T3,$D0,$D0 # d0 += h2*s3
+
+ vpmuludq $H2,$T4,$H2 # h2*s4
+ vpmuludq $H3,$T4,$H3 # h3*s4
+ vpsrldq \$6,$T0,$T2 # splat input
+ vpaddq $H2,$D1,$D1 # d1 += h2*s4
+ vpmuludq $H4,$T4,$H4 # h4*s4
+ vpsrldq \$6,$T1,$T3 #
+ vpaddq $H3,$D2,$H2 # h2 = d2 + h3*s4
+ vpaddq $H4,$D3,$H3 # h3 = d3 + h4*s4
+ vpmuludq -0x20(%r11),$H0,$H4 # h0*r4
+ vpmuludq $H1,$T4,$H0
+ vpunpckhqdq $T1,$T0,$T4 # 4
+ vpaddq $H4,$D4,$H4 # h4 = d4 + h0*r4
+ vpaddq $H0,$D0,$H0 # h0 = d0 + h1*s4
+
+ vpunpcklqdq $T1,$T0,$T0 # 0:1
+ vpunpcklqdq $T3,$T2,$T3 # 2:3
+
+ #vpsrlq \$40,$T4,$T4 # 4
+ vpsrldq \$`40/8`,$T4,$T4 # 4
+ vpsrlq \$26,$T0,$T1
+ vmovdqa 0x00(%rsp),$D4 # preload r0^2
+ vpand $MASK,$T0,$T0 # 0
+ vpsrlq \$4,$T3,$T2
+ vpand $MASK,$T1,$T1 # 1
+ vpand 0(%rcx),$T4,$T4 # .Lmask24
+ vpsrlq \$30,$T3,$T3
+ vpand $MASK,$T2,$T2 # 2
+ vpand $MASK,$T3,$T3 # 3
+ vpor 32(%rcx),$T4,$T4 # padbit, yes, always
+
+ ################################################################
+ # lazy reduction as discussed in "NEON crypto" by D.J. Bernstein
+ # and P. Schwabe
+
+ vpsrlq \$26,$H3,$D3
+ vpand $MASK,$H3,$H3
+ vpaddq $D3,$H4,$H4 # h3 -> h4
+
+ vpsrlq \$26,$H0,$D0
+ vpand $MASK,$H0,$H0
+ vpaddq $D0,$D1,$H1 # h0 -> h1
+
+ vpsrlq \$26,$H4,$D0
+ vpand $MASK,$H4,$H4
+
+ vpsrlq \$26,$H1,$D1
+ vpand $MASK,$H1,$H1
+ vpaddq $D1,$H2,$H2 # h1 -> h2
+
+ vpaddq $D0,$H0,$H0
+ vpsllq \$2,$D0,$D0
+ vpaddq $D0,$H0,$H0 # h4 -> h0
+
+ vpsrlq \$26,$H2,$D2
+ vpand $MASK,$H2,$H2
+ vpaddq $D2,$H3,$H3 # h2 -> h3
+
+ vpsrlq \$26,$H0,$D0
+ vpand $MASK,$H0,$H0
+ vpaddq $D0,$H1,$H1 # h0 -> h1
+
+ vpsrlq \$26,$H3,$D3
+ vpand $MASK,$H3,$H3
+ vpaddq $D3,$H4,$H4 # h3 -> h4
+
+ ja .Loop_avx
+
+.Lskip_loop_avx:
+ ################################################################
+ # multiply (inp[0:1]+hash) or inp[2:3] by r^2:r^1
+
+ vpshufd \$0x10,$D4,$D4 # r0^n, xx12 -> x1x2
+ add \$32,$len
+ jnz .Long_tail_avx
+
+ vpaddq $H2,$T2,$T2
+ vpaddq $H0,$T0,$T0
+ vpaddq $H1,$T1,$T1
+ vpaddq $H3,$T3,$T3
+ vpaddq $H4,$T4,$T4
+
+.Long_tail_avx:
+ vmovdqa $H2,0x20(%r11)
+ vmovdqa $H0,0x00(%r11)
+ vmovdqa $H1,0x10(%r11)
+ vmovdqa $H3,0x30(%r11)
+ vmovdqa $H4,0x40(%r11)
+
+ # d4 = h4*r0 + h3*r1 + h2*r2 + h1*r3 + h0*r4
+ # d3 = h3*r0 + h2*r1 + h1*r2 + h0*r3 + h4*5*r4
+ # d2 = h2*r0 + h1*r1 + h0*r2 + h4*5*r3 + h3*5*r4
+ # d1 = h1*r0 + h0*r1 + h4*5*r2 + h3*5*r3 + h2*5*r4
+ # d0 = h0*r0 + h4*5*r1 + h3*5*r2 + h2*5*r3 + h1*5*r4
+
+ vpmuludq $T2,$D4,$D2 # d2 = h2*r0
+ vpmuludq $T0,$D4,$D0 # d0 = h0*r0
+ vpshufd \$0x10,`16*1-64`($ctx),$H2 # r1^n
+ vpmuludq $T1,$D4,$D1 # d1 = h1*r0
+ vpmuludq $T3,$D4,$D3 # d3 = h3*r0
+ vpmuludq $T4,$D4,$D4 # d4 = h4*r0
+
+ vpmuludq $T3,$H2,$H0 # h3*r1
+ vpaddq $H0,$D4,$D4 # d4 += h3*r1
+ vpshufd \$0x10,`16*2-64`($ctx),$H3 # s1^n
+ vpmuludq $T2,$H2,$H1 # h2*r1
+ vpaddq $H1,$D3,$D3 # d3 += h2*r1
+ vpshufd \$0x10,`16*3-64`($ctx),$H4 # r2^n
+ vpmuludq $T1,$H2,$H0 # h1*r1
+ vpaddq $H0,$D2,$D2 # d2 += h1*r1
+ vpmuludq $T0,$H2,$H2 # h0*r1
+ vpaddq $H2,$D1,$D1 # d1 += h0*r1
+ vpmuludq $T4,$H3,$H3 # h4*s1
+ vpaddq $H3,$D0,$D0 # d0 += h4*s1
+
+ vpshufd \$0x10,`16*4-64`($ctx),$H2 # s2^n
+ vpmuludq $T2,$H4,$H1 # h2*r2
+ vpaddq $H1,$D4,$D4 # d4 += h2*r2
+ vpmuludq $T1,$H4,$H0 # h1*r2
+ vpaddq $H0,$D3,$D3 # d3 += h1*r2
+ vpshufd \$0x10,`16*5-64`($ctx),$H3 # r3^n
+ vpmuludq $T0,$H4,$H4 # h0*r2
+ vpaddq $H4,$D2,$D2 # d2 += h0*r2
+ vpmuludq $T4,$H2,$H1 # h4*s2
+ vpaddq $H1,$D1,$D1 # d1 += h4*s2
+ vpshufd \$0x10,`16*6-64`($ctx),$H4 # s3^n
+ vpmuludq $T3,$H2,$H2 # h3*s2
+ vpaddq $H2,$D0,$D0 # d0 += h3*s2
+
+ vpmuludq $T1,$H3,$H0 # h1*r3
+ vpaddq $H0,$D4,$D4 # d4 += h1*r3
+ vpmuludq $T0,$H3,$H3 # h0*r3
+ vpaddq $H3,$D3,$D3 # d3 += h0*r3
+ vpshufd \$0x10,`16*7-64`($ctx),$H2 # r4^n
+ vpmuludq $T4,$H4,$H1 # h4*s3
+ vpaddq $H1,$D2,$D2 # d2 += h4*s3
+ vpshufd \$0x10,`16*8-64`($ctx),$H3 # s4^n
+ vpmuludq $T3,$H4,$H0 # h3*s3
+ vpaddq $H0,$D1,$D1 # d1 += h3*s3
+ vpmuludq $T2,$H4,$H4 # h2*s3
+ vpaddq $H4,$D0,$D0 # d0 += h2*s3
+
+ vpmuludq $T0,$H2,$H2 # h0*r4
+ vpaddq $H2,$D4,$D4 # h4 = d4 + h0*r4
+ vpmuludq $T4,$H3,$H1 # h4*s4
+ vpaddq $H1,$D3,$D3 # h3 = d3 + h4*s4
+ vpmuludq $T3,$H3,$H0 # h3*s4
+ vpaddq $H0,$D2,$D2 # h2 = d2 + h3*s4
+ vpmuludq $T2,$H3,$H1 # h2*s4
+ vpaddq $H1,$D1,$D1 # h1 = d1 + h2*s4
+ vpmuludq $T1,$H3,$H3 # h1*s4
+ vpaddq $H3,$D0,$D0 # h0 = d0 + h1*s4
+
+ jz .Lshort_tail_avx
+
+ vmovdqu 16*0($inp),$H0 # load input
+ vmovdqu 16*1($inp),$H1
+
+ vpsrldq \$6,$H0,$H2 # splat input
+ vpsrldq \$6,$H1,$H3
+ vpunpckhqdq $H1,$H0,$H4 # 4
+ vpunpcklqdq $H1,$H0,$H0 # 0:1
+ vpunpcklqdq $H3,$H2,$H3 # 2:3
+
+ vpsrlq \$40,$H4,$H4 # 4
+ vpsrlq \$26,$H0,$H1
+ vpand $MASK,$H0,$H0 # 0
+ vpsrlq \$4,$H3,$H2
+ vpand $MASK,$H1,$H1 # 1
+ vpsrlq \$30,$H3,$H3
+ vpand $MASK,$H2,$H2 # 2
+ vpand $MASK,$H3,$H3 # 3
+ vpor 32(%rcx),$H4,$H4 # padbit, yes, always
+
+ vpshufd \$0x32,`16*0-64`($ctx),$T4 # r0^n, 34xx -> x3x4
+ vpaddq 0x00(%r11),$H0,$H0
+ vpaddq 0x10(%r11),$H1,$H1
+ vpaddq 0x20(%r11),$H2,$H2
+ vpaddq 0x30(%r11),$H3,$H3
+ vpaddq 0x40(%r11),$H4,$H4
+
+ ################################################################
+ # multiply (inp[0:1]+hash) by r^4:r^3 and accumulate
+
+ vpmuludq $H0,$T4,$T0 # h0*r0
+ vpaddq $T0,$D0,$D0 # d0 += h0*r0
+ vpmuludq $H1,$T4,$T1 # h1*r0
+ vpaddq $T1,$D1,$D1 # d1 += h1*r0
+ vpmuludq $H2,$T4,$T0 # h2*r0
+ vpaddq $T0,$D2,$D2 # d2 += h2*r0
+ vpshufd \$0x32,`16*1-64`($ctx),$T2 # r1^n
+ vpmuludq $H3,$T4,$T1 # h3*r0
+ vpaddq $T1,$D3,$D3 # d3 += h3*r0
+ vpmuludq $H4,$T4,$T4 # h4*r0
+ vpaddq $T4,$D4,$D4 # d4 += h4*r0
+
+ vpmuludq $H3,$T2,$T0 # h3*r1
+ vpaddq $T0,$D4,$D4 # d4 += h3*r1
+ vpshufd \$0x32,`16*2-64`($ctx),$T3 # s1
+ vpmuludq $H2,$T2,$T1 # h2*r1
+ vpaddq $T1,$D3,$D3 # d3 += h2*r1
+ vpshufd \$0x32,`16*3-64`($ctx),$T4 # r2
+ vpmuludq $H1,$T2,$T0 # h1*r1
+ vpaddq $T0,$D2,$D2 # d2 += h1*r1
+ vpmuludq $H0,$T2,$T2 # h0*r1
+ vpaddq $T2,$D1,$D1 # d1 += h0*r1
+ vpmuludq $H4,$T3,$T3 # h4*s1
+ vpaddq $T3,$D0,$D0 # d0 += h4*s1
+
+ vpshufd \$0x32,`16*4-64`($ctx),$T2 # s2
+ vpmuludq $H2,$T4,$T1 # h2*r2
+ vpaddq $T1,$D4,$D4 # d4 += h2*r2
+ vpmuludq $H1,$T4,$T0 # h1*r2
+ vpaddq $T0,$D3,$D3 # d3 += h1*r2
+ vpshufd \$0x32,`16*5-64`($ctx),$T3 # r3
+ vpmuludq $H0,$T4,$T4 # h0*r2
+ vpaddq $T4,$D2,$D2 # d2 += h0*r2
+ vpmuludq $H4,$T2,$T1 # h4*s2
+ vpaddq $T1,$D1,$D1 # d1 += h4*s2
+ vpshufd \$0x32,`16*6-64`($ctx),$T4 # s3
+ vpmuludq $H3,$T2,$T2 # h3*s2
+ vpaddq $T2,$D0,$D0 # d0 += h3*s2
+
+ vpmuludq $H1,$T3,$T0 # h1*r3
+ vpaddq $T0,$D4,$D4 # d4 += h1*r3
+ vpmuludq $H0,$T3,$T3 # h0*r3
+ vpaddq $T3,$D3,$D3 # d3 += h0*r3
+ vpshufd \$0x32,`16*7-64`($ctx),$T2 # r4
+ vpmuludq $H4,$T4,$T1 # h4*s3
+ vpaddq $T1,$D2,$D2 # d2 += h4*s3
+ vpshufd \$0x32,`16*8-64`($ctx),$T3 # s4
+ vpmuludq $H3,$T4,$T0 # h3*s3
+ vpaddq $T0,$D1,$D1 # d1 += h3*s3
+ vpmuludq $H2,$T4,$T4 # h2*s3
+ vpaddq $T4,$D0,$D0 # d0 += h2*s3
+
+ vpmuludq $H0,$T2,$T2 # h0*r4
+ vpaddq $T2,$D4,$D4 # d4 += h0*r4
+ vpmuludq $H4,$T3,$T1 # h4*s4
+ vpaddq $T1,$D3,$D3 # d3 += h4*s4
+ vpmuludq $H3,$T3,$T0 # h3*s4
+ vpaddq $T0,$D2,$D2 # d2 += h3*s4
+ vpmuludq $H2,$T3,$T1 # h2*s4
+ vpaddq $T1,$D1,$D1 # d1 += h2*s4
+ vpmuludq $H1,$T3,$T3 # h1*s4
+ vpaddq $T3,$D0,$D0 # d0 += h1*s4
+
+.Lshort_tail_avx:
+ ################################################################
+ # horizontal addition
+
+ vpsrldq \$8,$D4,$T4
+ vpsrldq \$8,$D3,$T3
+ vpsrldq \$8,$D1,$T1
+ vpsrldq \$8,$D0,$T0
+ vpsrldq \$8,$D2,$T2
+ vpaddq $T3,$D3,$D3
+ vpaddq $T4,$D4,$D4
+ vpaddq $T0,$D0,$D0
+ vpaddq $T1,$D1,$D1
+ vpaddq $T2,$D2,$D2
+
+ ################################################################
+ # lazy reduction
+
+ vpsrlq \$26,$D3,$H3
+ vpand $MASK,$D3,$D3
+ vpaddq $H3,$D4,$D4 # h3 -> h4
+
+ vpsrlq \$26,$D0,$H0
+ vpand $MASK,$D0,$D0
+ vpaddq $H0,$D1,$D1 # h0 -> h1
+
+ vpsrlq \$26,$D4,$H4
+ vpand $MASK,$D4,$D4
+
+ vpsrlq \$26,$D1,$H1
+ vpand $MASK,$D1,$D1
+ vpaddq $H1,$D2,$D2 # h1 -> h2
+
+ vpaddq $H4,$D0,$D0
+ vpsllq \$2,$H4,$H4
+ vpaddq $H4,$D0,$D0 # h4 -> h0
+
+ vpsrlq \$26,$D2,$H2
+ vpand $MASK,$D2,$D2
+ vpaddq $H2,$D3,$D3 # h2 -> h3
+
+ vpsrlq \$26,$D0,$H0
+ vpand $MASK,$D0,$D0
+ vpaddq $H0,$D1,$D1 # h0 -> h1
+
+ vpsrlq \$26,$D3,$H3
+ vpand $MASK,$D3,$D3
+ vpaddq $H3,$D4,$D4 # h3 -> h4
+
+ vmovd $D0,`4*0-48-64`($ctx) # save partially reduced
+ vmovd $D1,`4*1-48-64`($ctx)
+ vmovd $D2,`4*2-48-64`($ctx)
+ vmovd $D3,`4*3-48-64`($ctx)
+ vmovd $D4,`4*4-48-64`($ctx)
+___
+$code.=<<___ if ($win64);
+ vmovdqa 0x50(%r11),%xmm6
+ vmovdqa 0x60(%r11),%xmm7
+ vmovdqa 0x70(%r11),%xmm8
+ vmovdqa 0x80(%r11),%xmm9
+ vmovdqa 0x90(%r11),%xmm10
+ vmovdqa 0xa0(%r11),%xmm11
+ vmovdqa 0xb0(%r11),%xmm12
+ vmovdqa 0xc0(%r11),%xmm13
+ vmovdqa 0xd0(%r11),%xmm14
+ vmovdqa 0xe0(%r11),%xmm15
+ lea 0xf8(%r11),%rsp
+.Ldo_avx_epilogue:
+___
+$code.=<<___ if (!$win64);
+ lea 0x58(%r11),%rsp
+___
+$code.=<<___;
+ vzeroupper
+ ret
+.size poly1305_blocks_avx,.-poly1305_blocks_avx
+
+.type poly1305_emit_avx,\@function,3
+.align 32
+poly1305_emit_avx:
+ cmpl \$0,20($ctx) # is_base2_26?
+ je .Lemit
+
+ mov 0($ctx),%eax # load hash value base 2^26
+ mov 4($ctx),%ecx
+ mov 8($ctx),%r8d
+ mov 12($ctx),%r11d
+ mov 16($ctx),%r10d
+
+ shl \$26,%rcx # base 2^26 -> base 2^64
+ mov %r8,%r9
+ shl \$52,%r8
+ add %rcx,%rax
+ shr \$12,%r9
+ add %rax,%r8 # h0
+ adc \$0,%r9
+
+ shl \$14,%r11
+ mov %r10,%rax
+ shr \$24,%r10
+ add %r11,%r9
+ shl \$40,%rax
+ add %rax,%r9 # h1
+ adc \$0,%r10 # h2
+
+ mov %r10,%rax # could be partially reduced, so reduce
+ mov %r10,%rcx
+ and \$3,%r10
+ shr \$2,%rax
+ and \$-4,%rcx
+ add %rcx,%rax
+ add %rax,%r8
+ adc \$0,%r9
+
+ mov %r8,%rax
+ add \$5,%r8 # compare to modulus
+ mov %r9,%rcx
+ adc \$0,%r9
+ adc \$0,%r10
+ shr \$2,%r10 # did 130-bit value overfow?
+ cmovnz %r8,%rax
+ cmovnz %r9,%rcx
+
+ add 0($nonce),%rax # accumulate nonce
+ adc 8($nonce),%rcx
+ mov %rax,0($mac) # write result
+ mov %rcx,8($mac)
+
+ ret
+.size poly1305_emit_avx,.-poly1305_emit_avx
+___
+
+if ($avx>1) {
+my ($H0,$H1,$H2,$H3,$H4, $MASK, $T4,$T0,$T1,$T2,$T3, $D0,$D1,$D2,$D3,$D4) =
+ map("%ymm$_",(0..15));
+my $S4=$MASK;
+
+$code.=<<___;
+.type poly1305_blocks_avx2,\@function,4
+.align 32
+poly1305_blocks_avx2:
+ mov 20($ctx),%r8d # is_base2_26
+ cmp \$128,$len
+ jae .Lblocks_avx2
+ test %r8d,%r8d
+ jz .Lblocks
+
+.Lblocks_avx2:
+ and \$-16,$len
+ jz .Lno_data_avx2
+
+ vzeroupper
+
+ test %r8d,%r8d
+ jz .Lbase2_64_avx2
+
+ test \$63,$len
+ jz .Leven_avx2
+
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+.Lblocks_avx2_body:
+
+ mov $len,%r15 # reassign $len
+
+ mov 0($ctx),$d1 # load hash value
+ mov 8($ctx),$d2
+ mov 16($ctx),$h2#d
+
+ mov 24($ctx),$r0 # load r
+ mov 32($ctx),$s1
+
+ ################################# base 2^26 -> base 2^64
+ mov $d1#d,$h0#d
+ and \$-1<<31,$d1
+ mov $d2,$r1 # borrow $r1
+ mov $d2#d,$h1#d
+ and \$-1<<31,$d2
+
+ shr \$6,$d1
+ shl \$52,$r1
+ add $d1,$h0
+ shr \$12,$h1
+ shr \$18,$d2
+ add $r1,$h0
+ adc $d2,$h1
+
+ mov $h2,$d1
+ shl \$40,$d1
+ shr \$24,$h2
+ add $d1,$h1
+ adc \$0,$h2 # can be partially reduced...
+
+ mov \$-4,$d2 # ... so reduce
+ mov $h2,$d1
+ and $h2,$d2
+ shr \$2,$d1
+ and \$3,$h2
+ add $d2,$d1 # =*5
+ add $d1,$h0
+ adc \$0,$h1
+
+ mov $s1,$r1
+ mov $s1,%rax
+ shr \$2,$s1
+ add $r1,$s1 # s1 = r1 + (r1 >> 2)
+
+.Lbase2_26_pre_avx2:
+ add 0($inp),$h0 # accumulate input
+ adc 8($inp),$h1
+ lea 16($inp),$inp
+ adc $padbit,$h2
+ sub \$16,%r15
+
+ call __poly1305_block
+ mov $r1,%rax
+
+ test \$63,%r15
+ jnz .Lbase2_26_pre_avx2
+
+ test $padbit,$padbit # if $padbit is zero,
+ jz .Lstore_base2_64_avx2 # store hash in base 2^64 format
+
+ ################################# base 2^64 -> base 2^26
+ mov $h0,%rax
+ mov $h0,%rdx
+ shr \$52,$h0
+ mov $h1,$r0
+ mov $h1,$r1
+ shr \$26,%rdx
+ and \$0x3ffffff,%rax # h[0]
+ shl \$12,$r0
+ and \$0x3ffffff,%rdx # h[1]
+ shr \$14,$h1
+ or $r0,$h0
+ shl \$24,$h2
+ and \$0x3ffffff,$h0 # h[2]
+ shr \$40,$r1
+ and \$0x3ffffff,$h1 # h[3]
+ or $r1,$h2 # h[4]
+
+ test %r15,%r15
+ jz .Lstore_base2_26_avx2
+
+ vmovd %rax#d,%x#$H0
+ vmovd %rdx#d,%x#$H1
+ vmovd $h0#d,%x#$H2
+ vmovd $h1#d,%x#$H3
+ vmovd $h2#d,%x#$H4
+ jmp .Lproceed_avx2
+
+.align 32
+.Lstore_base2_64_avx2:
+ mov $h0,0($ctx)
+ mov $h1,8($ctx)
+ mov $h2,16($ctx) # note that is_base2_26 is zeroed
+ jmp .Ldone_avx2
+
+.align 16
+.Lstore_base2_26_avx2:
+ mov %rax#d,0($ctx) # store hash value base 2^26
+ mov %rdx#d,4($ctx)
+ mov $h0#d,8($ctx)
+ mov $h1#d,12($ctx)
+ mov $h2#d,16($ctx)
+.align 16
+.Ldone_avx2:
+ mov 0(%rsp),%r15
+ mov 8(%rsp),%r14
+ mov 16(%rsp),%r13
+ mov 24(%rsp),%r12
+ mov 32(%rsp),%rbp
+ mov 40(%rsp),%rbx
+ lea 48(%rsp),%rsp
+.Lno_data_avx2:
+.Lblocks_avx2_epilogue:
+ ret
+
+.align 32
+.Lbase2_64_avx2:
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+.Lbase2_64_avx2_body:
+
+ mov $len,%r15 # reassign $len
+
+ mov 24($ctx),$r0 # load r
+ mov 32($ctx),$s1
+
+ mov 0($ctx),$h0 # load hash value
+ mov 8($ctx),$h1
+ mov 16($ctx),$h2#d
+
+ mov $s1,$r1
+ mov $s1,%rax
+ shr \$2,$s1
+ add $r1,$s1 # s1 = r1 + (r1 >> 2)
+
+ test \$63,$len
+ jz .Linit_avx2
+
+.Lbase2_64_pre_avx2:
+ add 0($inp),$h0 # accumulate input
+ adc 8($inp),$h1
+ lea 16($inp),$inp
+ adc $padbit,$h2
+ sub \$16,%r15
+
+ call __poly1305_block
+ mov $r1,%rax
+
+ test \$63,%r15
+ jnz .Lbase2_64_pre_avx2
+
+.Linit_avx2:
+ ################################# base 2^64 -> base 2^26
+ mov $h0,%rax
+ mov $h0,%rdx
+ shr \$52,$h0
+ mov $h1,$d1
+ mov $h1,$d2
+ shr \$26,%rdx
+ and \$0x3ffffff,%rax # h[0]
+ shl \$12,$d1
+ and \$0x3ffffff,%rdx # h[1]
+ shr \$14,$h1
+ or $d1,$h0
+ shl \$24,$h2
+ and \$0x3ffffff,$h0 # h[2]
+ shr \$40,$d2
+ and \$0x3ffffff,$h1 # h[3]
+ or $d2,$h2 # h[4]
+
+ vmovd %rax#d,%x#$H0
+ vmovd %rdx#d,%x#$H1
+ vmovd $h0#d,%x#$H2
+ vmovd $h1#d,%x#$H3
+ vmovd $h2#d,%x#$H4
+ movl \$1,20($ctx) # set is_base2_26
+
+ call __poly1305_init_avx
+
+.Lproceed_avx2:
+ mov %r15,$len
+
+ mov 0(%rsp),%r15
+ mov 8(%rsp),%r14
+ mov 16(%rsp),%r13
+ mov 24(%rsp),%r12
+ mov 32(%rsp),%rbp
+ mov 40(%rsp),%rbx
+ lea 48(%rsp),%rax
+ lea 48(%rsp),%rsp
+.Lbase2_64_avx2_epilogue:
+ jmp .Ldo_avx2
+
+.align 32
+.Leven_avx2:
+ vmovd 4*0($ctx),%x#$H0 # load hash value base 2^26
+ vmovd 4*1($ctx),%x#$H1
+ vmovd 4*2($ctx),%x#$H2
+ vmovd 4*3($ctx),%x#$H3
+ vmovd 4*4($ctx),%x#$H4
+
+.Ldo_avx2:
+___
+$code.=<<___ if (!$win64);
+ lea -8(%rsp),%r11
+ sub \$0x128,%rsp
+___
+$code.=<<___ if ($win64);
+ lea -0xf8(%rsp),%r11
+ sub \$0x1c8,%rsp
+ vmovdqa %xmm6,0x50(%r11)
+ vmovdqa %xmm7,0x60(%r11)
+ vmovdqa %xmm8,0x70(%r11)
+ vmovdqa %xmm9,0x80(%r11)
+ vmovdqa %xmm10,0x90(%r11)
+ vmovdqa %xmm11,0xa0(%r11)
+ vmovdqa %xmm12,0xb0(%r11)
+ vmovdqa %xmm13,0xc0(%r11)
+ vmovdqa %xmm14,0xd0(%r11)
+ vmovdqa %xmm15,0xe0(%r11)
+.Ldo_avx2_body:
+___
+$code.=<<___;
+ lea 48+64($ctx),$ctx # size optimization
+ lea .Lconst(%rip),%rcx
+
+ # expand and copy pre-calculated table to stack
+ vmovdqu `16*0-64`($ctx),%x#$T2
+ and \$-512,%rsp
+ vmovdqu `16*1-64`($ctx),%x#$T3
+ vmovdqu `16*2-64`($ctx),%x#$T4
+ vmovdqu `16*3-64`($ctx),%x#$D0
+ vmovdqu `16*4-64`($ctx),%x#$D1
+ vmovdqu `16*5-64`($ctx),%x#$D2
+ vmovdqu `16*6-64`($ctx),%x#$D3
+ vpermq \$0x15,$T2,$T2 # 00003412 -> 12343434
+ vmovdqu `16*7-64`($ctx),%x#$D4
+ vpermq \$0x15,$T3,$T3
+ vpshufd \$0xc8,$T2,$T2 # 12343434 -> 14243444
+ vmovdqu `16*8-64`($ctx),%x#$MASK
+ vpermq \$0x15,$T4,$T4
+ vpshufd \$0xc8,$T3,$T3
+ vmovdqa $T2,0x00(%rsp)
+ vpermq \$0x15,$D0,$D0
+ vpshufd \$0xc8,$T4,$T4
+ vmovdqa $T3,0x20(%rsp)
+ vpermq \$0x15,$D1,$D1
+ vpshufd \$0xc8,$D0,$D0
+ vmovdqa $T4,0x40(%rsp)
+ vpermq \$0x15,$D2,$D2
+ vpshufd \$0xc8,$D1,$D1
+ vmovdqa $D0,0x60(%rsp)
+ vpermq \$0x15,$D3,$D3
+ vpshufd \$0xc8,$D2,$D2
+ vmovdqa $D1,0x80(%rsp)
+ vpermq \$0x15,$D4,$D4
+ vpshufd \$0xc8,$D3,$D3
+ vmovdqa $D2,0xa0(%rsp)
+ vpermq \$0x15,$MASK,$MASK
+ vpshufd \$0xc8,$D4,$D4
+ vmovdqa $D3,0xc0(%rsp)
+ vpshufd \$0xc8,$MASK,$MASK
+ vmovdqa $D4,0xe0(%rsp)
+ vmovdqa $MASK,0x100(%rsp)
+ vmovdqa 64(%rcx),$MASK # .Lmask26
+
+ ################################################################
+ # load input
+ vmovdqu 16*0($inp),%x#$T0
+ vmovdqu 16*1($inp),%x#$T1
+ vinserti128 \$1,16*2($inp),$T0,$T0
+ vinserti128 \$1,16*3($inp),$T1,$T1
+ lea 16*4($inp),$inp
+
+ vpsrldq \$6,$T0,$T2 # splat input
+ vpsrldq \$6,$T1,$T3
+ vpunpckhqdq $T1,$T0,$T4 # 4
+ vpunpcklqdq $T3,$T2,$T2 # 2:3
+ vpunpcklqdq $T1,$T0,$T0 # 0:1
+
+ vpsrlq \$30,$T2,$T3
+ vpsrlq \$4,$T2,$T2
+ vpsrlq \$26,$T0,$T1
+ vpsrlq \$40,$T4,$T4 # 4
+ vpand $MASK,$T2,$T2 # 2
+ vpand $MASK,$T0,$T0 # 0
+ vpand $MASK,$T1,$T1 # 1
+ vpand $MASK,$T3,$T3 # 3
+ vpor 32(%rcx),$T4,$T4 # padbit, yes, always
+
+ lea 0x90(%rsp),%rax # size optimization
+ vpaddq $H2,$T2,$H2 # accumulate input
+ sub \$64,$len
+ jz .Ltail_avx2
+ jmp .Loop_avx2
+
+.align 32
+.Loop_avx2:
+ ################################################################
+ # ((inp[0]*r^4+r[4])*r^4+r[8])*r^4
+ # ((inp[1]*r^4+r[5])*r^4+r[9])*r^3
+ # ((inp[2]*r^4+r[6])*r^4+r[10])*r^2
+ # ((inp[3]*r^4+r[7])*r^4+r[11])*r^1
+ # \________/\________/
+ ################################################################
+ #vpaddq $H2,$T2,$H2 # accumulate input
+ vpaddq $H0,$T0,$H0
+ vmovdqa `32*0`(%rsp),$T0 # r0^4
+ vpaddq $H1,$T1,$H1
+ vmovdqa `32*1`(%rsp),$T1 # r1^4
+ vpaddq $H3,$T3,$H3
+ vmovdqa `32*3`(%rsp),$T2 # r2^4
+ vpaddq $H4,$T4,$H4
+ vmovdqa `32*6-0x90`(%rax),$T3 # s3^4
+ vmovdqa `32*8-0x90`(%rax),$S4 # s4^4
+
+ # d4 = h4*r0 + h3*r1 + h2*r2 + h1*r3 + h0*r4
+ # d3 = h3*r0 + h2*r1 + h1*r2 + h0*r3 + h4*5*r4
+ # d2 = h2*r0 + h1*r1 + h0*r2 + h4*5*r3 + h3*5*r4
+ # d1 = h1*r0 + h0*r1 + h4*5*r2 + h3*5*r3 + h2*5*r4
+ # d0 = h0*r0 + h4*5*r1 + h3*5*r2 + h2*5*r3 + h1*5*r4
+ #
+ # however, as h2 is "chronologically" first one available pull
+ # corresponding operations up, so it's
+ #
+ # d4 = h2*r2 + h4*r0 + h3*r1 + h1*r3 + h0*r4
+ # d3 = h2*r1 + h3*r0 + h1*r2 + h0*r3 + h4*5*r4
+ # d2 = h2*r0 + h1*r1 + h0*r2 + h4*5*r3 + h3*5*r4
+ # d1 = h2*5*r4 + h1*r0 + h0*r1 + h4*5*r2 + h3*5*r3
+ # d0 = h2*5*r3 + h0*r0 + h4*5*r1 + h3*5*r2 + h1*5*r4
+
+ vpmuludq $H2,$T0,$D2 # d2 = h2*r0
+ vpmuludq $H2,$T1,$D3 # d3 = h2*r1
+ vpmuludq $H2,$T2,$D4 # d4 = h2*r2
+ vpmuludq $H2,$T3,$D0 # d0 = h2*s3
+ vpmuludq $H2,$S4,$D1 # d1 = h2*s4
+
+ vpmuludq $H0,$T1,$T4 # h0*r1
+ vpmuludq $H1,$T1,$H2 # h1*r1, borrow $H2 as temp
+ vpaddq $T4,$D1,$D1 # d1 += h0*r1
+ vpaddq $H2,$D2,$D2 # d2 += h1*r1
+ vpmuludq $H3,$T1,$T4 # h3*r1
+ vpmuludq `32*2`(%rsp),$H4,$H2 # h4*s1
+ vpaddq $T4,$D4,$D4 # d4 += h3*r1
+ vpaddq $H2,$D0,$D0 # d0 += h4*s1
+ vmovdqa `32*4-0x90`(%rax),$T1 # s2
+
+ vpmuludq $H0,$T0,$T4 # h0*r0
+ vpmuludq $H1,$T0,$H2 # h1*r0
+ vpaddq $T4,$D0,$D0 # d0 += h0*r0
+ vpaddq $H2,$D1,$D1 # d1 += h1*r0
+ vpmuludq $H3,$T0,$T4 # h3*r0
+ vpmuludq $H4,$T0,$H2 # h4*r0
+ vmovdqu 16*0($inp),%x#$T0 # load input
+ vpaddq $T4,$D3,$D3 # d3 += h3*r0
+ vpaddq $H2,$D4,$D4 # d4 += h4*r0
+ vinserti128 \$1,16*2($inp),$T0,$T0
+
+ vpmuludq $H3,$T1,$T4 # h3*s2
+ vpmuludq $H4,$T1,$H2 # h4*s2
+ vmovdqu 16*1($inp),%x#$T1
+ vpaddq $T4,$D0,$D0 # d0 += h3*s2
+ vpaddq $H2,$D1,$D1 # d1 += h4*s2
+ vmovdqa `32*5-0x90`(%rax),$H2 # r3
+ vpmuludq $H1,$T2,$T4 # h1*r2
+ vpmuludq $H0,$T2,$T2 # h0*r2
+ vpaddq $T4,$D3,$D3 # d3 += h1*r2
+ vpaddq $T2,$D2,$D2 # d2 += h0*r2
+ vinserti128 \$1,16*3($inp),$T1,$T1
+ lea 16*4($inp),$inp
+
+ vpmuludq $H1,$H2,$T4 # h1*r3
+ vpmuludq $H0,$H2,$H2 # h0*r3
+ vpsrldq \$6,$T0,$T2 # splat input
+ vpaddq $T4,$D4,$D4 # d4 += h1*r3
+ vpaddq $H2,$D3,$D3 # d3 += h0*r3
+ vpmuludq $H3,$T3,$T4 # h3*s3
+ vpmuludq $H4,$T3,$H2 # h4*s3
+ vpsrldq \$6,$T1,$T3
+ vpaddq $T4,$D1,$D1 # d1 += h3*s3
+ vpaddq $H2,$D2,$D2 # d2 += h4*s3
+ vpunpckhqdq $T1,$T0,$T4 # 4
+
+ vpmuludq $H3,$S4,$H3 # h3*s4
+ vpmuludq $H4,$S4,$H4 # h4*s4
+ vpunpcklqdq $T1,$T0,$T0 # 0:1
+ vpaddq $H3,$D2,$H2 # h2 = d2 + h3*r4
+ vpaddq $H4,$D3,$H3 # h3 = d3 + h4*r4
+ vpunpcklqdq $T3,$T2,$T3 # 2:3
+ vpmuludq `32*7-0x90`(%rax),$H0,$H4 # h0*r4
+ vpmuludq $H1,$S4,$H0 # h1*s4
+ vmovdqa 64(%rcx),$MASK # .Lmask26
+ vpaddq $H4,$D4,$H4 # h4 = d4 + h0*r4
+ vpaddq $H0,$D0,$H0 # h0 = d0 + h1*s4
+
+ ################################################################
+ # lazy reduction (interleaved with tail of input splat)
+
+ vpsrlq \$26,$H3,$D3
+ vpand $MASK,$H3,$H3
+ vpaddq $D3,$H4,$H4 # h3 -> h4
+
+ vpsrlq \$26,$H0,$D0
+ vpand $MASK,$H0,$H0
+ vpaddq $D0,$D1,$H1 # h0 -> h1
+
+ vpsrlq \$26,$H4,$D4
+ vpand $MASK,$H4,$H4
+
+ vpsrlq \$4,$T3,$T2
+
+ vpsrlq \$26,$H1,$D1
+ vpand $MASK,$H1,$H1
+ vpaddq $D1,$H2,$H2 # h1 -> h2
+
+ vpaddq $D4,$H0,$H0
+ vpsllq \$2,$D4,$D4
+ vpaddq $D4,$H0,$H0 # h4 -> h0
+
+ vpand $MASK,$T2,$T2 # 2
+ vpsrlq \$26,$T0,$T1
+
+ vpsrlq \$26,$H2,$D2
+ vpand $MASK,$H2,$H2
+ vpaddq $D2,$H3,$H3 # h2 -> h3
+
+ vpaddq $T2,$H2,$H2 # modulo-scheduled
+ vpsrlq \$30,$T3,$T3
+
+ vpsrlq \$26,$H0,$D0
+ vpand $MASK,$H0,$H0
+ vpaddq $D0,$H1,$H1 # h0 -> h1
+
+ vpsrlq \$40,$T4,$T4 # 4
+
+ vpsrlq \$26,$H3,$D3
+ vpand $MASK,$H3,$H3
+ vpaddq $D3,$H4,$H4 # h3 -> h4
+
+ vpand $MASK,$T0,$T0 # 0
+ vpand $MASK,$T1,$T1 # 1
+ vpand $MASK,$T3,$T3 # 3
+ vpor 32(%rcx),$T4,$T4 # padbit, yes, always
+
+ sub \$64,$len
+ jnz .Loop_avx2
+
+ .byte 0x66,0x90
+.Ltail_avx2:
+ ################################################################
+ # while above multiplications were by r^4 in all lanes, in last
+ # iteration we multiply least significant lane by r^4 and most
+ # significant one by r, so copy of above except that references
+ # to the precomputed table are displaced by 4...
+
+ #vpaddq $H2,$T2,$H2 # accumulate input
+ vpaddq $H0,$T0,$H0
+ vmovdqu `32*0+4`(%rsp),$T0 # r0^4
+ vpaddq $H1,$T1,$H1
+ vmovdqu `32*1+4`(%rsp),$T1 # r1^4
+ vpaddq $H3,$T3,$H3
+ vmovdqu `32*3+4`(%rsp),$T2 # r2^4
+ vpaddq $H4,$T4,$H4
+ vmovdqu `32*6+4-0x90`(%rax),$T3 # s3^4
+ vmovdqu `32*8+4-0x90`(%rax),$S4 # s4^4
+
+ vpmuludq $H2,$T0,$D2 # d2 = h2*r0
+ vpmuludq $H2,$T1,$D3 # d3 = h2*r1
+ vpmuludq $H2,$T2,$D4 # d4 = h2*r2
+ vpmuludq $H2,$T3,$D0 # d0 = h2*s3
+ vpmuludq $H2,$S4,$D1 # d1 = h2*s4
+
+ vpmuludq $H0,$T1,$T4 # h0*r1
+ vpmuludq $H1,$T1,$H2 # h1*r1
+ vpaddq $T4,$D1,$D1 # d1 += h0*r1
+ vpaddq $H2,$D2,$D2 # d2 += h1*r1
+ vpmuludq $H3,$T1,$T4 # h3*r1
+ vpmuludq `32*2+4`(%rsp),$H4,$H2 # h4*s1
+ vpaddq $T4,$D4,$D4 # d4 += h3*r1
+ vpaddq $H2,$D0,$D0 # d0 += h4*s1
+
+ vpmuludq $H0,$T0,$T4 # h0*r0
+ vpmuludq $H1,$T0,$H2 # h1*r0
+ vpaddq $T4,$D0,$D0 # d0 += h0*r0
+ vmovdqu `32*4+4-0x90`(%rax),$T1 # s2
+ vpaddq $H2,$D1,$D1 # d1 += h1*r0
+ vpmuludq $H3,$T0,$T4 # h3*r0
+ vpmuludq $H4,$T0,$H2 # h4*r0
+ vpaddq $T4,$D3,$D3 # d3 += h3*r0
+ vpaddq $H2,$D4,$D4 # d4 += h4*r0
+
+ vpmuludq $H3,$T1,$T4 # h3*s2
+ vpmuludq $H4,$T1,$H2 # h4*s2
+ vpaddq $T4,$D0,$D0 # d0 += h3*s2
+ vpaddq $H2,$D1,$D1 # d1 += h4*s2
+ vmovdqu `32*5+4-0x90`(%rax),$H2 # r3
+ vpmuludq $H1,$T2,$T4 # h1*r2
+ vpmuludq $H0,$T2,$T2 # h0*r2
+ vpaddq $T4,$D3,$D3 # d3 += h1*r2
+ vpaddq $T2,$D2,$D2 # d2 += h0*r2
+
+ vpmuludq $H1,$H2,$T4 # h1*r3
+ vpmuludq $H0,$H2,$H2 # h0*r3
+ vpaddq $T4,$D4,$D4 # d4 += h1*r3
+ vpaddq $H2,$D3,$D3 # d3 += h0*r3
+ vpmuludq $H3,$T3,$T4 # h3*s3
+ vpmuludq $H4,$T3,$H2 # h4*s3
+ vpaddq $T4,$D1,$D1 # d1 += h3*s3
+ vpaddq $H2,$D2,$D2 # d2 += h4*s3
+
+ vpmuludq $H3,$S4,$H3 # h3*s4
+ vpmuludq $H4,$S4,$H4 # h4*s4
+ vpaddq $H3,$D2,$H2 # h2 = d2 + h3*r4
+ vpaddq $H4,$D3,$H3 # h3 = d3 + h4*r4
+ vpmuludq `32*7+4-0x90`(%rax),$H0,$H4 # h0*r4
+ vpmuludq $H1,$S4,$H0 # h1*s4
+ vmovdqa 64(%rcx),$MASK # .Lmask26
+ vpaddq $H4,$D4,$H4 # h4 = d4 + h0*r4
+ vpaddq $H0,$D0,$H0 # h0 = d0 + h1*s4
+
+ ################################################################
+ # horizontal addition
+
+ vpsrldq \$8,$D1,$T1
+ vpsrldq \$8,$H2,$T2
+ vpsrldq \$8,$H3,$T3
+ vpsrldq \$8,$H4,$T4
+ vpsrldq \$8,$H0,$T0
+ vpaddq $T1,$D1,$D1
+ vpaddq $T2,$H2,$H2
+ vpaddq $T3,$H3,$H3
+ vpaddq $T4,$H4,$H4
+ vpaddq $T0,$H0,$H0
+
+ vpermq \$0x2,$H3,$T3
+ vpermq \$0x2,$H4,$T4
+ vpermq \$0x2,$H0,$T0
+ vpermq \$0x2,$D1,$T1
+ vpermq \$0x2,$H2,$T2
+ vpaddq $T3,$H3,$H3
+ vpaddq $T4,$H4,$H4
+ vpaddq $T0,$H0,$H0
+ vpaddq $T1,$D1,$D1
+ vpaddq $T2,$H2,$H2
+
+ ################################################################
+ # lazy reduction
+
+ vpsrlq \$26,$H3,$D3
+ vpand $MASK,$H3,$H3
+ vpaddq $D3,$H4,$H4 # h3 -> h4
+
+ vpsrlq \$26,$H0,$D0
+ vpand $MASK,$H0,$H0
+ vpaddq $D0,$D1,$H1 # h0 -> h1
+
+ vpsrlq \$26,$H4,$D4
+ vpand $MASK,$H4,$H4
+
+ vpsrlq \$26,$H1,$D1
+ vpand $MASK,$H1,$H1
+ vpaddq $D1,$H2,$H2 # h1 -> h2
+
+ vpaddq $D4,$H0,$H0
+ vpsllq \$2,$D4,$D4
+ vpaddq $D4,$H0,$H0 # h4 -> h0
+
+ vpsrlq \$26,$H2,$D2
+ vpand $MASK,$H2,$H2
+ vpaddq $D2,$H3,$H3 # h2 -> h3
+
+ vpsrlq \$26,$H0,$D0
+ vpand $MASK,$H0,$H0
+ vpaddq $D0,$H1,$H1 # h0 -> h1
+
+ vpsrlq \$26,$H3,$D3
+ vpand $MASK,$H3,$H3
+ vpaddq $D3,$H4,$H4 # h3 -> h4
+
+ vmovd %x#$H0,`4*0-48-64`($ctx)# save partially reduced
+ vmovd %x#$H1,`4*1-48-64`($ctx)
+ vmovd %x#$H2,`4*2-48-64`($ctx)
+ vmovd %x#$H3,`4*3-48-64`($ctx)
+ vmovd %x#$H4,`4*4-48-64`($ctx)
+___
+$code.=<<___ if ($win64);
+ vmovdqa 0x50(%r11),%xmm6
+ vmovdqa 0x60(%r11),%xmm7
+ vmovdqa 0x70(%r11),%xmm8
+ vmovdqa 0x80(%r11),%xmm9
+ vmovdqa 0x90(%r11),%xmm10
+ vmovdqa 0xa0(%r11),%xmm11
+ vmovdqa 0xb0(%r11),%xmm12
+ vmovdqa 0xc0(%r11),%xmm13
+ vmovdqa 0xd0(%r11),%xmm14
+ vmovdqa 0xe0(%r11),%xmm15
+ lea 0xf8(%r11),%rsp
+.Ldo_avx2_epilogue:
+___
+$code.=<<___ if (!$win64);
+ lea 8(%r11),%rsp
+___
+$code.=<<___;
+ vzeroupper
+ ret
+.size poly1305_blocks_avx2,.-poly1305_blocks_avx2
+___
+}
+$code.=<<___;
+.align 64
+.Lconst:
+.Lmask24:
+.long 0x0ffffff,0,0x0ffffff,0,0x0ffffff,0,0x0ffffff,0
+.L129:
+.long 1<<24,0,1<<24,0,1<<24,0,1<<24,0
+.Lmask26:
+.long 0x3ffffff,0,0x3ffffff,0,0x3ffffff,0,0x3ffffff,0
+.Lfive:
+.long 5,0,5,0,5,0,5,0
+___
+}
+
+$code.=<<___;
+.asciz "Poly1305 for x86_64, CRYPTOGAMS by <appro\@openssl.org>"
+.align 16
+___
+
+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
+# CONTEXT *context,DISPATCHER_CONTEXT *disp)
+if ($win64) {
+$rec="%rcx";
+$frame="%rdx";
+$context="%r8";
+$disp="%r9";
+
+$code.=<<___;
+.extern __imp_RtlVirtualUnwind
+.type se_handler,\@abi-omnipotent
+.align 16
+se_handler:
+ push %rsi
+ push %rdi
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+ pushfq
+ sub \$64,%rsp
+
+ mov 120($context),%rax # pull context->Rax
+ mov 248($context),%rbx # pull context->Rip
+
+ mov 8($disp),%rsi # disp->ImageBase
+ mov 56($disp),%r11 # disp->HandlerData
+
+ mov 0(%r11),%r10d # HandlerData[0]
+ lea (%rsi,%r10),%r10 # prologue label
+ cmp %r10,%rbx # context->Rip<.Lprologue
+ jb .Lcommon_seh_tail
+
+ mov 152($context),%rax # pull context->Rsp
+
+ mov 4(%r11),%r10d # HandlerData[1]
+ lea (%rsi,%r10),%r10 # epilogue label
+ cmp %r10,%rbx # context->Rip>=.Lepilogue
+ jae .Lcommon_seh_tail
+
+ lea 48(%rax),%rax
+
+ mov -8(%rax),%rbx
+ mov -16(%rax),%rbp
+ mov -24(%rax),%r12
+ mov -32(%rax),%r13
+ mov -40(%rax),%r14
+ mov -48(%rax),%r15
+ mov %rbx,144($context) # restore context->Rbx
+ mov %rbp,160($context) # restore context->Rbp
+ mov %r12,216($context) # restore context->R12
+ mov %r13,224($context) # restore context->R13
+ mov %r14,232($context) # restore context->R14
+ mov %r15,240($context) # restore context->R14
+
+ jmp .Lcommon_seh_tail
+.size se_handler,.-se_handler
+
+.type avx_handler,\@abi-omnipotent
+.align 16
+avx_handler:
+ push %rsi
+ push %rdi
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+ pushfq
+ sub \$64,%rsp
+
+ mov 120($context),%rax # pull context->Rax
+ mov 248($context),%rbx # pull context->Rip
+
+ mov 8($disp),%rsi # disp->ImageBase
+ mov 56($disp),%r11 # disp->HandlerData
+
+ mov 0(%r11),%r10d # HandlerData[0]
+ lea (%rsi,%r10),%r10 # prologue label
+ cmp %r10,%rbx # context->Rip<prologue label
+ jb .Lcommon_seh_tail
+
+ mov 152($context),%rax # pull context->Rsp
+
+ mov 4(%r11),%r10d # HandlerData[1]
+ lea (%rsi,%r10),%r10 # epilogue label
+ cmp %r10,%rbx # context->Rip>=epilogue label
+ jae .Lcommon_seh_tail
+
+ mov 208($context),%rax # pull context->R11
+
+ lea 0x50(%rax),%rsi
+ lea 0xf8(%rax),%rax
+ lea 512($context),%rdi # &context.Xmm6
+ mov \$20,%ecx
+ .long 0xa548f3fc # cld; rep movsq
+
+.Lcommon_seh_tail:
+ mov 8(%rax),%rdi
+ mov 16(%rax),%rsi
+ mov %rax,152($context) # restore context->Rsp
+ mov %rsi,168($context) # restore context->Rsi
+ mov %rdi,176($context) # restore context->Rdi
+
+ mov 40($disp),%rdi # disp->ContextRecord
+ mov $context,%rsi # context
+ mov \$154,%ecx # sizeof(CONTEXT)
+ .long 0xa548f3fc # cld; rep movsq
+
+ mov $disp,%rsi
+ xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER
+ mov 8(%rsi),%rdx # arg2, disp->ImageBase
+ mov 0(%rsi),%r8 # arg3, disp->ControlPc
+ mov 16(%rsi),%r9 # arg4, disp->FunctionEntry
+ mov 40(%rsi),%r10 # disp->ContextRecord
+ lea 56(%rsi),%r11 # &disp->HandlerData
+ lea 24(%rsi),%r12 # &disp->EstablisherFrame
+ mov %r10,32(%rsp) # arg5
+ mov %r11,40(%rsp) # arg6
+ mov %r12,48(%rsp) # arg7
+ mov %rcx,56(%rsp) # arg8, (NULL)
+ call *__imp_RtlVirtualUnwind(%rip)
+
+ mov \$1,%eax # ExceptionContinueSearch
+ add \$64,%rsp
+ popfq
+ pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ pop %rdi
+ pop %rsi
+ ret
+.size avx_handler,.-avx_handler
+
+.section .pdata
+.align 4
+ .rva .LSEH_begin_poly1305_init
+ .rva .LSEH_end_poly1305_init
+ .rva .LSEH_info_poly1305_init
+
+ .rva .LSEH_begin_poly1305_blocks
+ .rva .LSEH_end_poly1305_blocks
+ .rva .LSEH_info_poly1305_blocks
+
+ .rva .LSEH_begin_poly1305_emit
+ .rva .LSEH_end_poly1305_emit
+ .rva .LSEH_info_poly1305_emit
+___
+$code.=<<___ if ($avx);
+ .rva .LSEH_begin_poly1305_blocks_avx
+ .rva .Lbase2_64_avx
+ .rva .LSEH_info_poly1305_blocks_avx_1
+
+ .rva .Lbase2_64_avx
+ .rva .Leven_avx
+ .rva .LSEH_info_poly1305_blocks_avx_2
+
+ .rva .Leven_avx
+ .rva .LSEH_end_poly1305_blocks_avx
+ .rva .LSEH_info_poly1305_blocks_avx_3
+
+ .rva .LSEH_begin_poly1305_emit_avx
+ .rva .LSEH_end_poly1305_emit_avx
+ .rva .LSEH_info_poly1305_emit_avx
+___
+$code.=<<___ if ($avx>1);
+ .rva .LSEH_begin_poly1305_blocks_avx2
+ .rva .Lbase2_64_avx2
+ .rva .LSEH_info_poly1305_blocks_avx2_1
+
+ .rva .Lbase2_64_avx2
+ .rva .Leven_avx2
+ .rva .LSEH_info_poly1305_blocks_avx2_2
+
+ .rva .Leven_avx2
+ .rva .LSEH_end_poly1305_blocks_avx2
+ .rva .LSEH_info_poly1305_blocks_avx2_3
+___
+$code.=<<___;
+.section .xdata
+.align 8
+.LSEH_info_poly1305_init:
+ .byte 9,0,0,0
+ .rva se_handler
+ .rva .LSEH_begin_poly1305_init,.LSEH_begin_poly1305_init
+
+.LSEH_info_poly1305_blocks:
+ .byte 9,0,0,0
+ .rva se_handler
+ .rva .Lblocks_body,.Lblocks_epilogue
+
+.LSEH_info_poly1305_emit:
+ .byte 9,0,0,0
+ .rva se_handler
+ .rva .LSEH_begin_poly1305_emit,.LSEH_begin_poly1305_emit
+___
+$code.=<<___ if ($avx);
+.LSEH_info_poly1305_blocks_avx_1:
+ .byte 9,0,0,0
+ .rva se_handler
+ .rva .Lblocks_avx_body,.Lblocks_avx_epilogue # HandlerData[]
+
+.LSEH_info_poly1305_blocks_avx_2:
+ .byte 9,0,0,0
+ .rva se_handler
+ .rva .Lbase2_64_avx_body,.Lbase2_64_avx_epilogue # HandlerData[]
+
+.LSEH_info_poly1305_blocks_avx_3:
+ .byte 9,0,0,0
+ .rva avx_handler
+ .rva .Ldo_avx_body,.Ldo_avx_epilogue # HandlerData[]
+
+.LSEH_info_poly1305_emit_avx:
+ .byte 9,0,0,0
+ .rva se_handler
+ .rva .LSEH_begin_poly1305_emit_avx,.LSEH_begin_poly1305_emit_avx
+___
+$code.=<<___ if ($avx>1);
+.LSEH_info_poly1305_blocks_avx2_1:
+ .byte 9,0,0,0
+ .rva se_handler
+ .rva .Lblocks_avx2_body,.Lblocks_avx2_epilogue # HandlerData[]
+
+.LSEH_info_poly1305_blocks_avx2_2:
+ .byte 9,0,0,0
+ .rva se_handler
+ .rva .Lbase2_64_avx2_body,.Lbase2_64_avx2_epilogue # HandlerData[]
+
+.LSEH_info_poly1305_blocks_avx2_3:
+ .byte 9,0,0,0
+ .rva avx_handler
+ .rva .Ldo_avx2_body,.Ldo_avx2_epilogue # HandlerData[]
+___
+}
+
+foreach (split('\n',$code)) {
+ s/\`([^\`]*)\`/eval($1)/ge;
+ s/%r([a-z]+)#d/%e$1/g;
+ s/%r([0-9]+)#d/%r$1d/g;
+ s/%x#%y/%x/g;
+
+ print $_,"\n";
+}
+close STDOUT;
diff --git a/src/crypto/poly1305/internal.h b/src/crypto/poly1305/internal.h
new file mode 100644
index 00000000..df6769ea
--- /dev/null
+++ b/src/crypto/poly1305/internal.h
@@ -0,0 +1,40 @@
+/* Copyright (c) 2016, 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_POLY1305_INTERNAL_H
+#define OPENSSL_HEADER_POLY1305_INTERNAL_H
+
+#include <openssl/base.h>
+#include <openssl/poly1305.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+#if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM)
+void CRYPTO_poly1305_init_neon(poly1305_state *state, const uint8_t key[32]);
+
+void CRYPTO_poly1305_update_neon(poly1305_state *state, const uint8_t *in,
+ size_t in_len);
+
+void CRYPTO_poly1305_finish_neon(poly1305_state *state, uint8_t mac[16]);
+#endif
+
+
+#if defined(__cplusplus)
+} /* extern C */
+#endif
+
+#endif /* OPENSSL_HEADER_POLY1305_INTERNAL_H */
diff --git a/src/crypto/poly1305/poly1305.c b/src/crypto/poly1305/poly1305.c
index 5a49e2df..dc2d6a68 100644
--- a/src/crypto/poly1305/poly1305.c
+++ b/src/crypto/poly1305/poly1305.c
@@ -22,6 +22,8 @@
#include <openssl/cpu.h>
+#include "internal.h"
+
#if defined(OPENSSL_WINDOWS) || !defined(OPENSSL_X86_64)
@@ -48,15 +50,6 @@ static void U32TO8_LE(uint8_t *m, uint32_t v) {
}
#endif
-#if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM)
-void CRYPTO_poly1305_init_neon(poly1305_state *state, const uint8_t key[32]);
-
-void CRYPTO_poly1305_update_neon(poly1305_state *state, const uint8_t *in,
- size_t in_len);
-
-void CRYPTO_poly1305_finish_neon(poly1305_state *state, uint8_t mac[16]);
-#endif
-
static uint64_t mul32x32_64(uint32_t a, uint32_t b) { return (uint64_t)a * b; }
struct poly1305_state_st {
@@ -170,7 +163,7 @@ void CRYPTO_poly1305_init(poly1305_state *statep, const uint8_t key[32]) {
uint32_t t0, t1, t2, t3;
#if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM)
- if (CRYPTO_is_NEON_functional()) {
+ if (CRYPTO_is_NEON_capable()) {
CRYPTO_poly1305_init_neon(statep, key);
return;
}
@@ -217,7 +210,7 @@ void CRYPTO_poly1305_update(poly1305_state *statep, const uint8_t *in,
struct poly1305_state_st *state = (struct poly1305_state_st *)statep;
#if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM)
- if (CRYPTO_is_NEON_functional()) {
+ if (CRYPTO_is_NEON_capable()) {
CRYPTO_poly1305_update_neon(statep, in, in_len);
return;
}
@@ -263,7 +256,7 @@ void CRYPTO_poly1305_finish(poly1305_state *statep, uint8_t mac[16]) {
uint32_t b, nb;
#if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM)
- if (CRYPTO_is_NEON_functional()) {
+ if (CRYPTO_is_NEON_capable()) {
CRYPTO_poly1305_finish_neon(statep, mac);
return;
}
diff --git a/src/crypto/poly1305/poly1305_arm.c b/src/crypto/poly1305/poly1305_arm.c
index 5e78dc06..de31d6b2 100644
--- a/src/crypto/poly1305/poly1305_arm.c
+++ b/src/crypto/poly1305/poly1305_arm.c
@@ -21,6 +21,9 @@
#include <string.h>
+#include "../internal.h"
+#include "internal.h"
+
typedef struct {
uint32_t v[12]; /* for alignment; only using 10 */
@@ -170,7 +173,7 @@ static void fe1305x2_frombytearray(fe1305x2 *r, const uint8_t *x,
}
}
-static const fe1305x2 zero __attribute__((aligned(16)));
+static const alignas(16) fe1305x2 zero;
struct poly1305_state_st {
uint8_t data[sizeof(fe1305x2[5]) + 128];
diff --git a/src/crypto/poly1305/poly1305_test.cc b/src/crypto/poly1305/poly1305_test.cc
index 3a726683..2c25e93b 100644
--- a/src/crypto/poly1305/poly1305_test.cc
+++ b/src/crypto/poly1305/poly1305_test.cc
@@ -20,16 +20,57 @@
#include <openssl/crypto.h>
#include <openssl/poly1305.h>
+#include "../internal.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 TestSIMD(FileTest *t, unsigned excess,
+ const std::vector<uint8_t> &key,
+ const std::vector<uint8_t> &in,
+ const std::vector<uint8_t> &mac) {
+ poly1305_state state;
+ CRYPTO_poly1305_init(&state, key.data());
+
+ size_t done = 0;
+
+ // Feed 16 bytes in. Some implementations begin in non-SIMD mode and upgrade
+ // on-demand. Stress the upgrade path.
+ size_t todo = 16;
+ if (todo > in.size()) {
+ todo = in.size();
+ }
+ CRYPTO_poly1305_update(&state, in.data(), todo);
+ done += todo;
+
+ for (;;) {
+ // Feed 128 + |excess| bytes to test SIMD mode.
+ if (done + 128 + excess > in.size()) {
+ break;
+ }
+ CRYPTO_poly1305_update(&state, in.data() + done, 128 + excess);
+ done += 128 + excess;
+
+ // Feed |excess| bytes to ensure SIMD mode can handle short inputs.
+ if (done + excess > in.size()) {
+ break;
+ }
+ CRYPTO_poly1305_update(&state, in.data() + done, excess);
+ done += excess;
+ }
+
+ // Consume the remainder and finish.
+ CRYPTO_poly1305_update(&state, in.data() + done, in.size() - done);
+
+ // |CRYPTO_poly1305_finish| requires a 16-byte-aligned output.
+ alignas(16) uint8_t out[16];
+ CRYPTO_poly1305_finish(&state, out);
+ if (!t->ExpectBytesEqual(mac.data(), mac.size(), out, 16)) {
+ t->PrintLine("SIMD pattern %u failed.", excess);
+ return false;
+ }
+
+ return true;
+}
static bool TestPoly1305(FileTest *t, void *arg) {
std::vector<uint8_t> key, in, mac;
@@ -47,7 +88,8 @@ static bool TestPoly1305(FileTest *t, void *arg) {
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| requires a 16-byte-aligned output.
+ alignas(16) uint8_t out[16];
CRYPTO_poly1305_finish(&state, out);
if (!t->ExpectBytesEqual(out, 16, mac.data(), mac.size())) {
t->PrintLine("Single-shot Poly1305 failed.");
@@ -60,11 +102,20 @@ static bool TestPoly1305(FileTest *t, void *arg) {
CRYPTO_poly1305_update(&state, &in[i], 1);
}
CRYPTO_poly1305_finish(&state, out);
- if (!t->ExpectBytesEqual(out, 16, mac.data(), mac.size())) {
+ if (!t->ExpectBytesEqual(mac.data(), mac.size(), out, 16)) {
t->PrintLine("Streaming Poly1305 failed.");
return false;
}
+ // Test SIMD stress patterns. OpenSSL's AVX2 assembly needs a multiple of
+ // four blocks, so test up to three blocks of excess.
+ if (!TestSIMD(t, 0, key, in, mac) ||
+ !TestSIMD(t, 16, key, in, mac) ||
+ !TestSIMD(t, 32, key, in, mac) ||
+ !TestSIMD(t, 48, key, in, mac)) {
+ return false;
+ }
+
return true;
}
diff --git a/src/crypto/poly1305/poly1305_test.txt b/src/crypto/poly1305/poly1305_test.txt
index ad40699e..611007a0 100644
--- a/src/crypto/poly1305/poly1305_test.txt
+++ b/src/crypto/poly1305/poly1305_test.txt
@@ -50,3 +50,110 @@ MAC = 14000000000000005500000000000000
Key = 0100000000000000040000000000000000000000000000000000000000000000
Input = e33594d7505e43b900000000000000003394d7505e4379cd010000000000000000000000000000000000000000000000
MAC = 13000000000000000000000000000000
+
+
+# Additional test vectors that are long enough to ensure OpenSSL's SIMD
+# assembly is fully tested.
+
+# Length 2048.
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfed
+MAC = 69d28f73dd09d39a92aa179da354b7ea
+
+# Length 2049.
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc8
+MAC = d6a26654b88572e875d9661c83471c1b
+
+# Length 2050.
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852
+MAC = 9fbbb7f7adcd0cd5b46a4a520b22499a
+
+# Length 2051.
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852f5
+MAC = eb7cdceb97ade2a07622f8f5a4b1ce15
+
+# Length 2052.
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852f590
+MAC = d41c310927cd92e14784ea78b85503db
+
+# Length 2053.
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852f59073
+MAC = 16af133c423f783a14c49d9f526384cf
+
+# Length 2054.
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852f59073f4
+MAC = 00c75db8f0636b22f195645b03091f5f
+
+# Length 2055.
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852f59073f434
+MAC = 4a532bc740f581555831345f3b75bf33
+
+# Length 2056.
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852f59073f4347a
+MAC = 698c7d32c5923871d124a2479e521706
+
+# Length 2057.
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852f59073f4347a8c
+MAC = a677187dbf3c927aeeafb9ebce0f61dc
+
+# Length 2058.
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852f59073f4347a8c8a
+MAC = 201fed7eee981b31d2cc42ff6c38141a
+
+# Length 2059.
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852f59073f4347a8c8a28
+MAC = 0c3d3d01a37f347c4f7c5826bcafb3e1
+
+# Length 2060.
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852f59073f4347a8c8a28c9
+MAC = 33a4e0e0bed7c84c5cc5dd4784410f07
+
+# Length 2061.
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852f59073f4347a8c8a28c99e
+MAC = 8e41c40a2f8ec58fe594f3a3a2de4ae1
+
+# Length 2062.
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852f59073f4347a8c8a28c99e21
+MAC = c6e5d1810fd878ac6b844c66cef36a22
+
+# Length 2063.
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852f59073f4347a8c8a28c99e21df
+MAC = f6eaae369c3cb5c05748e8d919178e00
+
+# Regression test for https://rt.openssl.org/Ticket/Display.html?id=4439
+Key = 2d773be37adb1e4d683bf0075e79c4ee037918535a7f99ccb7040fb5f5f43aea
+Input = 89dab80b7717c1db5db437860a3f70218e93e1b8f461fb677f16f35f6f87e2a91c99bc3a47ace47640cc95c345be5ecca5a3523c35cc01893af0b64a620334270372ec12482d1b1e363561698a578b359803495bb4e2ef1930b17a5190b580f141300df30adbeca28f6427a8bc1a999fd51c554a017d095d8c3e3127daf9f595
+MAC = c85d15ed44c378d6b00e23064c7bcd51
+
+# Regression tests for https://rt.openssl.org/Ticket/Display.html?id=4483
+
+Key = 7f1b02640000000000000000000000000000000000000000cccccccccccccccc
+Input = cccccccccccccccccccccccccccccccccccccccccccccccccc80ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccceccccccccccccccccccccccccccccccccccccc5cccccccccccccccccccccccccccccccccccccccccce3ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccaccccccccccccccccccccce6cccccccccc000000afccccccccccccccccccfffffff5000000000000000000000000000000000000000000000000000000ffffffe70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000719205a8521dfc
+MAC = 8559b876eceed66eb37798c0457baff9
+
+Key = e00016000000000000000000000000000000aaaaaaaaaaaaaaaaaaaaaaaaaaaa
+Input = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa000000000000000000800264
+MAC = 00bd1258978e205444c9aaaa82006fed
+
+Key = 0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c
+Input = 02fc
+MAC = 06120c0c0c0c0c0c0c0c0c0c0c0c0c0c
+
+Key = 00ff000000000000000000000000000000000000001e00000000000000007b7b
+Input = 7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7a7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b5c7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b6e7b007b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7a7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b5c7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b6e7b001300000000b300000000000000000000000000000000000000000000f20000000000000000000000000000000000002000efff0009000000000000000000000000100000000009000000640000000000000000000000001300000000b300000000000000000000000000000000000000000000f20000000000000000000000000000000000002000efff00090000000000000000007a000010000000000900000064000000000000000000000000000000000000000000000000fc
+MAC = 33205bbf9e9f8f7212ab9e2ab9b7e4a5
diff --git a/src/crypto/poly1305/poly1305_vec.c b/src/crypto/poly1305/poly1305_vec.c
index 07578d08..3045a2f1 100644
--- a/src/crypto/poly1305/poly1305_vec.c
+++ b/src/crypto/poly1305/poly1305_vec.c
@@ -20,42 +20,40 @@
#include <openssl/poly1305.h>
+#include "../internal.h"
+
#if !defined(OPENSSL_WINDOWS) && defined(OPENSSL_X86_64)
#include <emmintrin.h>
-#define ALIGN(x) __attribute__((aligned(x)))
-/* inline is not a keyword in C89. */
-#define INLINE
-#define U8TO64_LE(m) (*(uint64_t *)(m))
-#define U8TO32_LE(m) (*(uint32_t *)(m))
+#define U8TO64_LE(m) (*(const uint64_t *)(m))
+#define U8TO32_LE(m) (*(const uint32_t *)(m))
#define U64TO8_LE(m, v) (*(uint64_t *)(m)) = v
typedef __m128i xmmi;
-typedef unsigned __int128 uint128_t;
-static const uint32_t ALIGN(16) poly1305_x64_sse2_message_mask[4] = {
+static const alignas(16) uint32_t poly1305_x64_sse2_message_mask[4] = {
(1 << 26) - 1, 0, (1 << 26) - 1, 0};
-static const uint32_t ALIGN(16) poly1305_x64_sse2_5[4] = {5, 0, 5, 0};
-static const uint32_t ALIGN(16) poly1305_x64_sse2_1shl128[4] = {(1 << 24), 0,
- (1 << 24), 0};
+static const alignas(16) uint32_t poly1305_x64_sse2_5[4] = {5, 0, 5, 0};
+static const alignas(16) uint32_t poly1305_x64_sse2_1shl128[4] = {
+ (1 << 24), 0, (1 << 24), 0};
-static uint128_t INLINE add128(uint128_t a, uint128_t b) { return a + b; }
+static inline uint128_t add128(uint128_t a, uint128_t b) { return a + b; }
-static uint128_t INLINE add128_64(uint128_t a, uint64_t b) { return a + b; }
+static inline uint128_t add128_64(uint128_t a, uint64_t b) { return a + b; }
-static uint128_t INLINE mul64x64_128(uint64_t a, uint64_t b) {
+static inline uint128_t mul64x64_128(uint64_t a, uint64_t b) {
return (uint128_t)a * b;
}
-static uint64_t INLINE lo128(uint128_t a) { return (uint64_t)a; }
+static inline uint64_t lo128(uint128_t a) { return (uint64_t)a; }
-static uint64_t INLINE shr128(uint128_t v, const int shift) {
+static inline uint64_t shr128(uint128_t v, const int shift) {
return (uint64_t)(v >> shift);
}
-static uint64_t INLINE shr128_pair(uint64_t hi, uint64_t lo, const int shift) {
+static inline uint64_t shr128_pair(uint64_t hi, uint64_t lo, const int shift) {
return (uint64_t)((((uint128_t)hi << 64) | lo) >> shift);
}
@@ -82,32 +80,32 @@ typedef struct poly1305_state_internal_t {
} poly1305_state_internal; /* 448 bytes total + 63 bytes for
alignment = 511 bytes raw */
-static poly1305_state_internal INLINE *poly1305_aligned_state(
+static inline poly1305_state_internal *poly1305_aligned_state(
poly1305_state *state) {
return (poly1305_state_internal *)(((uint64_t)state + 63) & ~63);
}
/* copy 0-63 bytes */
-static void INLINE
+static inline void
poly1305_block_copy(uint8_t *dst, const uint8_t *src, size_t bytes) {
size_t offset = src - dst;
if (bytes & 32) {
_mm_storeu_si128((xmmi *)(dst + 0),
- _mm_loadu_si128((xmmi *)(dst + offset + 0)));
+ _mm_loadu_si128((const xmmi *)(dst + offset + 0)));
_mm_storeu_si128((xmmi *)(dst + 16),
- _mm_loadu_si128((xmmi *)(dst + offset + 16)));
+ _mm_loadu_si128((const xmmi *)(dst + offset + 16)));
dst += 32;
}
if (bytes & 16) {
- _mm_storeu_si128((xmmi *)dst, _mm_loadu_si128((xmmi *)(dst + offset)));
+ _mm_storeu_si128((xmmi *)dst, _mm_loadu_si128((const xmmi *)(dst + offset)));
dst += 16;
}
if (bytes & 8) {
- *(uint64_t *)dst = *(uint64_t *)(dst + offset);
+ *(uint64_t *)dst = *(const uint64_t *)(dst + offset);
dst += 8;
}
if (bytes & 4) {
- *(uint32_t *)dst = *(uint32_t *)(dst + offset);
+ *(uint32_t *)dst = *(const uint32_t *)(dst + offset);
dst += 4;
}
if (bytes & 2) {
@@ -120,7 +118,7 @@ poly1305_block_copy(uint8_t *dst, const uint8_t *src, size_t bytes) {
}
/* zero 0-15 bytes */
-static void INLINE poly1305_block_zero(uint8_t *dst, size_t bytes) {
+static inline void poly1305_block_zero(uint8_t *dst, size_t bytes) {
if (bytes & 8) {
*(uint64_t *)dst = 0;
dst += 8;
@@ -138,7 +136,7 @@ static void INLINE poly1305_block_zero(uint8_t *dst, size_t bytes) {
}
}
-static size_t INLINE poly1305_min(size_t a, size_t b) {
+static inline size_t poly1305_min(size_t a, size_t b) {
return (a < b) ? a : b;
}
@@ -186,9 +184,9 @@ void CRYPTO_poly1305_init(poly1305_state *state, const uint8_t key[32]) {
static void poly1305_first_block(poly1305_state_internal *st,
const uint8_t *m) {
- const xmmi MMASK = _mm_load_si128((xmmi *)poly1305_x64_sse2_message_mask);
- const xmmi FIVE = _mm_load_si128((xmmi *)poly1305_x64_sse2_5);
- const xmmi HIBIT = _mm_load_si128((xmmi *)poly1305_x64_sse2_1shl128);
+ const xmmi MMASK = _mm_load_si128((const xmmi *)poly1305_x64_sse2_message_mask);
+ const xmmi FIVE = _mm_load_si128((const xmmi *)poly1305_x64_sse2_5);
+ const xmmi HIBIT = _mm_load_si128((const xmmi *)poly1305_x64_sse2_1shl128);
xmmi T5, T6;
poly1305_power *p;
uint128_t d[3];
@@ -265,10 +263,10 @@ static void poly1305_first_block(poly1305_state_internal *st,
p->R24.d[3] = (uint32_t)(pad1 >> 32);
/* H = [Mx,My] */
- T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 0)),
- _mm_loadl_epi64((xmmi *)(m + 16)));
- T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 8)),
- _mm_loadl_epi64((xmmi *)(m + 24)));
+ T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 0)),
+ _mm_loadl_epi64((const xmmi *)(m + 16)));
+ T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 8)),
+ _mm_loadl_epi64((const xmmi *)(m + 24)));
st->H[0] = _mm_and_si128(MMASK, T5);
st->H[1] = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26));
T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12));
@@ -279,9 +277,9 @@ static void poly1305_first_block(poly1305_state_internal *st,
static void poly1305_blocks(poly1305_state_internal *st, const uint8_t *m,
size_t bytes) {
- const xmmi MMASK = _mm_load_si128((xmmi *)poly1305_x64_sse2_message_mask);
- const xmmi FIVE = _mm_load_si128((xmmi *)poly1305_x64_sse2_5);
- const xmmi HIBIT = _mm_load_si128((xmmi *)poly1305_x64_sse2_1shl128);
+ const xmmi MMASK = _mm_load_si128((const xmmi *)poly1305_x64_sse2_message_mask);
+ const xmmi FIVE = _mm_load_si128((const xmmi *)poly1305_x64_sse2_5);
+ const xmmi HIBIT = _mm_load_si128((const xmmi *)poly1305_x64_sse2_1shl128);
poly1305_power *p;
xmmi H0, H1, H2, H3, H4;
@@ -345,10 +343,10 @@ static void poly1305_blocks(poly1305_state_internal *st, const uint8_t *m,
T4 = _mm_add_epi64(T4, T5);
/* H += [Mx,My]*[r^2,r^2] */
- T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 0)),
- _mm_loadl_epi64((xmmi *)(m + 16)));
- T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 8)),
- _mm_loadl_epi64((xmmi *)(m + 24)));
+ T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 0)),
+ _mm_loadl_epi64((const xmmi *)(m + 16)));
+ T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 8)),
+ _mm_loadl_epi64((const xmmi *)(m + 24)));
M0 = _mm_and_si128(MMASK, T5);
M1 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26));
T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12));
@@ -409,10 +407,10 @@ static void poly1305_blocks(poly1305_state_internal *st, const uint8_t *m,
T4 = _mm_add_epi64(T4, T5);
/* H += [Mx,My] */
- T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 32)),
- _mm_loadl_epi64((xmmi *)(m + 48)));
- T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 40)),
- _mm_loadl_epi64((xmmi *)(m + 56)));
+ T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 32)),
+ _mm_loadl_epi64((const xmmi *)(m + 48)));
+ T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 40)),
+ _mm_loadl_epi64((const xmmi *)(m + 56)));
M0 = _mm_and_si128(MMASK, T5);
M1 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26));
T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12));
@@ -469,9 +467,9 @@ static void poly1305_blocks(poly1305_state_internal *st, const uint8_t *m,
static size_t poly1305_combine(poly1305_state_internal *st, const uint8_t *m,
size_t bytes) {
- const xmmi MMASK = _mm_load_si128((xmmi *)poly1305_x64_sse2_message_mask);
- const xmmi HIBIT = _mm_load_si128((xmmi *)poly1305_x64_sse2_1shl128);
- const xmmi FIVE = _mm_load_si128((xmmi *)poly1305_x64_sse2_5);
+ const xmmi MMASK = _mm_load_si128((const xmmi *)poly1305_x64_sse2_message_mask);
+ const xmmi HIBIT = _mm_load_si128((const xmmi *)poly1305_x64_sse2_1shl128);
+ const xmmi FIVE = _mm_load_si128((const xmmi *)poly1305_x64_sse2_5);
poly1305_power *p;
xmmi H0, H1, H2, H3, H4;
@@ -542,10 +540,10 @@ static size_t poly1305_combine(poly1305_state_internal *st, const uint8_t *m,
T4 = _mm_add_epi64(T4, T5);
/* H += [Mx,My] */
- T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 0)),
- _mm_loadl_epi64((xmmi *)(m + 16)));
- T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 8)),
- _mm_loadl_epi64((xmmi *)(m + 24)));
+ T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 0)),
+ _mm_loadl_epi64((const xmmi *)(m + 16)));
+ T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 8)),
+ _mm_loadl_epi64((const xmmi *)(m + 24)));
M0 = _mm_and_si128(MMASK, T5);
M1 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26));
T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12));
@@ -703,9 +701,9 @@ static size_t poly1305_combine(poly1305_state_internal *st, const uint8_t *m,
t0 &= 0x3ffffff;
t1 = t1 + c;
- st->HH[0] = ((t0) | (t1 << 26)) & 0xfffffffffffull;
- st->HH[1] = ((t1 >> 18) | (t2 << 8) | (t3 << 34)) & 0xfffffffffffull;
- st->HH[2] = ((t3 >> 10) | (t4 << 16)) & 0x3ffffffffffull;
+ st->HH[0] = ((t0) | (t1 << 26)) & UINT64_C(0xfffffffffff);
+ st->HH[1] = ((t1 >> 18) | (t2 << 8) | (t3 << 34)) & UINT64_C(0xfffffffffff);
+ st->HH[2] = ((t3 >> 10) | (t4 << 16)) & UINT64_C(0x3ffffffffff);
return consumed;
}
diff --git a/src/crypto/rand/CMakeLists.txt b/src/crypto/rand/CMakeLists.txt
index eedf81b8..c66d2eeb 100644
--- a/src/crypto/rand/CMakeLists.txt
+++ b/src/crypto/rand/CMakeLists.txt
@@ -13,6 +13,7 @@ add_library(
OBJECT
+ deterministic.c
rand.c
urandom.c
windows.c
diff --git a/src/crypto/rand/deterministic.c b/src/crypto/rand/deterministic.c
new file mode 100644
index 00000000..e6b7bb7e
--- /dev/null
+++ b/src/crypto/rand/deterministic.c
@@ -0,0 +1,49 @@
+/* Copyright (c) 2016, 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/rand.h>
+
+#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
+
+#include <string.h>
+
+#include <openssl/chacha.h>
+
+#include "internal.h"
+
+
+/* g_num_calls is the number of calls to |CRYPTO_sysrand| that have occured.
+ *
+ * TODO(davidben): This is intentionally not thread-safe. If the fuzzer mode is
+ * ever used in a multi-threaded program, replace this with a thread-local. (A
+ * mutex would not be deterministic.) */
+static uint64_t g_num_calls = 0;
+
+void RAND_cleanup(void) {}
+
+void RAND_reset_for_fuzzing(void) { g_num_calls = 0; }
+
+void CRYPTO_sysrand(uint8_t *out, size_t requested) {
+ static const uint8_t kZeroKey[32];
+
+ uint8_t nonce[12];
+ memset(nonce, 0, sizeof(nonce));
+ memcpy(nonce, &g_num_calls, sizeof(g_num_calls));
+
+ memset(out, 0, requested);
+ CRYPTO_chacha_20(out, out, requested, kZeroKey, nonce, 0);
+ g_num_calls++;
+}
+
+#endif /* BORINGSSL_UNSAFE_FUZZER_MODE */
diff --git a/src/crypto/rand/rand.c b/src/crypto/rand/rand.c
index 892b4ba8..5a1bec2e 100644
--- a/src/crypto/rand/rand.c
+++ b/src/crypto/rand/rand.c
@@ -72,7 +72,8 @@ static void rand_thread_state_free(void *state) {
OPENSSL_free(state);
}
-#if defined(OPENSSL_X86_64) && !defined(OPENSSL_NO_ASM)
+#if defined(OPENSSL_X86_64) && !defined(OPENSSL_NO_ASM) && \
+ !defined(BORINGSSL_UNSAFE_FUZZER_MODE)
/* These functions are defined in asm/rdrand-x86_64.pl */
extern int CRYPTO_rdrand(uint8_t out[8]);
@@ -209,6 +210,8 @@ int RAND_load_file(const char *path, long num) {
}
}
+const char *RAND_file_name(char *buf, size_t num) { return NULL; }
+
void RAND_add(const void *buf, int num, double entropy) {}
int RAND_egd(const char *path) {
diff --git a/src/crypto/rand/urandom.c b/src/crypto/rand/urandom.c
index 5bf5c739..a519983c 100644
--- a/src/crypto/rand/urandom.c
+++ b/src/crypto/rand/urandom.c
@@ -14,7 +14,7 @@
#include <openssl/rand.h>
-#if !defined(OPENSSL_WINDOWS)
+#if !defined(OPENSSL_WINDOWS) && !defined(BORINGSSL_UNSAFE_FUZZER_MODE)
#include <assert.h>
#include <errno.h>
@@ -220,4 +220,4 @@ void CRYPTO_sysrand(uint8_t *out, size_t requested) {
}
}
-#endif /* !OPENSSL_WINDOWS */
+#endif /* !OPENSSL_WINDOWS && !BORINGSSL_UNSAFE_FUZZER_MODE */
diff --git a/src/crypto/rand/windows.c b/src/crypto/rand/windows.c
index 1a0cb8b0..9d7dd782 100644
--- a/src/crypto/rand/windows.c
+++ b/src/crypto/rand/windows.c
@@ -14,7 +14,7 @@
#include <openssl/rand.h>
-#if defined(OPENSSL_WINDOWS)
+#if defined(OPENSSL_WINDOWS) && !defined(BORINGSSL_UNSAFE_FUZZER_MODE)
#include <limits.h>
#include <stdlib.h>
@@ -53,4 +53,4 @@ void CRYPTO_sysrand(uint8_t *out, size_t requested) {
return;
}
-#endif /* OPENSSL_WINDOWS */
+#endif /* OPENSSL_WINDOWS && !BORINGSSL_UNSAFE_FUZZER_MODE */
diff --git a/src/crypto/rc4/asm/rc4-586.pl b/src/crypto/rc4/asm/rc4-586.pl
index fc860ae2..8d3ccb72 100644
--- a/src/crypto/rc4/asm/rc4-586.pl
+++ b/src/crypto/rc4/asm/rc4-586.pl
@@ -384,31 +384,5 @@ $idx="edx";
&mov (&DWP(-4,$out),"eax"); # key->y=0;
&function_end("asm_RC4_set_key");
-# const char *RC4_options(void);
-&function_begin_B("RC4_options");
- &call (&label("pic_point"));
-&set_label("pic_point");
- &blindpop("eax");
- &lea ("eax",&DWP(&label("opts")."-".&label("pic_point"),"eax"));
- &picmeup("edx","OPENSSL_ia32cap_P");
- &mov ("edx",&DWP(0,"edx"));
- &bt ("edx",20);
- &jc (&label("1xchar"));
- &bt ("edx",26);
- &jnc (&label("ret"));
- &add ("eax",25);
- &ret ();
-&set_label("1xchar");
- &add ("eax",12);
-&set_label("ret");
- &ret ();
-&set_label("opts",64);
-&asciz ("rc4(4x,int)");
-&asciz ("rc4(1x,char)");
-&asciz ("rc4(8x,mmx)");
-&asciz ("RC4 for x86, CRYPTOGAMS by <appro\@openssl.org>");
-&align (64);
-&function_end_B("RC4_options");
-
&asm_finish();
diff --git a/src/crypto/rsa/blinding.c b/src/crypto/rsa/blinding.c
index d21633f8..d9d90c2b 100644
--- a/src/crypto/rsa/blinding.c
+++ b/src/crypto/rsa/blinding.c
@@ -113,7 +113,6 @@
#include <openssl/bn.h>
#include <openssl/mem.h>
#include <openssl/err.h>
-#include <openssl/thread.h>
#include "internal.h"
@@ -121,54 +120,35 @@
#define BN_BLINDING_COUNTER 32
struct bn_blinding_st {
- BIGNUM *A;
- BIGNUM *Ai;
- BIGNUM *e;
- BIGNUM *mod; /* just a reference */
- int counter;
- unsigned long flags;
- /* 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, const BN_MONT_CTX *mont);
+ BIGNUM *A; /* The base blinding factor, Montgomery-encoded. */
+ BIGNUM *Ai; /* The inverse of the blinding factor, Montgomery-encoded. */
+ unsigned counter;
};
-BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod) {
- BN_BLINDING *ret = NULL;
+static int bn_blinding_create_param(BN_BLINDING *b, const BIGNUM *e,
+ const BN_MONT_CTX *mont, BN_CTX *ctx);
- ret = (BN_BLINDING*) OPENSSL_malloc(sizeof(BN_BLINDING));
+BN_BLINDING *BN_BLINDING_new(void) {
+ BN_BLINDING *ret = OPENSSL_malloc(sizeof(BN_BLINDING));
if (ret == NULL) {
OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
return NULL;
}
memset(ret, 0, sizeof(BN_BLINDING));
- if (A != NULL) {
- ret->A = BN_dup(A);
- if (ret->A == NULL) {
- goto err;
- }
- }
- if (Ai != NULL) {
- ret->Ai = BN_dup(Ai);
- if (ret->Ai == NULL) {
- goto err;
- }
- }
- /* save a copy of mod in the BN_BLINDING structure */
- ret->mod = BN_dup(mod);
- if (ret->mod == NULL) {
+ ret->A = BN_new();
+ if (ret->A == NULL) {
goto err;
}
- if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0) {
- BN_set_flags(ret->mod, BN_FLG_CONSTTIME);
+
+ ret->Ai = BN_new();
+ if (ret->Ai == NULL) {
+ goto err;
}
- /* Set the counter to the special value -1
- * to indicate that this is never-used fresh blinding
- * that does not need updating before first use. */
- ret->counter = -1;
+ /* The blinding values need to be created before this blinding can be used. */
+ ret->counter = BN_BLINDING_COUNTER - 1;
+
return ret;
err:
@@ -183,280 +163,105 @@ void BN_BLINDING_free(BN_BLINDING *r) {
BN_free(r->A);
BN_free(r->Ai);
- BN_free(r->e);
- BN_free(r->mod);
OPENSSL_free(r);
}
-int BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx) {
- int ret = 0;
-
- if (b->A == NULL || b->Ai == NULL) {
- OPENSSL_PUT_ERROR(RSA, RSA_R_BN_NOT_INITIALIZED);
- goto err;
- }
-
- if (b->counter == -1) {
- b->counter = 0;
- }
-
- if (++b->counter == BN_BLINDING_COUNTER && b->e != NULL &&
- !(b->flags & BN_BLINDING_NO_RECREATE)) {
+static int bn_blinding_update(BN_BLINDING *b, const BIGNUM *e,
+ const BN_MONT_CTX *mont, BN_CTX *ctx) {
+ if (++b->counter == BN_BLINDING_COUNTER) {
/* re-create blinding parameters */
- if (!BN_BLINDING_create_param(b, NULL, NULL, ctx, NULL, NULL)) {
+ if (!bn_blinding_create_param(b, e, mont, ctx)) {
goto err;
}
- } else if (!(b->flags & BN_BLINDING_NO_UPDATE)) {
- if (!BN_mod_mul(b->A, b->A, b->A, b->mod, ctx)) {
- goto err;
- }
- if (!BN_mod_mul(b->Ai, b->Ai, b->Ai, b->mod, ctx)) {
+ b->counter = 0;
+ } else {
+ if (!BN_mod_mul_montgomery(b->A, b->A, b->A, mont, ctx) ||
+ !BN_mod_mul_montgomery(b->Ai, b->Ai, b->Ai, mont, ctx)) {
goto err;
}
}
- ret = 1;
+ return 1;
err:
- if (b->counter == BN_BLINDING_COUNTER) {
- b->counter = 0;
- }
- return ret;
-}
+ /* |A| and |Ai| may be in an inconsistent state so they both need to be
+ * replaced the next time this blinding is used. Note that this is only
+ * sufficient because support for |BN_BLINDING_NO_UPDATE| and
+ * |BN_BLINDING_NO_RECREATE| was previously dropped. */
+ b->counter = BN_BLINDING_COUNTER - 1;
-int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx) {
- return BN_BLINDING_convert_ex(n, NULL, b, ctx);
+ return 0;
}
-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, RSA_R_BN_NOT_INITIALIZED);
+int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, const BIGNUM *e,
+ const BN_MONT_CTX *mont, BN_CTX *ctx) {
+ /* |n| is not Montgomery-encoded and |b->A| is. |BN_mod_mul_montgomery|
+ * cancels one Montgomery factor, so the resulting value of |n| is unencoded.
+ */
+ if (!bn_blinding_update(b, e, mont, ctx) ||
+ !BN_mod_mul_montgomery(n, n, b->A, mont, ctx)) {
return 0;
}
- if (b->counter == -1) {
- /* Fresh blinding, doesn't need updating. */
- b->counter = 0;
- } else if (!BN_BLINDING_update(b, ctx)) {
- return 0;
- }
-
- if (r != NULL) {
- if (!BN_copy(r, b->Ai)) {
- ret = 0;
- }
- }
-
- if (!BN_mod_mul(n, n, b->A, b->mod, ctx)) {
- ret = 0;
- }
-
- return ret;
+ return 1;
}
-int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx) {
- return BN_BLINDING_invert_ex(n, NULL, b, ctx);
+int BN_BLINDING_invert(BIGNUM *n, const BN_BLINDING *b, BN_MONT_CTX *mont,
+ BN_CTX *ctx) {
+ /* |n| is not Montgomery-encoded and |b->A| is. |BN_mod_mul_montgomery|
+ * cancels one Montgomery factor, so the resulting value of |n| is unencoded.
+ */
+ return BN_mod_mul_montgomery(n, n, b->Ai, mont, ctx);
}
-int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b,
- BN_CTX *ctx) {
- int ret;
+static int bn_blinding_create_param(BN_BLINDING *b, const BIGNUM *e,
+ const BN_MONT_CTX *mont, BN_CTX *ctx) {
+ BIGNUM mont_N_consttime;
+ BN_init(&mont_N_consttime);
+ BN_with_flags(&mont_N_consttime, &mont->N, BN_FLG_CONSTTIME);
+ int retry_counter = 32;
- if (r != NULL) {
- ret = BN_mod_mul(n, n, r, b->mod, ctx);
- } else {
- if (b->Ai == NULL) {
- OPENSSL_PUT_ERROR(RSA, RSA_R_BN_NOT_INITIALIZED);
+ do {
+ if (!BN_rand_range(b->A, &mont->N)) {
+ OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
return 0;
}
- ret = BN_mod_mul(n, n, b->Ai, b->mod, ctx);
- }
-
- return ret;
-}
-
-unsigned long BN_BLINDING_get_flags(const BN_BLINDING *b) { return b->flags; }
-
-void BN_BLINDING_set_flags(BN_BLINDING *b, unsigned long flags) {
- b->flags = 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, const BN_MONT_CTX *mont),
- const BN_MONT_CTX *mont) {
- int retry_counter = 32;
- BN_BLINDING *ret = NULL;
-
- if (b == NULL) {
- ret = BN_BLINDING_new(NULL, NULL, m);
- } else {
- ret = b;
- }
-
- if (ret == NULL) {
- goto err;
- }
-
- if (ret->A == NULL && (ret->A = BN_new()) == NULL) {
- goto err;
- }
- if (ret->Ai == NULL && (ret->Ai = BN_new()) == NULL) {
- goto err;
- }
-
- if (e != NULL) {
- BN_free(ret->e);
- ret->e = BN_dup(e);
- }
- if (ret->e == NULL) {
- goto err;
- }
-
- if (bn_mod_exp != NULL) {
- ret->bn_mod_exp = bn_mod_exp;
- }
- if (mont != NULL) {
- ret->mont = mont;
- }
- do {
- if (!BN_rand_range(ret->A, ret->mod)) {
- goto err;
+ /* |BN_from_montgomery| + |BN_mod_inverse_no_branch| is equivalent to, but
+ * more efficient than, |BN_mod_inverse_no_branch| + |BN_to_montgomery|. */
+ if (!BN_from_montgomery(b->Ai, b->A, mont, ctx)) {
+ OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
+ return 0;
}
int no_inverse;
- if (BN_mod_inverse_ex(ret->Ai, &no_inverse, ret->A, ret->mod, ctx) == NULL) {
+ if (BN_mod_inverse_ex(b->Ai, &no_inverse, b->Ai, &mont_N_consttime, ctx) ==
+ NULL) {
/* this should almost never happen for good RSA keys */
if (no_inverse) {
if (retry_counter-- == 0) {
OPENSSL_PUT_ERROR(RSA, RSA_R_TOO_MANY_ITERATIONS);
- goto err;
+ return 0;
}
ERR_clear_error();
} else {
- goto err;
+ OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
+ return 0;
}
} else {
break;
}
} while (1);
- 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 {
- if (!BN_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx)) {
- goto err;
- }
- }
-
- return ret;
-
-err:
- if (b == NULL) {
- BN_BLINDING_free(ret);
- ret = NULL;
- }
-
- return ret;
-}
-
-static BIGNUM *rsa_get_public_exp(const BIGNUM *d, const BIGNUM *p,
- const BIGNUM *q, BN_CTX *ctx) {
- BIGNUM *ret = NULL, *r0, *r1, *r2;
-
- if (d == NULL || p == NULL || q == NULL) {
- return NULL;
- }
-
- BN_CTX_start(ctx);
- r0 = BN_CTX_get(ctx);
- r1 = BN_CTX_get(ctx);
- r2 = BN_CTX_get(ctx);
- if (r2 == NULL) {
- goto err;
- }
-
- if (!BN_sub(r1, p, BN_value_one())) {
- goto err;
- }
- if (!BN_sub(r2, q, BN_value_one())) {
- goto err;
- }
- if (!BN_mul(r0, r1, r2, ctx)) {
- goto err;
- }
-
- ret = BN_mod_inverse(NULL, d, r0, ctx);
-
-err:
- BN_CTX_end(ctx);
- return ret;
-}
-
-BN_BLINDING *rsa_setup_blinding(RSA *rsa, BN_CTX *in_ctx) {
- BIGNUM local_n;
- BIGNUM *e, *n;
- BN_CTX *ctx;
- BN_BLINDING *ret = NULL;
- BN_MONT_CTX *mont_ctx = NULL;
-
- if (in_ctx == NULL) {
- ctx = BN_CTX_new();
- if (ctx == NULL) {
- return 0;
- }
- } else {
- ctx = in_ctx;
- }
-
- BN_CTX_start(ctx);
- e = BN_CTX_get(ctx);
- if (e == NULL) {
- 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_R_NO_PUBLIC_EXPONENT);
- goto err;
- }
- } else {
- e = rsa->e;
- }
-
- n = &local_n;
- BN_with_flags(n, rsa->n, BN_FLG_CONSTTIME);
-
- if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) {
- mont_ctx = BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx);
- if (mont_ctx == NULL) {
- goto err;
- }
- }
-
- ret = BN_BLINDING_create_param(NULL, e, n, ctx, rsa->meth->bn_mod_exp,
- mont_ctx);
- if (ret == NULL) {
- OPENSSL_PUT_ERROR(RSA, ERR_R_BN_LIB);
- goto err;
+ if (!BN_mod_exp_mont(b->A, b->A, e, &mont->N, ctx, mont)) {
+ OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
+ return 0;
}
-err:
- BN_CTX_end(ctx);
- if (in_ctx == NULL) {
- BN_CTX_free(ctx);
- }
- if (rsa->e == NULL) {
- BN_free(e);
+ if (!BN_to_montgomery(b->A, b->A, mont, ctx)) {
+ OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
+ return 0;
}
- return ret;
+ return 1;
}
diff --git a/src/crypto/rsa/internal.h b/src/crypto/rsa/internal.h
index 4e896e28..c6ea97f0 100644
--- a/src/crypto/rsa/internal.h
+++ b/src/crypto/rsa/internal.h
@@ -77,9 +77,6 @@ int rsa_default_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out,
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,
@@ -90,25 +87,12 @@ int rsa_default_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb);
#define RSA_PKCS1_PADDING_SIZE 11
-/* BN_BLINDING flags */
-#define BN_BLINDING_NO_UPDATE 0x00000001
-#define BN_BLINDING_NO_RECREATE 0x00000002
-
-BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod);
+BN_BLINDING *BN_BLINDING_new(void);
void BN_BLINDING_free(BN_BLINDING *b);
-int BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx);
-int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
-int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
-int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *);
-int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, BN_CTX *);
-unsigned long BN_BLINDING_get_flags(const BN_BLINDING *);
-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, const BN_MONT_CTX *mont),
- const BN_MONT_CTX *mont);
-BN_BLINDING *rsa_setup_blinding(RSA *rsa, BN_CTX *in_ctx);
+int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, const BIGNUM *e,
+ const BN_MONT_CTX *mont_ctx, BN_CTX *ctx);
+int BN_BLINDING_invert(BIGNUM *n, const BN_BLINDING *b, BN_MONT_CTX *mont_ctx,
+ BN_CTX *ctx);
int RSA_padding_add_PKCS1_type_1(uint8_t *to, unsigned to_len,
diff --git a/src/crypto/rsa/padding.c b/src/crypto/rsa/padding.c
index 032df2e6..12147ea4 100644
--- a/src/crypto/rsa/padding.c
+++ b/src/crypto/rsa/padding.c
@@ -59,6 +59,7 @@
#include <limits.h>
#include <string.h>
+#include <openssl/bn.h>
#include <openssl/digest.h>
#include <openssl/err.h>
#include <openssl/mem.h>
@@ -73,7 +74,6 @@
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 (to_len < RSA_PKCS1_PADDING_SIZE) {
OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL);
@@ -85,7 +85,7 @@ int RSA_padding_add_PKCS1_type_1(uint8_t *to, unsigned to_len,
return 0;
}
- p = (uint8_t *)to;
+ uint8_t *p = to;
*(p++) = 0;
*(p++) = 1; /* Private Key BT (Block Type) */
@@ -95,7 +95,7 @@ int RSA_padding_add_PKCS1_type_1(uint8_t *to, unsigned to_len,
memset(p, 0xff, j);
p += j;
*(p++) = 0;
- memcpy(p, from, (unsigned int)from_len);
+ memcpy(p, from, from_len);
return 1;
}
@@ -154,7 +154,6 @@ int RSA_padding_check_PKCS1_type_1(uint8_t *to, unsigned to_len,
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 (to_len < RSA_PKCS1_PADDING_SIZE) {
OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL);
@@ -166,7 +165,7 @@ int RSA_padding_add_PKCS1_type_2(uint8_t *to, unsigned to_len,
return 0;
}
- p = (unsigned char *)to;
+ uint8_t *p = to;
*(p++) = 0;
*(p++) = 2; /* Public Key BT (Block Type) */
@@ -189,7 +188,7 @@ int RSA_padding_add_PKCS1_type_2(uint8_t *to, unsigned to_len,
*(p++) = 0;
- memcpy(p, from, (unsigned int)from_len);
+ memcpy(p, from, from_len);
return 1;
}
@@ -271,12 +270,12 @@ int RSA_padding_add_none(uint8_t *to, unsigned to_len, const uint8_t *from,
return 0;
}
- memcpy(to, from, (unsigned int)from_len);
+ memcpy(to, from, from_len);
return 1;
}
-int PKCS1_MGF1(uint8_t *mask, unsigned len, const uint8_t *seed,
- unsigned seedlen, const EVP_MD *dgst) {
+static int PKCS1_MGF1(uint8_t *mask, unsigned len, const uint8_t *seed,
+ unsigned seedlen, const EVP_MD *dgst) {
unsigned outlen = 0;
uint32_t i;
uint8_t cnt[4];
@@ -357,7 +356,7 @@ int RSA_padding_add_PKCS1_OAEP_mgf1(uint8_t *to, unsigned to_len,
seed = to + 1;
db = to + mdlen + 1;
- if (!EVP_Digest((void *)param, param_len, db, NULL, md, NULL)) {
+ if (!EVP_Digest(param, param_len, db, NULL, md, NULL)) {
return 0;
}
memset(db + mdlen, 0, emlen - from_len - 2 * mdlen - 1);
@@ -443,7 +442,7 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *to, unsigned to_len,
db[i] ^= maskeddb[i];
}
- if (!EVP_Digest((void *)param, param_len, phash, NULL, md, NULL)) {
+ if (!EVP_Digest(param, param_len, phash, NULL, md, NULL)) {
goto err;
}
diff --git a/src/crypto/rsa/rsa.c b/src/crypto/rsa/rsa.c
index 6c28ad76..e5f98916 100644
--- a/src/crypto/rsa/rsa.c
+++ b/src/crypto/rsa/rsa.c
@@ -64,7 +64,7 @@
#include <openssl/err.h>
#include <openssl/ex_data.h>
#include <openssl/mem.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
#include <openssl/thread.h>
#include "internal.h"
@@ -76,7 +76,7 @@ static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT;
RSA *RSA_new(void) { return RSA_new_method(NULL); }
RSA *RSA_new_method(const ENGINE *engine) {
- RSA *rsa = (RSA *)OPENSSL_malloc(sizeof(RSA));
+ RSA *rsa = OPENSSL_malloc(sizeof(RSA));
if (rsa == NULL) {
OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
return NULL;
@@ -258,16 +258,6 @@ int RSA_private_decrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
return out_len;
}
-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) {
- if (rsa->meth->verify_raw) {
- return rsa->meth->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(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
int padding) {
size_t out_len;
@@ -473,6 +463,11 @@ finish:
int RSA_verify(int hash_nid, const uint8_t *msg, size_t msg_len,
const uint8_t *sig, size_t sig_len, RSA *rsa) {
+ if (rsa->n == NULL || rsa->e == NULL) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING);
+ return 0;
+ }
+
const size_t rsa_size = RSA_size(rsa);
uint8_t *buf = NULL;
int ret = 0;
@@ -480,15 +475,6 @@ int RSA_verify(int hash_nid, const uint8_t *msg, size_t msg_len,
size_t signed_msg_len, len;
int signed_msg_is_alloced = 0;
- if (rsa->meth->verify) {
- return rsa->meth->verify(hash_nid, msg, msg_len, sig, sig_len, rsa);
- }
-
- if (sig_len != rsa_size) {
- 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_R_INVALID_MESSAGE_LENGTH);
return 0;
@@ -510,7 +496,7 @@ int RSA_verify(int hash_nid, const uint8_t *msg, size_t msg_len,
goto out;
}
- if (len != signed_msg_len || CRYPTO_memcmp(buf, signed_msg, len) != 0) {
+ if (len != signed_msg_len || memcmp(buf, signed_msg, len) != 0) {
OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_SIGNATURE);
goto out;
}
diff --git a/src/crypto/rsa/rsa_asn1.c b/src/crypto/rsa/rsa_asn1.c
index b73a0e19..d14ecaee 100644
--- a/src/crypto/rsa/rsa_asn1.c
+++ b/src/crypto/rsa/rsa_asn1.c
@@ -59,14 +59,13 @@
#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"
+#include "../bytestring/internal.h"
static int parse_integer_buggy(CBS *cbs, BIGNUM **out, int buggy) {
@@ -76,9 +75,9 @@ static int parse_integer_buggy(CBS *cbs, BIGNUM **out, int buggy) {
return 0;
}
if (buggy) {
- return BN_cbs2unsigned_buggy(cbs, *out);
+ return BN_parse_asn1_unsigned_buggy(cbs, *out);
}
- return BN_cbs2unsigned(cbs, *out);
+ return BN_parse_asn1_unsigned(cbs, *out);
}
static int parse_integer(CBS *cbs, BIGNUM **out) {
@@ -91,7 +90,7 @@ static int marshal_integer(CBB *cbb, BIGNUM *bn) {
OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING);
return 0;
}
- return BN_bn2cbb(cbb, bn);
+ return BN_marshal_asn1(cbb, bn);
}
static RSA *parse_public_key(CBS *cbs, int buggy) {
@@ -232,9 +231,11 @@ RSA *RSA_parse_private_key(CBS *cbs) {
goto err;
}
- /* Multi-prime RSA requires a newer version. */
- if (version == kVersionMulti &&
- CBS_peek_asn1_tag(&child, CBS_ASN1_SEQUENCE)) {
+ if (version == kVersionMulti) {
+ /* Although otherPrimeInfos is written as OPTIONAL in RFC 3447, it later
+ * says "[otherPrimeInfos] shall be omitted if version is 0 and shall
+ * contain at least one instance of OtherPrimeInfo if version is 1." The
+ * OPTIONAL is just so both versions share a single definition. */
CBS other_prime_infos;
if (!CBS_get_asn1(&child, &other_prime_infos, CBS_ASN1_SEQUENCE) ||
CBS_len(&other_prime_infos) == 0) {
@@ -379,32 +380,18 @@ RSA *d2i_RSAPublicKey(RSA **out, const uint8_t **inp, long len) {
RSA_free(*out);
*out = ret;
}
- *inp += (size_t)len - CBS_len(&cbs);
+ *inp = CBS_data(&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);
+ CBB cbb;
+ if (!CBB_init(&cbb, 0) ||
+ !RSA_marshal_public_key(&cbb, in)) {
+ CBB_cleanup(&cbb);
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;
+ return CBB_finish_i2d(&cbb, outp);
}
RSA *d2i_RSAPrivateKey(RSA **out, const uint8_t **inp, long len) {
@@ -421,43 +408,20 @@ RSA *d2i_RSAPrivateKey(RSA **out, const uint8_t **inp, long len) {
RSA_free(*out);
*out = ret;
}
- *inp += (size_t)len - CBS_len(&cbs);
+ *inp = CBS_data(&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);
+ CBB cbb;
+ if (!CBB_init(&cbb, 0) ||
+ !RSA_marshal_private_key(&cbb, in)) {
+ CBB_cleanup(&cbb);
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;
+ return CBB_finish_i2d(&cbb, outp);
}
-ASN1_SEQUENCE(RSA_PSS_PARAMS) = {
- ASN1_EXP_OPT(RSA_PSS_PARAMS, hashAlgorithm, X509_ALGOR,0),
- ASN1_EXP_OPT(RSA_PSS_PARAMS, maskGenAlgorithm, X509_ALGOR,1),
- ASN1_EXP_OPT(RSA_PSS_PARAMS, saltLength, ASN1_INTEGER,2),
- ASN1_EXP_OPT(RSA_PSS_PARAMS, trailerField, ASN1_INTEGER,3),
-} ASN1_SEQUENCE_END(RSA_PSS_PARAMS);
-
-IMPLEMENT_ASN1_FUNCTIONS(RSA_PSS_PARAMS);
-
RSA *RSAPublicKey_dup(const RSA *rsa) {
uint8_t *der;
size_t der_len;
diff --git a/src/crypto/rsa/rsa_impl.c b/src/crypto/rsa/rsa_impl.c
index b1cfaa63..3e30d898 100644
--- a/src/crypto/rsa/rsa_impl.c
+++ b/src/crypto/rsa/rsa_impl.c
@@ -56,6 +56,7 @@
#include <openssl/rsa.h>
+#include <assert.h>
#include <string.h>
#include <openssl/bn.h>
@@ -67,11 +68,42 @@
#include "../internal.h"
-#define OPENSSL_RSA_MAX_MODULUS_BITS 16384
-#define OPENSSL_RSA_SMALL_MODULUS_BITS 3072
-#define OPENSSL_RSA_MAX_PUBEXP_BITS \
- 64 /* exponent limit enforced for "large" modulus only */
+static int check_modulus_and_exponent_sizes(const RSA *rsa) {
+ unsigned rsa_bits = BN_num_bits(rsa->n);
+ if (rsa_bits > 16 * 1024) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_MODULUS_TOO_LARGE);
+ return 0;
+ }
+
+ /* Mitigate DoS attacks by limiting the exponent size. 33 bits was chosen as
+ * the limit based on the recommendations in [1] and [2]. Windows CryptoAPI
+ * doesn't support values larger than 32 bits [3], so it is unlikely that
+ * exponents larger than 32 bits are being used for anything Windows commonly
+ * does.
+ *
+ * [1] https://www.imperialviolet.org/2012/03/16/rsae.html
+ * [2] https://www.imperialviolet.org/2012/03/17/rsados.html
+ * [3] https://msdn.microsoft.com/en-us/library/aa387685(VS.85).aspx */
+ static const unsigned kMaxExponentBits = 33;
+
+ if (BN_num_bits(rsa->e) > kMaxExponentBits) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_E_VALUE);
+ return 0;
+ }
+
+ /* Verify |n > e|. Comparing |rsa_bits| to |kMaxExponentBits| is a small
+ * shortcut to comparing |n| and |e| directly. In reality, |kMaxExponentBits|
+ * is much smaller than the minimum RSA key size that any application should
+ * accept. */
+ if (rsa_bits <= kMaxExponentBits) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL);
+ return 0;
+ }
+ assert(BN_ucmp(rsa->n, rsa->e) > 0);
+
+ return 1;
+}
size_t rsa_default_size(const RSA *rsa) {
return BN_num_bytes(rsa->n);
@@ -85,25 +117,12 @@ int rsa_default_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
BN_CTX *ctx = NULL;
int i, ret = 0;
- if (rsa_size > OPENSSL_RSA_MAX_MODULUS_BITS) {
- OPENSSL_PUT_ERROR(RSA, RSA_R_MODULUS_TOO_LARGE);
- return 0;
- }
-
if (max_out < rsa_size) {
OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL);
return 0;
}
- if (BN_ucmp(rsa->n, rsa->e) <= 0) {
- 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, RSA_R_BAD_E_VALUE);
+ if (!check_modulus_and_exponent_sizes(rsa)) {
return 0;
}
@@ -152,13 +171,8 @@ int rsa_default_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
goto err;
}
- if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) {
- 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->mont_n)) {
+ if (!BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx) ||
+ !BN_mod_exp_mont(result, f, rsa->e, rsa->n, ctx, rsa->mont_n)) {
goto err;
}
@@ -199,6 +213,9 @@ err:
* |*index_used| and must be passed to |rsa_blinding_release| when finished. */
static BN_BLINDING *rsa_blinding_get(RSA *rsa, unsigned *index_used,
BN_CTX *ctx) {
+ assert(ctx != NULL);
+ assert(rsa->mont_n != NULL);
+
BN_BLINDING *ret = NULL;
BN_BLINDING **new_blindings;
uint8_t *new_blindings_inuse;
@@ -227,7 +244,7 @@ static BN_BLINDING *rsa_blinding_get(RSA *rsa, unsigned *index_used,
* the arrays by one and use the newly created element. */
CRYPTO_MUTEX_unlock(&rsa->lock);
- ret = rsa_setup_blinding(rsa, ctx);
+ ret = BN_BLINDING_new();
if (ret == NULL) {
return NULL;
}
@@ -407,46 +424,49 @@ err:
return ret;
}
-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) {
+static int mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
+
+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) {
+ if (rsa->n == NULL || rsa->e == NULL) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING);
+ return 0;
+ }
+
const unsigned rsa_size = RSA_size(rsa);
BIGNUM *f, *result;
- int ret = 0;
int r = -1;
- uint8_t *buf = NULL;
- BN_CTX *ctx = NULL;
- if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) {
- OPENSSL_PUT_ERROR(RSA, RSA_R_MODULUS_TOO_LARGE);
+ if (max_out < rsa_size) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL);
return 0;
}
- if (BN_ucmp(rsa->n, rsa->e) <= 0) {
- OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_E_VALUE);
+ if (in_len != rsa_size) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_LEN_NOT_EQUAL_TO_MOD_LEN);
return 0;
}
- if (max_out < rsa_size) {
- OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL);
+ if (!check_modulus_and_exponent_sizes(rsa)) {
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, RSA_R_BAD_E_VALUE);
+ BN_CTX *ctx = BN_CTX_new();
+ if (ctx == NULL) {
return 0;
}
- ctx = BN_CTX_new();
- if (ctx == NULL) {
- goto err;
- }
+ int ret = 0;
+ uint8_t *buf = NULL;
BN_CTX_start(ctx);
f = BN_CTX_get(ctx);
result = BN_CTX_get(ctx);
+ if (f == NULL || result == NULL) {
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
if (padding == RSA_NO_PADDING) {
buf = out;
} else {
@@ -457,15 +477,6 @@ int rsa_default_verify_raw(RSA *rsa, size_t *out_len, uint8_t *out,
goto err;
}
}
- if (!f || !result) {
- OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
- goto err;
- }
-
- if (in_len != rsa_size) {
- OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_LEN_NOT_EQUAL_TO_MOD_LEN);
- goto err;
- }
if (BN_bin2bn(in, in_len, f) == NULL) {
goto err;
@@ -476,13 +487,8 @@ int rsa_default_verify_raw(RSA *rsa, size_t *out_len, uint8_t *out,
goto err;
}
- if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) {
- 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->mont_n)) {
+ if (!BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx) ||
+ !BN_mod_exp_mont(result, f, rsa->e, rsa->n, ctx, rsa->mont_n)) {
goto err;
}
@@ -511,12 +517,9 @@ int rsa_default_verify_raw(RSA *rsa, size_t *out_len, uint8_t *out,
}
err:
- if (ctx != NULL) {
- BN_CTX_end(ctx);
- BN_CTX_free(ctx);
- }
- if (padding != RSA_NO_PADDING && buf != NULL) {
- OPENSSL_cleanse(buf, rsa_size);
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ if (buf != out) {
OPENSSL_free(buf);
}
return ret;
@@ -554,20 +557,31 @@ int rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in,
}
if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) {
+ /* Keys without public exponents must have blinding explicitly disabled to
+ * be used. */
+ if (rsa->e == NULL) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_NO_PUBLIC_EXPONENT);
+ goto err;
+ }
+
+ if (!BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx)) {
+ OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+
blinding = rsa_blinding_get(rsa, &blinding_index, ctx);
if (blinding == NULL) {
OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
goto err;
}
- if (!BN_BLINDING_convert_ex(f, NULL, blinding, ctx)) {
+ if (!BN_BLINDING_convert(f, blinding, rsa->e, rsa->mont_n, ctx)) {
goto err;
}
}
- if ((rsa->flags & RSA_FLAG_EXT_PKEY) ||
- ((rsa->p != NULL) && (rsa->q != NULL) && (rsa->dmp1 != NULL) &&
- (rsa->dmq1 != NULL) && (rsa->iqmp != NULL))) {
- if (!rsa->meth->mod_exp(result, f, rsa, ctx)) {
+ if (rsa->p != NULL && rsa->q != NULL && rsa->e != NULL && rsa->dmp1 != NULL &&
+ rsa->dmq1 != NULL && rsa->iqmp != NULL) {
+ if (!mod_exp(result, f, rsa, ctx)) {
goto err;
}
} else {
@@ -578,20 +592,14 @@ int rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in,
d = &local_d;
BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
- if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) {
- 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->mont_n)) {
+ if (!BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx) ||
+ !BN_mod_exp_mont_consttime(result, f, d, rsa->n, ctx, rsa->mont_n)) {
goto err;
}
}
if (blinding) {
- if (!BN_BLINDING_invert_ex(result, NULL, blinding, ctx)) {
+ if (!BN_BLINDING_invert(result, blinding, rsa->mont_n, ctx)) {
goto err;
}
}
@@ -616,6 +624,17 @@ err:
}
static int mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) {
+ assert(ctx != NULL);
+
+ assert(rsa->n != NULL);
+ assert(rsa->e != NULL);
+ assert(rsa->d != NULL);
+ assert(rsa->p != NULL);
+ assert(rsa->q != NULL);
+ assert(rsa->dmp1 != NULL);
+ assert(rsa->dmq1 != NULL);
+ assert(rsa->iqmp != NULL);
+
BIGNUM *r1, *m1, *vrfy;
BIGNUM local_dmp1, local_dmq1, local_c, local_r1;
BIGNUM *dmp1, *dmq1, *c, *pr1;
@@ -630,6 +649,11 @@ static int mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) {
r1 = BN_CTX_get(ctx);
m1 = BN_CTX_get(ctx);
vrfy = BN_CTX_get(ctx);
+ if (r1 == NULL ||
+ m1 == NULL ||
+ vrfy == NULL) {
+ goto err;
+ }
{
BIGNUM local_p, local_q;
@@ -645,20 +669,14 @@ static int mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) {
q = &local_q;
BN_with_flags(q, rsa->q, BN_FLG_CONSTTIME);
- if (rsa->flags & RSA_FLAG_CACHE_PRIVATE) {
- if (BN_MONT_CTX_set_locked(&rsa->mont_p, &rsa->lock, p, ctx) == NULL) {
- goto err;
- }
- if (BN_MONT_CTX_set_locked(&rsa->mont_q, &rsa->lock, q, ctx) == NULL) {
- goto err;
- }
+ if (!BN_MONT_CTX_set_locked(&rsa->mont_p, &rsa->lock, p, ctx) ||
+ !BN_MONT_CTX_set_locked(&rsa->mont_q, &rsa->lock, q, ctx)) {
+ goto err;
}
}
- if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) {
- if (BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx) == NULL) {
- goto err;
- }
+ if (!BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx)) {
+ goto err;
}
/* compute I mod q */
@@ -671,7 +689,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->mont_q)) {
+ if (!BN_mod_exp_mont_consttime(m1, r1, dmq1, rsa->q, ctx, rsa->mont_q)) {
goto err;
}
@@ -685,7 +703,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->mont_p)) {
+ if (!BN_mod_exp_mont_consttime(r0, r1, dmp1, rsa->p, ctx, rsa->mont_p)) {
goto err;
}
@@ -745,12 +763,8 @@ static int mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *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)) {
+ if (!BN_MONT_CTX_set_locked(&ap->mont, &rsa->lock, prime, ctx) ||
+ !BN_mod_exp_mont_consttime(m1, r1, exp, prime, ctx, ap->mont)) {
goto err;
}
@@ -766,38 +780,35 @@ static int mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) {
}
}
- if (rsa->e && rsa->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
- * will be equivalent to using 'I mod n'. However, the result of
- * the verify will *always* be less than 'n' so we don't check
- * for absolute equality, just congruency. */
- if (!BN_sub(vrfy, vrfy, I)) {
- goto err;
- }
- if (!BN_mod(vrfy, vrfy, rsa->n, ctx)) {
+ if (!BN_mod_exp_mont(vrfy, r0, rsa->e, rsa->n, ctx, rsa->mont_n)) {
+ goto err;
+ }
+ /* If 'I' was greater than (or equal to) rsa->n, the operation will be
+ * equivalent to using 'I mod n'. However, the result of the verify will
+ * *always* be less than 'n' so we don't check for absolute equality, just
+ * congruency. */
+ if (!BN_sub(vrfy, vrfy, I)) {
+ goto err;
+ }
+ if (!BN_mod(vrfy, vrfy, rsa->n, ctx)) {
+ goto err;
+ }
+ if (BN_is_negative(vrfy)) {
+ if (!BN_add(vrfy, vrfy, rsa->n)) {
goto err;
}
- if (BN_is_negative(vrfy)) {
- if (!BN_add(vrfy, vrfy, rsa->n)) {
- goto err;
- }
- }
- if (!BN_is_zero(vrfy)) {
- /* 'I' and 'vrfy' aren't congruent mod n. Don't leak
- * miscalculated CRT output, just do a raw (slower)
- * mod_exp and return that instead. */
+ }
+ if (!BN_is_zero(vrfy)) {
+ /* 'I' and 'vrfy' aren't congruent mod n. Don't leak miscalculated CRT
+ * output, just do a raw (slower) mod_exp and return that instead. */
- BIGNUM local_d;
- BIGNUM *d = NULL;
+ BIGNUM local_d;
+ BIGNUM *d = NULL;
- 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->mont_n)) {
- goto err;
- }
+ d = &local_d;
+ BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
+ if (!BN_mod_exp_mont_consttime(r0, I, d, rsa->n, ctx, rsa->mont_n)) {
+ goto err;
}
}
ret = 1;
@@ -1101,9 +1112,9 @@ int rsa_default_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) {
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. */
+/* All of the methods are NULL to make it easier for the compiler/linker to drop
+ * unused functions. The wrapper functions will select the appropriate
+ * |rsa_default_*| implementation. */
const RSA_METHOD RSA_default_method = {
{
0 /* references */,
@@ -1126,8 +1137,8 @@ const RSA_METHOD RSA_default_method = {
NULL /* private_transform (defaults to rsa_default_private_transform) */,
- mod_exp,
- BN_mod_exp_mont /* bn_mod_exp */,
+ NULL /* mod_exp (ignored) */,
+ NULL /* bn_mod_exp (ignored) */,
RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE,
diff --git a/src/crypto/rsa/rsa_test.cc b/src/crypto/rsa/rsa_test.cc
index 5545161c..62177a4c 100644
--- a/src/crypto/rsa/rsa_test.cc
+++ b/src/crypto/rsa/rsa_test.cc
@@ -63,7 +63,7 @@
#include <openssl/bytestring.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
#include "../test/scoped_types.h"
@@ -593,6 +593,7 @@ static bool TestRSA(const uint8_t *der, size_t der_len,
fprintf(stderr, "Corrupt data decrypted!\n");
return false;
}
+ ERR_clear_error();
ciphertext[i] ^= 1;
}
@@ -603,6 +604,7 @@ static bool TestRSA(const uint8_t *der, size_t der_len,
fprintf(stderr, "Corrupt data decrypted!\n");
return false;
}
+ ERR_clear_error();
}
return true;
@@ -693,25 +695,27 @@ static bool TestBadKey() {
}
static bool TestOnlyDGiven() {
+ static const char kN[] =
+ "00e77bbf3889d4ef36a9a25d4d69f3f632eb4362214c74517da6d6aeaa9bd09ac42b2662"
+ "1cd88f3a6eb013772fc3bf9f83914b6467231c630202c35b3e5808c659";
+ static const char kE[] = "010001";
+ static const char kD[] =
+ "0365db9eb6d73b53b015c40cd8db4de7dd7035c68b5ac1bf786d7a4ee2cea316eaeca21a"
+ "73ac365e58713195f2ae9849348525ca855386b6d028e437a9495a01";
+
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") ||
+ !BN_hex2bn(&key->n, kN) ||
+ !BN_hex2bn(&key->e, kE) ||
+ !BN_hex2bn(&key->d, kD) ||
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");
+ fprintf(stderr, "RSA_check_key failed with only n, d, and e given.\n");
ERR_print_errors_fp(stderr);
return false;
}
@@ -720,14 +724,46 @@ static bool TestOnlyDGiven() {
if (!RSA_sign(NID_sha256, kDummyHash, sizeof(kDummyHash), buf, &buf_len,
key.get())) {
- fprintf(stderr, "RSA_sign failed with only d given.\n");
+ fprintf(stderr, "RSA_sign failed with only n, d, and e 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 n, d, and e given.\n");
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ // Keys without the public exponent must continue to work when blinding is
+ // disabled to support Java's RSAPrivateKeySpec API. See
+ // https://bugs.chromium.org/p/boringssl/issues/detail?id=12.
+ ScopedRSA key2(RSA_new());
+ if (!key2 ||
+ !BN_hex2bn(&key2->n, kN) ||
+ !BN_hex2bn(&key2->d, kD)) {
+ return false;
+ }
+ key2->flags |= RSA_FLAG_NO_BLINDING;
+
+ if (RSA_size(key2.get()) > sizeof(buf)) {
+ return false;
+ }
+
+ if (!RSA_sign(NID_sha256, kDummyHash, sizeof(kDummyHash), buf, &buf_len,
+ key2.get())) {
+ fprintf(stderr, "RSA_sign failed with only n and d given.\n");
ERR_print_errors_fp(stderr);
return false;
}
+ // Verify the signature with |key|. |key2| has no public exponent.
if (!RSA_verify(NID_sha256, kDummyHash, sizeof(kDummyHash), buf, buf_len,
key.get())) {
- fprintf(stderr, "RSA_verify failed with only d given.\n");
+ fprintf(stderr,
+ "Could not verify signature produced from key with only n and d "
+ "given.\n");
ERR_print_errors_fp(stderr);
return false;
}
diff --git a/src/crypto/sha/asm/sha512-armv4.pl b/src/crypto/sha/asm/sha512-armv4.pl
index cd3662a5..15d50f28 100644
--- a/src/crypto/sha/asm/sha512-armv4.pl
+++ b/src/crypto/sha/asm/sha512-armv4.pl
@@ -291,7 +291,7 @@ sha512_block_data_order:
#ifdef __APPLE__
ldr r12,[r12]
#endif
- tst r12,#1
+ tst r12,#ARMV7_NEON
bne .LNEON
#endif
add $len,$inp,$len,lsl#7 @ len to point at the end of inp
diff --git a/src/crypto/sha/sha256.c b/src/crypto/sha/sha256.c
index 0ddacbad..58f7c42c 100644
--- a/src/crypto/sha/sha256.c
+++ b/src/crypto/sha/sha256.c
@@ -104,8 +104,8 @@ uint8_t *SHA224(const uint8_t *data, size_t len, uint8_t *out) {
out = buf;
}
SHA224_Init(&ctx);
- SHA256_Update(&ctx, data, len);
- SHA256_Final(out, &ctx);
+ SHA224_Update(&ctx, data, len);
+ SHA224_Final(out, &ctx);
OPENSSL_cleanse(&ctx, sizeof(ctx));
return out;
}
diff --git a/src/crypto/sha/sha512.c b/src/crypto/sha/sha512.c
index 6ad8d40c..f4730463 100644
--- a/src/crypto/sha/sha512.c
+++ b/src/crypto/sha/sha512.c
@@ -129,8 +129,8 @@ uint8_t *SHA384(const uint8_t *data, size_t len, uint8_t *out) {
}
SHA384_Init(&ctx);
- SHA512_Update(&ctx, data, len);
- SHA512_Final(out, &ctx);
+ SHA384_Update(&ctx, data, len);
+ SHA384_Final(out, &ctx);
OPENSSL_cleanse(&ctx, sizeof(ctx));
return out;
}
diff --git a/src/crypto/stack/stack.c b/src/crypto/stack/stack.c
index c5845159..e8932217 100644
--- a/src/crypto/stack/stack.c
+++ b/src/crypto/stack/stack.c
@@ -329,7 +329,7 @@ err:
void sk_sort(_STACK *sk) {
int (*comp_func)(const void *,const void *);
- if (sk == NULL || sk->sorted) {
+ if (sk == NULL || sk->comp == NULL || sk->sorted) {
return;
}
diff --git a/src/crypto/test/file_test.cc b/src/crypto/test/file_test.cc
index 4752f04a..d684aa09 100644
--- a/src/crypto/test/file_test.cc
+++ b/src/crypto/test/file_test.cc
@@ -14,6 +14,8 @@
#include "file_test.h"
+#include <memory>
+
#include <ctype.h>
#include <errno.h>
#include <stdarg.h>
@@ -63,30 +65,23 @@ static std::string StripSpace(const char *str, size_t len) {
}
FileTest::ReadResult FileTest::ReadNext() {
- // If the previous test had unused attributes or block, it is an error.
+ // If the previous test had unused attributes, it is an error.
if (!unused_attributes_.empty()) {
for (const std::string &key : unused_attributes_) {
PrintLine("Unused attribute: %s", key.c_str());
}
return kReadError;
}
- if (!block_.empty() && !used_block_) {
- PrintLine("Unused block");
- return kReadError;
- }
ClearTest();
- bool in_block = false;
+ static const size_t kBufLen = 64 + 8192*2;
+ std::unique_ptr<char[]> buf(new char[kBufLen]);
+
while (true) {
// Read the next line.
- char buf[4096];
- if (fgets(buf, sizeof(buf), file_) == nullptr) {
+ if (fgets(buf.get(), kBufLen, file_) == nullptr) {
if (feof(file_)) {
- if (in_block) {
- fprintf(stderr, "Unterminated block.\n");
- return kReadError;
- }
// EOF is a valid terminator for a test.
return start_line_ > 0 ? kReadSuccess : kReadEOF;
}
@@ -95,42 +90,28 @@ FileTest::ReadResult FileTest::ReadNext() {
}
line_++;
- size_t len = strlen(buf);
+ size_t len = strlen(buf.get());
// Check for truncation.
if (len > 0 && buf[len - 1] != '\n' && !feof(file_)) {
fprintf(stderr, "Line %u too long.\n", line_);
return kReadError;
}
- bool is_delimiter = strncmp(buf, "---", 3) == 0;
- if (in_block) {
- block_ += buf;
- if (is_delimiter) {
- // Ending the block completes the test.
- return kReadSuccess;
- }
- } else if (is_delimiter) {
- if (start_line_ == 0) {
- fprintf(stderr, "Line %u: Unexpected block.\n", line_);
- return kReadError;
- }
- in_block = true;
- block_ += buf;
- } else if (buf[0] == '\n' || buf[0] == '\0') {
+ if (buf[0] == '\n' || buf[0] == '\0') {
// Empty lines delimit tests.
if (start_line_ > 0) {
return kReadSuccess;
}
} else if (buf[0] != '#') { // Comment lines are ignored.
// Parse the line as an attribute.
- const char *delimiter = FindDelimiter(buf);
+ const char *delimiter = FindDelimiter(buf.get());
if (delimiter == nullptr) {
fprintf(stderr, "Line %u: Could not parse attribute.\n", line_);
return kReadError;
}
- std::string key = StripSpace(buf, delimiter - buf);
+ std::string key = StripSpace(buf.get(), delimiter - buf.get());
std::string value = StripSpace(delimiter + 1,
- buf + len - delimiter - 1);
+ buf.get() + len - delimiter - 1);
unused_attributes_.insert(key);
attributes_[key] = value;
@@ -165,11 +146,6 @@ const std::string &FileTest::GetParameter() {
return parameter_;
}
-const std::string &FileTest::GetBlock() {
- used_block_ = true;
- return block_;
-}
-
bool FileTest::HasAttribute(const std::string &key) {
OnKeyUsed(key);
return attributes_.count(key) > 0;
@@ -224,6 +200,7 @@ bool FileTest::GetBytes(std::vector<uint8_t> *out, const std::string &key) {
PrintLine("Error decoding value: %s", value.c_str());
return false;
}
+ out->clear();
out->reserve(value.size() / 2);
for (size_t i = 0; i < value.size(); i += 2) {
uint8_t hi, lo;
@@ -266,9 +243,7 @@ void FileTest::ClearTest() {
type_.clear();
parameter_.clear();
attributes_.clear();
- block_.clear();
unused_attributes_.clear();
- used_block_ = false;
}
void FileTest::OnKeyUsed(const std::string &key) {
@@ -304,6 +279,7 @@ int FileTestMain(bool (*run_test)(FileTest *t, void *arg), void *arg,
t.GetAttributeOrDie("Error").c_str(),
ERR_reason_error_string(err));
failed = true;
+ ERR_clear_error();
continue;
}
ERR_clear_error();
diff --git a/src/crypto/test/file_test.h b/src/crypto/test/file_test.h
index 24651ab8..e90cc86a 100644
--- a/src/crypto/test/file_test.h
+++ b/src/crypto/test/file_test.h
@@ -15,6 +15,8 @@
#ifndef OPENSSL_HEADER_CRYPTO_TEST_FILE_TEST_H
#define OPENSSL_HEADER_CRYPTO_TEST_FILE_TEST_H
+#include <openssl/base.h>
+
#include <stdint.h>
#include <stdio.h>
@@ -36,7 +38,7 @@
//
// This module provides a file-based test framework. The file format is based on
// that of OpenSSL upstream's evp_test and BoringSSL's aead_test. Each input
-// file is a sequence of attributes, blocks, and blank lines.
+// file is a sequence of attributes and blank lines.
//
// Each attribute has the form:
//
@@ -45,15 +47,11 @@
// Either '=' or ':' may be used to delimit the name from the value. Both the
// name and value have leading and trailing spaces stripped.
//
-// Blocks are delimited by lines beginning with three hyphens, "---". One such
-// line begins a block and another ends it. Blocks are intended as a convenient
-// way to embed PEM data and include their delimiters.
-//
-// Outside a block, lines beginning with # are ignored.
+// Lines beginning with # are ignored.
//
-// A test is a sequence of one or more attributes followed by a block or blank
-// line. Blank lines are otherwise ignored. For tests that process multiple
-// kinds of test cases, the first attribute is parsed out as the test's type and
+// A test is a sequence of one or more attributes followed by a blank line.
+// Blank lines are otherwise ignored. For tests that process multiple kinds of
+// test cases, the first attribute is parsed out as the test's type and
// parameter. Otherwise, attributes are unordered. The first attribute is also
// included in the set of attributes, so tests which do not dispatch may ignore
// this mechanism.
@@ -88,11 +86,7 @@ class FileTest {
// PrintLine is a variant of printf which prepends the line number and appends
// a trailing newline.
- void PrintLine(const char *format, ...)
-#ifdef __GNUC__
- __attribute__((__format__(__printf__, 2, 3)))
-#endif
- ;
+ void PrintLine(const char *format, ...) OPENSSL_PRINTF_FORMAT_FUNC(2, 3);
unsigned start_line() const { return start_line_; }
@@ -100,9 +94,6 @@ class FileTest {
const std::string &GetType();
// GetParameter returns the value of the first attribute of the current test.
const std::string &GetParameter();
- // GetBlock returns the optional block of the current test, or the empty
- // if there was no block.
- const std::string &GetBlock();
// HasAttribute returns true if the current test has an attribute named |key|.
bool HasAttribute(const std::string &key);
@@ -113,7 +104,7 @@ class FileTest {
bool GetAttribute(std::string *out_value, const std::string &key);
// GetAttributeOrDie looks up the attribute with key |key| and aborts if it is
- // missing. It only be used after a |HasAttribute| call.
+ // missing. It should only be used after a |HasAttribute| call.
const std::string &GetAttributeOrDie(const std::string &key);
// GetBytes looks up the attribute with key |key| and decodes it as a byte
@@ -144,13 +135,9 @@ class FileTest {
std::string parameter_;
// attributes_ contains all attributes in the test, including the first.
std::map<std::string, std::string> attributes_;
- // block_, if non-empty, is the test's optional trailing block.
- std::string block_;
// unused_attributes_ is the set of attributes that have been queried.
std::set<std::string> unused_attributes_;
- // used_block_ is true if the block has been queried.
- bool used_block_ = false;
FileTest(const FileTest&) = delete;
FileTest &operator=(const FileTest&) = delete;
diff --git a/src/crypto/test/scoped_types.h b/src/crypto/test/scoped_types.h
index 590f926a..5c49a7ee 100644
--- a/src/crypto/test/scoped_types.h
+++ b/src/crypto/test/scoped_types.h
@@ -21,13 +21,16 @@
#include <memory>
#include <openssl/aead.h>
+#include <openssl/asn1.h>
#include <openssl/bio.h>
#include <openssl/bn.h>
+#include <openssl/bytestring.h>
#include <openssl/cmac.h>
+#include <openssl/curve25519.h>
#include <openssl/dh.h>
+#include <openssl/ecdsa.h>
#include <openssl/ec.h>
#include <openssl/ec_key.h>
-#include <openssl/ecdsa.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/mem.h>
@@ -95,6 +98,7 @@ class ScopedOpenSSLContext {
T ctx_;
};
+using ScopedASN1_TYPE = ScopedOpenSSLType<ASN1_TYPE, ASN1_TYPE_free>;
using ScopedBIO = ScopedOpenSSLType<BIO, BIO_vfree>;
using ScopedBIGNUM = ScopedOpenSSLType<BIGNUM, BN_free>;
using ScopedBN_CTX = ScopedOpenSSLType<BN_CTX, BN_CTX_free>;
@@ -110,10 +114,12 @@ using ScopedEVP_PKEY_CTX = ScopedOpenSSLType<EVP_PKEY_CTX, EVP_PKEY_CTX_free>;
using ScopedPKCS8_PRIV_KEY_INFO = ScopedOpenSSLType<PKCS8_PRIV_KEY_INFO,
PKCS8_PRIV_KEY_INFO_free>;
using ScopedPKCS12 = ScopedOpenSSLType<PKCS12, PKCS12_free>;
+using ScopedSPAKE2_CTX = ScopedOpenSSLType<SPAKE2_CTX, SPAKE2_CTX_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 ScopedX509_STORE_CTX = ScopedOpenSSLType<X509_STORE_CTX, X509_STORE_CTX_free>;
using ScopedX509Stack = ScopedOpenSSLStack<STACK_OF(X509), X509, X509_free>;
diff --git a/src/crypto/test/test_util.h b/src/crypto/test/test_util.h
index 972e2065..89e70c6d 100644
--- a/src/crypto/test/test_util.h
+++ b/src/crypto/test/test_util.h
@@ -28,6 +28,14 @@ extern "C" {
void hexdump(FILE *fp, const char *msg, const void *in, size_t len);
+#if defined(_MSC_VER) && _MSC_VER < 1900
+/* https://msdn.microsoft.com/en-us/library/tcxf1dw6(v=vs.120).aspx */
+#define OPENSSL_PR_SIZE_T "Iu"
+#else
+#define OPENSSL_PR_SIZE_T "zu"
+#endif
+
+
#if defined(__cplusplus)
}
#endif
diff --git a/src/crypto/thread_pthread.c b/src/crypto/thread_pthread.c
index 68aaab5b..2a1c9f8a 100644
--- a/src/crypto/thread_pthread.c
+++ b/src/crypto/thread_pthread.c
@@ -17,7 +17,6 @@
#if !defined(OPENSSL_WINDOWS) && !defined(OPENSSL_NO_THREADS)
#include <pthread.h>
-#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -76,8 +75,6 @@ void CRYPTO_STATIC_MUTEX_unlock(struct CRYPTO_STATIC_MUTEX *lock) {
void CRYPTO_once(CRYPTO_once_t *once, void (*init)(void)) {
if (pthread_once(once, init) != 0) {
- fprintf(stderr,
- "pthread_once failed. Did you link against a threading library?\n");
abort();
}
}
diff --git a/src/crypto/thread_test.c b/src/crypto/thread_test.c
index e028b1be..92a5373b 100644
--- a/src/crypto/thread_test.c
+++ b/src/crypto/thread_test.c
@@ -53,6 +53,8 @@ static int wait_for_thread(thread_t thread) {
#else
#include <pthread.h>
+#include <string.h>
+#include <time.h>
typedef pthread_t thread_t;
@@ -77,6 +79,17 @@ static unsigned g_once_init_called = 0;
static void once_init(void) {
g_once_init_called++;
+
+ /* Sleep briefly so one |call_once_thread| instance will call |CRYPTO_once|
+ * while the other is running this function. */
+#if defined(OPENSSL_WINDOWS)
+ Sleep(1 /* milliseconds */);
+#else
+ struct timespec req;
+ memset(&req, 0, sizeof(req));
+ req.tv_nsec = 1000000;
+ nanosleep(&req, NULL);
+#endif
}
static CRYPTO_once_t g_test_once = CRYPTO_ONCE_INIT;
@@ -91,9 +104,11 @@ static int test_once(void) {
return 0;
}
- thread_t thread;
- if (!run_thread(&thread, call_once_thread) ||
- !wait_for_thread(thread)) {
+ thread_t thread1, thread2;
+ if (!run_thread(&thread1, call_once_thread) ||
+ !run_thread(&thread2, call_once_thread) ||
+ !wait_for_thread(thread1) ||
+ !wait_for_thread(thread2)) {
fprintf(stderr, "thread failed.\n");
return 0;
}
diff --git a/src/crypto/thread_win.c b/src/crypto/thread_win.c
index 5efd8be3..26325656 100644
--- a/src/crypto/thread_win.c
+++ b/src/crypto/thread_win.c
@@ -20,7 +20,6 @@
#include <windows.h>
#pragma warning(pop)
-#include <assert.h>
#include <stdlib.h>
#include <string.h>
@@ -31,61 +30,16 @@
OPENSSL_COMPILE_ASSERT(sizeof(CRYPTO_MUTEX) >= sizeof(CRITICAL_SECTION),
CRYPTO_MUTEX_too_small);
-static void run_once(CRYPTO_once_t *in_once, void (*init)(void *), void *arg) {
- volatile LONG *once = in_once;
-
- /* Values must be aligned. */
- assert((((uintptr_t) once) & 3) == 0);
-
- /* This assumes that reading *once has acquire semantics. This should be true
- * on x86 and x86-64, where we expect Windows to run. */
-#if !defined(OPENSSL_X86) && !defined(OPENSSL_X86_64)
-#error "Windows once code may not work on other platforms." \
- "You can use InitOnceBeginInitialize on >=Vista"
-#endif
- if (*once == 1) {
- return;
- }
-
- for (;;) {
- switch (InterlockedCompareExchange(once, 2, 0)) {
- case 0:
- /* The value was zero so we are the first thread to call |CRYPTO_once|
- * on it. */
- init(arg);
- /* Write one to indicate that initialisation is complete. */
- InterlockedExchange(once, 1);
- return;
-
- case 1:
- /* Another thread completed initialisation between our fast-path check
- * and |InterlockedCompareExchange|. */
- return;
-
- case 2:
- /* Another thread is running the initialisation. Switch to it then try
- * again. */
- SwitchToThread();
- break;
-
- default:
- abort();
- }
- }
+static BOOL CALLBACK call_once_init(INIT_ONCE *once, void *arg, void **out) {
+ void (**init)(void) = (void (**)(void))arg;
+ (**init)();
+ return TRUE;
}
-static void call_once_init(void *arg) {
- void (*init_func)(void);
- /* MSVC does not like casting between data and function pointers. */
- memcpy(&init_func, &arg, sizeof(void *));
- init_func();
-}
-
-void CRYPTO_once(CRYPTO_once_t *in_once, void (*init)(void)) {
- void *arg;
- /* MSVC does not like casting between data and function pointers. */
- memcpy(&arg, &init, sizeof(void *));
- run_once(in_once, call_once_init, arg);
+void CRYPTO_once(CRYPTO_once_t *once, void (*init)(void)) {
+ if (!InitOnceExecuteOnce(once, call_once_init, &init, NULL)) {
+ abort();
+ }
}
void CRYPTO_MUTEX_init(CRYPTO_MUTEX *lock) {
@@ -111,16 +65,21 @@ void CRYPTO_MUTEX_cleanup(CRYPTO_MUTEX *lock) {
DeleteCriticalSection((CRITICAL_SECTION *) lock);
}
-static void static_lock_init(void *arg) {
+static BOOL CALLBACK static_lock_init(INIT_ONCE *once, void *arg, void **out) {
struct CRYPTO_STATIC_MUTEX *lock = arg;
if (!InitializeCriticalSectionAndSpinCount(&lock->lock, 0x400)) {
abort();
}
+ return TRUE;
}
void CRYPTO_STATIC_MUTEX_lock_read(struct CRYPTO_STATIC_MUTEX *lock) {
- /* Since we have to support Windows XP, read locks are actually exclusive. */
- run_once(&lock->once, static_lock_init, lock);
+ /* TODO(davidben): Consider replacing these with SRWLOCK now that we no longer
+ * need to support Windows XP. Currently, read locks are actually
+ * exclusive. */
+ if (!InitOnceExecuteOnce(&lock->once, static_lock_init, lock, NULL)) {
+ abort();
+ }
EnterCriticalSection(&lock->lock);
}
@@ -148,9 +107,14 @@ static void thread_local_init(void) {
g_thread_local_failed = (g_thread_local_key == TLS_OUT_OF_INDEXES);
}
-static void NTAPI thread_local_destructor(PVOID module,
- DWORD reason, PVOID reserved) {
- if (DLL_THREAD_DETACH != reason && DLL_PROCESS_DETACH != reason) {
+static void NTAPI thread_local_destructor(PVOID module, DWORD reason,
+ PVOID reserved) {
+ /* Only free memory on |DLL_THREAD_DETACH|, not |DLL_PROCESS_DETACH|. In
+ * VS2015's debug runtime, the C runtime has been unloaded by the time
+ * |DLL_PROCESS_DETACH| runs. See https://crbug.com/575795. This is consistent
+ * with |pthread_key_create| which does not call destructors on process exit,
+ * only thread exit. */
+ if (reason != DLL_THREAD_DETACH) {
return;
}
diff --git a/src/crypto/x509/CMakeLists.txt b/src/crypto/x509/CMakeLists.txt
index 8ffeaa0d..5d82e0a9 100644
--- a/src/crypto/x509/CMakeLists.txt
+++ b/src/crypto/x509/CMakeLists.txt
@@ -9,11 +9,13 @@ add_library(
a_sign.c
a_strex.c
a_verify.c
+ algorithm.c
asn1_gen.c
by_dir.c
by_file.c
i2d_pr.c
pkcs7.c
+ rsa_pss.c
t_crl.c
t_req.c
t_x509.c
@@ -64,5 +66,14 @@ add_executable(
$<TARGET_OBJECTS:test_support>
)
+add_executable(
+ x509_test
+
+ x509_test.cc
+
+ $<TARGET_OBJECTS:test_support>
+)
+
target_link_libraries(pkcs7_test crypto)
-add_dependencies(all_tests pkcs7_test)
+target_link_libraries(x509_test crypto)
+add_dependencies(all_tests pkcs7_test x509_test)
diff --git a/src/crypto/x509/a_digest.c b/src/crypto/x509/a_digest.c
index 430e2e6c..b88d6ac7 100644
--- a/src/crypto/x509/a_digest.c
+++ b/src/crypto/x509/a_digest.c
@@ -61,37 +61,36 @@
#include <openssl/err.h>
#include <openssl/mem.h>
-
int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data,
- unsigned char *md, unsigned int *len)
- {
- int i, ret;
- unsigned char *str,*p;
+ unsigned char *md, unsigned int *len)
+{
+ int i, ret;
+ unsigned char *str, *p;
- i=i2d(data,NULL);
- if ((str=(unsigned char *)OPENSSL_malloc(i)) == NULL)
- {
- OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
- return(0);
- }
- p=str;
- i2d(data,&p);
+ i = i2d(data, NULL);
+ if ((str = (unsigned char *)OPENSSL_malloc(i)) == NULL) {
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+ return (0);
+ }
+ p = str;
+ i2d(data, &p);
- ret = EVP_Digest(str, i, md, len, type, NULL);
- OPENSSL_free(str);
- return ret;
- }
+ ret = EVP_Digest(str, i, md, len, type, NULL);
+ OPENSSL_free(str);
+ return ret;
+}
int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *asn,
- unsigned char *md, unsigned int *len)
- {
- int i, ret;
- unsigned char *str = NULL;
+ unsigned char *md, unsigned int *len)
+{
+ int i, ret;
+ unsigned char *str = NULL;
- i=ASN1_item_i2d(asn,&str, it);
- if (!str) return(0);
+ i = ASN1_item_i2d(asn, &str, it);
+ if (!str)
+ return (0);
- ret = EVP_Digest(str, i, md, len, type, NULL);
- OPENSSL_free(str);
- return ret;
- }
+ ret = EVP_Digest(str, i, md, len, type, NULL);
+ OPENSSL_free(str);
+ return ret;
+}
diff --git a/src/crypto/x509/a_sign.c b/src/crypto/x509/a_sign.c
index 4e9be8a4..13a3ac25 100644
--- a/src/crypto/x509/a_sign.c
+++ b/src/crypto/x509/a_sign.c
@@ -62,75 +62,74 @@
#include <openssl/obj.h>
#include <openssl/x509.h>
-#include "../evp/internal.h"
+#include "internal.h"
-
-int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
- ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey,
- const EVP_MD *type)
- {
- EVP_MD_CTX ctx;
- EVP_MD_CTX_init(&ctx);
- if (!EVP_DigestSignInit(&ctx, NULL, type, NULL, pkey))
- {
- EVP_MD_CTX_cleanup(&ctx);
- return 0;
- }
- return ASN1_item_sign_ctx(it, algor1, algor2, signature, asn, &ctx);
- }
-
+int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1,
+ X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *asn,
+ EVP_PKEY *pkey, const EVP_MD *type)
+{
+ EVP_MD_CTX ctx;
+ EVP_MD_CTX_init(&ctx);
+ if (!EVP_DigestSignInit(&ctx, NULL, type, NULL, pkey)) {
+ EVP_MD_CTX_cleanup(&ctx);
+ return 0;
+ }
+ return ASN1_item_sign_ctx(it, algor1, algor2, signature, asn, &ctx);
+}
int ASN1_item_sign_ctx(const ASN1_ITEM *it,
- X509_ALGOR *algor1, X509_ALGOR *algor2,
- ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx)
- {
- EVP_PKEY *pkey;
- unsigned char *buf_in=NULL,*buf_out=NULL;
- size_t inl=0,outl=0,outll=0;
+ X509_ALGOR *algor1, X509_ALGOR *algor2,
+ ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx)
+{
+ EVP_PKEY *pkey;
+ unsigned char *buf_in = NULL, *buf_out = NULL;
+ size_t inl = 0, outl = 0, outll = 0;
- pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx);
+ pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx);
- /* Write out the requested copies of the AlgorithmIdentifier. */
- if (algor1 && !EVP_DigestSignAlgorithm(ctx, algor1))
- {
- goto err;
- }
- if (algor2 && !EVP_DigestSignAlgorithm(ctx, algor2))
- {
- goto err;
- }
+ /* Write out the requested copies of the AlgorithmIdentifier. */
+ if (algor1 && !x509_digest_sign_algorithm(ctx, algor1)) {
+ goto err;
+ }
+ if (algor2 && !x509_digest_sign_algorithm(ctx, algor2)) {
+ goto err;
+ }
- inl=ASN1_item_i2d(asn,&buf_in, it);
- outll=outl=EVP_PKEY_size(pkey);
- buf_out=OPENSSL_malloc((unsigned int)outl);
- if ((buf_in == NULL) || (buf_out == NULL))
- {
- outl=0;
- OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
- goto err;
- }
+ inl = ASN1_item_i2d(asn, &buf_in, it);
+ outll = outl = EVP_PKEY_size(pkey);
+ buf_out = OPENSSL_malloc((unsigned int)outl);
+ if ((buf_in == NULL) || (buf_out == NULL)) {
+ outl = 0;
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
- if (!EVP_DigestSignUpdate(ctx, buf_in, inl)
- || !EVP_DigestSignFinal(ctx, buf_out, &outl))
- {
- outl=0;
- OPENSSL_PUT_ERROR(X509, ERR_R_EVP_LIB);
- goto err;
- }
- if (signature->data != NULL) OPENSSL_free(signature->data);
- signature->data=buf_out;
- buf_out=NULL;
- signature->length=outl;
- /* In the interests of compatibility, I'll make sure that
- * the bit string has a 'not-used bits' value of 0
- */
- signature->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
- signature->flags|=ASN1_STRING_FLAG_BITS_LEFT;
-err:
- EVP_MD_CTX_cleanup(ctx);
- if (buf_in != NULL)
- { OPENSSL_cleanse((char *)buf_in,(unsigned int)inl); OPENSSL_free(buf_in); }
- if (buf_out != NULL)
- { OPENSSL_cleanse((char *)buf_out,outll); OPENSSL_free(buf_out); }
- return(outl);
- }
+ if (!EVP_DigestSignUpdate(ctx, buf_in, inl)
+ || !EVP_DigestSignFinal(ctx, buf_out, &outl)) {
+ outl = 0;
+ OPENSSL_PUT_ERROR(X509, ERR_R_EVP_LIB);
+ goto err;
+ }
+ if (signature->data != NULL)
+ OPENSSL_free(signature->data);
+ signature->data = buf_out;
+ buf_out = NULL;
+ signature->length = outl;
+ /*
+ * In the interests of compatibility, I'll make sure that the bit string
+ * has a 'not-used bits' value of 0
+ */
+ signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
+ signature->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+ err:
+ EVP_MD_CTX_cleanup(ctx);
+ if (buf_in != NULL) {
+ OPENSSL_cleanse((char *)buf_in, (unsigned int)inl);
+ OPENSSL_free(buf_in);
+ }
+ if (buf_out != NULL) {
+ OPENSSL_cleanse((char *)buf_out, outll);
+ OPENSSL_free(buf_out);
+ }
+ return (outl);
+}
diff --git a/src/crypto/x509/a_strex.c b/src/crypto/x509/a_strex.c
index b194d180..aa2501a4 100644
--- a/src/crypto/x509/a_strex.c
+++ b/src/crypto/x509/a_strex.c
@@ -64,501 +64,570 @@
#include "charmap.h"
-
-/* ASN1_STRING_print_ex() and X509_NAME_print_ex().
- * Enhanced string and name printing routines handling
- * multibyte characters, RFC2253 and a host of other
- * options.
+/*
+ * ASN1_STRING_print_ex() and X509_NAME_print_ex(). Enhanced string and name
+ * printing routines handling multibyte characters, RFC2253 and a host of
+ * other options.
*/
-
-#define CHARTYPE_BS_ESC (ASN1_STRFLGS_ESC_2253 | CHARTYPE_FIRST_ESC_2253 | CHARTYPE_LAST_ESC_2253)
+#define CHARTYPE_BS_ESC (ASN1_STRFLGS_ESC_2253 | CHARTYPE_FIRST_ESC_2253 | CHARTYPE_LAST_ESC_2253)
#define ESC_FLAGS (ASN1_STRFLGS_ESC_2253 | \
- ASN1_STRFLGS_ESC_QUOTE | \
- ASN1_STRFLGS_ESC_CTRL | \
- ASN1_STRFLGS_ESC_MSB)
-
+ ASN1_STRFLGS_ESC_QUOTE | \
+ ASN1_STRFLGS_ESC_CTRL | \
+ ASN1_STRFLGS_ESC_MSB)
static int send_bio_chars(void *arg, const void *buf, int len)
{
- if(!arg) return 1;
- if(BIO_write(arg, buf, len) != len) return 0;
- return 1;
+ if (!arg)
+ return 1;
+ if (BIO_write(arg, buf, len) != len)
+ return 0;
+ return 1;
}
static int send_fp_chars(void *arg, const void *buf, int len)
{
- if(!arg) return 1;
- if(fwrite(buf, 1, len, arg) != (unsigned int)len) return 0;
- return 1;
+ if (!arg)
+ return 1;
+ if (fwrite(buf, 1, len, arg) != (unsigned int)len)
+ return 0;
+ return 1;
}
-typedef int char_io(void *arg, const void *buf, int len);
+typedef int char_io (void *arg, const void *buf, int len);
-/* This function handles display of
- * strings, one character at a time.
- * It is passed an unsigned long for each
- * character because it could come from 2 or even
- * 4 byte forms.
+/*
+ * This function handles display of strings, one character at a time. It is
+ * passed an unsigned long for each character because it could come from 2 or
+ * even 4 byte forms.
*/
#define HEX_SIZE(type) (sizeof(type)*2)
-static int do_esc_char(unsigned long c, unsigned char flags, char *do_quotes, char_io *io_ch, void *arg)
+static int do_esc_char(unsigned long c, unsigned char flags, char *do_quotes,
+ char_io *io_ch, void *arg)
{
- unsigned char chflgs, chtmp;
- char tmphex[HEX_SIZE(long)+3];
-
- if(c > 0xffffffffL)
- return -1;
- if(c > 0xffff) {
- BIO_snprintf(tmphex, sizeof tmphex, "\\W%08lX", c);
- if(!io_ch(arg, tmphex, 10)) return -1;
- return 10;
- }
- if(c > 0xff) {
- BIO_snprintf(tmphex, sizeof tmphex, "\\U%04lX", c);
- if(!io_ch(arg, tmphex, 6)) return -1;
- return 6;
- }
- chtmp = (unsigned char)c;
- if(chtmp > 0x7f) chflgs = flags & ASN1_STRFLGS_ESC_MSB;
- else chflgs = char_type[chtmp] & flags;
- if(chflgs & CHARTYPE_BS_ESC) {
- /* If we don't escape with quotes, signal we need quotes */
- if(chflgs & ASN1_STRFLGS_ESC_QUOTE) {
- if(do_quotes) *do_quotes = 1;
- if(!io_ch(arg, &chtmp, 1)) return -1;
- return 1;
- }
- if(!io_ch(arg, "\\", 1)) return -1;
- if(!io_ch(arg, &chtmp, 1)) return -1;
- return 2;
- }
- if(chflgs & (ASN1_STRFLGS_ESC_CTRL|ASN1_STRFLGS_ESC_MSB)) {
- BIO_snprintf(tmphex, 11, "\\%02X", chtmp);
- if(!io_ch(arg, tmphex, 3)) return -1;
- return 3;
- }
- /* If we get this far and do any escaping at all must escape
- * the escape character itself: backslash.
- */
- if (chtmp == '\\' && flags & ESC_FLAGS) {
- if(!io_ch(arg, "\\\\", 2)) return -1;
- return 2;
- }
- if(!io_ch(arg, &chtmp, 1)) return -1;
- return 1;
+ unsigned char chflgs, chtmp;
+ char tmphex[HEX_SIZE(long) + 3];
+
+ if (c > 0xffffffffL)
+ return -1;
+ if (c > 0xffff) {
+ BIO_snprintf(tmphex, sizeof tmphex, "\\W%08lX", c);
+ if (!io_ch(arg, tmphex, 10))
+ return -1;
+ return 10;
+ }
+ if (c > 0xff) {
+ BIO_snprintf(tmphex, sizeof tmphex, "\\U%04lX", c);
+ if (!io_ch(arg, tmphex, 6))
+ return -1;
+ return 6;
+ }
+ chtmp = (unsigned char)c;
+ if (chtmp > 0x7f)
+ chflgs = flags & ASN1_STRFLGS_ESC_MSB;
+ else
+ chflgs = char_type[chtmp] & flags;
+ if (chflgs & CHARTYPE_BS_ESC) {
+ /* If we don't escape with quotes, signal we need quotes */
+ if (chflgs & ASN1_STRFLGS_ESC_QUOTE) {
+ if (do_quotes)
+ *do_quotes = 1;
+ if (!io_ch(arg, &chtmp, 1))
+ return -1;
+ return 1;
+ }
+ if (!io_ch(arg, "\\", 1))
+ return -1;
+ if (!io_ch(arg, &chtmp, 1))
+ return -1;
+ return 2;
+ }
+ if (chflgs & (ASN1_STRFLGS_ESC_CTRL | ASN1_STRFLGS_ESC_MSB)) {
+ BIO_snprintf(tmphex, 11, "\\%02X", chtmp);
+ if (!io_ch(arg, tmphex, 3))
+ return -1;
+ return 3;
+ }
+ /*
+ * If we get this far and do any escaping at all must escape the escape
+ * character itself: backslash.
+ */
+ if (chtmp == '\\' && flags & ESC_FLAGS) {
+ if (!io_ch(arg, "\\\\", 2))
+ return -1;
+ return 2;
+ }
+ if (!io_ch(arg, &chtmp, 1))
+ return -1;
+ return 1;
}
-#define BUF_TYPE_WIDTH_MASK 0x7
-#define BUF_TYPE_CONVUTF8 0x8
+#define BUF_TYPE_WIDTH_MASK 0x7
+#define BUF_TYPE_CONVUTF8 0x8
-/* This function sends each character in a buffer to
- * do_esc_char(). It interprets the content formats
- * and converts to or from UTF8 as appropriate.
+/*
+ * This function sends each character in a buffer to do_esc_char(). It
+ * interprets the content formats and converts to or from UTF8 as
+ * appropriate.
*/
static int do_buf(unsigned char *buf, int buflen,
- int type, unsigned char flags, char *quotes, char_io *io_ch, void *arg)
+ int type, unsigned char flags, char *quotes, char_io *io_ch,
+ void *arg)
{
- int i, outlen, len;
- unsigned char orflags, *p, *q;
- unsigned long c;
- p = buf;
- q = buf + buflen;
- outlen = 0;
- while(p != q) {
- if(p == buf && flags & ASN1_STRFLGS_ESC_2253) orflags = CHARTYPE_FIRST_ESC_2253;
- else orflags = 0;
- switch(type & BUF_TYPE_WIDTH_MASK) {
- case 4:
- c = ((unsigned long)*p++) << 24;
- c |= ((unsigned long)*p++) << 16;
- c |= ((unsigned long)*p++) << 8;
- c |= *p++;
- break;
-
- case 2:
- c = ((unsigned long)*p++) << 8;
- c |= *p++;
- break;
-
- case 1:
- c = *p++;
- break;
-
- case 0:
- i = UTF8_getc(p, buflen, &c);
- if(i < 0) return -1; /* Invalid UTF8String */
- p += i;
- break;
- default:
- return -1; /* invalid width */
- }
- if (p == q && flags & ASN1_STRFLGS_ESC_2253) orflags = CHARTYPE_LAST_ESC_2253;
- if(type & BUF_TYPE_CONVUTF8) {
- unsigned char utfbuf[6];
- int utflen;
- utflen = UTF8_putc(utfbuf, sizeof utfbuf, c);
- for(i = 0; i < utflen; i++) {
- /* We don't need to worry about setting orflags correctly
- * because if utflen==1 its value will be correct anyway
- * otherwise each character will be > 0x7f and so the
- * character will never be escaped on first and last.
- */
- len = do_esc_char(utfbuf[i], (unsigned char)(flags | orflags), quotes, io_ch, arg);
- if(len < 0) return -1;
- outlen += len;
- }
- } else {
- len = do_esc_char(c, (unsigned char)(flags | orflags), quotes, io_ch, arg);
- if(len < 0) return -1;
- outlen += len;
- }
- }
- return outlen;
+ int i, outlen, len;
+ unsigned char orflags, *p, *q;
+ unsigned long c;
+ p = buf;
+ q = buf + buflen;
+ outlen = 0;
+ while (p != q) {
+ if (p == buf && flags & ASN1_STRFLGS_ESC_2253)
+ orflags = CHARTYPE_FIRST_ESC_2253;
+ else
+ orflags = 0;
+ switch (type & BUF_TYPE_WIDTH_MASK) {
+ case 4:
+ c = ((unsigned long)*p++) << 24;
+ c |= ((unsigned long)*p++) << 16;
+ c |= ((unsigned long)*p++) << 8;
+ c |= *p++;
+ break;
+
+ case 2:
+ c = ((unsigned long)*p++) << 8;
+ c |= *p++;
+ break;
+
+ case 1:
+ c = *p++;
+ break;
+
+ case 0:
+ i = UTF8_getc(p, buflen, &c);
+ if (i < 0)
+ return -1; /* Invalid UTF8String */
+ p += i;
+ break;
+ default:
+ return -1; /* invalid width */
+ }
+ if (p == q && flags & ASN1_STRFLGS_ESC_2253)
+ orflags = CHARTYPE_LAST_ESC_2253;
+ if (type & BUF_TYPE_CONVUTF8) {
+ unsigned char utfbuf[6];
+ int utflen;
+ utflen = UTF8_putc(utfbuf, sizeof utfbuf, c);
+ for (i = 0; i < utflen; i++) {
+ /*
+ * We don't need to worry about setting orflags correctly
+ * because if utflen==1 its value will be correct anyway
+ * otherwise each character will be > 0x7f and so the
+ * character will never be escaped on first and last.
+ */
+ len =
+ do_esc_char(utfbuf[i], (unsigned char)(flags | orflags),
+ quotes, io_ch, arg);
+ if (len < 0)
+ return -1;
+ outlen += len;
+ }
+ } else {
+ len =
+ do_esc_char(c, (unsigned char)(flags | orflags), quotes,
+ io_ch, arg);
+ if (len < 0)
+ return -1;
+ outlen += len;
+ }
+ }
+ return outlen;
}
/* This function hex dumps a buffer of characters */
-static int do_hex_dump(char_io *io_ch, void *arg, unsigned char *buf, int buflen)
+static int do_hex_dump(char_io *io_ch, void *arg, unsigned char *buf,
+ int buflen)
{
- static const char hexdig[] = "0123456789ABCDEF";
- unsigned char *p, *q;
- char hextmp[2];
- if(arg) {
- p = buf;
- q = buf + buflen;
- while(p != q) {
- hextmp[0] = hexdig[*p >> 4];
- hextmp[1] = hexdig[*p & 0xf];
- if(!io_ch(arg, hextmp, 2)) return -1;
- p++;
- }
- }
- return buflen << 1;
+ static const char hexdig[] = "0123456789ABCDEF";
+ unsigned char *p, *q;
+ char hextmp[2];
+ if (arg) {
+ p = buf;
+ q = buf + buflen;
+ while (p != q) {
+ hextmp[0] = hexdig[*p >> 4];
+ hextmp[1] = hexdig[*p & 0xf];
+ if (!io_ch(arg, hextmp, 2))
+ return -1;
+ p++;
+ }
+ }
+ return buflen << 1;
}
-/* "dump" a string. This is done when the type is unknown,
- * or the flags request it. We can either dump the content
- * octets or the entire DER encoding. This uses the RFC2253
- * #01234 format.
+/*
+ * "dump" a string. This is done when the type is unknown, or the flags
+ * request it. We can either dump the content octets or the entire DER
+ * encoding. This uses the RFC2253 #01234 format.
*/
-static int do_dump(unsigned long lflags, char_io *io_ch, void *arg, ASN1_STRING *str)
+static int do_dump(unsigned long lflags, char_io *io_ch, void *arg,
+ ASN1_STRING *str)
{
- /* Placing the ASN1_STRING in a temp ASN1_TYPE allows
- * the DER encoding to readily obtained
- */
- ASN1_TYPE t;
- unsigned char *der_buf, *p;
- int outlen, der_len;
-
- if(!io_ch(arg, "#", 1)) return -1;
- /* If we don't dump DER encoding just dump content octets */
- if(!(lflags & ASN1_STRFLGS_DUMP_DER)) {
- outlen = do_hex_dump(io_ch, arg, str->data, str->length);
- if(outlen < 0) return -1;
- return outlen + 1;
- }
- t.type = str->type;
- t.value.ptr = (char *)str;
- der_len = i2d_ASN1_TYPE(&t, NULL);
- der_buf = OPENSSL_malloc(der_len);
- if(!der_buf) return -1;
- p = der_buf;
- i2d_ASN1_TYPE(&t, &p);
- outlen = do_hex_dump(io_ch, arg, der_buf, der_len);
- OPENSSL_free(der_buf);
- if(outlen < 0) return -1;
- return outlen + 1;
+ /*
+ * Placing the ASN1_STRING in a temp ASN1_TYPE allows the DER encoding to
+ * readily obtained
+ */
+ ASN1_TYPE t;
+ unsigned char *der_buf, *p;
+ int outlen, der_len;
+
+ if (!io_ch(arg, "#", 1))
+ return -1;
+ /* If we don't dump DER encoding just dump content octets */
+ if (!(lflags & ASN1_STRFLGS_DUMP_DER)) {
+ outlen = do_hex_dump(io_ch, arg, str->data, str->length);
+ if (outlen < 0)
+ return -1;
+ return outlen + 1;
+ }
+ t.type = str->type;
+ t.value.ptr = (char *)str;
+ der_len = i2d_ASN1_TYPE(&t, NULL);
+ der_buf = OPENSSL_malloc(der_len);
+ if (!der_buf)
+ return -1;
+ p = der_buf;
+ i2d_ASN1_TYPE(&t, &p);
+ outlen = do_hex_dump(io_ch, arg, der_buf, der_len);
+ OPENSSL_free(der_buf);
+ if (outlen < 0)
+ return -1;
+ return outlen + 1;
}
-/* Lookup table to convert tags to character widths,
- * 0 = UTF8 encoded, -1 is used for non string types
- * otherwise it is the number of bytes per character
+/*
+ * Lookup table to convert tags to character widths, 0 = UTF8 encoded, -1 is
+ * used for non string types otherwise it is the number of bytes per
+ * character
*/
static const signed char tag2nbyte[] = {
- -1, -1, -1, -1, -1, /* 0-4 */
- -1, -1, -1, -1, -1, /* 5-9 */
- -1, -1, 0, -1, /* 10-13 */
- -1, -1, -1, -1, /* 15-17 */
- -1, 1, 1, /* 18-20 */
- -1, 1, 1, 1, /* 21-24 */
- -1, 1, -1, /* 25-27 */
- 4, -1, 2 /* 28-30 */
+ -1, -1, -1, -1, -1, /* 0-4 */
+ -1, -1, -1, -1, -1, /* 5-9 */
+ -1, -1, 0, -1, /* 10-13 */
+ -1, -1, -1, -1, /* 15-17 */
+ -1, 1, 1, /* 18-20 */
+ -1, 1, 1, 1, /* 21-24 */
+ -1, 1, -1, /* 25-27 */
+ 4, -1, 2 /* 28-30 */
};
-/* This is the main function, print out an
- * ASN1_STRING taking note of various escape
- * and display options. Returns number of
- * characters written or -1 if an error
- * occurred.
+/*
+ * This is the main function, print out an ASN1_STRING taking note of various
+ * escape and display options. Returns number of characters written or -1 if
+ * an error occurred.
*/
-static int do_print_ex(char_io *io_ch, void *arg, unsigned long lflags, ASN1_STRING *str)
+static int do_print_ex(char_io *io_ch, void *arg, unsigned long lflags,
+ ASN1_STRING *str)
{
- int outlen, len;
- int type;
- char quotes;
- unsigned char flags;
- quotes = 0;
- /* Keep a copy of escape flags */
- flags = (unsigned char)(lflags & ESC_FLAGS);
-
- type = str->type;
-
- outlen = 0;
-
-
- if(lflags & ASN1_STRFLGS_SHOW_TYPE) {
- const char *tagname;
- tagname = ASN1_tag2str(type);
- outlen += strlen(tagname);
- if(!io_ch(arg, tagname, outlen) || !io_ch(arg, ":", 1)) return -1;
- outlen++;
- }
-
- /* Decide what to do with type, either dump content or display it */
-
- /* Dump everything */
- if(lflags & ASN1_STRFLGS_DUMP_ALL) type = -1;
- /* Ignore the string type */
- else if(lflags & ASN1_STRFLGS_IGNORE_TYPE) type = 1;
- else {
- /* Else determine width based on type */
- if((type > 0) && (type < 31)) type = tag2nbyte[type];
- else type = -1;
- if((type == -1) && !(lflags & ASN1_STRFLGS_DUMP_UNKNOWN)) type = 1;
- }
-
- if(type == -1) {
- len = do_dump(lflags, io_ch, arg, str);
- if(len < 0) return -1;
- outlen += len;
- return outlen;
- }
-
- if(lflags & ASN1_STRFLGS_UTF8_CONVERT) {
- /* Note: if string is UTF8 and we want
- * to convert to UTF8 then we just interpret
- * it as 1 byte per character to avoid converting
- * twice.
- */
- if(!type) type = 1;
- else type |= BUF_TYPE_CONVUTF8;
- }
-
- len = do_buf(str->data, str->length, type, flags, &quotes, io_ch, NULL);
- if(len < 0) return -1;
- outlen += len;
- if(quotes) outlen += 2;
- if(!arg) return outlen;
- if(quotes && !io_ch(arg, "\"", 1)) return -1;
- if(do_buf(str->data, str->length, type, flags, NULL, io_ch, arg) < 0)
- return -1;
- if(quotes && !io_ch(arg, "\"", 1)) return -1;
- return outlen;
+ int outlen, len;
+ int type;
+ char quotes;
+ unsigned char flags;
+ quotes = 0;
+ /* Keep a copy of escape flags */
+ flags = (unsigned char)(lflags & ESC_FLAGS);
+
+ type = str->type;
+
+ outlen = 0;
+
+ if (lflags & ASN1_STRFLGS_SHOW_TYPE) {
+ const char *tagname;
+ tagname = ASN1_tag2str(type);
+ outlen += strlen(tagname);
+ if (!io_ch(arg, tagname, outlen) || !io_ch(arg, ":", 1))
+ return -1;
+ outlen++;
+ }
+
+ /* Decide what to do with type, either dump content or display it */
+
+ /* Dump everything */
+ if (lflags & ASN1_STRFLGS_DUMP_ALL)
+ type = -1;
+ /* Ignore the string type */
+ else if (lflags & ASN1_STRFLGS_IGNORE_TYPE)
+ type = 1;
+ else {
+ /* Else determine width based on type */
+ if ((type > 0) && (type < 31))
+ type = tag2nbyte[type];
+ else
+ type = -1;
+ if ((type == -1) && !(lflags & ASN1_STRFLGS_DUMP_UNKNOWN))
+ type = 1;
+ }
+
+ if (type == -1) {
+ len = do_dump(lflags, io_ch, arg, str);
+ if (len < 0)
+ return -1;
+ outlen += len;
+ return outlen;
+ }
+
+ if (lflags & ASN1_STRFLGS_UTF8_CONVERT) {
+ /*
+ * Note: if string is UTF8 and we want to convert to UTF8 then we
+ * just interpret it as 1 byte per character to avoid converting
+ * twice.
+ */
+ if (!type)
+ type = 1;
+ else
+ type |= BUF_TYPE_CONVUTF8;
+ }
+
+ len = do_buf(str->data, str->length, type, flags, &quotes, io_ch, NULL);
+ if (len < 0)
+ return -1;
+ outlen += len;
+ if (quotes)
+ outlen += 2;
+ if (!arg)
+ return outlen;
+ if (quotes && !io_ch(arg, "\"", 1))
+ return -1;
+ if (do_buf(str->data, str->length, type, flags, NULL, io_ch, arg) < 0)
+ return -1;
+ if (quotes && !io_ch(arg, "\"", 1))
+ return -1;
+ return outlen;
}
/* Used for line indenting: print 'indent' spaces */
static int do_indent(char_io *io_ch, void *arg, int indent)
{
- int i;
- for(i = 0; i < indent; i++)
- if(!io_ch(arg, " ", 1)) return 0;
- return 1;
+ int i;
+ for (i = 0; i < indent; i++)
+ if (!io_ch(arg, " ", 1))
+ return 0;
+ return 1;
}
-#define FN_WIDTH_LN 25
-#define FN_WIDTH_SN 10
+#define FN_WIDTH_LN 25
+#define FN_WIDTH_SN 10
static int do_name_ex(char_io *io_ch, void *arg, X509_NAME *n,
- int indent, unsigned long flags)
+ int indent, unsigned long flags)
{
- int i, prev = -1, orflags, cnt;
- int fn_opt, fn_nid;
- ASN1_OBJECT *fn;
- ASN1_STRING *val;
- X509_NAME_ENTRY *ent;
- char objtmp[80];
- const char *objbuf;
- int outlen, len;
- const char *sep_dn, *sep_mv, *sep_eq;
- int sep_dn_len, sep_mv_len, sep_eq_len;
- if(indent < 0) indent = 0;
- outlen = indent;
- if(!do_indent(io_ch, arg, indent)) return -1;
- switch (flags & XN_FLAG_SEP_MASK)
- {
- case XN_FLAG_SEP_MULTILINE:
- sep_dn = "\n";
- sep_dn_len = 1;
- sep_mv = " + ";
- sep_mv_len = 3;
- break;
-
- case XN_FLAG_SEP_COMMA_PLUS:
- sep_dn = ",";
- sep_dn_len = 1;
- sep_mv = "+";
- sep_mv_len = 1;
- indent = 0;
- break;
-
- case XN_FLAG_SEP_CPLUS_SPC:
- sep_dn = ", ";
- sep_dn_len = 2;
- sep_mv = " + ";
- sep_mv_len = 3;
- indent = 0;
- break;
-
- case XN_FLAG_SEP_SPLUS_SPC:
- sep_dn = "; ";
- sep_dn_len = 2;
- sep_mv = " + ";
- sep_mv_len = 3;
- indent = 0;
- break;
-
- default:
- return -1;
- }
-
- if(flags & XN_FLAG_SPC_EQ) {
- sep_eq = " = ";
- sep_eq_len = 3;
- } else {
- sep_eq = "=";
- sep_eq_len = 1;
- }
-
- fn_opt = flags & XN_FLAG_FN_MASK;
-
- cnt = X509_NAME_entry_count(n);
- for(i = 0; i < cnt; i++) {
- if(flags & XN_FLAG_DN_REV)
- ent = X509_NAME_get_entry(n, cnt - i - 1);
- else ent = X509_NAME_get_entry(n, i);
- if(prev != -1) {
- if(prev == ent->set) {
- if(!io_ch(arg, sep_mv, sep_mv_len)) return -1;
- outlen += sep_mv_len;
- } else {
- if(!io_ch(arg, sep_dn, sep_dn_len)) return -1;
- outlen += sep_dn_len;
- if(!do_indent(io_ch, arg, indent)) return -1;
- outlen += indent;
- }
- }
- prev = ent->set;
- fn = X509_NAME_ENTRY_get_object(ent);
- val = X509_NAME_ENTRY_get_data(ent);
- fn_nid = OBJ_obj2nid(fn);
- if(fn_opt != XN_FLAG_FN_NONE) {
- int objlen, fld_len;
- if((fn_opt == XN_FLAG_FN_OID) || (fn_nid==NID_undef) ) {
- OBJ_obj2txt(objtmp, sizeof objtmp, fn, 1);
- fld_len = 0; /* XXX: what should this be? */
- objbuf = objtmp;
- } else {
- if(fn_opt == XN_FLAG_FN_SN) {
- fld_len = FN_WIDTH_SN;
- objbuf = OBJ_nid2sn(fn_nid);
- } else if(fn_opt == XN_FLAG_FN_LN) {
- fld_len = FN_WIDTH_LN;
- objbuf = OBJ_nid2ln(fn_nid);
- } else {
- fld_len = 0; /* XXX: what should this be? */
- objbuf = "";
- }
- }
- objlen = strlen(objbuf);
- if(!io_ch(arg, objbuf, objlen)) return -1;
- if ((objlen < fld_len) && (flags & XN_FLAG_FN_ALIGN)) {
- if (!do_indent(io_ch, arg, fld_len - objlen)) return -1;
- outlen += fld_len - objlen;
- }
- if(!io_ch(arg, sep_eq, sep_eq_len)) return -1;
- outlen += objlen + sep_eq_len;
- }
- /* If the field name is unknown then fix up the DER dump
- * flag. We might want to limit this further so it will
- * DER dump on anything other than a few 'standard' fields.
- */
- if((fn_nid == NID_undef) && (flags & XN_FLAG_DUMP_UNKNOWN_FIELDS))
- orflags = ASN1_STRFLGS_DUMP_ALL;
- else orflags = 0;
-
- len = do_print_ex(io_ch, arg, flags | orflags, val);
- if(len < 0) return -1;
- outlen += len;
- }
- return outlen;
+ int i, prev = -1, orflags, cnt;
+ int fn_opt, fn_nid;
+ ASN1_OBJECT *fn;
+ ASN1_STRING *val;
+ X509_NAME_ENTRY *ent;
+ char objtmp[80];
+ const char *objbuf;
+ int outlen, len;
+ const char *sep_dn, *sep_mv, *sep_eq;
+ int sep_dn_len, sep_mv_len, sep_eq_len;
+ if (indent < 0)
+ indent = 0;
+ outlen = indent;
+ if (!do_indent(io_ch, arg, indent))
+ return -1;
+ switch (flags & XN_FLAG_SEP_MASK) {
+ case XN_FLAG_SEP_MULTILINE:
+ sep_dn = "\n";
+ sep_dn_len = 1;
+ sep_mv = " + ";
+ sep_mv_len = 3;
+ break;
+
+ case XN_FLAG_SEP_COMMA_PLUS:
+ sep_dn = ",";
+ sep_dn_len = 1;
+ sep_mv = "+";
+ sep_mv_len = 1;
+ indent = 0;
+ break;
+
+ case XN_FLAG_SEP_CPLUS_SPC:
+ sep_dn = ", ";
+ sep_dn_len = 2;
+ sep_mv = " + ";
+ sep_mv_len = 3;
+ indent = 0;
+ break;
+
+ case XN_FLAG_SEP_SPLUS_SPC:
+ sep_dn = "; ";
+ sep_dn_len = 2;
+ sep_mv = " + ";
+ sep_mv_len = 3;
+ indent = 0;
+ break;
+
+ default:
+ return -1;
+ }
+
+ if (flags & XN_FLAG_SPC_EQ) {
+ sep_eq = " = ";
+ sep_eq_len = 3;
+ } else {
+ sep_eq = "=";
+ sep_eq_len = 1;
+ }
+
+ fn_opt = flags & XN_FLAG_FN_MASK;
+
+ cnt = X509_NAME_entry_count(n);
+ for (i = 0; i < cnt; i++) {
+ if (flags & XN_FLAG_DN_REV)
+ ent = X509_NAME_get_entry(n, cnt - i - 1);
+ else
+ ent = X509_NAME_get_entry(n, i);
+ if (prev != -1) {
+ if (prev == ent->set) {
+ if (!io_ch(arg, sep_mv, sep_mv_len))
+ return -1;
+ outlen += sep_mv_len;
+ } else {
+ if (!io_ch(arg, sep_dn, sep_dn_len))
+ return -1;
+ outlen += sep_dn_len;
+ if (!do_indent(io_ch, arg, indent))
+ return -1;
+ outlen += indent;
+ }
+ }
+ prev = ent->set;
+ fn = X509_NAME_ENTRY_get_object(ent);
+ val = X509_NAME_ENTRY_get_data(ent);
+ fn_nid = OBJ_obj2nid(fn);
+ if (fn_opt != XN_FLAG_FN_NONE) {
+ int objlen, fld_len;
+ if ((fn_opt == XN_FLAG_FN_OID) || (fn_nid == NID_undef)) {
+ OBJ_obj2txt(objtmp, sizeof objtmp, fn, 1);
+ fld_len = 0; /* XXX: what should this be? */
+ objbuf = objtmp;
+ } else {
+ if (fn_opt == XN_FLAG_FN_SN) {
+ fld_len = FN_WIDTH_SN;
+ objbuf = OBJ_nid2sn(fn_nid);
+ } else if (fn_opt == XN_FLAG_FN_LN) {
+ fld_len = FN_WIDTH_LN;
+ objbuf = OBJ_nid2ln(fn_nid);
+ } else {
+ fld_len = 0; /* XXX: what should this be? */
+ objbuf = "";
+ }
+ }
+ objlen = strlen(objbuf);
+ if (!io_ch(arg, objbuf, objlen))
+ return -1;
+ if ((objlen < fld_len) && (flags & XN_FLAG_FN_ALIGN)) {
+ if (!do_indent(io_ch, arg, fld_len - objlen))
+ return -1;
+ outlen += fld_len - objlen;
+ }
+ if (!io_ch(arg, sep_eq, sep_eq_len))
+ return -1;
+ outlen += objlen + sep_eq_len;
+ }
+ /*
+ * If the field name is unknown then fix up the DER dump flag. We
+ * might want to limit this further so it will DER dump on anything
+ * other than a few 'standard' fields.
+ */
+ if ((fn_nid == NID_undef) && (flags & XN_FLAG_DUMP_UNKNOWN_FIELDS))
+ orflags = ASN1_STRFLGS_DUMP_ALL;
+ else
+ orflags = 0;
+
+ len = do_print_ex(io_ch, arg, flags | orflags, val);
+ if (len < 0)
+ return -1;
+ outlen += len;
+ }
+ return outlen;
}
/* Wrappers round the main functions */
-int X509_NAME_print_ex(BIO *out, X509_NAME *nm, int indent, unsigned long flags)
+int X509_NAME_print_ex(BIO *out, X509_NAME *nm, int indent,
+ unsigned long flags)
{
- if(flags == XN_FLAG_COMPAT)
- return X509_NAME_print(out, nm, indent);
- return do_name_ex(send_bio_chars, out, nm, indent, flags);
+ if (flags == XN_FLAG_COMPAT)
+ return X509_NAME_print(out, nm, indent);
+ return do_name_ex(send_bio_chars, out, nm, indent, flags);
}
#ifndef OPENSSL_NO_FP_API
-int X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent, unsigned long flags)
+int X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent,
+ unsigned long flags)
{
- if(flags == XN_FLAG_COMPAT)
- {
- BIO *btmp;
- int ret;
- btmp = BIO_new_fp(fp, BIO_NOCLOSE);
- if(!btmp) return -1;
- ret = X509_NAME_print(btmp, nm, indent);
- BIO_free(btmp);
- return ret;
- }
- return do_name_ex(send_fp_chars, fp, nm, indent, flags);
+ if (flags == XN_FLAG_COMPAT) {
+ BIO *btmp;
+ int ret;
+ btmp = BIO_new_fp(fp, BIO_NOCLOSE);
+ if (!btmp)
+ return -1;
+ ret = X509_NAME_print(btmp, nm, indent);
+ BIO_free(btmp);
+ return ret;
+ }
+ return do_name_ex(send_fp_chars, fp, nm, indent, flags);
}
#endif
int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags)
{
- return do_print_ex(send_bio_chars, out, flags, str);
+ return do_print_ex(send_bio_chars, out, flags, str);
}
#ifndef OPENSSL_NO_FP_API
int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags)
{
- return do_print_ex(send_fp_chars, fp, flags, str);
+ return do_print_ex(send_fp_chars, fp, flags, str);
}
#endif
-/* Utility function: convert any string type to UTF8, returns number of bytes
+/*
+ * Utility function: convert any string type to UTF8, returns number of bytes
* in output string or a negative error code
*/
int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in)
{
- ASN1_STRING stmp, *str = &stmp;
- int mbflag, type, ret;
- if(!in) return -1;
- type = in->type;
- if((type < 0) || (type > 30)) return -1;
- mbflag = tag2nbyte[type];
- if(mbflag == -1) return -1;
- mbflag |= MBSTRING_FLAG;
- stmp.data = NULL;
- stmp.length = 0;
- stmp.flags = 0;
- ret = ASN1_mbstring_copy(&str, in->data, in->length, mbflag, B_ASN1_UTF8STRING);
- if(ret < 0) return ret;
- *out = stmp.data;
- return stmp.length;
+ ASN1_STRING stmp, *str = &stmp;
+ int mbflag, type, ret;
+ if (!in)
+ return -1;
+ type = in->type;
+ if ((type < 0) || (type > 30))
+ return -1;
+ mbflag = tag2nbyte[type];
+ if (mbflag == -1)
+ return -1;
+ mbflag |= MBSTRING_FLAG;
+ stmp.data = NULL;
+ stmp.length = 0;
+ stmp.flags = 0;
+ ret =
+ ASN1_mbstring_copy(&str, in->data, in->length, mbflag,
+ B_ASN1_UTF8STRING);
+ if (ret < 0)
+ return ret;
+ *out = stmp.data;
+ return stmp.length;
}
diff --git a/src/crypto/x509/a_verify.c b/src/crypto/x509/a_verify.c
index 572a1392..5a9adb65 100644
--- a/src/crypto/x509/a_verify.c
+++ b/src/crypto/x509/a_verify.c
@@ -68,66 +68,60 @@
#include <openssl/mem.h>
#include <openssl/obj.h>
-#include "../evp/internal.h"
-
+#include "internal.h"
int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
- ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey)
- {
- EVP_MD_CTX ctx;
- uint8_t *buf_in = NULL;
- int ret = 0, inl;
+ ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey)
+{
+ EVP_MD_CTX ctx;
+ uint8_t *buf_in = NULL;
+ int ret = 0, inl;
- if (!pkey)
- {
- OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER);
- return 0;
- }
+ if (!pkey) {
+ 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, X509_R_INVALID_BIT_STRING_BITS_LEFT);
- return 0;
- }
+ if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7) {
+ OPENSSL_PUT_ERROR(X509, X509_R_INVALID_BIT_STRING_BITS_LEFT);
+ return 0;
+ }
- EVP_MD_CTX_init(&ctx);
+ EVP_MD_CTX_init(&ctx);
- if (!EVP_DigestVerifyInitFromAlgorithm(&ctx, a, pkey))
- {
- goto err;
- }
+ if (!x509_digest_verify_init(&ctx, a, pkey)) {
+ goto err;
+ }
- inl = ASN1_item_i2d(asn, &buf_in, it);
-
- if (buf_in == NULL)
- {
- OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
- goto err;
- }
+ inl = ASN1_item_i2d(asn, &buf_in, it);
- if (!EVP_DigestVerifyUpdate(&ctx,buf_in,inl))
- {
- OPENSSL_cleanse(buf_in,(unsigned int)inl);
- OPENSSL_free(buf_in);
- OPENSSL_PUT_ERROR(X509, ERR_R_EVP_LIB);
- goto err;
- }
+ if (buf_in == NULL) {
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
- OPENSSL_cleanse(buf_in,(unsigned int)inl);
- OPENSSL_free(buf_in);
+ if (!EVP_DigestVerifyUpdate(&ctx, buf_in, inl)) {
+ OPENSSL_cleanse(buf_in, (unsigned int)inl);
+ OPENSSL_free(buf_in);
+ OPENSSL_PUT_ERROR(X509, ERR_R_EVP_LIB);
+ goto err;
+ }
- if (EVP_DigestVerifyFinal(&ctx,signature->data,
- (size_t)signature->length) <= 0)
- {
- OPENSSL_PUT_ERROR(X509, ERR_R_EVP_LIB);
- goto err;
- }
- /* we don't need to zero the 'ctx' because we just checked
- * public information */
- /* memset(&ctx,0,sizeof(ctx)); */
- ret = 1;
-err:
- EVP_MD_CTX_cleanup(&ctx);
- return ret;
- }
+ OPENSSL_cleanse(buf_in, (unsigned int)inl);
+ OPENSSL_free(buf_in);
+ if (EVP_DigestVerifyFinal(&ctx, signature->data,
+ (size_t)signature->length) <= 0) {
+ OPENSSL_PUT_ERROR(X509, ERR_R_EVP_LIB);
+ goto err;
+ }
+ /*
+ * we don't need to zero the 'ctx' because we just checked public
+ * information
+ */
+ /* memset(&ctx,0,sizeof(ctx)); */
+ ret = 1;
+ err:
+ EVP_MD_CTX_cleanup(&ctx);
+ return ret;
+}
diff --git a/src/crypto/evp/algorithm.c b/src/crypto/x509/algorithm.c
index 63bc77af..78ae882b 100644
--- a/src/crypto/evp/algorithm.c
+++ b/src/crypto/x509/algorithm.c
@@ -54,100 +54,84 @@
* copied and put under another distribution licence
* [including the GNU Public Licence.] */
-#include <openssl/evp.h>
-
-#include <assert.h>
+#include <openssl/x509.h>
#include <openssl/asn1.h>
+#include <openssl/digest.h>
#include <openssl/err.h>
+#include <openssl/evp.h>
#include <openssl/obj.h>
-#include <openssl/x509.h>
#include "internal.h"
-int EVP_DigestSignAlgorithm(EVP_MD_CTX *ctx, X509_ALGOR *algor) {
- const EVP_MD *digest;
- EVP_PKEY *pkey;
- int sign_nid, paramtype;
-
- digest = EVP_MD_CTX_md(ctx);
- pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx);
- if (!digest || !pkey) {
- OPENSSL_PUT_ERROR(EVP, EVP_R_CONTEXT_NOT_INITIALISED);
+int x509_digest_sign_algorithm(EVP_MD_CTX *ctx, X509_ALGOR *algor) {
+ const EVP_MD *digest = EVP_MD_CTX_md(ctx);
+ EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx);
+ if (digest == NULL || pkey == NULL) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_CONTEXT_NOT_INITIALISED);
return 0;
}
- if (pkey->ameth->digest_sign_algorithm) {
- switch (pkey->ameth->digest_sign_algorithm(ctx, algor)) {
- case EVP_DIGEST_SIGN_ALGORITHM_ERROR:
- return 0;
- case EVP_DIGEST_SIGN_ALGORITHM_SUCCESS:
- return 1;
- case EVP_DIGEST_SIGN_ALGORITHM_DEFAULT:
- /* Use default behavior. */
- break;
- default:
- assert(0);
+ if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA) {
+ int pad_mode;
+ if (!EVP_PKEY_CTX_get_rsa_padding(ctx->pctx, &pad_mode)) {
+ return 0;
+ }
+ /* RSA-PSS has special signature algorithm logic. */
+ if (pad_mode == RSA_PKCS1_PSS_PADDING) {
+ return x509_rsa_ctx_to_pss(ctx, algor);
}
}
/* Default behavior: look up the OID for the algorithm/hash pair and encode
* that. */
+ int sign_nid;
if (!OBJ_find_sigid_by_algs(&sign_nid, EVP_MD_type(digest),
- pkey->ameth->pkey_id)) {
- OPENSSL_PUT_ERROR(EVP, EVP_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
+ EVP_PKEY_id(pkey))) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
return 0;
}
- if (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL) {
- paramtype = V_ASN1_NULL;
- } else {
- paramtype = V_ASN1_UNDEF;
- }
-
+ /* RSA signature algorithms include an explicit NULL parameter. Others omit
+ * it. */
+ int paramtype =
+ (EVP_PKEY_id(pkey) == EVP_PKEY_RSA) ? V_ASN1_NULL : V_ASN1_UNDEF;
X509_ALGOR_set0(algor, OBJ_nid2obj(sign_nid), paramtype, NULL);
return 1;
}
-int EVP_DigestVerifyInitFromAlgorithm(EVP_MD_CTX *ctx,
- X509_ALGOR *algor,
- EVP_PKEY *pkey) {
+int x509_digest_verify_init(EVP_MD_CTX *ctx, X509_ALGOR *sigalg,
+ EVP_PKEY *pkey) {
+ /* Convert the signature OID into digest and public key OIDs. */
+ int sigalg_nid = OBJ_obj2nid(sigalg->algorithm);
int digest_nid, pkey_nid;
- const EVP_PKEY_ASN1_METHOD *ameth;
- const EVP_MD *digest;
-
- /* 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_R_UNKNOWN_SIGNATURE_ALGORITHM);
+ if (!OBJ_find_sigid_algs(sigalg_nid, &digest_nid, &pkey_nid)) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_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_R_WRONG_PUBLIC_KEY_TYPE);
+ /* Check the public key OID matches the public key type. */
+ if (pkey_nid != EVP_PKEY_id(pkey)) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_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_R_UNKNOWN_SIGNATURE_ALGORITHM);
+ if (sigalg_nid != NID_rsassaPss) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
return 0;
}
-
- return pkey->ameth->digest_verify_init_from_algorithm(ctx, algor, pkey);
+ return x509_rsa_pss_to_ctx(ctx, sigalg, pkey);
}
/* Otherwise, initialize with the digest from the OID. */
- digest = EVP_get_digestbynid(digest_nid);
+ const EVP_MD *digest = EVP_get_digestbynid(digest_nid);
if (digest == NULL) {
- OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
return 0;
}
return EVP_DigestVerifyInit(ctx, NULL, digest, NULL, pkey);
}
-
diff --git a/src/crypto/x509/asn1_gen.c b/src/crypto/x509/asn1_gen.c
index 850a8167..03a0ab9f 100644
--- a/src/crypto/x509/asn1_gen.c
+++ b/src/crypto/x509/asn1_gen.c
@@ -66,808 +66,753 @@
#include "../internal.h"
+/*
+ * Although this file is in crypto/x509 for layering purposes, it emits
+ * errors from the ASN.1 module for OpenSSL compatibility.
+ */
-/* Although this file is in crypto/x509 for layering purposes, it emits errors
- * from the ASN.1 module for OpenSSL compatibility. */
+#define ASN1_GEN_FLAG 0x10000
+#define ASN1_GEN_FLAG_IMP (ASN1_GEN_FLAG|1)
+#define ASN1_GEN_FLAG_EXP (ASN1_GEN_FLAG|2)
+#define ASN1_GEN_FLAG_TAG (ASN1_GEN_FLAG|3)
+#define ASN1_GEN_FLAG_BITWRAP (ASN1_GEN_FLAG|4)
+#define ASN1_GEN_FLAG_OCTWRAP (ASN1_GEN_FLAG|5)
+#define ASN1_GEN_FLAG_SEQWRAP (ASN1_GEN_FLAG|6)
+#define ASN1_GEN_FLAG_SETWRAP (ASN1_GEN_FLAG|7)
+#define ASN1_GEN_FLAG_FORMAT (ASN1_GEN_FLAG|8)
-#define ASN1_GEN_FLAG 0x10000
-#define ASN1_GEN_FLAG_IMP (ASN1_GEN_FLAG|1)
-#define ASN1_GEN_FLAG_EXP (ASN1_GEN_FLAG|2)
-#define ASN1_GEN_FLAG_TAG (ASN1_GEN_FLAG|3)
-#define ASN1_GEN_FLAG_BITWRAP (ASN1_GEN_FLAG|4)
-#define ASN1_GEN_FLAG_OCTWRAP (ASN1_GEN_FLAG|5)
-#define ASN1_GEN_FLAG_SEQWRAP (ASN1_GEN_FLAG|6)
-#define ASN1_GEN_FLAG_SETWRAP (ASN1_GEN_FLAG|7)
-#define ASN1_GEN_FLAG_FORMAT (ASN1_GEN_FLAG|8)
+#define ASN1_GEN_STR(str,val) {str, sizeof(str) - 1, val}
-#define ASN1_GEN_STR(str,val) {str, sizeof(str) - 1, val}
-
-#define ASN1_FLAG_EXP_MAX 20
+#define ASN1_FLAG_EXP_MAX 20
/* Input formats */
/* ASCII: default */
-#define ASN1_GEN_FORMAT_ASCII 1
+#define ASN1_GEN_FORMAT_ASCII 1
/* UTF8 */
-#define ASN1_GEN_FORMAT_UTF8 2
+#define ASN1_GEN_FORMAT_UTF8 2
/* Hex */
-#define ASN1_GEN_FORMAT_HEX 3
+#define ASN1_GEN_FORMAT_HEX 3
/* List of bits */
-#define ASN1_GEN_FORMAT_BITLIST 4
-
-
-struct tag_name_st
- {
- const char *strnam;
- int len;
- int tag;
- };
-
-typedef struct
- {
- int exp_tag;
- int exp_class;
- int exp_constructed;
- int exp_pad;
- long exp_len;
- } tag_exp_type;
-
-typedef struct
- {
- int imp_tag;
- int imp_class;
- int utype;
- int format;
- const char *str;
- tag_exp_type exp_list[ASN1_FLAG_EXP_MAX];
- int exp_count;
- } tag_exp_arg;
+#define ASN1_GEN_FORMAT_BITLIST 4
+
+struct tag_name_st {
+ const char *strnam;
+ int len;
+ int tag;
+};
+
+typedef struct {
+ int exp_tag;
+ int exp_class;
+ int exp_constructed;
+ int exp_pad;
+ long exp_len;
+} tag_exp_type;
+
+typedef struct {
+ int imp_tag;
+ int imp_class;
+ int utype;
+ int format;
+ const char *str;
+ tag_exp_type exp_list[ASN1_FLAG_EXP_MAX];
+ int exp_count;
+} tag_exp_arg;
static int bitstr_cb(const char *elem, int len, void *bitstr);
static int asn1_cb(const char *elem, int len, void *bitstr);
-static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, int exp_constructed, int exp_pad, int imp_ok);
-static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass);
+static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class,
+ int exp_constructed, int exp_pad, int imp_ok);
+static int parse_tagging(const char *vstart, int vlen, int *ptag,
+ int *pclass);
static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf);
static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype);
static int asn1_str2tag(const char *tagstr, int len);
ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf)
- {
- X509V3_CTX cnf;
+{
+ X509V3_CTX cnf;
- if (!nconf)
- return ASN1_generate_v3(str, NULL);
+ if (!nconf)
+ return ASN1_generate_v3(str, NULL);
- X509V3_set_nconf(&cnf, nconf);
- return ASN1_generate_v3(str, &cnf);
- }
+ X509V3_set_nconf(&cnf, nconf);
+ return ASN1_generate_v3(str, &cnf);
+}
ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf)
- OPENSSL_SUPPRESS_POTENTIALLY_UNINITIALIZED_WARNINGS
- {
- ASN1_TYPE *ret;
- tag_exp_arg asn1_tags;
- tag_exp_type *etmp;
-
- int i, len;
-
- unsigned char *orig_der = NULL, *new_der = NULL;
- const unsigned char *cpy_start;
- unsigned char *p;
- const unsigned char *cp;
- int cpy_len;
- long hdr_len;
- int hdr_constructed = 0, hdr_tag, hdr_class;
- int r;
-
- asn1_tags.imp_tag = -1;
- asn1_tags.imp_class = -1;
- asn1_tags.format = ASN1_GEN_FORMAT_ASCII;
- asn1_tags.exp_count = 0;
- if (CONF_parse_list(str, ',', 1, asn1_cb, &asn1_tags) != 0)
- return NULL;
-
- if ((asn1_tags.utype == V_ASN1_SEQUENCE) || (asn1_tags.utype == V_ASN1_SET))
- {
- if (!cnf)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG);
- return NULL;
- }
- ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf);
- }
- else
- ret = asn1_str2type(asn1_tags.str, asn1_tags.format, asn1_tags.utype);
-
- if (!ret)
- return NULL;
-
- /* If no tagging return base type */
- if ((asn1_tags.imp_tag == -1) && (asn1_tags.exp_count == 0))
- return ret;
-
- /* Generate the encoding */
- cpy_len = i2d_ASN1_TYPE(ret, &orig_der);
- ASN1_TYPE_free(ret);
- ret = NULL;
- /* Set point to start copying for modified encoding */
- cpy_start = orig_der;
-
- /* Do we need IMPLICIT tagging? */
- if (asn1_tags.imp_tag != -1)
- {
- /* If IMPLICIT we will replace the underlying tag */
- /* Skip existing tag+len */
- r = ASN1_get_object(&cpy_start, &hdr_len, &hdr_tag, &hdr_class, cpy_len);
- if (r & 0x80)
- goto err;
- /* Update copy length */
- cpy_len -= cpy_start - orig_der;
- /* For IMPLICIT tagging the length should match the
- * original length and constructed flag should be
- * consistent.
- */
- if (r & 0x1)
- {
- /* Indefinite length constructed */
- hdr_constructed = 2;
- hdr_len = 0;
- }
- else
- /* Just retain constructed flag */
- hdr_constructed = r & V_ASN1_CONSTRUCTED;
- /* Work out new length with IMPLICIT tag: ignore constructed
- * because it will mess up if indefinite length
- */
- len = ASN1_object_size(0, hdr_len, asn1_tags.imp_tag);
- }
- else
- len = cpy_len;
-
- /* Work out length in any EXPLICIT, starting from end */
-
- for(i = 0, etmp = asn1_tags.exp_list + asn1_tags.exp_count - 1; i < asn1_tags.exp_count; i++, etmp--)
- {
- /* Content length: number of content octets + any padding */
- len += etmp->exp_pad;
- etmp->exp_len = len;
- /* Total object length: length including new header */
- len = ASN1_object_size(0, len, etmp->exp_tag);
- }
-
- /* Allocate buffer for new encoding */
-
- new_der = OPENSSL_malloc(len);
- if (!new_der)
- goto err;
-
- /* Generate tagged encoding */
-
- p = new_der;
-
- /* Output explicit tags first */
-
- for (i = 0, etmp = asn1_tags.exp_list; i < asn1_tags.exp_count; i++, etmp++)
- {
- ASN1_put_object(&p, etmp->exp_constructed, etmp->exp_len,
- etmp->exp_tag, etmp->exp_class);
- if (etmp->exp_pad)
- *p++ = 0;
- }
-
- /* If IMPLICIT, output tag */
-
- if (asn1_tags.imp_tag != -1)
- {
- if (asn1_tags.imp_class == V_ASN1_UNIVERSAL
- && (asn1_tags.imp_tag == V_ASN1_SEQUENCE
- || asn1_tags.imp_tag == V_ASN1_SET) )
- hdr_constructed = V_ASN1_CONSTRUCTED;
- ASN1_put_object(&p, hdr_constructed, hdr_len,
- asn1_tags.imp_tag, asn1_tags.imp_class);
- }
-
- /* Copy across original encoding */
- memcpy(p, cpy_start, cpy_len);
-
- cp = new_der;
-
- /* Obtain new ASN1_TYPE structure */
- ret = d2i_ASN1_TYPE(NULL, &cp, len);
-
- err:
- if (orig_der)
- OPENSSL_free(orig_der);
- if (new_der)
- OPENSSL_free(new_der);
-
- return ret;
-
- }
+{
+ ASN1_TYPE *ret;
+ tag_exp_arg asn1_tags;
+ tag_exp_type *etmp;
+
+ int i, len;
+
+ unsigned char *orig_der = NULL, *new_der = NULL;
+ const unsigned char *cpy_start;
+ unsigned char *p;
+ const unsigned char *cp;
+ int cpy_len;
+ long hdr_len = 0;
+ int hdr_constructed = 0, hdr_tag, hdr_class;
+ int r;
+
+ asn1_tags.imp_tag = -1;
+ asn1_tags.imp_class = -1;
+ asn1_tags.format = ASN1_GEN_FORMAT_ASCII;
+ asn1_tags.exp_count = 0;
+ if (CONF_parse_list(str, ',', 1, asn1_cb, &asn1_tags) != 0)
+ return NULL;
+
+ if ((asn1_tags.utype == V_ASN1_SEQUENCE)
+ || (asn1_tags.utype == V_ASN1_SET)) {
+ if (!cnf) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG);
+ return NULL;
+ }
+ ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf);
+ } else
+ ret = asn1_str2type(asn1_tags.str, asn1_tags.format, asn1_tags.utype);
+
+ if (!ret)
+ return NULL;
+
+ /* If no tagging return base type */
+ if ((asn1_tags.imp_tag == -1) && (asn1_tags.exp_count == 0))
+ return ret;
+
+ /* Generate the encoding */
+ cpy_len = i2d_ASN1_TYPE(ret, &orig_der);
+ ASN1_TYPE_free(ret);
+ ret = NULL;
+ /* Set point to start copying for modified encoding */
+ cpy_start = orig_der;
+
+ /* Do we need IMPLICIT tagging? */
+ if (asn1_tags.imp_tag != -1) {
+ /* If IMPLICIT we will replace the underlying tag */
+ /* Skip existing tag+len */
+ r = ASN1_get_object(&cpy_start, &hdr_len, &hdr_tag, &hdr_class,
+ cpy_len);
+ if (r & 0x80)
+ goto err;
+ /* Update copy length */
+ cpy_len -= cpy_start - orig_der;
+ /*
+ * For IMPLICIT tagging the length should match the original length
+ * and constructed flag should be consistent.
+ */
+ if (r & 0x1) {
+ /* Indefinite length constructed */
+ hdr_constructed = 2;
+ hdr_len = 0;
+ } else
+ /* Just retain constructed flag */
+ hdr_constructed = r & V_ASN1_CONSTRUCTED;
+ /*
+ * Work out new length with IMPLICIT tag: ignore constructed because
+ * it will mess up if indefinite length
+ */
+ len = ASN1_object_size(0, hdr_len, asn1_tags.imp_tag);
+ } else
+ len = cpy_len;
+
+ /* Work out length in any EXPLICIT, starting from end */
+
+ for (i = 0, etmp = asn1_tags.exp_list + asn1_tags.exp_count - 1;
+ i < asn1_tags.exp_count; i++, etmp--) {
+ /* Content length: number of content octets + any padding */
+ len += etmp->exp_pad;
+ etmp->exp_len = len;
+ /* Total object length: length including new header */
+ len = ASN1_object_size(0, len, etmp->exp_tag);
+ }
+
+ /* Allocate buffer for new encoding */
+
+ new_der = OPENSSL_malloc(len);
+ if (!new_der)
+ goto err;
+
+ /* Generate tagged encoding */
+
+ p = new_der;
+
+ /* Output explicit tags first */
+
+ for (i = 0, etmp = asn1_tags.exp_list; i < asn1_tags.exp_count;
+ i++, etmp++) {
+ ASN1_put_object(&p, etmp->exp_constructed, etmp->exp_len,
+ etmp->exp_tag, etmp->exp_class);
+ if (etmp->exp_pad)
+ *p++ = 0;
+ }
+
+ /* If IMPLICIT, output tag */
+
+ if (asn1_tags.imp_tag != -1) {
+ if (asn1_tags.imp_class == V_ASN1_UNIVERSAL
+ && (asn1_tags.imp_tag == V_ASN1_SEQUENCE
+ || asn1_tags.imp_tag == V_ASN1_SET))
+ hdr_constructed = V_ASN1_CONSTRUCTED;
+ ASN1_put_object(&p, hdr_constructed, hdr_len,
+ asn1_tags.imp_tag, asn1_tags.imp_class);
+ }
+
+ /* Copy across original encoding */
+ memcpy(p, cpy_start, cpy_len);
+
+ cp = new_der;
+
+ /* Obtain new ASN1_TYPE structure */
+ ret = d2i_ASN1_TYPE(NULL, &cp, len);
+
+ err:
+ if (orig_der)
+ OPENSSL_free(orig_der);
+ if (new_der)
+ OPENSSL_free(new_der);
+
+ return ret;
+
+}
static int asn1_cb(const char *elem, int len, void *bitstr)
- {
- tag_exp_arg *arg = bitstr;
- int i;
- int utype;
- int vlen = 0;
- const char *p, *vstart = NULL;
-
- int tmp_tag, tmp_class;
-
- if (elem == NULL)
- return 0;
-
- for(i = 0, p = elem; i < len; p++, i++)
- {
- /* Look for the ':' in name value pairs */
- if (*p == ':')
- {
- vstart = p + 1;
- vlen = len - (vstart - elem);
- len = p - elem;
- break;
- }
- }
-
- utype = asn1_str2tag(elem, len);
-
- if (utype == -1)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_TAG);
- ERR_add_error_data(2, "tag=", elem);
- return -1;
- }
-
- /* If this is not a modifier mark end of string and exit */
- if (!(utype & ASN1_GEN_FLAG))
- {
- arg->utype = utype;
- arg->str = vstart;
- /* If no value and not end of string, error */
- if (!vstart && elem[len])
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_VALUE);
- return -1;
- }
- return 0;
- }
-
- switch(utype)
- {
-
- case ASN1_GEN_FLAG_IMP:
- /* Check for illegal multiple IMPLICIT tagging */
- if (arg->imp_tag != -1)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NESTED_TAGGING);
- return -1;
- }
- if (!parse_tagging(vstart, vlen, &arg->imp_tag, &arg->imp_class))
- return -1;
- break;
-
- case ASN1_GEN_FLAG_EXP:
-
- if (!parse_tagging(vstart, vlen, &tmp_tag, &tmp_class))
- return -1;
- if (!append_exp(arg, tmp_tag, tmp_class, 1, 0, 0))
- return -1;
- break;
-
- case ASN1_GEN_FLAG_SEQWRAP:
- if (!append_exp(arg, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, 1, 0, 1))
- return -1;
- break;
-
- case ASN1_GEN_FLAG_SETWRAP:
- if (!append_exp(arg, V_ASN1_SET, V_ASN1_UNIVERSAL, 1, 0, 1))
- return -1;
- break;
-
- case ASN1_GEN_FLAG_BITWRAP:
- if (!append_exp(arg, V_ASN1_BIT_STRING, V_ASN1_UNIVERSAL, 0, 1, 1))
- return -1;
- break;
-
- case ASN1_GEN_FLAG_OCTWRAP:
- if (!append_exp(arg, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL, 0, 0, 1))
- return -1;
- break;
-
- case ASN1_GEN_FLAG_FORMAT:
- if (!vstart)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_FORMAT);
- return -1;
- }
- if (!strncmp(vstart, "ASCII", 5))
- arg->format = ASN1_GEN_FORMAT_ASCII;
- else if (!strncmp(vstart, "UTF8", 4))
- arg->format = ASN1_GEN_FORMAT_UTF8;
- else if (!strncmp(vstart, "HEX", 3))
- arg->format = ASN1_GEN_FORMAT_HEX;
- else if (!strncmp(vstart, "BITLIST", 7))
- arg->format = ASN1_GEN_FORMAT_BITLIST;
- else
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_FORMAT);
- return -1;
- }
- break;
-
- }
-
- return 1;
-
- }
+{
+ tag_exp_arg *arg = bitstr;
+ int i;
+ int utype;
+ int vlen = 0;
+ const char *p, *vstart = NULL;
+
+ int tmp_tag, tmp_class;
+
+ if (elem == NULL)
+ return 0;
+
+ for (i = 0, p = elem; i < len; p++, i++) {
+ /* Look for the ':' in name value pairs */
+ if (*p == ':') {
+ vstart = p + 1;
+ vlen = len - (vstart - elem);
+ len = p - elem;
+ break;
+ }
+ }
+
+ utype = asn1_str2tag(elem, len);
+
+ if (utype == -1) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_TAG);
+ ERR_add_error_data(2, "tag=", elem);
+ return -1;
+ }
+
+ /* If this is not a modifier mark end of string and exit */
+ if (!(utype & ASN1_GEN_FLAG)) {
+ arg->utype = utype;
+ arg->str = vstart;
+ /* If no value and not end of string, error */
+ if (!vstart && elem[len]) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_VALUE);
+ return -1;
+ }
+ return 0;
+ }
+
+ switch (utype) {
+
+ case ASN1_GEN_FLAG_IMP:
+ /* Check for illegal multiple IMPLICIT tagging */
+ if (arg->imp_tag != -1) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NESTED_TAGGING);
+ return -1;
+ }
+ if (!parse_tagging(vstart, vlen, &arg->imp_tag, &arg->imp_class))
+ return -1;
+ break;
+
+ case ASN1_GEN_FLAG_EXP:
+
+ if (!parse_tagging(vstart, vlen, &tmp_tag, &tmp_class))
+ return -1;
+ if (!append_exp(arg, tmp_tag, tmp_class, 1, 0, 0))
+ return -1;
+ break;
+
+ case ASN1_GEN_FLAG_SEQWRAP:
+ if (!append_exp(arg, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, 1, 0, 1))
+ return -1;
+ break;
+
+ case ASN1_GEN_FLAG_SETWRAP:
+ if (!append_exp(arg, V_ASN1_SET, V_ASN1_UNIVERSAL, 1, 0, 1))
+ return -1;
+ break;
+
+ case ASN1_GEN_FLAG_BITWRAP:
+ if (!append_exp(arg, V_ASN1_BIT_STRING, V_ASN1_UNIVERSAL, 0, 1, 1))
+ return -1;
+ break;
+
+ case ASN1_GEN_FLAG_OCTWRAP:
+ if (!append_exp(arg, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL, 0, 0, 1))
+ return -1;
+ break;
+
+ case ASN1_GEN_FLAG_FORMAT:
+ if (!vstart) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_FORMAT);
+ return -1;
+ }
+ if (!strncmp(vstart, "ASCII", 5))
+ arg->format = ASN1_GEN_FORMAT_ASCII;
+ else if (!strncmp(vstart, "UTF8", 4))
+ arg->format = ASN1_GEN_FORMAT_UTF8;
+ else if (!strncmp(vstart, "HEX", 3))
+ arg->format = ASN1_GEN_FORMAT_HEX;
+ else if (!strncmp(vstart, "BITLIST", 7))
+ arg->format = ASN1_GEN_FORMAT_BITLIST;
+ else {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_FORMAT);
+ return -1;
+ }
+ break;
+
+ }
+
+ return 1;
+
+}
static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass)
- {
- char erch[2];
- long tag_num;
- char *eptr;
- if (!vstart)
- return 0;
- tag_num = strtoul(vstart, &eptr, 10);
- /* Check we haven't gone past max length: should be impossible */
- if (eptr && *eptr && (eptr > vstart + vlen))
- return 0;
- if (tag_num < 0)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_NUMBER);
- return 0;
- }
- *ptag = tag_num;
- /* If we have non numeric characters, parse them */
- if (eptr)
- vlen -= eptr - vstart;
- else
- vlen = 0;
- if (vlen)
- {
- switch (*eptr)
- {
-
- case 'U':
- *pclass = V_ASN1_UNIVERSAL;
- break;
-
- case 'A':
- *pclass = V_ASN1_APPLICATION;
- break;
-
- case 'P':
- *pclass = V_ASN1_PRIVATE;
- break;
-
- case 'C':
- *pclass = V_ASN1_CONTEXT_SPECIFIC;
- break;
-
- default:
- erch[0] = *eptr;
- erch[1] = 0;
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_MODIFIER);
- ERR_add_error_data(2, "Char=", erch);
- return 0;
- break;
-
- }
- }
- else
- *pclass = V_ASN1_CONTEXT_SPECIFIC;
-
- return 1;
-
- }
+{
+ char erch[2];
+ long tag_num;
+ char *eptr;
+ if (!vstart)
+ return 0;
+ tag_num = strtoul(vstart, &eptr, 10);
+ /* Check we haven't gone past max length: should be impossible */
+ if (eptr && *eptr && (eptr > vstart + vlen))
+ return 0;
+ if (tag_num < 0) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_NUMBER);
+ return 0;
+ }
+ *ptag = tag_num;
+ /* If we have non numeric characters, parse them */
+ if (eptr)
+ vlen -= eptr - vstart;
+ else
+ vlen = 0;
+ if (vlen) {
+ switch (*eptr) {
+
+ case 'U':
+ *pclass = V_ASN1_UNIVERSAL;
+ break;
+
+ case 'A':
+ *pclass = V_ASN1_APPLICATION;
+ break;
+
+ case 'P':
+ *pclass = V_ASN1_PRIVATE;
+ break;
+
+ case 'C':
+ *pclass = V_ASN1_CONTEXT_SPECIFIC;
+ break;
+
+ default:
+ erch[0] = *eptr;
+ erch[1] = 0;
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_MODIFIER);
+ ERR_add_error_data(2, "Char=", erch);
+ return 0;
+ break;
+
+ }
+ } else
+ *pclass = V_ASN1_CONTEXT_SPECIFIC;
+
+ return 1;
+
+}
/* Handle multiple types: SET and SEQUENCE */
static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf)
- {
- ASN1_TYPE *ret = NULL;
- STACK_OF(ASN1_TYPE) *sk = NULL;
- STACK_OF(CONF_VALUE) *sect = NULL;
- unsigned char *der = NULL;
- int derlen;
- size_t i;
- sk = sk_ASN1_TYPE_new_null();
- if (!sk)
- goto bad;
- if (section)
- {
- if (!cnf)
- goto bad;
- sect = X509V3_get_section(cnf, (char *)section);
- if (!sect)
- goto bad;
- for (i = 0; i < sk_CONF_VALUE_num(sect); i++)
- {
- ASN1_TYPE *typ = ASN1_generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf);
- if (!typ)
- goto bad;
- if (!sk_ASN1_TYPE_push(sk, typ))
- goto bad;
- }
- }
-
- /* Now we has a STACK of the components, convert to the correct form */
-
- if (utype == V_ASN1_SET)
- derlen = i2d_ASN1_SET_ANY(sk, &der);
- else
- derlen = i2d_ASN1_SEQUENCE_ANY(sk, &der);
-
- if (derlen < 0)
- goto bad;
-
- if (!(ret = ASN1_TYPE_new()))
- goto bad;
-
- if (!(ret->value.asn1_string = ASN1_STRING_type_new(utype)))
- goto bad;
-
- ret->type = utype;
-
- ret->value.asn1_string->data = der;
- ret->value.asn1_string->length = derlen;
-
- der = NULL;
-
- bad:
-
- if (der)
- OPENSSL_free(der);
-
- if (sk)
- sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free);
- if (sect)
- X509V3_section_free(cnf, sect);
-
- return ret;
- }
-
-static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, int exp_constructed, int exp_pad, int imp_ok)
- {
- tag_exp_type *exp_tmp;
- /* Can only have IMPLICIT if permitted */
- if ((arg->imp_tag != -1) && !imp_ok)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_IMPLICIT_TAG);
- return 0;
- }
-
- if (arg->exp_count == ASN1_FLAG_EXP_MAX)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_DEPTH_EXCEEDED);
- return 0;
- }
-
- exp_tmp = &arg->exp_list[arg->exp_count++];
-
- /* If IMPLICIT set tag to implicit value then
- * reset implicit tag since it has been used.
- */
- if (arg->imp_tag != -1)
- {
- exp_tmp->exp_tag = arg->imp_tag;
- exp_tmp->exp_class = arg->imp_class;
- arg->imp_tag = -1;
- arg->imp_class = -1;
- }
- else
- {
- exp_tmp->exp_tag = exp_tag;
- exp_tmp->exp_class = exp_class;
- }
- exp_tmp->exp_constructed = exp_constructed;
- exp_tmp->exp_pad = exp_pad;
-
- return 1;
- }
-
+{
+ ASN1_TYPE *ret = NULL;
+ STACK_OF(ASN1_TYPE) *sk = NULL;
+ STACK_OF(CONF_VALUE) *sect = NULL;
+ unsigned char *der = NULL;
+ int derlen;
+ size_t i;
+ sk = sk_ASN1_TYPE_new_null();
+ if (!sk)
+ goto bad;
+ if (section) {
+ if (!cnf)
+ goto bad;
+ sect = X509V3_get_section(cnf, (char *)section);
+ if (!sect)
+ goto bad;
+ for (i = 0; i < sk_CONF_VALUE_num(sect); i++) {
+ ASN1_TYPE *typ =
+ ASN1_generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf);
+ if (!typ)
+ goto bad;
+ if (!sk_ASN1_TYPE_push(sk, typ))
+ goto bad;
+ }
+ }
+
+ /*
+ * Now we has a STACK of the components, convert to the correct form
+ */
+
+ if (utype == V_ASN1_SET)
+ derlen = i2d_ASN1_SET_ANY(sk, &der);
+ else
+ derlen = i2d_ASN1_SEQUENCE_ANY(sk, &der);
+
+ if (derlen < 0)
+ goto bad;
+
+ if (!(ret = ASN1_TYPE_new()))
+ goto bad;
+
+ if (!(ret->value.asn1_string = ASN1_STRING_type_new(utype)))
+ goto bad;
+
+ ret->type = utype;
+
+ ret->value.asn1_string->data = der;
+ ret->value.asn1_string->length = derlen;
+
+ der = NULL;
+
+ bad:
+
+ if (der)
+ OPENSSL_free(der);
+
+ if (sk)
+ sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free);
+ if (sect)
+ X509V3_section_free(cnf, sect);
+
+ return ret;
+}
+
+static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class,
+ int exp_constructed, int exp_pad, int imp_ok)
+{
+ tag_exp_type *exp_tmp;
+ /* Can only have IMPLICIT if permitted */
+ if ((arg->imp_tag != -1) && !imp_ok) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_IMPLICIT_TAG);
+ return 0;
+ }
+
+ if (arg->exp_count == ASN1_FLAG_EXP_MAX) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_DEPTH_EXCEEDED);
+ return 0;
+ }
+
+ exp_tmp = &arg->exp_list[arg->exp_count++];
+
+ /*
+ * If IMPLICIT set tag to implicit value then reset implicit tag since it
+ * has been used.
+ */
+ if (arg->imp_tag != -1) {
+ exp_tmp->exp_tag = arg->imp_tag;
+ exp_tmp->exp_class = arg->imp_class;
+ arg->imp_tag = -1;
+ arg->imp_class = -1;
+ } else {
+ exp_tmp->exp_tag = exp_tag;
+ exp_tmp->exp_class = exp_class;
+ }
+ exp_tmp->exp_constructed = exp_constructed;
+ exp_tmp->exp_pad = exp_pad;
+
+ return 1;
+}
static int asn1_str2tag(const char *tagstr, int len)
- {
- unsigned int i;
- static const struct tag_name_st *tntmp, tnst [] = {
- ASN1_GEN_STR("BOOL", V_ASN1_BOOLEAN),
- ASN1_GEN_STR("BOOLEAN", V_ASN1_BOOLEAN),
- ASN1_GEN_STR("NULL", V_ASN1_NULL),
- ASN1_GEN_STR("INT", V_ASN1_INTEGER),
- ASN1_GEN_STR("INTEGER", V_ASN1_INTEGER),
- ASN1_GEN_STR("ENUM", V_ASN1_ENUMERATED),
- ASN1_GEN_STR("ENUMERATED", V_ASN1_ENUMERATED),
- ASN1_GEN_STR("OID", V_ASN1_OBJECT),
- ASN1_GEN_STR("OBJECT", V_ASN1_OBJECT),
- ASN1_GEN_STR("UTCTIME", V_ASN1_UTCTIME),
- ASN1_GEN_STR("UTC", V_ASN1_UTCTIME),
- ASN1_GEN_STR("GENERALIZEDTIME", V_ASN1_GENERALIZEDTIME),
- ASN1_GEN_STR("GENTIME", V_ASN1_GENERALIZEDTIME),
- ASN1_GEN_STR("OCT", V_ASN1_OCTET_STRING),
- ASN1_GEN_STR("OCTETSTRING", V_ASN1_OCTET_STRING),
- ASN1_GEN_STR("BITSTR", V_ASN1_BIT_STRING),
- ASN1_GEN_STR("BITSTRING", V_ASN1_BIT_STRING),
- ASN1_GEN_STR("UNIVERSALSTRING", V_ASN1_UNIVERSALSTRING),
- ASN1_GEN_STR("UNIV", V_ASN1_UNIVERSALSTRING),
- ASN1_GEN_STR("IA5", V_ASN1_IA5STRING),
- ASN1_GEN_STR("IA5STRING", V_ASN1_IA5STRING),
- ASN1_GEN_STR("UTF8", V_ASN1_UTF8STRING),
- ASN1_GEN_STR("UTF8String", V_ASN1_UTF8STRING),
- ASN1_GEN_STR("BMP", V_ASN1_BMPSTRING),
- ASN1_GEN_STR("BMPSTRING", V_ASN1_BMPSTRING),
- ASN1_GEN_STR("VISIBLESTRING", V_ASN1_VISIBLESTRING),
- ASN1_GEN_STR("VISIBLE", V_ASN1_VISIBLESTRING),
- ASN1_GEN_STR("PRINTABLESTRING", V_ASN1_PRINTABLESTRING),
- ASN1_GEN_STR("PRINTABLE", V_ASN1_PRINTABLESTRING),
- ASN1_GEN_STR("T61", V_ASN1_T61STRING),
- ASN1_GEN_STR("T61STRING", V_ASN1_T61STRING),
- ASN1_GEN_STR("TELETEXSTRING", V_ASN1_T61STRING),
- ASN1_GEN_STR("GeneralString", V_ASN1_GENERALSTRING),
- ASN1_GEN_STR("GENSTR", V_ASN1_GENERALSTRING),
- ASN1_GEN_STR("NUMERIC", V_ASN1_NUMERICSTRING),
- ASN1_GEN_STR("NUMERICSTRING", V_ASN1_NUMERICSTRING),
-
- /* Special cases */
- ASN1_GEN_STR("SEQUENCE", V_ASN1_SEQUENCE),
- ASN1_GEN_STR("SEQ", V_ASN1_SEQUENCE),
- ASN1_GEN_STR("SET", V_ASN1_SET),
- /* type modifiers */
- /* Explicit tag */
- ASN1_GEN_STR("EXP", ASN1_GEN_FLAG_EXP),
- ASN1_GEN_STR("EXPLICIT", ASN1_GEN_FLAG_EXP),
- /* Implicit tag */
- ASN1_GEN_STR("IMP", ASN1_GEN_FLAG_IMP),
- ASN1_GEN_STR("IMPLICIT", ASN1_GEN_FLAG_IMP),
- /* OCTET STRING wrapper */
- ASN1_GEN_STR("OCTWRAP", ASN1_GEN_FLAG_OCTWRAP),
- /* SEQUENCE wrapper */
- ASN1_GEN_STR("SEQWRAP", ASN1_GEN_FLAG_SEQWRAP),
- /* SET wrapper */
- ASN1_GEN_STR("SETWRAP", ASN1_GEN_FLAG_SETWRAP),
- /* BIT STRING wrapper */
- ASN1_GEN_STR("BITWRAP", ASN1_GEN_FLAG_BITWRAP),
- ASN1_GEN_STR("FORM", ASN1_GEN_FLAG_FORMAT),
- ASN1_GEN_STR("FORMAT", ASN1_GEN_FLAG_FORMAT),
- };
-
- if (len == -1)
- len = strlen(tagstr);
-
- tntmp = tnst;
- for (i = 0; i < sizeof(tnst) / sizeof(struct tag_name_st); i++, tntmp++)
- {
- if ((len == tntmp->len) && !strncmp(tntmp->strnam, tagstr, len))
- return tntmp->tag;
- }
-
- return -1;
- }
+{
+ unsigned int i;
+ static const struct tag_name_st *tntmp, tnst[] = {
+ ASN1_GEN_STR("BOOL", V_ASN1_BOOLEAN),
+ ASN1_GEN_STR("BOOLEAN", V_ASN1_BOOLEAN),
+ ASN1_GEN_STR("NULL", V_ASN1_NULL),
+ ASN1_GEN_STR("INT", V_ASN1_INTEGER),
+ ASN1_GEN_STR("INTEGER", V_ASN1_INTEGER),
+ ASN1_GEN_STR("ENUM", V_ASN1_ENUMERATED),
+ ASN1_GEN_STR("ENUMERATED", V_ASN1_ENUMERATED),
+ ASN1_GEN_STR("OID", V_ASN1_OBJECT),
+ ASN1_GEN_STR("OBJECT", V_ASN1_OBJECT),
+ ASN1_GEN_STR("UTCTIME", V_ASN1_UTCTIME),
+ ASN1_GEN_STR("UTC", V_ASN1_UTCTIME),
+ ASN1_GEN_STR("GENERALIZEDTIME", V_ASN1_GENERALIZEDTIME),
+ ASN1_GEN_STR("GENTIME", V_ASN1_GENERALIZEDTIME),
+ ASN1_GEN_STR("OCT", V_ASN1_OCTET_STRING),
+ ASN1_GEN_STR("OCTETSTRING", V_ASN1_OCTET_STRING),
+ ASN1_GEN_STR("BITSTR", V_ASN1_BIT_STRING),
+ ASN1_GEN_STR("BITSTRING", V_ASN1_BIT_STRING),
+ ASN1_GEN_STR("UNIVERSALSTRING", V_ASN1_UNIVERSALSTRING),
+ ASN1_GEN_STR("UNIV", V_ASN1_UNIVERSALSTRING),
+ ASN1_GEN_STR("IA5", V_ASN1_IA5STRING),
+ ASN1_GEN_STR("IA5STRING", V_ASN1_IA5STRING),
+ ASN1_GEN_STR("UTF8", V_ASN1_UTF8STRING),
+ ASN1_GEN_STR("UTF8String", V_ASN1_UTF8STRING),
+ ASN1_GEN_STR("BMP", V_ASN1_BMPSTRING),
+ ASN1_GEN_STR("BMPSTRING", V_ASN1_BMPSTRING),
+ ASN1_GEN_STR("VISIBLESTRING", V_ASN1_VISIBLESTRING),
+ ASN1_GEN_STR("VISIBLE", V_ASN1_VISIBLESTRING),
+ ASN1_GEN_STR("PRINTABLESTRING", V_ASN1_PRINTABLESTRING),
+ ASN1_GEN_STR("PRINTABLE", V_ASN1_PRINTABLESTRING),
+ ASN1_GEN_STR("T61", V_ASN1_T61STRING),
+ ASN1_GEN_STR("T61STRING", V_ASN1_T61STRING),
+ ASN1_GEN_STR("TELETEXSTRING", V_ASN1_T61STRING),
+ ASN1_GEN_STR("GeneralString", V_ASN1_GENERALSTRING),
+ ASN1_GEN_STR("GENSTR", V_ASN1_GENERALSTRING),
+ ASN1_GEN_STR("NUMERIC", V_ASN1_NUMERICSTRING),
+ ASN1_GEN_STR("NUMERICSTRING", V_ASN1_NUMERICSTRING),
+
+ /* Special cases */
+ ASN1_GEN_STR("SEQUENCE", V_ASN1_SEQUENCE),
+ ASN1_GEN_STR("SEQ", V_ASN1_SEQUENCE),
+ ASN1_GEN_STR("SET", V_ASN1_SET),
+ /* type modifiers */
+ /* Explicit tag */
+ ASN1_GEN_STR("EXP", ASN1_GEN_FLAG_EXP),
+ ASN1_GEN_STR("EXPLICIT", ASN1_GEN_FLAG_EXP),
+ /* Implicit tag */
+ ASN1_GEN_STR("IMP", ASN1_GEN_FLAG_IMP),
+ ASN1_GEN_STR("IMPLICIT", ASN1_GEN_FLAG_IMP),
+ /* OCTET STRING wrapper */
+ ASN1_GEN_STR("OCTWRAP", ASN1_GEN_FLAG_OCTWRAP),
+ /* SEQUENCE wrapper */
+ ASN1_GEN_STR("SEQWRAP", ASN1_GEN_FLAG_SEQWRAP),
+ /* SET wrapper */
+ ASN1_GEN_STR("SETWRAP", ASN1_GEN_FLAG_SETWRAP),
+ /* BIT STRING wrapper */
+ ASN1_GEN_STR("BITWRAP", ASN1_GEN_FLAG_BITWRAP),
+ ASN1_GEN_STR("FORM", ASN1_GEN_FLAG_FORMAT),
+ ASN1_GEN_STR("FORMAT", ASN1_GEN_FLAG_FORMAT),
+ };
+
+ if (len == -1)
+ len = strlen(tagstr);
+
+ tntmp = tnst;
+ for (i = 0; i < sizeof(tnst) / sizeof(struct tag_name_st); i++, tntmp++) {
+ if ((len == tntmp->len) && !strncmp(tntmp->strnam, tagstr, len))
+ return tntmp->tag;
+ }
+
+ return -1;
+}
static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
- {
- ASN1_TYPE *atmp = NULL;
-
- CONF_VALUE vtmp;
-
- unsigned char *rdata;
- long rdlen;
-
- int no_unused = 1;
-
- if (!(atmp = ASN1_TYPE_new()))
- {
- OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
-
- if (!str)
- str = "";
-
- switch(utype)
- {
-
- case V_ASN1_NULL:
- if (str && *str)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NULL_VALUE);
- goto bad_form;
- }
- break;
-
- case V_ASN1_BOOLEAN:
- if (format != ASN1_GEN_FORMAT_ASCII)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ASCII_FORMAT);
- goto bad_form;
- }
- vtmp.name = NULL;
- vtmp.section = NULL;
- vtmp.value = (char *)str;
- if (!X509V3_get_value_bool(&vtmp, &atmp->value.boolean))
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_BOOLEAN);
- goto bad_str;
- }
- break;
-
- case V_ASN1_INTEGER:
- case V_ASN1_ENUMERATED:
- if (format != ASN1_GEN_FORMAT_ASCII)
- {
- 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_R_ILLEGAL_INTEGER);
- goto bad_str;
- }
- break;
-
- case V_ASN1_OBJECT:
- if (format != ASN1_GEN_FORMAT_ASCII)
- {
- 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_R_ILLEGAL_OBJECT);
- goto bad_str;
- }
- break;
-
- case V_ASN1_UTCTIME:
- case V_ASN1_GENERALIZEDTIME:
- if (format != ASN1_GEN_FORMAT_ASCII)
- {
- 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, ERR_R_MALLOC_FAILURE);
- goto bad_str;
- }
- if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1))
- {
- 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_R_ILLEGAL_TIME_VALUE);
- goto bad_str;
- }
-
- break;
-
- case V_ASN1_BMPSTRING:
- case V_ASN1_PRINTABLESTRING:
- case V_ASN1_IA5STRING:
- case V_ASN1_T61STRING:
- case V_ASN1_UTF8STRING:
- case V_ASN1_VISIBLESTRING:
- case V_ASN1_UNIVERSALSTRING:
- case V_ASN1_GENERALSTRING:
- case V_ASN1_NUMERICSTRING:
-
- if (format == ASN1_GEN_FORMAT_ASCII)
- format = MBSTRING_ASC;
- else if (format == ASN1_GEN_FORMAT_UTF8)
- format = MBSTRING_UTF8;
- else
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_FORMAT);
- goto bad_form;
- }
-
-
- if (ASN1_mbstring_copy(&atmp->value.asn1_string, (unsigned char *)str,
- -1, format, ASN1_tag2bit(utype)) <= 0)
- {
- OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
- goto bad_str;
- }
-
-
- break;
-
- case V_ASN1_BIT_STRING:
-
- case V_ASN1_OCTET_STRING:
-
- if (!(atmp->value.asn1_string = ASN1_STRING_new()))
- {
- OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
- goto bad_form;
- }
-
- if (format == ASN1_GEN_FORMAT_HEX)
- {
-
- if (!(rdata = string_to_hex((char *)str, &rdlen)))
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_HEX);
- goto bad_str;
- }
-
- atmp->value.asn1_string->data = rdata;
- atmp->value.asn1_string->length = rdlen;
- atmp->value.asn1_string->type = utype;
-
- }
- else if (format == ASN1_GEN_FORMAT_ASCII)
- ASN1_STRING_set(atmp->value.asn1_string, str, -1);
- else if ((format == ASN1_GEN_FORMAT_BITLIST) && (utype == V_ASN1_BIT_STRING))
- {
- if (!CONF_parse_list(str, ',', 1, bitstr_cb, atmp->value.bit_string))
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_LIST_ERROR);
- goto bad_str;
- }
- no_unused = 0;
-
- }
- else
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_BITSTRING_FORMAT);
- goto bad_form;
- }
-
- if ((utype == V_ASN1_BIT_STRING) && no_unused)
- {
- atmp->value.asn1_string->flags
- &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
- atmp->value.asn1_string->flags
- |= ASN1_STRING_FLAG_BITS_LEFT;
- }
-
-
- break;
-
- default:
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNSUPPORTED_TYPE);
- goto bad_str;
- break;
- }
-
-
- atmp->type = utype;
- return atmp;
-
-
- bad_str:
- ERR_add_error_data(2, "string=", str);
- bad_form:
-
- ASN1_TYPE_free(atmp);
- return NULL;
-
- }
+{
+ ASN1_TYPE *atmp = NULL;
+
+ CONF_VALUE vtmp;
+
+ unsigned char *rdata;
+ long rdlen;
+
+ int no_unused = 1;
+
+ if (!(atmp = ASN1_TYPE_new())) {
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ if (!str)
+ str = "";
+
+ switch (utype) {
+
+ case V_ASN1_NULL:
+ if (str && *str) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NULL_VALUE);
+ goto bad_form;
+ }
+ break;
+
+ case V_ASN1_BOOLEAN:
+ if (format != ASN1_GEN_FORMAT_ASCII) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ASCII_FORMAT);
+ goto bad_form;
+ }
+ vtmp.name = NULL;
+ vtmp.section = NULL;
+ vtmp.value = (char *)str;
+ if (!X509V3_get_value_bool(&vtmp, &atmp->value.boolean)) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_BOOLEAN);
+ goto bad_str;
+ }
+ break;
+
+ case V_ASN1_INTEGER:
+ case V_ASN1_ENUMERATED:
+ if (format != ASN1_GEN_FORMAT_ASCII) {
+ 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_R_ILLEGAL_INTEGER);
+ goto bad_str;
+ }
+ break;
+
+ case V_ASN1_OBJECT:
+ if (format != ASN1_GEN_FORMAT_ASCII) {
+ 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_R_ILLEGAL_OBJECT);
+ goto bad_str;
+ }
+ break;
+
+ case V_ASN1_UTCTIME:
+ case V_ASN1_GENERALIZEDTIME:
+ if (format != ASN1_GEN_FORMAT_ASCII) {
+ 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, ERR_R_MALLOC_FAILURE);
+ goto bad_str;
+ }
+ if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1)) {
+ 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_R_ILLEGAL_TIME_VALUE);
+ goto bad_str;
+ }
+
+ break;
+
+ case V_ASN1_BMPSTRING:
+ case V_ASN1_PRINTABLESTRING:
+ case V_ASN1_IA5STRING:
+ case V_ASN1_T61STRING:
+ case V_ASN1_UTF8STRING:
+ case V_ASN1_VISIBLESTRING:
+ case V_ASN1_UNIVERSALSTRING:
+ case V_ASN1_GENERALSTRING:
+ case V_ASN1_NUMERICSTRING:
+
+ if (format == ASN1_GEN_FORMAT_ASCII)
+ format = MBSTRING_ASC;
+ else if (format == ASN1_GEN_FORMAT_UTF8)
+ format = MBSTRING_UTF8;
+ else {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_FORMAT);
+ goto bad_form;
+ }
+
+ if (ASN1_mbstring_copy(&atmp->value.asn1_string, (unsigned char *)str,
+ -1, format, ASN1_tag2bit(utype)) <= 0) {
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+ goto bad_str;
+ }
+
+ break;
+
+ case V_ASN1_BIT_STRING:
+
+ case V_ASN1_OCTET_STRING:
+
+ if (!(atmp->value.asn1_string = ASN1_STRING_new())) {
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+ goto bad_form;
+ }
+
+ if (format == ASN1_GEN_FORMAT_HEX) {
+
+ if (!(rdata = string_to_hex((char *)str, &rdlen))) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_HEX);
+ goto bad_str;
+ }
+
+ atmp->value.asn1_string->data = rdata;
+ atmp->value.asn1_string->length = rdlen;
+ atmp->value.asn1_string->type = utype;
+
+ } else if (format == ASN1_GEN_FORMAT_ASCII)
+ ASN1_STRING_set(atmp->value.asn1_string, str, -1);
+ else if ((format == ASN1_GEN_FORMAT_BITLIST)
+ && (utype == V_ASN1_BIT_STRING)) {
+ if (!CONF_parse_list
+ (str, ',', 1, bitstr_cb, atmp->value.bit_string)) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_LIST_ERROR);
+ goto bad_str;
+ }
+ no_unused = 0;
+
+ } else {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_BITSTRING_FORMAT);
+ goto bad_form;
+ }
+
+ if ((utype == V_ASN1_BIT_STRING) && no_unused) {
+ atmp->value.asn1_string->flags
+ &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
+ atmp->value.asn1_string->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+ }
+
+ break;
+
+ default:
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNSUPPORTED_TYPE);
+ goto bad_str;
+ break;
+ }
+
+ atmp->type = utype;
+ return atmp;
+
+ bad_str:
+ ERR_add_error_data(2, "string=", str);
+ bad_form:
+
+ ASN1_TYPE_free(atmp);
+ return NULL;
+
+}
static int bitstr_cb(const char *elem, int len, void *bitstr)
- {
- long bitnum;
- char *eptr;
- if (!elem)
- return 0;
- bitnum = strtoul(elem, &eptr, 10);
- if (eptr && *eptr && (eptr != elem + len))
- return 0;
- if (bitnum < 0)
- {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_NUMBER);
- return 0;
- }
- if (!ASN1_BIT_STRING_set_bit(bitstr, bitnum, 1))
- {
- OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
- return 0;
- }
- return 1;
- }
-
+{
+ long bitnum;
+ char *eptr;
+ if (!elem)
+ return 0;
+ bitnum = strtoul(elem, &eptr, 10);
+ if (eptr && *eptr && (eptr != elem + len))
+ return 0;
+ if (bitnum < 0) {
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_NUMBER);
+ return 0;
+ }
+ if (!ASN1_BIT_STRING_set_bit(bitstr, bitnum, 1)) {
+ 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 ae50ae1e..4f0a49e2 100644
--- a/src/crypto/x509/by_dir.c
+++ b/src/crypto/x509/by_dir.c
@@ -68,424 +68,386 @@
#include "../internal.h"
-
-typedef struct lookup_dir_hashes_st
- {
- unsigned long hash;
- int suffix;
- } BY_DIR_HASH;
-
-typedef struct lookup_dir_entry_st
- {
- char *dir;
- int dir_type;
- STACK_OF(BY_DIR_HASH) *hashes;
- } BY_DIR_ENTRY;
-
-typedef struct lookup_dir_st
- {
- BUF_MEM *buffer;
- STACK_OF(BY_DIR_ENTRY) *dirs;
- } BY_DIR;
+typedef struct lookup_dir_hashes_st {
+ unsigned long hash;
+ int suffix;
+} BY_DIR_HASH;
+
+typedef struct lookup_dir_entry_st {
+ char *dir;
+ int dir_type;
+ STACK_OF(BY_DIR_HASH) *hashes;
+} BY_DIR_ENTRY;
+
+typedef struct lookup_dir_st {
+ BUF_MEM *buffer;
+ STACK_OF(BY_DIR_ENTRY) *dirs;
+} BY_DIR;
DECLARE_STACK_OF(BY_DIR_HASH)
DECLARE_STACK_OF(BY_DIR_ENTRY)
static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl,
- char **ret);
+ char **ret);
static int new_dir(X509_LOOKUP *lu);
static void free_dir(X509_LOOKUP *lu);
-static int add_cert_dir(BY_DIR *ctx,const char *dir,int type);
-static int get_cert_by_subject(X509_LOOKUP *xl,int type,X509_NAME *name,
- X509_OBJECT *ret);
-static X509_LOOKUP_METHOD x509_dir_lookup=
- {
- "Load certs from files in a directory",
- new_dir, /* new */
- free_dir, /* free */
- NULL, /* init */
- NULL, /* shutdown */
- dir_ctrl, /* ctrl */
- get_cert_by_subject, /* get_by_subject */
- NULL, /* get_by_issuer_serial */
- NULL, /* get_by_fingerprint */
- NULL, /* get_by_alias */
- };
+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);
+static X509_LOOKUP_METHOD x509_dir_lookup = {
+ "Load certs from files in a directory",
+ new_dir, /* new */
+ free_dir, /* free */
+ NULL, /* init */
+ NULL, /* shutdown */
+ dir_ctrl, /* ctrl */
+ get_cert_by_subject, /* get_by_subject */
+ NULL, /* get_by_issuer_serial */
+ NULL, /* get_by_fingerprint */
+ NULL, /* get_by_alias */
+};
X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void)
- {
- return(&x509_dir_lookup);
- }
+{
+ return (&x509_dir_lookup);
+}
static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl,
- char **retp)
- {
- int ret=0;
- BY_DIR *ld;
- char *dir = NULL;
-
- ld=(BY_DIR *)ctx->method_data;
-
- switch (cmd)
- {
- case X509_L_ADD_DIR:
- if (argl == X509_FILETYPE_DEFAULT)
- {
- dir=(char *)getenv(X509_get_default_cert_dir_env());
- if (dir)
- ret=add_cert_dir(ld,dir,X509_FILETYPE_PEM);
- else
- ret=add_cert_dir(ld,X509_get_default_cert_dir(),
- X509_FILETYPE_PEM);
- if (!ret)
- {
- OPENSSL_PUT_ERROR(X509, X509_R_LOADING_CERT_DIR);
- }
- }
- else
- ret=add_cert_dir(ld,argp,(int)argl);
- break;
- }
- return(ret);
- }
+ char **retp)
+{
+ int ret = 0;
+ BY_DIR *ld;
+ char *dir = NULL;
+
+ ld = (BY_DIR *)ctx->method_data;
+
+ switch (cmd) {
+ case X509_L_ADD_DIR:
+ if (argl == X509_FILETYPE_DEFAULT) {
+ dir = (char *)getenv(X509_get_default_cert_dir_env());
+ if (dir)
+ ret = add_cert_dir(ld, dir, X509_FILETYPE_PEM);
+ else
+ ret = add_cert_dir(ld, X509_get_default_cert_dir(),
+ X509_FILETYPE_PEM);
+ if (!ret) {
+ OPENSSL_PUT_ERROR(X509, X509_R_LOADING_CERT_DIR);
+ }
+ } else
+ ret = add_cert_dir(ld, argp, (int)argl);
+ break;
+ }
+ return (ret);
+}
static int new_dir(X509_LOOKUP *lu)
- {
- BY_DIR *a;
-
- if ((a=(BY_DIR *)OPENSSL_malloc(sizeof(BY_DIR))) == NULL)
- return(0);
- if ((a->buffer=BUF_MEM_new()) == NULL)
- {
- OPENSSL_free(a);
- return(0);
- }
- a->dirs=NULL;
- lu->method_data=(char *)a;
- return(1);
- }
+{
+ BY_DIR *a;
+
+ if ((a = (BY_DIR *)OPENSSL_malloc(sizeof(BY_DIR))) == NULL)
+ return (0);
+ if ((a->buffer = BUF_MEM_new()) == NULL) {
+ OPENSSL_free(a);
+ return (0);
+ }
+ a->dirs = NULL;
+ lu->method_data = (char *)a;
+ return (1);
+}
static void by_dir_hash_free(BY_DIR_HASH *hash)
- {
- OPENSSL_free(hash);
- }
-
-static int by_dir_hash_cmp(const BY_DIR_HASH **a,
- const BY_DIR_HASH **b)
- {
- if ((*a)->hash > (*b)->hash)
- return 1;
- if ((*a)->hash < (*b)->hash)
- return -1;
- return 0;
- }
+{
+ OPENSSL_free(hash);
+}
+
+static int by_dir_hash_cmp(const BY_DIR_HASH **a, const BY_DIR_HASH **b)
+{
+ if ((*a)->hash > (*b)->hash)
+ return 1;
+ if ((*a)->hash < (*b)->hash)
+ return -1;
+ return 0;
+}
static void by_dir_entry_free(BY_DIR_ENTRY *ent)
- {
- if (ent->dir)
- OPENSSL_free(ent->dir);
- if (ent->hashes)
- sk_BY_DIR_HASH_pop_free(ent->hashes, by_dir_hash_free);
- OPENSSL_free(ent);
- }
+{
+ if (ent->dir)
+ OPENSSL_free(ent->dir);
+ if (ent->hashes)
+ sk_BY_DIR_HASH_pop_free(ent->hashes, by_dir_hash_free);
+ OPENSSL_free(ent);
+}
static void free_dir(X509_LOOKUP *lu)
- {
- BY_DIR *a;
+{
+ BY_DIR *a;
- a=(BY_DIR *)lu->method_data;
- if (a->dirs != NULL)
- sk_BY_DIR_ENTRY_pop_free(a->dirs, by_dir_entry_free);
- if (a->buffer != NULL)
- BUF_MEM_free(a->buffer);
- OPENSSL_free(a);
- }
+ a = (BY_DIR *)lu->method_data;
+ if (a->dirs != NULL)
+ sk_BY_DIR_ENTRY_pop_free(a->dirs, by_dir_entry_free);
+ if (a->buffer != NULL)
+ BUF_MEM_free(a->buffer);
+ OPENSSL_free(a);
+}
static int add_cert_dir(BY_DIR *ctx, const char *dir, int type)
- {
- size_t j,len;
- const char *s,*ss,*p;
-
- if (dir == NULL || !*dir)
- {
- OPENSSL_PUT_ERROR(X509, X509_R_INVALID_DIRECTORY);
- return 0;
- }
-
- s=dir;
- p=s;
- do
- {
- if ((*p == ':') || (*p == '\0'))
- {
- BY_DIR_ENTRY *ent;
- ss=s;
- s=p+1;
- len=p-ss;
- if (len == 0) continue;
- for (j=0; j < sk_BY_DIR_ENTRY_num(ctx->dirs); j++)
- {
- ent = sk_BY_DIR_ENTRY_value(ctx->dirs, j);
- if (strlen(ent->dir) == len &&
- strncmp(ent->dir,ss,len) == 0)
- break;
- }
- if (j < sk_BY_DIR_ENTRY_num(ctx->dirs))
- continue;
- if (ctx->dirs == NULL)
- {
- ctx->dirs = sk_BY_DIR_ENTRY_new_null();
- if (!ctx->dirs)
- {
- OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
- return 0;
- }
- }
- ent = OPENSSL_malloc(sizeof(BY_DIR_ENTRY));
- if (!ent)
- return 0;
- ent->dir_type = type;
- ent->hashes = sk_BY_DIR_HASH_new(by_dir_hash_cmp);
- ent->dir = OPENSSL_malloc(len+1);
- if (!ent->dir || !ent->hashes)
- {
- by_dir_entry_free(ent);
- return 0;
- }
- strncpy(ent->dir,ss,len);
- ent->dir[len] = '\0';
- if (!sk_BY_DIR_ENTRY_push(ctx->dirs, ent))
- {
- by_dir_entry_free(ent);
- return 0;
- }
- }
- } while (*p++ != '\0');
- return 1;
- }
-
-/* g_ent_hashes_lock protects the |hashes| member of all |BY_DIR_ENTRY|
- * objects. */
-static struct CRYPTO_STATIC_MUTEX g_ent_hashes_lock = CRYPTO_STATIC_MUTEX_INIT;
+{
+ size_t j, len;
+ const char *s, *ss, *p;
+
+ if (dir == NULL || !*dir) {
+ OPENSSL_PUT_ERROR(X509, X509_R_INVALID_DIRECTORY);
+ return 0;
+ }
+
+ s = dir;
+ p = s;
+ do {
+ if ((*p == ':') || (*p == '\0')) {
+ BY_DIR_ENTRY *ent;
+ ss = s;
+ s = p + 1;
+ len = p - ss;
+ if (len == 0)
+ continue;
+ for (j = 0; j < sk_BY_DIR_ENTRY_num(ctx->dirs); j++) {
+ ent = sk_BY_DIR_ENTRY_value(ctx->dirs, j);
+ if (strlen(ent->dir) == len &&
+ strncmp(ent->dir, ss, len) == 0)
+ break;
+ }
+ if (j < sk_BY_DIR_ENTRY_num(ctx->dirs))
+ continue;
+ if (ctx->dirs == NULL) {
+ ctx->dirs = sk_BY_DIR_ENTRY_new_null();
+ if (!ctx->dirs) {
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ }
+ ent = OPENSSL_malloc(sizeof(BY_DIR_ENTRY));
+ if (!ent)
+ return 0;
+ ent->dir_type = type;
+ ent->hashes = sk_BY_DIR_HASH_new(by_dir_hash_cmp);
+ ent->dir = OPENSSL_malloc(len + 1);
+ if (!ent->dir || !ent->hashes) {
+ by_dir_entry_free(ent);
+ return 0;
+ }
+ strncpy(ent->dir, ss, len);
+ ent->dir[len] = '\0';
+ if (!sk_BY_DIR_ENTRY_push(ctx->dirs, ent)) {
+ by_dir_entry_free(ent);
+ return 0;
+ }
+ }
+ } while (*p++ != '\0');
+ return 1;
+}
+
+/*
+ * g_ent_hashes_lock protects the |hashes| member of all |BY_DIR_ENTRY|
+ * objects.
+ */
+static struct CRYPTO_STATIC_MUTEX g_ent_hashes_lock =
+ CRYPTO_STATIC_MUTEX_INIT;
static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
- X509_OBJECT *ret)
- {
- BY_DIR *ctx;
- union {
- struct {
- X509 st_x509;
- X509_CINF st_x509_cinf;
- } x509;
- struct {
- X509_CRL st_crl;
- X509_CRL_INFO st_crl_info;
- } crl;
- } data;
- int ok=0;
- size_t i;
- int j,k;
- unsigned long h;
- unsigned long hash_array[2];
- int hash_index;
- BUF_MEM *b=NULL;
- X509_OBJECT stmp,*tmp;
- const char *postfix="";
-
- if (name == NULL) return(0);
-
- stmp.type=type;
- if (type == X509_LU_X509)
- {
- data.x509.st_x509.cert_info= &data.x509.st_x509_cinf;
- data.x509.st_x509_cinf.subject=name;
- stmp.data.x509= &data.x509.st_x509;
- postfix="";
- }
- else if (type == X509_LU_CRL)
- {
- data.crl.st_crl.crl= &data.crl.st_crl_info;
- data.crl.st_crl_info.issuer=name;
- stmp.data.crl= &data.crl.st_crl;
- postfix="r";
- }
- else
- {
- OPENSSL_PUT_ERROR(X509, X509_R_WRONG_LOOKUP_TYPE);
- goto finish;
- }
-
- if ((b=BUF_MEM_new()) == NULL)
- {
- OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB);
- goto finish;
- }
-
- ctx=(BY_DIR *)xl->method_data;
-
- hash_array[0]=X509_NAME_hash(name);
- hash_array[1]=X509_NAME_hash_old(name);
- for (hash_index=0; hash_index < 2; ++hash_index)
- {
- h=hash_array[hash_index];
- for (i=0; i < sk_BY_DIR_ENTRY_num(ctx->dirs); i++)
- {
- BY_DIR_ENTRY *ent;
- size_t idx;
- BY_DIR_HASH htmp, *hent;
- ent = sk_BY_DIR_ENTRY_value(ctx->dirs, i);
- j=strlen(ent->dir)+1+8+6+1+1;
- if (!BUF_MEM_grow(b,j))
- {
- OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
- goto finish;
- }
- if (type == X509_LU_CRL && ent->hashes)
- {
- htmp.hash = h;
- CRYPTO_STATIC_MUTEX_lock_read(&g_ent_hashes_lock);
- if (sk_BY_DIR_HASH_find(ent->hashes, &idx, &htmp))
- {
- hent = sk_BY_DIR_HASH_value(ent->hashes, idx);
- k = hent->suffix;
- }
- else
- {
- hent = NULL;
- k=0;
- }
- CRYPTO_STATIC_MUTEX_unlock(&g_ent_hashes_lock);
- }
- else
- {
- k = 0;
- hent = NULL;
- }
- for (;;)
- {
- char c = '/';
+ X509_OBJECT *ret)
+{
+ BY_DIR *ctx;
+ union {
+ struct {
+ X509 st_x509;
+ X509_CINF st_x509_cinf;
+ } x509;
+ struct {
+ X509_CRL st_crl;
+ X509_CRL_INFO st_crl_info;
+ } crl;
+ } data;
+ int ok = 0;
+ size_t i;
+ int j, k;
+ unsigned long h;
+ unsigned long hash_array[2];
+ int hash_index;
+ BUF_MEM *b = NULL;
+ X509_OBJECT stmp, *tmp;
+ const char *postfix = "";
+
+ if (name == NULL)
+ return (0);
+
+ stmp.type = type;
+ if (type == X509_LU_X509) {
+ data.x509.st_x509.cert_info = &data.x509.st_x509_cinf;
+ data.x509.st_x509_cinf.subject = name;
+ stmp.data.x509 = &data.x509.st_x509;
+ postfix = "";
+ } else if (type == X509_LU_CRL) {
+ data.crl.st_crl.crl = &data.crl.st_crl_info;
+ data.crl.st_crl_info.issuer = name;
+ stmp.data.crl = &data.crl.st_crl;
+ postfix = "r";
+ } else {
+ OPENSSL_PUT_ERROR(X509, X509_R_WRONG_LOOKUP_TYPE);
+ goto finish;
+ }
+
+ if ((b = BUF_MEM_new()) == NULL) {
+ OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB);
+ goto finish;
+ }
+
+ ctx = (BY_DIR *)xl->method_data;
+
+ hash_array[0] = X509_NAME_hash(name);
+ hash_array[1] = X509_NAME_hash_old(name);
+ for (hash_index = 0; hash_index < 2; ++hash_index) {
+ h = hash_array[hash_index];
+ for (i = 0; i < sk_BY_DIR_ENTRY_num(ctx->dirs); i++) {
+ BY_DIR_ENTRY *ent;
+ size_t idx;
+ BY_DIR_HASH htmp, *hent;
+ ent = sk_BY_DIR_ENTRY_value(ctx->dirs, i);
+ j = strlen(ent->dir) + 1 + 8 + 6 + 1 + 1;
+ if (!BUF_MEM_grow(b, j)) {
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+ goto finish;
+ }
+ if (type == X509_LU_CRL && ent->hashes) {
+ htmp.hash = h;
+ CRYPTO_STATIC_MUTEX_lock_read(&g_ent_hashes_lock);
+ if (sk_BY_DIR_HASH_find(ent->hashes, &idx, &htmp)) {
+ hent = sk_BY_DIR_HASH_value(ent->hashes, idx);
+ k = hent->suffix;
+ } else {
+ hent = NULL;
+ k = 0;
+ }
+ CRYPTO_STATIC_MUTEX_unlock(&g_ent_hashes_lock);
+ } else {
+ k = 0;
+ hent = NULL;
+ }
+ for (;;) {
+ char c = '/';
#ifdef OPENSSL_SYS_VMS
- c = ent->dir[strlen(ent->dir)-1];
- if (c != ':' && c != '>' && c != ']')
- {
- /* If no separator is present, we assume the
- directory specifier is a logical name, and
- add a colon. We really should use better
- VMS routines for merging things like this,
- but this will do for now...
- -- Richard Levitte */
- c = ':';
- }
- else
- {
- c = '\0';
- }
+ c = ent->dir[strlen(ent->dir) - 1];
+ if (c != ':' && c != '>' && c != ']') {
+ /*
+ * If no separator is present, we assume the directory
+ * specifier is a logical name, and add a colon. We
+ * really should use better VMS routines for merging
+ * things like this, but this will do for now... --
+ * Richard Levitte
+ */
+ c = ':';
+ } else {
+ c = '\0';
+ }
#endif
- if (c == '\0')
- {
- /* This is special. When c == '\0', no
- directory separator should be added. */
- BIO_snprintf(b->data,b->max,
- "%s%08lx.%s%d",ent->dir,h,
- postfix,k);
- }
- else
- {
- BIO_snprintf(b->data,b->max,
- "%s%c%08lx.%s%d",ent->dir,c,h,
- postfix,k);
- }
+ if (c == '\0') {
+ /*
+ * This is special. When c == '\0', no directory
+ * separator should be added.
+ */
+ BIO_snprintf(b->data, b->max,
+ "%s%08lx.%s%d", ent->dir, h, postfix, k);
+ } else {
+ BIO_snprintf(b->data, b->max,
+ "%s%c%08lx.%s%d", ent->dir, c, h,
+ postfix, k);
+ }
#ifndef OPENSSL_NO_POSIX_IO
-#ifdef _WIN32
-#define stat _stat
-#endif
- {
- struct stat st;
- if (stat(b->data,&st) < 0)
- break;
- }
+# ifdef _WIN32
+# define stat _stat
+# endif
+ {
+ struct stat st;
+ if (stat(b->data, &st) < 0)
+ break;
+ }
#endif
- /* found one. */
- if (type == X509_LU_X509)
- {
- if ((X509_load_cert_file(xl,b->data,
- ent->dir_type)) == 0)
- break;
- }
- else if (type == X509_LU_CRL)
- {
- if ((X509_load_crl_file(xl,b->data,
- ent->dir_type)) == 0)
- break;
- }
- /* else case will caught higher up */
- k++;
- }
-
- /* we have added it to the cache so now pull
- * it out again */
- CRYPTO_MUTEX_lock_write(&xl->store_ctx->objs_lock);
- tmp = NULL;
- if (sk_X509_OBJECT_find(xl->store_ctx->objs, &idx, &stmp)) {
- tmp=sk_X509_OBJECT_value(xl->store_ctx->objs,idx);
- }
- CRYPTO_MUTEX_unlock(&xl->store_ctx->objs_lock);
-
-
- /* If a CRL, update the last file suffix added for this */
-
- if (type == X509_LU_CRL)
- {
- CRYPTO_STATIC_MUTEX_lock_write(&g_ent_hashes_lock);
- /* Look for entry again in case another thread added
- * an entry first.
- */
- if (!hent)
- {
- htmp.hash = h;
- if (sk_BY_DIR_HASH_find(ent->hashes, &idx, &htmp))
- hent = sk_BY_DIR_HASH_value(ent->hashes, idx);
- }
- if (!hent)
- {
- hent = OPENSSL_malloc(sizeof(BY_DIR_HASH));
- if (hent == NULL)
- {
- CRYPTO_STATIC_MUTEX_unlock(&g_ent_hashes_lock);
- ok = 0;
- goto finish;
- }
- hent->hash = h;
- hent->suffix = k;
- if (!sk_BY_DIR_HASH_push(ent->hashes, hent))
- {
- CRYPTO_STATIC_MUTEX_unlock(&g_ent_hashes_lock);
- OPENSSL_free(hent);
- ok = 0;
- goto finish;
- }
- }
- else if (hent->suffix < k)
- hent->suffix = k;
-
- CRYPTO_STATIC_MUTEX_unlock(&g_ent_hashes_lock);
- }
-
- if (tmp != NULL)
- {
- ok=1;
- ret->type=tmp->type;
- memcpy(&ret->data,&tmp->data,sizeof(ret->data));
- /* If we were going to up the reference count,
- * we would need to do it on a perl 'type'
- * basis */
- /* CRYPTO_add(&tmp->data.x509->references,1,
- CRYPTO_LOCK_X509);*/
- goto finish;
- }
- }
- }
-finish:
- if (b != NULL) BUF_MEM_free(b);
- return(ok);
- }
+ /* found one. */
+ if (type == X509_LU_X509) {
+ if ((X509_load_cert_file(xl, b->data,
+ ent->dir_type)) == 0)
+ break;
+ } else if (type == X509_LU_CRL) {
+ if ((X509_load_crl_file(xl, b->data, ent->dir_type)) == 0)
+ break;
+ }
+ /* else case will caught higher up */
+ k++;
+ }
+
+ /*
+ * we have added it to the cache so now pull it out again
+ */
+ CRYPTO_MUTEX_lock_write(&xl->store_ctx->objs_lock);
+ tmp = NULL;
+ if (sk_X509_OBJECT_find(xl->store_ctx->objs, &idx, &stmp)) {
+ tmp = sk_X509_OBJECT_value(xl->store_ctx->objs, idx);
+ }
+ CRYPTO_MUTEX_unlock(&xl->store_ctx->objs_lock);
+
+ /*
+ * If a CRL, update the last file suffix added for this
+ */
+
+ if (type == X509_LU_CRL) {
+ CRYPTO_STATIC_MUTEX_lock_write(&g_ent_hashes_lock);
+ /*
+ * Look for entry again in case another thread added an entry
+ * first.
+ */
+ if (!hent) {
+ htmp.hash = h;
+ if (sk_BY_DIR_HASH_find(ent->hashes, &idx, &htmp))
+ hent = sk_BY_DIR_HASH_value(ent->hashes, idx);
+ }
+ if (!hent) {
+ hent = OPENSSL_malloc(sizeof(BY_DIR_HASH));
+ if (hent == NULL) {
+ CRYPTO_STATIC_MUTEX_unlock(&g_ent_hashes_lock);
+ ok = 0;
+ goto finish;
+ }
+ hent->hash = h;
+ hent->suffix = k;
+ if (!sk_BY_DIR_HASH_push(ent->hashes, hent)) {
+ CRYPTO_STATIC_MUTEX_unlock(&g_ent_hashes_lock);
+ OPENSSL_free(hent);
+ ok = 0;
+ goto finish;
+ }
+ } else if (hent->suffix < k)
+ hent->suffix = k;
+
+ CRYPTO_STATIC_MUTEX_unlock(&g_ent_hashes_lock);
+ }
+
+ if (tmp != NULL) {
+ ok = 1;
+ ret->type = tmp->type;
+ memcpy(&ret->data, &tmp->data, sizeof(ret->data));
+ /*
+ * If we were going to up the reference count, we would need
+ * to do it on a perl 'type' basis
+ */
+ /*
+ * CRYPTO_add(&tmp->data.x509->references,1,
+ * CRYPTO_LOCK_X509);
+ */
+ goto finish;
+ }
+ }
+ }
+ finish:
+ if (b != NULL)
+ BUF_MEM_free(b);
+ return (ok);
+}
diff --git a/src/crypto/x509/by_file.c b/src/crypto/x509/by_file.c
index 3460b570..ebeb72e5 100644
--- a/src/crypto/x509/by_file.c
+++ b/src/crypto/x509/by_file.c
@@ -63,233 +63,213 @@
#include <openssl/pem.h>
#include <openssl/thread.h>
-
#ifndef OPENSSL_NO_STDIO
static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc,
- long argl, char **ret);
-static X509_LOOKUP_METHOD x509_file_lookup=
- {
- "Load file into cache",
- NULL, /* new */
- NULL, /* free */
- NULL, /* init */
- NULL, /* shutdown */
- by_file_ctrl, /* ctrl */
- NULL, /* get_by_subject */
- NULL, /* get_by_issuer_serial */
- NULL, /* get_by_fingerprint */
- NULL, /* get_by_alias */
- };
+ long argl, char **ret);
+static X509_LOOKUP_METHOD x509_file_lookup = {
+ "Load file into cache",
+ NULL, /* new */
+ NULL, /* free */
+ NULL, /* init */
+ NULL, /* shutdown */
+ by_file_ctrl, /* ctrl */
+ NULL, /* get_by_subject */
+ NULL, /* get_by_issuer_serial */
+ NULL, /* get_by_fingerprint */
+ NULL, /* get_by_alias */
+};
X509_LOOKUP_METHOD *X509_LOOKUP_file(void)
- {
- return(&x509_file_lookup);
- }
+{
+ return (&x509_file_lookup);
+}
-static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl,
- char **ret)
- {
- int ok=0;
- char *file;
+static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp,
+ long argl, char **ret)
+{
+ int ok = 0;
+ char *file;
- switch (cmd)
- {
- case X509_L_FILE_LOAD:
- if (argl == X509_FILETYPE_DEFAULT)
- {
- file = (char *)getenv(X509_get_default_cert_file_env());
- if (file)
- ok = (X509_load_cert_crl_file(ctx,file,
- X509_FILETYPE_PEM) != 0);
+ switch (cmd) {
+ case X509_L_FILE_LOAD:
+ if (argl == X509_FILETYPE_DEFAULT) {
+ file = (char *)getenv(X509_get_default_cert_file_env());
+ if (file)
+ ok = (X509_load_cert_crl_file(ctx, file,
+ X509_FILETYPE_PEM) != 0);
- else
- ok = (X509_load_cert_crl_file(ctx,X509_get_default_cert_file(),
- X509_FILETYPE_PEM) != 0);
+ else
+ ok = (X509_load_cert_crl_file
+ (ctx, X509_get_default_cert_file(),
+ X509_FILETYPE_PEM) != 0);
- if (!ok)
- {
- OPENSSL_PUT_ERROR(X509, X509_R_LOADING_DEFAULTS);
- }
- }
- else
- {
- if(argl == X509_FILETYPE_PEM)
- ok = (X509_load_cert_crl_file(ctx,argp,
- X509_FILETYPE_PEM) != 0);
- else
- ok = (X509_load_cert_file(ctx,argp,(int)argl) != 0);
- }
- break;
- }
- return(ok);
- }
+ if (!ok) {
+ OPENSSL_PUT_ERROR(X509, X509_R_LOADING_DEFAULTS);
+ }
+ } else {
+ if (argl == X509_FILETYPE_PEM)
+ ok = (X509_load_cert_crl_file(ctx, argp,
+ X509_FILETYPE_PEM) != 0);
+ else
+ ok = (X509_load_cert_file(ctx, argp, (int)argl) != 0);
+ }
+ break;
+ }
+ return (ok);
+}
int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type)
- {
- int ret=0;
- BIO *in=NULL;
- int i,count=0;
- X509 *x=NULL;
+{
+ int ret = 0;
+ BIO *in = NULL;
+ int i, count = 0;
+ X509 *x = NULL;
- if (file == NULL) return(1);
- in=BIO_new(BIO_s_file());
+ if (file == NULL)
+ return (1);
+ in = BIO_new(BIO_s_file());
- if ((in == NULL) || (BIO_read_filename(in,file) <= 0))
- {
- OPENSSL_PUT_ERROR(X509, ERR_R_SYS_LIB);
- goto err;
- }
+ if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) {
+ OPENSSL_PUT_ERROR(X509, ERR_R_SYS_LIB);
+ goto err;
+ }
- if (type == X509_FILETYPE_PEM)
- {
- for (;;)
- {
- x=PEM_read_bio_X509_AUX(in,NULL,NULL,NULL);
- if (x == NULL)
- {
- if ((ERR_GET_REASON(ERR_peek_last_error()) ==
- PEM_R_NO_START_LINE) && (count > 0))
- {
- ERR_clear_error();
- break;
- }
- else
- {
- OPENSSL_PUT_ERROR(X509, ERR_R_PEM_LIB);
- goto err;
- }
- }
- i=X509_STORE_add_cert(ctx->store_ctx,x);
- if (!i) goto err;
- count++;
- X509_free(x);
- x=NULL;
- }
- ret=count;
- }
- else if (type == X509_FILETYPE_ASN1)
- {
- x=d2i_X509_bio(in,NULL);
- if (x == NULL)
- {
- OPENSSL_PUT_ERROR(X509, ERR_R_ASN1_LIB);
- goto err;
- }
- i=X509_STORE_add_cert(ctx->store_ctx,x);
- if (!i) goto err;
- ret=i;
- }
- else
- {
- OPENSSL_PUT_ERROR(X509, X509_R_BAD_X509_FILETYPE);
- goto err;
- }
-err:
- if (x != NULL) X509_free(x);
- if (in != NULL) BIO_free(in);
- return(ret);
- }
+ if (type == X509_FILETYPE_PEM) {
+ for (;;) {
+ x = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
+ if (x == NULL) {
+ if ((ERR_GET_REASON(ERR_peek_last_error()) ==
+ PEM_R_NO_START_LINE) && (count > 0)) {
+ ERR_clear_error();
+ break;
+ } else {
+ OPENSSL_PUT_ERROR(X509, ERR_R_PEM_LIB);
+ goto err;
+ }
+ }
+ i = X509_STORE_add_cert(ctx->store_ctx, x);
+ if (!i)
+ goto err;
+ count++;
+ X509_free(x);
+ x = NULL;
+ }
+ ret = count;
+ } else if (type == X509_FILETYPE_ASN1) {
+ x = d2i_X509_bio(in, NULL);
+ if (x == NULL) {
+ OPENSSL_PUT_ERROR(X509, ERR_R_ASN1_LIB);
+ goto err;
+ }
+ i = X509_STORE_add_cert(ctx->store_ctx, x);
+ if (!i)
+ goto err;
+ ret = i;
+ } else {
+ OPENSSL_PUT_ERROR(X509, X509_R_BAD_X509_FILETYPE);
+ goto err;
+ }
+ err:
+ if (x != NULL)
+ X509_free(x);
+ if (in != NULL)
+ BIO_free(in);
+ return (ret);
+}
int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type)
- {
- int ret=0;
- BIO *in=NULL;
- int i,count=0;
- X509_CRL *x=NULL;
+{
+ int ret = 0;
+ BIO *in = NULL;
+ int i, count = 0;
+ X509_CRL *x = NULL;
- if (file == NULL) return(1);
- in=BIO_new(BIO_s_file());
+ if (file == NULL)
+ return (1);
+ in = BIO_new(BIO_s_file());
- if ((in == NULL) || (BIO_read_filename(in,file) <= 0))
- {
- OPENSSL_PUT_ERROR(X509, ERR_R_SYS_LIB);
- goto err;
- }
+ if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) {
+ OPENSSL_PUT_ERROR(X509, ERR_R_SYS_LIB);
+ goto err;
+ }
- if (type == X509_FILETYPE_PEM)
- {
- for (;;)
- {
- x=PEM_read_bio_X509_CRL(in,NULL,NULL,NULL);
- if (x == NULL)
- {
- if ((ERR_GET_REASON(ERR_peek_last_error()) ==
- PEM_R_NO_START_LINE) && (count > 0))
- {
- ERR_clear_error();
- break;
- }
- else
- {
- OPENSSL_PUT_ERROR(X509, ERR_R_PEM_LIB);
- goto err;
- }
- }
- i=X509_STORE_add_crl(ctx->store_ctx,x);
- if (!i) goto err;
- count++;
- X509_CRL_free(x);
- x=NULL;
- }
- ret=count;
- }
- else if (type == X509_FILETYPE_ASN1)
- {
- x=d2i_X509_CRL_bio(in,NULL);
- if (x == NULL)
- {
- OPENSSL_PUT_ERROR(X509, ERR_R_ASN1_LIB);
- goto err;
- }
- i=X509_STORE_add_crl(ctx->store_ctx,x);
- if (!i) goto err;
- ret=i;
- }
- else
- {
- OPENSSL_PUT_ERROR(X509, X509_R_BAD_X509_FILETYPE);
- goto err;
- }
-err:
- if (x != NULL) X509_CRL_free(x);
- if (in != NULL) BIO_free(in);
- return(ret);
- }
+ if (type == X509_FILETYPE_PEM) {
+ for (;;) {
+ x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
+ if (x == NULL) {
+ if ((ERR_GET_REASON(ERR_peek_last_error()) ==
+ PEM_R_NO_START_LINE) && (count > 0)) {
+ ERR_clear_error();
+ break;
+ } else {
+ OPENSSL_PUT_ERROR(X509, ERR_R_PEM_LIB);
+ goto err;
+ }
+ }
+ i = X509_STORE_add_crl(ctx->store_ctx, x);
+ if (!i)
+ goto err;
+ count++;
+ X509_CRL_free(x);
+ x = NULL;
+ }
+ ret = count;
+ } else if (type == X509_FILETYPE_ASN1) {
+ x = d2i_X509_CRL_bio(in, NULL);
+ if (x == NULL) {
+ OPENSSL_PUT_ERROR(X509, ERR_R_ASN1_LIB);
+ goto err;
+ }
+ i = X509_STORE_add_crl(ctx->store_ctx, x);
+ if (!i)
+ goto err;
+ ret = i;
+ } else {
+ OPENSSL_PUT_ERROR(X509, X509_R_BAD_X509_FILETYPE);
+ goto err;
+ }
+ err:
+ if (x != NULL)
+ X509_CRL_free(x);
+ if (in != NULL)
+ BIO_free(in);
+ return (ret);
+}
int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type)
{
- STACK_OF(X509_INFO) *inf;
- X509_INFO *itmp;
- BIO *in;
- size_t i;
- int count = 0;
- if(type != X509_FILETYPE_PEM)
- return X509_load_cert_file(ctx, file, type);
- in = BIO_new_file(file, "r");
- if(!in) {
- 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, ERR_R_PEM_LIB);
- return 0;
- }
- for(i = 0; i < sk_X509_INFO_num(inf); i++) {
- itmp = sk_X509_INFO_value(inf, i);
- if(itmp->x509) {
- X509_STORE_add_cert(ctx->store_ctx, itmp->x509);
- count++;
- }
- if(itmp->crl) {
- X509_STORE_add_crl(ctx->store_ctx, itmp->crl);
- count++;
- }
- }
- sk_X509_INFO_pop_free(inf, X509_INFO_free);
- return count;
+ STACK_OF(X509_INFO) *inf;
+ X509_INFO *itmp;
+ BIO *in;
+ size_t i;
+ int count = 0;
+ if (type != X509_FILETYPE_PEM)
+ return X509_load_cert_file(ctx, file, type);
+ in = BIO_new_file(file, "r");
+ if (!in) {
+ 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, ERR_R_PEM_LIB);
+ return 0;
+ }
+ for (i = 0; i < sk_X509_INFO_num(inf); i++) {
+ itmp = sk_X509_INFO_value(inf, i);
+ if (itmp->x509) {
+ X509_STORE_add_cert(ctx->store_ctx, itmp->x509);
+ count++;
+ }
+ if (itmp->crl) {
+ X509_STORE_add_crl(ctx->store_ctx, itmp->crl);
+ count++;
+ }
+ }
+ sk_X509_INFO_pop_free(inf, X509_INFO_free);
+ return count;
}
-#endif /* OPENSSL_NO_STDIO */
+#endif /* OPENSSL_NO_STDIO */
diff --git a/src/crypto/x509/charmap.h b/src/crypto/x509/charmap.h
index b55e6387..3305ad14 100644
--- a/src/crypto/x509/charmap.h
+++ b/src/crypto/x509/charmap.h
@@ -1,15 +1,15 @@
-/* Auto generated with chartype.pl script.
- * Mask of various character properties
+/*
+ * Auto generated with chartype.pl script. Mask of various character
+ * properties
*/
static const unsigned char char_type[] = {
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-120, 0, 1,40, 0, 0, 0,16,16,16, 0,25,25,16,16,16,
-16,16,16,16,16,16,16,16,16,16,16, 9, 9,16, 9,16,
- 0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
-16,16,16,16,16,16,16,16,16,16,16, 0, 1, 0, 0, 0,
- 0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
-16,16,16,16,16,16,16,16,16,16,16, 0, 0, 0, 0, 2
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 120, 0, 1, 40, 0, 0, 0, 16, 16, 16, 0, 25, 25, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 9, 9, 16, 9, 16,
+ 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 1, 0, 0, 0,
+ 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 2
};
-
diff --git a/src/crypto/x509/i2d_pr.c b/src/crypto/x509/i2d_pr.c
index e7f4269d..c3fb8a8a 100644
--- a/src/crypto/x509/i2d_pr.c
+++ b/src/crypto/x509/i2d_pr.c
@@ -55,30 +55,29 @@
* copied and put under another distribution licence
* [including the GNU Public Licence.] */
-#include <openssl/x509.h>
-
#include <openssl/asn1.h>
+#include <openssl/ec_key.h>
#include <openssl/err.h>
#include <openssl/evp.h>
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
-#include "../evp/internal.h"
-
-
-int i2d_PrivateKey(const EVP_PKEY *a, unsigned char **pp)
- {
- if (a->ameth && a->ameth->old_priv_encode)
- {
- return a->ameth->old_priv_encode(a, pp);
- }
- if (a->ameth && a->ameth->priv_encode) {
- PKCS8_PRIV_KEY_INFO *p8 = EVP_PKEY2PKCS8((EVP_PKEY*)a);
- int ret = i2d_PKCS8_PRIV_KEY_INFO(p8,pp);
- PKCS8_PRIV_KEY_INFO_free(p8);
- return ret;
- }
- /* Although this file is in crypto/x509 for layering reasons, it emits
- * an error code from ASN1 for OpenSSL compatibility. */
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
- return -1;
- }
+int i2d_PrivateKey(const EVP_PKEY *a, uint8_t **pp)
+{
+ switch (EVP_PKEY_id(a)) {
+ case EVP_PKEY_RSA:
+ return i2d_RSAPrivateKey(a->pkey.rsa, pp);
+ case EVP_PKEY_EC:
+ return i2d_ECPrivateKey(a->pkey.ec, pp);
+ case EVP_PKEY_DSA:
+ return i2d_DSAPrivateKey(a->pkey.dsa, pp);
+ default:
+ /*
+ * Although this file is in crypto/x509 for layering reasons, it emits
+ * an error code from ASN1 for OpenSSL compatibility.
+ */
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
+ return -1;
+ }
+}
diff --git a/src/crypto/x509/internal.h b/src/crypto/x509/internal.h
new file mode 100644
index 00000000..4957c1e1
--- /dev/null
+++ b/src/crypto/x509/internal.h
@@ -0,0 +1,66 @@
+/* Copyright (c) 2016, 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_X509_INTERNAL_H
+#define OPENSSL_HEADER_X509_INTERNAL_H
+
+#include <openssl/base.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+/* RSA-PSS functions. */
+
+/* x509_rsa_pss_to_ctx configures |ctx| for an RSA-PSS operation based on
+ * signature algorithm parameters in |sigalg| (which must have type
+ * |NID_rsassaPss|) and key |pkey|. It returns one on success and zero on
+ * error. */
+int x509_rsa_pss_to_ctx(EVP_MD_CTX *ctx, X509_ALGOR *sigalg, EVP_PKEY *pkey);
+
+/* x509_rsa_pss_to_ctx sets |algor| to the signature algorithm parameters for
+ * |ctx|, which must have been configured for an RSA-PSS signing operation. It
+ * returns one on success and zero on error. */
+int x509_rsa_ctx_to_pss(EVP_MD_CTX *ctx, X509_ALGOR *algor);
+
+/* x509_print_rsa_pss_params prints a human-readable representation of RSA-PSS
+ * parameters in |sigalg| to |bp|. It returns one on success and zero on
+ * error. */
+int x509_print_rsa_pss_params(BIO *bp, const X509_ALGOR *sigalg, int indent,
+ ASN1_PCTX *pctx);
+
+
+/* Signature algorithm functions. */
+
+/* x509_digest_sign_algorithm encodes the signing parameters of |ctx| as an
+ * AlgorithmIdentifer and saves the result in |algor|. It returns one on
+ * success, or zero on error. */
+int x509_digest_sign_algorithm(EVP_MD_CTX *ctx, X509_ALGOR *algor);
+
+/* x509_digest_verify_init sets up |ctx| for a signature verification operation
+ * with public key |pkey| and parameters from |algor|. The |ctx| argument must
+ * have been initialised with |EVP_MD_CTX_init|. It returns one on success, or
+ * zero on error. */
+int x509_digest_verify_init(EVP_MD_CTX *ctx, X509_ALGOR *sigalg,
+ EVP_PKEY *pkey);
+
+
+#if defined(__cplusplus)
+} /* extern C */
+#endif
+
+#endif /* OPENSSL_HEADER_X509_INTERNAL_H */
diff --git a/src/crypto/x509/pkcs7_test.c b/src/crypto/x509/pkcs7_test.c
index 38beb3e8..2dfeb5ed 100644
--- a/src/crypto/x509/pkcs7_test.c
+++ b/src/crypto/x509/pkcs7_test.c
@@ -22,6 +22,8 @@
#include <openssl/stack.h>
#include <openssl/x509.h>
+#include "../test/test_util.h"
+
/* kPKCS7NSS contains the certificate chain of mail.google.com, as saved by NSS
* using the Chrome UI. */
@@ -504,7 +506,7 @@ static int test_cert_reparse(const uint8_t *der_bytes, size_t der_len) {
X509 *b = sk_X509_value(certs2, i);
if (X509_cmp(a, b) != 0) {
- fprintf(stderr, "Certificate %u differs.\n", (unsigned) i);
+ fprintf(stderr, "Certificate %" OPENSSL_PR_SIZE_T " differs.\n", i);
return 0;
}
}
@@ -568,7 +570,7 @@ static int test_crl_reparse(const uint8_t *der_bytes, size_t der_len) {
X509_CRL *b = sk_X509_CRL_value(crls2, i);
if (X509_CRL_cmp(a, b) != 0) {
- fprintf(stderr, "CRL %u differs.\n", (unsigned) i);
+ fprintf(stderr, "CRL %" OPENSSL_PR_SIZE_T " differs.\n", i);
return 0;
}
}
@@ -596,7 +598,7 @@ static int test_crl_reparse(const uint8_t *der_bytes, size_t der_len) {
}
static int test_pem_certs(const char *pem) {
- BIO *bio = BIO_new_mem_buf((char *) pem, strlen(pem));
+ BIO *bio = BIO_new_mem_buf(pem, strlen(pem));
STACK_OF(X509) *certs = sk_X509_new_null();
if (!PKCS7_get_PEM_certificates(certs, bio)) {
@@ -606,8 +608,9 @@ static int test_pem_certs(const char *pem) {
if (sk_X509_num(certs) != 1) {
fprintf(stderr,
- "Bad number of certificates from PKCS7_get_PEM_certificates: %u\n",
- (unsigned)sk_X509_num(certs));
+ "Bad number of certificates from PKCS7_get_PEM_certificates: "
+ "%" OPENSSL_PR_SIZE_T "\n",
+ sk_X509_num(certs));
return 0;
}
@@ -618,7 +621,7 @@ static int test_pem_certs(const char *pem) {
}
static int test_pem_crls(const char *pem) {
- BIO *bio = BIO_new_mem_buf((char *) pem, strlen(pem));
+ BIO *bio = BIO_new_mem_buf(pem, strlen(pem));
STACK_OF(X509_CRL) *crls = sk_X509_CRL_new_null();
if (!PKCS7_get_PEM_CRLs(crls, bio)) {
@@ -628,8 +631,9 @@ static int test_pem_crls(const char *pem) {
if (sk_X509_CRL_num(crls) != 1) {
fprintf(stderr,
- "Bad number of CRLs from PKCS7_get_PEM_CRLs: %u\n",
- (unsigned)sk_X509_CRL_num(crls));
+ "Bad number of CRLs from PKCS7_get_PEM_CRLs: %" OPENSSL_PR_SIZE_T
+ "\n",
+ sk_X509_CRL_num(crls));
return 0;
}
@@ -653,4 +657,3 @@ int main(void) {
printf("PASS\n");
return 0;
}
-
diff --git a/src/crypto/x509/rsa_pss.c b/src/crypto/x509/rsa_pss.c
new file mode 100644
index 00000000..1ae01a3d
--- /dev/null
+++ b/src/crypto/x509/rsa_pss.c
@@ -0,0 +1,385 @@
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 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
+ * 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/x509.h>
+
+#include <assert.h>
+
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/bio.h>
+#include <openssl/evp.h>
+#include <openssl/err.h>
+#include <openssl/obj.h>
+
+#include "internal.h"
+
+
+ASN1_SEQUENCE(RSA_PSS_PARAMS) = {
+ ASN1_EXP_OPT(RSA_PSS_PARAMS, hashAlgorithm, X509_ALGOR,0),
+ ASN1_EXP_OPT(RSA_PSS_PARAMS, maskGenAlgorithm, X509_ALGOR,1),
+ ASN1_EXP_OPT(RSA_PSS_PARAMS, saltLength, ASN1_INTEGER,2),
+ ASN1_EXP_OPT(RSA_PSS_PARAMS, trailerField, ASN1_INTEGER,3),
+} ASN1_SEQUENCE_END(RSA_PSS_PARAMS);
+
+IMPLEMENT_ASN1_FUNCTIONS(RSA_PSS_PARAMS);
+
+
+/* Given an MGF1 Algorithm ID decode to an Algorithm Identifier */
+static X509_ALGOR *rsa_mgf1_decode(X509_ALGOR *alg) {
+ if (alg == NULL || alg->parameter == NULL ||
+ OBJ_obj2nid(alg->algorithm) != NID_mgf1 ||
+ alg->parameter->type != V_ASN1_SEQUENCE) {
+ return NULL;
+ }
+
+ const uint8_t *p = alg->parameter->value.sequence->data;
+ int plen = alg->parameter->value.sequence->length;
+ return d2i_X509_ALGOR(NULL, &p, plen);
+}
+
+static RSA_PSS_PARAMS *rsa_pss_decode(const X509_ALGOR *alg,
+ X509_ALGOR **pmaskHash) {
+ *pmaskHash = NULL;
+
+ if (alg->parameter == NULL || alg->parameter->type != V_ASN1_SEQUENCE) {
+ return NULL;
+ }
+
+ const uint8_t *p = alg->parameter->value.sequence->data;
+ int plen = alg->parameter->value.sequence->length;
+ RSA_PSS_PARAMS *pss = d2i_RSA_PSS_PARAMS(NULL, &p, plen);
+ if (pss == NULL) {
+ return NULL;
+ }
+
+ *pmaskHash = rsa_mgf1_decode(pss->maskGenAlgorithm);
+ return pss;
+}
+
+/* allocate and set algorithm ID from EVP_MD, default SHA1 */
+static int rsa_md_to_algor(X509_ALGOR **palg, const EVP_MD *md) {
+ if (EVP_MD_type(md) == NID_sha1) {
+ return 1;
+ }
+ *palg = X509_ALGOR_new();
+ if (*palg == NULL) {
+ return 0;
+ }
+ X509_ALGOR_set_md(*palg, md);
+ return 1;
+}
+
+/* Allocate and set MGF1 algorithm ID from EVP_MD */
+static int rsa_md_to_mgf1(X509_ALGOR **palg, const EVP_MD *mgf1md) {
+ X509_ALGOR *algtmp = NULL;
+ ASN1_STRING *stmp = NULL;
+ *palg = NULL;
+
+ if (EVP_MD_type(mgf1md) == NID_sha1) {
+ return 1;
+ }
+ /* need to embed algorithm ID inside another */
+ if (!rsa_md_to_algor(&algtmp, mgf1md) ||
+ !ASN1_item_pack(algtmp, ASN1_ITEM_rptr(X509_ALGOR), &stmp)) {
+ goto err;
+ }
+ *palg = X509_ALGOR_new();
+ if (!*palg) {
+ goto err;
+ }
+ X509_ALGOR_set0(*palg, OBJ_nid2obj(NID_mgf1), V_ASN1_SEQUENCE, stmp);
+ stmp = NULL;
+
+err:
+ ASN1_STRING_free(stmp);
+ X509_ALGOR_free(algtmp);
+ if (*palg) {
+ return 1;
+ }
+
+ return 0;
+}
+
+/* convert algorithm ID to EVP_MD, default SHA1 */
+static const EVP_MD *rsa_algor_to_md(X509_ALGOR *alg) {
+ const EVP_MD *md;
+ if (!alg) {
+ return EVP_sha1();
+ }
+ md = EVP_get_digestbyobj(alg->algorithm);
+ if (md == NULL) {
+ OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS);
+ }
+ return md;
+}
+
+/* convert MGF1 algorithm ID to EVP_MD, default SHA1 */
+static const EVP_MD *rsa_mgf1_to_md(X509_ALGOR *alg, X509_ALGOR *maskHash) {
+ const EVP_MD *md;
+ if (!alg) {
+ return EVP_sha1();
+ }
+ /* Check mask and lookup mask hash algorithm */
+ if (OBJ_obj2nid(alg->algorithm) != NID_mgf1 ||
+ maskHash == NULL) {
+ OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS);
+ return NULL;
+ }
+ md = EVP_get_digestbyobj(maskHash->algorithm);
+ if (md == NULL) {
+ OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS);
+ return NULL;
+ }
+ return md;
+}
+
+int x509_rsa_ctx_to_pss(EVP_MD_CTX *ctx, X509_ALGOR *algor) {
+ const EVP_MD *sigmd, *mgf1md;
+ int saltlen;
+ if (!EVP_PKEY_CTX_get_signature_md(ctx->pctx, &sigmd) ||
+ !EVP_PKEY_CTX_get_rsa_mgf1_md(ctx->pctx, &mgf1md) ||
+ !EVP_PKEY_CTX_get_rsa_pss_saltlen(ctx->pctx, &saltlen)) {
+ return 0;
+ }
+
+ EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(ctx->pctx);
+ if (saltlen == -1) {
+ saltlen = EVP_MD_size(sigmd);
+ } else if (saltlen == -2) {
+ saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2;
+ if (((EVP_PKEY_bits(pk) - 1) & 0x7) == 0) {
+ saltlen--;
+ }
+ } else {
+ return 0;
+ }
+
+ int ret = 0;
+ ASN1_STRING *os = NULL;
+ RSA_PSS_PARAMS *pss = RSA_PSS_PARAMS_new();
+ if (!pss) {
+ goto err;
+ }
+
+ if (saltlen != 20) {
+ pss->saltLength = ASN1_INTEGER_new();
+ if (!pss->saltLength ||
+ !ASN1_INTEGER_set(pss->saltLength, saltlen)) {
+ goto err;
+ }
+ }
+
+ if (!rsa_md_to_algor(&pss->hashAlgorithm, sigmd) ||
+ !rsa_md_to_mgf1(&pss->maskGenAlgorithm, mgf1md)) {
+ goto err;
+ }
+
+ /* Finally create string with pss parameter encoding. */
+ if (!ASN1_item_pack(pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), &os)) {
+ goto err;
+ }
+
+ X509_ALGOR_set0(algor, OBJ_nid2obj(NID_rsassaPss), V_ASN1_SEQUENCE, os);
+ os = NULL;
+ ret = 1;
+
+err:
+ RSA_PSS_PARAMS_free(pss);
+ ASN1_STRING_free(os);
+ return ret;
+}
+
+int x509_rsa_pss_to_ctx(EVP_MD_CTX *ctx, X509_ALGOR *sigalg, EVP_PKEY *pkey) {
+ assert(OBJ_obj2nid(sigalg->algorithm) == NID_rsassaPss);
+
+ /* Decode PSS parameters */
+ int ret = 0;
+ X509_ALGOR *maskHash;
+ RSA_PSS_PARAMS *pss = rsa_pss_decode(sigalg, &maskHash);
+ if (pss == NULL) {
+ OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS);
+ goto err;
+ }
+
+ const EVP_MD *mgf1md = rsa_mgf1_to_md(pss->maskGenAlgorithm, maskHash);
+ const EVP_MD *md = rsa_algor_to_md(pss->hashAlgorithm);
+ if (mgf1md == NULL || md == NULL) {
+ goto err;
+ }
+
+ int saltlen = 20;
+ if (pss->saltLength != NULL) {
+ saltlen = ASN1_INTEGER_get(pss->saltLength);
+
+ /* Could perform more salt length sanity checks but the main
+ * RSA routines will trap other invalid values anyway. */
+ if (saltlen < 0) {
+ OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS);
+ goto err;
+ }
+ }
+
+ /* low-level routines support only trailer field 0xbc (value 1)
+ * and PKCS#1 says we should reject any other value anyway. */
+ if (pss->trailerField != NULL && ASN1_INTEGER_get(pss->trailerField) != 1) {
+ OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS);
+ goto err;
+ }
+
+ EVP_PKEY_CTX *pkctx;
+ if (!EVP_DigestVerifyInit(ctx, &pkctx, md, NULL, pkey) ||
+ !EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) ||
+ !EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) ||
+ !EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md)) {
+ goto err;
+ }
+
+ ret = 1;
+
+err:
+ RSA_PSS_PARAMS_free(pss);
+ X509_ALGOR_free(maskHash);
+ return ret;
+}
+
+int x509_print_rsa_pss_params(BIO *bp, const X509_ALGOR *sigalg, int indent,
+ ASN1_PCTX *pctx) {
+ assert(OBJ_obj2nid(sigalg->algorithm) == NID_rsassaPss);
+
+ int rv = 0;
+ X509_ALGOR *maskHash;
+ RSA_PSS_PARAMS *pss = rsa_pss_decode(sigalg, &maskHash);
+ if (!pss) {
+ if (BIO_puts(bp, " (INVALID PSS PARAMETERS)\n") <= 0) {
+ goto err;
+ }
+ rv = 1;
+ goto err;
+ }
+
+ if (BIO_puts(bp, "\n") <= 0 ||
+ !BIO_indent(bp, indent, 128) ||
+ BIO_puts(bp, "Hash Algorithm: ") <= 0) {
+ goto err;
+ }
+
+ if (pss->hashAlgorithm) {
+ if (i2a_ASN1_OBJECT(bp, pss->hashAlgorithm->algorithm) <= 0) {
+ goto err;
+ }
+ } else if (BIO_puts(bp, "sha1 (default)") <= 0) {
+ goto err;
+ }
+
+ if (BIO_puts(bp, "\n") <= 0 ||
+ !BIO_indent(bp, indent, 128) ||
+ BIO_puts(bp, "Mask Algorithm: ") <= 0) {
+ goto err;
+ }
+
+ if (pss->maskGenAlgorithm) {
+ if (i2a_ASN1_OBJECT(bp, pss->maskGenAlgorithm->algorithm) <= 0 ||
+ BIO_puts(bp, " with ") <= 0) {
+ goto err;
+ }
+
+ if (maskHash) {
+ if (i2a_ASN1_OBJECT(bp, maskHash->algorithm) <= 0) {
+ goto err;
+ }
+ } else if (BIO_puts(bp, "INVALID") <= 0) {
+ goto err;
+ }
+ } else if (BIO_puts(bp, "mgf1 with sha1 (default)") <= 0) {
+ goto err;
+ }
+ BIO_puts(bp, "\n");
+
+ if (!BIO_indent(bp, indent, 128) ||
+ BIO_puts(bp, "Salt Length: 0x") <= 0) {
+ goto err;
+ }
+
+ if (pss->saltLength) {
+ if (i2a_ASN1_INTEGER(bp, pss->saltLength) <= 0) {
+ goto err;
+ }
+ } else if (BIO_puts(bp, "14 (default)") <= 0) {
+ goto err;
+ }
+ BIO_puts(bp, "\n");
+
+ if (!BIO_indent(bp, indent, 128) ||
+ BIO_puts(bp, "Trailer Field: 0x") <= 0) {
+ goto err;
+ }
+
+ if (pss->trailerField) {
+ if (i2a_ASN1_INTEGER(bp, pss->trailerField) <= 0) {
+ goto err;
+ }
+ } else if (BIO_puts(bp, "BC (default)") <= 0) {
+ goto err;
+ }
+ BIO_puts(bp, "\n");
+
+ rv = 1;
+
+err:
+ RSA_PSS_PARAMS_free(pss);
+ X509_ALGOR_free(maskHash);
+ return rv;
+}
diff --git a/src/crypto/x509/t_crl.c b/src/crypto/x509/t_crl.c
index a2d8bc74..6c347cb8 100644
--- a/src/crypto/x509/t_crl.c
+++ b/src/crypto/x509/t_crl.c
@@ -61,69 +61,68 @@
#include <openssl/x509.h>
#include <openssl/x509v3.h>
-
#ifndef OPENSSL_NO_FP_API
int X509_CRL_print_fp(FILE *fp, X509_CRL *x)
- {
- BIO *b;
- int ret;
+{
+ BIO *b;
+ int ret;
- if ((b=BIO_new(BIO_s_file())) == NULL)
- {
- OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB);
- return(0);
- }
- BIO_set_fp(b,fp,BIO_NOCLOSE);
- ret=X509_CRL_print(b, x);
- BIO_free(b);
- return(ret);
- }
+ if ((b = BIO_new(BIO_s_file())) == NULL) {
+ OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB);
+ return (0);
+ }
+ BIO_set_fp(b, fp, BIO_NOCLOSE);
+ ret = X509_CRL_print(b, x);
+ BIO_free(b);
+ return (ret);
+}
#endif
int X509_CRL_print(BIO *out, X509_CRL *x)
{
- STACK_OF(X509_REVOKED) *rev;
- X509_REVOKED *r;
- long l;
- size_t i;
- char *p;
+ STACK_OF(X509_REVOKED) *rev;
+ X509_REVOKED *r;
+ long l;
+ size_t i;
+ char *p;
- BIO_printf(out, "Certificate Revocation List (CRL):\n");
- l = X509_CRL_get_version(x);
- BIO_printf(out, "%8sVersion %lu (0x%lx)\n", "", l+1, l);
- X509_signature_print(out, x->sig_alg, NULL);
- p=X509_NAME_oneline(X509_CRL_get_issuer(x),NULL,0);
- BIO_printf(out,"%8sIssuer: %s\n","",p);
- OPENSSL_free(p);
- BIO_printf(out,"%8sLast Update: ","");
- ASN1_TIME_print(out,X509_CRL_get_lastUpdate(x));
- BIO_printf(out,"\n%8sNext Update: ","");
- if (X509_CRL_get_nextUpdate(x))
- ASN1_TIME_print(out,X509_CRL_get_nextUpdate(x));
- else BIO_printf(out,"NONE");
- BIO_printf(out,"\n");
+ BIO_printf(out, "Certificate Revocation List (CRL):\n");
+ l = X509_CRL_get_version(x);
+ BIO_printf(out, "%8sVersion %lu (0x%lx)\n", "", l + 1, l);
+ X509_signature_print(out, x->sig_alg, NULL);
+ p = X509_NAME_oneline(X509_CRL_get_issuer(x), NULL, 0);
+ BIO_printf(out, "%8sIssuer: %s\n", "", p);
+ OPENSSL_free(p);
+ BIO_printf(out, "%8sLast Update: ", "");
+ ASN1_TIME_print(out, X509_CRL_get_lastUpdate(x));
+ BIO_printf(out, "\n%8sNext Update: ", "");
+ if (X509_CRL_get_nextUpdate(x))
+ ASN1_TIME_print(out, X509_CRL_get_nextUpdate(x));
+ else
+ BIO_printf(out, "NONE");
+ BIO_printf(out, "\n");
- X509V3_extensions_print(out, "CRL extensions",
- x->crl->extensions, 0, 8);
+ X509V3_extensions_print(out, "CRL extensions", x->crl->extensions, 0, 8);
- rev = X509_CRL_get_REVOKED(x);
+ rev = X509_CRL_get_REVOKED(x);
- if(sk_X509_REVOKED_num(rev) > 0)
- BIO_printf(out, "Revoked Certificates:\n");
- else BIO_printf(out, "No Revoked Certificates.\n");
+ if (sk_X509_REVOKED_num(rev) > 0)
+ BIO_printf(out, "Revoked Certificates:\n");
+ else
+ BIO_printf(out, "No Revoked Certificates.\n");
- for(i = 0; i < sk_X509_REVOKED_num(rev); i++) {
- r = sk_X509_REVOKED_value(rev, i);
- BIO_printf(out," Serial Number: ");
- i2a_ASN1_INTEGER(out,r->serialNumber);
- BIO_printf(out,"\n Revocation Date: ");
- ASN1_TIME_print(out,r->revocationDate);
- BIO_printf(out,"\n");
- X509V3_extensions_print(out, "CRL entry extensions",
- r->extensions, 0, 8);
- }
- X509_signature_print(out, x->sig_alg, x->signature);
+ for (i = 0; i < sk_X509_REVOKED_num(rev); i++) {
+ r = sk_X509_REVOKED_value(rev, i);
+ BIO_printf(out, " Serial Number: ");
+ i2a_ASN1_INTEGER(out, r->serialNumber);
+ BIO_printf(out, "\n Revocation Date: ");
+ ASN1_TIME_print(out, r->revocationDate);
+ BIO_printf(out, "\n");
+ X509V3_extensions_print(out, "CRL entry extensions",
+ r->extensions, 0, 8);
+ }
+ X509_signature_print(out, x->sig_alg, x->signature);
- return 1;
+ return 1;
}
diff --git a/src/crypto/x509/t_x509.c b/src/crypto/x509/t_x509.c
index 7785ebff..1fba9b43 100644
--- a/src/crypto/x509/t_x509.c
+++ b/src/crypto/x509/t_x509.c
@@ -64,437 +64,443 @@
#include <openssl/x509.h>
#include <openssl/x509v3.h>
-#include "../evp/internal.h"
+#include "internal.h"
+
#ifndef OPENSSL_NO_FP_API
-int X509_print_ex_fp(FILE *fp, X509 *x, unsigned long nmflag, unsigned long cflag)
- {
- BIO *b;
- int ret;
-
- if ((b=BIO_new(BIO_s_file())) == NULL)
- {
- OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB);
- return(0);
- }
- BIO_set_fp(b,fp,BIO_NOCLOSE);
- ret=X509_print_ex(b, x, nmflag, cflag);
- BIO_free(b);
- return(ret);
- }
+int X509_print_ex_fp(FILE *fp, X509 *x, unsigned long nmflag,
+ unsigned long cflag)
+{
+ BIO *b;
+ int ret;
+
+ if ((b = BIO_new(BIO_s_file())) == NULL) {
+ OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB);
+ return (0);
+ }
+ BIO_set_fp(b, fp, BIO_NOCLOSE);
+ ret = X509_print_ex(b, x, nmflag, cflag);
+ BIO_free(b);
+ return (ret);
+}
int X509_print_fp(FILE *fp, X509 *x)
- {
- return X509_print_ex_fp(fp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
- }
+{
+ return X509_print_ex_fp(fp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
+}
#endif
int X509_print(BIO *bp, X509 *x)
{
- return X509_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
+ return X509_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
}
-int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, unsigned long cflag)
- {
- long l;
- int ret=0,i;
- char *m=NULL,mlch = ' ';
- int nmindent = 0;
- X509_CINF *ci;
- ASN1_INTEGER *bs;
- EVP_PKEY *pkey=NULL;
- const char *neg;
-
- if((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
- mlch = '\n';
- nmindent = 12;
- }
-
- if(nmflags == X509_FLAG_COMPAT)
- nmindent = 16;
-
- ci=x->cert_info;
- if(!(cflag & X509_FLAG_NO_HEADER))
- {
- if (BIO_write(bp,"Certificate:\n",13) <= 0) goto err;
- if (BIO_write(bp," Data:\n",10) <= 0) goto err;
- }
- if(!(cflag & X509_FLAG_NO_VERSION))
- {
- l=X509_get_version(x);
- if (BIO_printf(bp,"%8sVersion: %lu (0x%lx)\n","",l+1,l) <= 0) goto err;
- }
- if(!(cflag & X509_FLAG_NO_SERIAL))
- {
-
- if (BIO_write(bp," Serial Number:",22) <= 0) goto err;
-
- bs=X509_get_serialNumber(x);
- if (bs->length <= (int)sizeof(long))
- {
- l=ASN1_INTEGER_get(bs);
- if (bs->type == V_ASN1_NEG_INTEGER)
- {
- l= -l;
- neg="-";
- }
- else
- neg="";
- if (BIO_printf(bp," %s%lu (%s0x%lx)\n",neg,l,neg,l) <= 0)
- goto err;
- }
- else
- {
- neg=(bs->type == V_ASN1_NEG_INTEGER)?" (Negative)":"";
- if (BIO_printf(bp,"\n%12s%s","",neg) <= 0) goto err;
-
- for (i=0; i<bs->length; i++)
- {
- if (BIO_printf(bp,"%02x%c",bs->data[i],
- ((i+1 == bs->length)?'\n':':')) <= 0)
- goto err;
- }
- }
-
- }
-
- if(!(cflag & X509_FLAG_NO_SIGNAME))
- {
- if (X509_signature_print(bp, ci->signature, NULL) <= 0)
- goto err;
- }
-
- if(!(cflag & X509_FLAG_NO_ISSUER))
- {
- if (BIO_printf(bp," Issuer:%c",mlch) <= 0) goto err;
- if (X509_NAME_print_ex(bp,X509_get_issuer_name(x),nmindent, nmflags) < 0) goto err;
- if (BIO_write(bp,"\n",1) <= 0) goto err;
- }
- if(!(cflag & X509_FLAG_NO_VALIDITY))
- {
- if (BIO_write(bp," Validity\n",17) <= 0) goto err;
- if (BIO_write(bp," Not Before: ",24) <= 0) goto err;
- if (!ASN1_TIME_print(bp,X509_get_notBefore(x))) goto err;
- if (BIO_write(bp,"\n Not After : ",25) <= 0) goto err;
- if (!ASN1_TIME_print(bp,X509_get_notAfter(x))) goto err;
- if (BIO_write(bp,"\n",1) <= 0) goto err;
- }
- if(!(cflag & X509_FLAG_NO_SUBJECT))
- {
- if (BIO_printf(bp," Subject:%c",mlch) <= 0) goto err;
- if (X509_NAME_print_ex(bp,X509_get_subject_name(x),nmindent, nmflags) < 0) goto err;
- if (BIO_write(bp,"\n",1) <= 0) goto err;
- }
- if(!(cflag & X509_FLAG_NO_PUBKEY))
- {
- if (BIO_write(bp," Subject Public Key Info:\n",33) <= 0)
- goto err;
- if (BIO_printf(bp,"%12sPublic Key Algorithm: ","") <= 0)
- goto err;
- if (i2a_ASN1_OBJECT(bp, ci->key->algor->algorithm) <= 0)
- goto err;
- if (BIO_puts(bp, "\n") <= 0)
- goto err;
-
- pkey=X509_get_pubkey(x);
- if (pkey == NULL)
- {
- BIO_printf(bp,"%12sUnable to load Public Key\n","");
- BIO_print_errors(bp);
- }
- else
- {
- EVP_PKEY_print_public(bp, pkey, 16, NULL);
- EVP_PKEY_free(pkey);
- }
- }
-
- if(!(cflag & X509_FLAG_NO_IDS))
- {
- if (ci->issuerUID)
- {
- if (BIO_printf(bp,"%8sIssuer Unique ID: ","") <= 0)
- goto err;
- if (!X509_signature_dump(bp, ci->issuerUID, 12))
- goto err;
- }
- if (ci->subjectUID)
- {
- if (BIO_printf(bp,"%8sSubject Unique ID: ","") <= 0)
- goto err;
- if (!X509_signature_dump(bp, ci->subjectUID, 12))
- goto err;
- }
- }
-
- if (!(cflag & X509_FLAG_NO_EXTENSIONS))
- X509V3_extensions_print(bp, "X509v3 extensions",
- ci->extensions, cflag, 8);
-
- if(!(cflag & X509_FLAG_NO_SIGDUMP))
- {
- if(X509_signature_print(bp, x->sig_alg, x->signature) <= 0) goto err;
- }
- if(!(cflag & X509_FLAG_NO_AUX))
- {
- if (!X509_CERT_AUX_print(bp, x->aux, 0)) goto err;
- }
- ret=1;
-err:
- if (m != NULL) OPENSSL_free(m);
- return(ret);
- }
-
-int X509_ocspid_print (BIO *bp, X509 *x)
- {
- unsigned char *der=NULL ;
- unsigned char *dertmp;
- int derlen;
- int i;
- unsigned char SHA1md[SHA_DIGEST_LENGTH];
-
- /* display the hash of the subject as it would appear
- in OCSP requests */
- if (BIO_printf(bp," Subject OCSP hash: ") <= 0)
- goto err;
- derlen = i2d_X509_NAME(x->cert_info->subject, NULL);
- if ((der = dertmp = (unsigned char *)OPENSSL_malloc (derlen)) == NULL)
- goto err;
- i2d_X509_NAME(x->cert_info->subject, &dertmp);
-
- if (!EVP_Digest(der, derlen, SHA1md, NULL, EVP_sha1(), NULL))
- goto err;
- for (i=0; i < SHA_DIGEST_LENGTH; i++)
- {
- if (BIO_printf(bp,"%02X",SHA1md[i]) <= 0) goto err;
- }
- OPENSSL_free (der);
- der=NULL;
-
- /* display the hash of the public key as it would appear
- in OCSP requests */
- if (BIO_printf(bp,"\n Public key OCSP hash: ") <= 0)
- goto err;
-
- if (!EVP_Digest(x->cert_info->key->public_key->data,
- x->cert_info->key->public_key->length,
- SHA1md, NULL, EVP_sha1(), NULL))
- goto err;
- for (i=0; i < SHA_DIGEST_LENGTH; i++)
- {
- if (BIO_printf(bp,"%02X",SHA1md[i]) <= 0)
- goto err;
- }
- BIO_printf(bp,"\n");
-
- return (1);
-err:
- if (der != NULL) OPENSSL_free(der);
- return(0);
- }
+int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags,
+ unsigned long cflag)
+{
+ long l;
+ int ret = 0, i;
+ char *m = NULL, mlch = ' ';
+ int nmindent = 0;
+ X509_CINF *ci;
+ ASN1_INTEGER *bs;
+ EVP_PKEY *pkey = NULL;
+ const char *neg;
+
+ if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
+ mlch = '\n';
+ nmindent = 12;
+ }
+
+ if (nmflags == X509_FLAG_COMPAT)
+ nmindent = 16;
+
+ ci = x->cert_info;
+ if (!(cflag & X509_FLAG_NO_HEADER)) {
+ if (BIO_write(bp, "Certificate:\n", 13) <= 0)
+ goto err;
+ if (BIO_write(bp, " Data:\n", 10) <= 0)
+ goto err;
+ }
+ if (!(cflag & X509_FLAG_NO_VERSION)) {
+ l = X509_get_version(x);
+ if (BIO_printf(bp, "%8sVersion: %lu (0x%lx)\n", "", l + 1, l) <= 0)
+ goto err;
+ }
+ if (!(cflag & X509_FLAG_NO_SERIAL)) {
+
+ if (BIO_write(bp, " Serial Number:", 22) <= 0)
+ goto err;
+
+ bs = X509_get_serialNumber(x);
+ if (bs->length < (int)sizeof(long)
+ || (bs->length == sizeof(long) && (bs->data[0] & 0x80) == 0)) {
+ l = ASN1_INTEGER_get(bs);
+ if (bs->type == V_ASN1_NEG_INTEGER) {
+ l = -l;
+ neg = "-";
+ } else
+ neg = "";
+ if (BIO_printf(bp, " %s%lu (%s0x%lx)\n", neg, l, neg, l) <= 0)
+ goto err;
+ } else {
+ neg = (bs->type == V_ASN1_NEG_INTEGER) ? " (Negative)" : "";
+ if (BIO_printf(bp, "\n%12s%s", "", neg) <= 0)
+ goto err;
+
+ for (i = 0; i < bs->length; i++) {
+ if (BIO_printf(bp, "%02x%c", bs->data[i],
+ ((i + 1 == bs->length) ? '\n' : ':')) <= 0)
+ goto err;
+ }
+ }
+
+ }
+
+ if (!(cflag & X509_FLAG_NO_SIGNAME)) {
+ if (X509_signature_print(bp, ci->signature, NULL) <= 0)
+ goto err;
+ }
+
+ if (!(cflag & X509_FLAG_NO_ISSUER)) {
+ if (BIO_printf(bp, " Issuer:%c", mlch) <= 0)
+ goto err;
+ if (X509_NAME_print_ex(bp, X509_get_issuer_name(x), nmindent, nmflags)
+ < 0)
+ goto err;
+ if (BIO_write(bp, "\n", 1) <= 0)
+ goto err;
+ }
+ if (!(cflag & X509_FLAG_NO_VALIDITY)) {
+ if (BIO_write(bp, " Validity\n", 17) <= 0)
+ goto err;
+ if (BIO_write(bp, " Not Before: ", 24) <= 0)
+ goto err;
+ if (!ASN1_TIME_print(bp, X509_get_notBefore(x)))
+ goto err;
+ if (BIO_write(bp, "\n Not After : ", 25) <= 0)
+ goto err;
+ if (!ASN1_TIME_print(bp, X509_get_notAfter(x)))
+ goto err;
+ if (BIO_write(bp, "\n", 1) <= 0)
+ goto err;
+ }
+ if (!(cflag & X509_FLAG_NO_SUBJECT)) {
+ if (BIO_printf(bp, " Subject:%c", mlch) <= 0)
+ goto err;
+ if (X509_NAME_print_ex
+ (bp, X509_get_subject_name(x), nmindent, nmflags) < 0)
+ goto err;
+ if (BIO_write(bp, "\n", 1) <= 0)
+ goto err;
+ }
+ if (!(cflag & X509_FLAG_NO_PUBKEY)) {
+ if (BIO_write(bp, " Subject Public Key Info:\n", 33) <= 0)
+ goto err;
+ if (BIO_printf(bp, "%12sPublic Key Algorithm: ", "") <= 0)
+ goto err;
+ if (i2a_ASN1_OBJECT(bp, ci->key->algor->algorithm) <= 0)
+ goto err;
+ if (BIO_puts(bp, "\n") <= 0)
+ goto err;
+
+ pkey = X509_get_pubkey(x);
+ if (pkey == NULL) {
+ BIO_printf(bp, "%12sUnable to load Public Key\n", "");
+ BIO_print_errors(bp);
+ } else {
+ EVP_PKEY_print_public(bp, pkey, 16, NULL);
+ EVP_PKEY_free(pkey);
+ }
+ }
+
+ if (!(cflag & X509_FLAG_NO_IDS)) {
+ if (ci->issuerUID) {
+ if (BIO_printf(bp, "%8sIssuer Unique ID: ", "") <= 0)
+ goto err;
+ if (!X509_signature_dump(bp, ci->issuerUID, 12))
+ goto err;
+ }
+ if (ci->subjectUID) {
+ if (BIO_printf(bp, "%8sSubject Unique ID: ", "") <= 0)
+ goto err;
+ if (!X509_signature_dump(bp, ci->subjectUID, 12))
+ goto err;
+ }
+ }
+
+ if (!(cflag & X509_FLAG_NO_EXTENSIONS))
+ X509V3_extensions_print(bp, "X509v3 extensions",
+ ci->extensions, cflag, 8);
+
+ if (!(cflag & X509_FLAG_NO_SIGDUMP)) {
+ if (X509_signature_print(bp, x->sig_alg, x->signature) <= 0)
+ goto err;
+ }
+ if (!(cflag & X509_FLAG_NO_AUX)) {
+ if (!X509_CERT_AUX_print(bp, x->aux, 0))
+ goto err;
+ }
+ ret = 1;
+ err:
+ if (m != NULL)
+ OPENSSL_free(m);
+ return (ret);
+}
+
+int X509_ocspid_print(BIO *bp, X509 *x)
+{
+ unsigned char *der = NULL;
+ unsigned char *dertmp;
+ int derlen;
+ int i;
+ unsigned char SHA1md[SHA_DIGEST_LENGTH];
+
+ /*
+ * display the hash of the subject as it would appear in OCSP requests
+ */
+ if (BIO_printf(bp, " Subject OCSP hash: ") <= 0)
+ goto err;
+ derlen = i2d_X509_NAME(x->cert_info->subject, NULL);
+ if ((der = dertmp = (unsigned char *)OPENSSL_malloc(derlen)) == NULL)
+ goto err;
+ i2d_X509_NAME(x->cert_info->subject, &dertmp);
+
+ if (!EVP_Digest(der, derlen, SHA1md, NULL, EVP_sha1(), NULL))
+ goto err;
+ for (i = 0; i < SHA_DIGEST_LENGTH; i++) {
+ if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0)
+ goto err;
+ }
+ OPENSSL_free(der);
+ der = NULL;
+
+ /*
+ * display the hash of the public key as it would appear in OCSP requests
+ */
+ if (BIO_printf(bp, "\n Public key OCSP hash: ") <= 0)
+ goto err;
+
+ if (!EVP_Digest(x->cert_info->key->public_key->data,
+ x->cert_info->key->public_key->length,
+ SHA1md, NULL, EVP_sha1(), NULL))
+ goto err;
+ for (i = 0; i < SHA_DIGEST_LENGTH; i++) {
+ if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0)
+ goto err;
+ }
+ BIO_printf(bp, "\n");
+
+ return (1);
+ err:
+ if (der != NULL)
+ OPENSSL_free(der);
+ return (0);
+}
int X509_signature_print(BIO *bp, X509_ALGOR *sigalg, ASN1_STRING *sig)
{
- int sig_nid;
- if (BIO_puts(bp," Signature Algorithm: ") <= 0) return 0;
- if (i2a_ASN1_OBJECT(bp, sigalg->algorithm) <= 0) return 0;
-
- sig_nid = OBJ_obj2nid(sigalg->algorithm);
- if (sig_nid != NID_undef)
- {
- int pkey_nid, dig_nid;
- const EVP_PKEY_ASN1_METHOD *ameth;
- if (OBJ_find_sigid_algs(sig_nid, &dig_nid, &pkey_nid))
- {
- ameth = EVP_PKEY_asn1_find(NULL, pkey_nid);
- if (ameth && ameth->sig_print)
- return ameth->sig_print(bp, sigalg, sig, 9, 0);
- }
- }
- if (sig)
- return X509_signature_dump(bp, sig, 9);
- else if (BIO_puts(bp, "\n") <= 0)
- return 0;
- return 1;
+ if (BIO_puts(bp, " Signature Algorithm: ") <= 0)
+ return 0;
+ if (i2a_ASN1_OBJECT(bp, sigalg->algorithm) <= 0)
+ return 0;
+
+ /* RSA-PSS signatures have parameters to print. */
+ int sig_nid = OBJ_obj2nid(sigalg->algorithm);
+ if (sig_nid == NID_rsassaPss &&
+ !x509_print_rsa_pss_params(bp, sigalg, 9, 0)) {
+ return 0;
+ }
+
+ if (sig)
+ return X509_signature_dump(bp, sig, 9);
+ else if (BIO_puts(bp, "\n") <= 0)
+ return 0;
+ return 1;
}
int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v)
- {
- int i,n;
- char buf[80];
- const char *p;
-
- if (v == NULL) return(0);
- n=0;
- p=(const char *)v->data;
- for (i=0; i<v->length; i++)
- {
- if ((p[i] > '~') || ((p[i] < ' ') &&
- (p[i] != '\n') && (p[i] != '\r')))
- buf[n]='.';
- else
- buf[n]=p[i];
- n++;
- if (n >= 80)
- {
- if (BIO_write(bp,buf,n) <= 0)
- return(0);
- n=0;
- }
- }
- if (n > 0)
- if (BIO_write(bp,buf,n) <= 0)
- return(0);
- return(1);
- }
+{
+ int i, n;
+ char buf[80];
+ const char *p;
+
+ if (v == NULL)
+ return (0);
+ n = 0;
+ p = (const char *)v->data;
+ for (i = 0; i < v->length; i++) {
+ if ((p[i] > '~') || ((p[i] < ' ') &&
+ (p[i] != '\n') && (p[i] != '\r')))
+ buf[n] = '.';
+ else
+ buf[n] = p[i];
+ n++;
+ if (n >= 80) {
+ if (BIO_write(bp, buf, n) <= 0)
+ return (0);
+ n = 0;
+ }
+ }
+ if (n > 0)
+ if (BIO_write(bp, buf, n) <= 0)
+ return (0);
+ return (1);
+}
int ASN1_TIME_print(BIO *bp, const ASN1_TIME *tm)
{
- if(tm->type == V_ASN1_UTCTIME) return ASN1_UTCTIME_print(bp, tm);
- if(tm->type == V_ASN1_GENERALIZEDTIME)
- return ASN1_GENERALIZEDTIME_print(bp, tm);
- BIO_write(bp,"Bad time value",14);
- return(0);
+ if (tm->type == V_ASN1_UTCTIME)
+ return ASN1_UTCTIME_print(bp, tm);
+ if (tm->type == V_ASN1_GENERALIZEDTIME)
+ return ASN1_GENERALIZEDTIME_print(bp, tm);
+ BIO_write(bp, "Bad time value", 14);
+ return (0);
}
-static const char *const mon[12]=
- {
- "Jan","Feb","Mar","Apr","May","Jun",
- "Jul","Aug","Sep","Oct","Nov","Dec"
- };
+static const char *const mon[12] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+};
int ASN1_GENERALIZEDTIME_print(BIO *bp, const ASN1_GENERALIZEDTIME *tm)
- {
- char *v;
- int gmt=0;
- int i;
- int y=0,M=0,d=0,h=0,m=0,s=0;
- char *f = NULL;
- int f_len = 0;
-
- i=tm->length;
- v=(char *)tm->data;
-
- if (i < 12) goto err;
- if (v[i-1] == 'Z') gmt=1;
- for (i=0; i<12; i++)
- if ((v[i] > '9') || (v[i] < '0')) goto err;
- y= (v[0]-'0')*1000+(v[1]-'0')*100 + (v[2]-'0')*10+(v[3]-'0');
- M= (v[4]-'0')*10+(v[5]-'0');
- if ((M > 12) || (M < 1)) goto err;
- d= (v[6]-'0')*10+(v[7]-'0');
- h= (v[8]-'0')*10+(v[9]-'0');
- m= (v[10]-'0')*10+(v[11]-'0');
- if (tm->length >= 14 &&
- (v[12] >= '0') && (v[12] <= '9') &&
- (v[13] >= '0') && (v[13] <= '9'))
- {
- s= (v[12]-'0')*10+(v[13]-'0');
- /* Check for fractions of seconds. */
- if (tm->length >= 15 && v[14] == '.')
- {
- int l = tm->length;
- f = &v[14]; /* The decimal point. */
- f_len = 1;
- while (14 + f_len < l && f[f_len] >= '0' && f[f_len] <= '9')
- ++f_len;
- }
- }
-
- if (BIO_printf(bp,"%s %2d %02d:%02d:%02d%.*s %d%s",
- mon[M-1],d,h,m,s,f_len,f,y,(gmt)?" GMT":"") <= 0)
- return(0);
- else
- return(1);
-err:
- BIO_write(bp,"Bad time value",14);
- return(0);
- }
+{
+ char *v;
+ int gmt = 0;
+ int i;
+ int y = 0, M = 0, d = 0, h = 0, m = 0, s = 0;
+ char *f = NULL;
+ int f_len = 0;
+
+ i = tm->length;
+ v = (char *)tm->data;
+
+ if (i < 12)
+ goto err;
+ if (v[i - 1] == 'Z')
+ gmt = 1;
+ for (i = 0; i < 12; i++)
+ if ((v[i] > '9') || (v[i] < '0'))
+ goto err;
+ y = (v[0] - '0') * 1000 + (v[1] - '0') * 100 + (v[2] - '0') * 10 + (v[3] -
+ '0');
+ M = (v[4] - '0') * 10 + (v[5] - '0');
+ if ((M > 12) || (M < 1))
+ goto err;
+ d = (v[6] - '0') * 10 + (v[7] - '0');
+ h = (v[8] - '0') * 10 + (v[9] - '0');
+ m = (v[10] - '0') * 10 + (v[11] - '0');
+ if (tm->length >= 14 &&
+ (v[12] >= '0') && (v[12] <= '9') &&
+ (v[13] >= '0') && (v[13] <= '9')) {
+ s = (v[12] - '0') * 10 + (v[13] - '0');
+ /* Check for fractions of seconds. */
+ if (tm->length >= 15 && v[14] == '.') {
+ int l = tm->length;
+ f = &v[14]; /* The decimal point. */
+ f_len = 1;
+ while (14 + f_len < l && f[f_len] >= '0' && f[f_len] <= '9')
+ ++f_len;
+ }
+ }
+
+ if (BIO_printf(bp, "%s %2d %02d:%02d:%02d%.*s %d%s",
+ mon[M - 1], d, h, m, s, f_len, f, y,
+ (gmt) ? " GMT" : "") <= 0)
+ return (0);
+ else
+ return (1);
+ err:
+ BIO_write(bp, "Bad time value", 14);
+ return (0);
+}
int ASN1_UTCTIME_print(BIO *bp, const ASN1_UTCTIME *tm)
- {
- const char *v;
- int gmt=0;
- int i;
- int y=0,M=0,d=0,h=0,m=0,s=0;
-
- i=tm->length;
- v=(const char *)tm->data;
-
- if (i < 10) goto err;
- if (v[i-1] == 'Z') gmt=1;
- for (i=0; i<10; i++)
- if ((v[i] > '9') || (v[i] < '0')) goto err;
- y= (v[0]-'0')*10+(v[1]-'0');
- if (y < 50) y+=100;
- M= (v[2]-'0')*10+(v[3]-'0');
- if ((M > 12) || (M < 1)) goto err;
- d= (v[4]-'0')*10+(v[5]-'0');
- h= (v[6]-'0')*10+(v[7]-'0');
- m= (v[8]-'0')*10+(v[9]-'0');
- if (tm->length >=12 &&
- (v[10] >= '0') && (v[10] <= '9') &&
- (v[11] >= '0') && (v[11] <= '9'))
- s= (v[10]-'0')*10+(v[11]-'0');
-
- if (BIO_printf(bp,"%s %2d %02d:%02d:%02d %d%s",
- mon[M-1],d,h,m,s,y+1900,(gmt)?" GMT":"") <= 0)
- return(0);
- else
- return(1);
-err:
- BIO_write(bp,"Bad time value",14);
- return(0);
- }
+{
+ const char *v;
+ int gmt = 0;
+ int i;
+ int y = 0, M = 0, d = 0, h = 0, m = 0, s = 0;
+
+ i = tm->length;
+ v = (const char *)tm->data;
+
+ if (i < 10)
+ goto err;
+ if (v[i - 1] == 'Z')
+ gmt = 1;
+ for (i = 0; i < 10; i++)
+ if ((v[i] > '9') || (v[i] < '0'))
+ goto err;
+ y = (v[0] - '0') * 10 + (v[1] - '0');
+ if (y < 50)
+ y += 100;
+ M = (v[2] - '0') * 10 + (v[3] - '0');
+ if ((M > 12) || (M < 1))
+ goto err;
+ d = (v[4] - '0') * 10 + (v[5] - '0');
+ h = (v[6] - '0') * 10 + (v[7] - '0');
+ m = (v[8] - '0') * 10 + (v[9] - '0');
+ if (tm->length >= 12 &&
+ (v[10] >= '0') && (v[10] <= '9') && (v[11] >= '0') && (v[11] <= '9'))
+ s = (v[10] - '0') * 10 + (v[11] - '0');
+
+ if (BIO_printf(bp, "%s %2d %02d:%02d:%02d %d%s",
+ mon[M - 1], d, h, m, s, y + 1900,
+ (gmt) ? " GMT" : "") <= 0)
+ return (0);
+ else
+ return (1);
+ err:
+ BIO_write(bp, "Bad time value", 14);
+ return (0);
+}
int X509_NAME_print(BIO *bp, X509_NAME *name, int obase)
- {
- char *s,*c,*b;
- int ret=0,l,i;
-
- l=80-2-obase;
-
- b=X509_NAME_oneline(name,NULL,0);
- if (!b)
- return 0;
- if (!*b)
- {
- OPENSSL_free(b);
- return 1;
- }
- s=b+1; /* skip the first slash */
-
- c=s;
- for (;;)
- {
- if ( ((*s == '/') &&
- ((s[1] >= 'A') && (s[1] <= 'Z') && (
- (s[2] == '=') ||
- ((s[2] >= 'A') && (s[2] <= 'Z') &&
- (s[3] == '='))
- ))) ||
- (*s == '\0'))
- {
- i=s-c;
- if (BIO_write(bp,c,i) != i) goto err;
- c=s+1; /* skip following slash */
- if (*s != '\0')
- {
- if (BIO_write(bp,", ",2) != 2) goto err;
- }
- l--;
- }
- if (*s == '\0') break;
- s++;
- l--;
- }
-
- ret=1;
- if (0)
- {
-err:
- OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB);
- }
- OPENSSL_free(b);
- return(ret);
- }
+{
+ char *s, *c, *b;
+ int ret = 0, l, i;
+
+ l = 80 - 2 - obase;
+
+ b = X509_NAME_oneline(name, NULL, 0);
+ if (!b)
+ return 0;
+ if (!*b) {
+ OPENSSL_free(b);
+ return 1;
+ }
+ s = b + 1; /* skip the first slash */
+
+ c = s;
+ for (;;) {
+ if (((*s == '/') &&
+ ((s[1] >= 'A') && (s[1] <= 'Z') && ((s[2] == '=') ||
+ ((s[2] >= 'A')
+ && (s[2] <= 'Z')
+ && (s[3] == '='))
+ ))) || (*s == '\0')) {
+ i = s - c;
+ if (BIO_write(bp, c, i) != i)
+ goto err;
+ c = s + 1; /* skip following slash */
+ if (*s != '\0') {
+ if (BIO_write(bp, ", ", 2) != 2)
+ goto err;
+ }
+ l--;
+ }
+ if (*s == '\0')
+ break;
+ s++;
+ l--;
+ }
+
+ ret = 1;
+ if (0) {
+ err:
+ OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB);
+ }
+ OPENSSL_free(b);
+ return (ret);
+}
diff --git a/src/crypto/x509/t_x509a.c b/src/crypto/x509/t_x509a.c
index 76672688..54368286 100644
--- a/src/crypto/x509/t_x509a.c
+++ b/src/crypto/x509/t_x509a.c
@@ -60,50 +60,52 @@
#include <openssl/obj.h>
#include <openssl/x509.h>
-
/* X509_CERT_AUX and string set routines */
int X509_CERT_AUX_print(BIO *out, X509_CERT_AUX *aux, int indent)
{
- char oidstr[80], first;
- size_t i;
- int j;
- if(!aux) return 1;
- if(aux->trust) {
- first = 1;
- BIO_printf(out, "%*sTrusted Uses:\n%*s",
- indent, "", indent + 2, "");
- for(i = 0; i < sk_ASN1_OBJECT_num(aux->trust); i++) {
- if(!first) BIO_puts(out, ", ");
- else first = 0;
- OBJ_obj2txt(oidstr, sizeof oidstr,
- sk_ASN1_OBJECT_value(aux->trust, i), 0);
- BIO_puts(out, oidstr);
- }
- BIO_puts(out, "\n");
- } else BIO_printf(out, "%*sNo Trusted Uses.\n", indent, "");
- if(aux->reject) {
- first = 1;
- BIO_printf(out, "%*sRejected Uses:\n%*s",
- indent, "", indent + 2, "");
- for(i = 0; i < sk_ASN1_OBJECT_num(aux->reject); i++) {
- if(!first) BIO_puts(out, ", ");
- else first = 0;
- OBJ_obj2txt(oidstr, sizeof oidstr,
- sk_ASN1_OBJECT_value(aux->reject, i), 0);
- BIO_puts(out, oidstr);
- }
- BIO_puts(out, "\n");
- } else BIO_printf(out, "%*sNo Rejected Uses.\n", indent, "");
- if(aux->alias) BIO_printf(out, "%*sAlias: %s\n", indent, "",
- aux->alias->data);
- if(aux->keyid) {
- BIO_printf(out, "%*sKey Id: ", indent, "");
- for(j = 0; j < aux->keyid->length; j++)
- BIO_printf(out, "%s%02X",
- j ? ":" : "",
- aux->keyid->data[j]);
- BIO_write(out,"\n",1);
- }
- return 1;
+ char oidstr[80], first;
+ size_t i;
+ int j;
+ if (!aux)
+ return 1;
+ if (aux->trust) {
+ first = 1;
+ BIO_printf(out, "%*sTrusted Uses:\n%*s", indent, "", indent + 2, "");
+ for (i = 0; i < sk_ASN1_OBJECT_num(aux->trust); i++) {
+ if (!first)
+ BIO_puts(out, ", ");
+ else
+ first = 0;
+ OBJ_obj2txt(oidstr, sizeof oidstr,
+ sk_ASN1_OBJECT_value(aux->trust, i), 0);
+ BIO_puts(out, oidstr);
+ }
+ BIO_puts(out, "\n");
+ } else
+ BIO_printf(out, "%*sNo Trusted Uses.\n", indent, "");
+ if (aux->reject) {
+ first = 1;
+ BIO_printf(out, "%*sRejected Uses:\n%*s", indent, "", indent + 2, "");
+ for (i = 0; i < sk_ASN1_OBJECT_num(aux->reject); i++) {
+ if (!first)
+ BIO_puts(out, ", ");
+ else
+ first = 0;
+ OBJ_obj2txt(oidstr, sizeof oidstr,
+ sk_ASN1_OBJECT_value(aux->reject, i), 0);
+ BIO_puts(out, oidstr);
+ }
+ BIO_puts(out, "\n");
+ } else
+ BIO_printf(out, "%*sNo Rejected Uses.\n", indent, "");
+ if (aux->alias)
+ BIO_printf(out, "%*sAlias: %s\n", indent, "", aux->alias->data);
+ if (aux->keyid) {
+ BIO_printf(out, "%*sKey Id: ", indent, "");
+ for (j = 0; j < aux->keyid->length; j++)
+ BIO_printf(out, "%s%02X", j ? ":" : "", aux->keyid->data[j]);
+ BIO_write(out, "\n", 1);
+ }
+ return 1;
}
diff --git a/src/crypto/x509/vpm_int.h b/src/crypto/x509/vpm_int.h
index 9edbd5ad..9c55defc 100644
--- a/src/crypto/x509/vpm_int.h
+++ b/src/crypto/x509/vpm_int.h
@@ -1,6 +1,7 @@
/* vpm_int.h */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2013.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2013.
*/
/* ====================================================================
* Copyright (c) 2013 The OpenSSL Project. All rights reserved.
@@ -10,7 +11,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -58,13 +59,12 @@
/* internal only structure to hold additional X509_VERIFY_PARAM data */
-struct X509_VERIFY_PARAM_ID_st
- {
- STACK_OF(OPENSSL_STRING) *hosts; /* Set of acceptable names */
- unsigned int hostflags; /* Flags to control matching features */
- char *peername; /* Matching hostname in peer certificate */
- char *email; /* If not NULL email address to match */
- size_t emaillen;
- unsigned char *ip; /* If not NULL IP address to match */
- size_t iplen; /* Length of IP address */
- };
+struct X509_VERIFY_PARAM_ID_st {
+ STACK_OF(OPENSSL_STRING) *hosts; /* Set of acceptable names */
+ unsigned int hostflags; /* Flags to control matching features */
+ char *peername; /* Matching hostname in peer certificate */
+ char *email; /* If not NULL email address to match */
+ size_t emaillen;
+ unsigned char *ip; /* If not NULL IP address to match */
+ size_t iplen; /* Length of IP address */
+};
diff --git a/src/crypto/x509/x509.c b/src/crypto/x509/x509.c
index 31f9e1eb..188fd496 100644
--- a/src/crypto/x509/x509.c
+++ b/src/crypto/x509/x509.c
@@ -57,9 +57,14 @@
#include <openssl/x509.h>
#include <openssl/bio.h>
+#include <openssl/err.h>
#include <openssl/mem.h>
+/* |X509_R_UNSUPPORTED_ALGORITHM| is no longer emitted, but continue to define
+ * it to avoid downstream churn. */
+OPENSSL_DECLARE_ERROR_REASON(X509, UNSUPPORTED_ALGORITHM)
+
int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj, int version,
int ptype, void *pval, uint8_t *penc, int penclen) {
uint8_t **ppenc = NULL;
diff --git a/src/crypto/x509/x509_att.c b/src/crypto/x509/x509_att.c
index 14914849..b83d32f9 100644
--- a/src/crypto/x509/x509_att.c
+++ b/src/crypto/x509/x509_att.c
@@ -62,292 +62,314 @@
#include <openssl/stack.h>
#include <openssl/x509.h>
-
int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x)
{
- return sk_X509_ATTRIBUTE_num(x);
+ return sk_X509_ATTRIBUTE_num(x);
}
int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid,
- int lastpos)
+ int lastpos)
{
- const ASN1_OBJECT *obj;
+ const ASN1_OBJECT *obj;
- obj=OBJ_nid2obj(nid);
- if (obj == NULL) return(-2);
- return(X509at_get_attr_by_OBJ(x,obj,lastpos));
+ obj = OBJ_nid2obj(nid);
+ if (obj == NULL)
+ return (-2);
+ return (X509at_get_attr_by_OBJ(x, obj, lastpos));
}
-int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk, const ASN1_OBJECT *obj,
- int lastpos)
+int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk,
+ const ASN1_OBJECT *obj, int lastpos)
{
- int n;
- X509_ATTRIBUTE *ex;
-
- if (sk == NULL) return(-1);
- lastpos++;
- if (lastpos < 0)
- lastpos=0;
- n=sk_X509_ATTRIBUTE_num(sk);
- for ( ; lastpos < n; lastpos++)
- {
- ex=sk_X509_ATTRIBUTE_value(sk,lastpos);
- if (OBJ_cmp(ex->object,obj) == 0)
- return(lastpos);
- }
- return(-1);
+ int n;
+ X509_ATTRIBUTE *ex;
+
+ if (sk == NULL)
+ return (-1);
+ lastpos++;
+ if (lastpos < 0)
+ lastpos = 0;
+ n = sk_X509_ATTRIBUTE_num(sk);
+ for (; lastpos < n; lastpos++) {
+ ex = sk_X509_ATTRIBUTE_value(sk, lastpos);
+ if (OBJ_cmp(ex->object, obj) == 0)
+ return (lastpos);
+ }
+ return (-1);
}
X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc)
{
- if (x == NULL || loc < 0 || sk_X509_ATTRIBUTE_num(x) <= (size_t) loc)
- return NULL;
- else
- return sk_X509_ATTRIBUTE_value(x,loc);
+ if (x == NULL || loc < 0 || sk_X509_ATTRIBUTE_num(x) <= (size_t)loc)
+ return NULL;
+ else
+ return sk_X509_ATTRIBUTE_value(x, loc);
}
X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc)
{
- X509_ATTRIBUTE *ret;
+ X509_ATTRIBUTE *ret;
- if (x == NULL || loc < 0 || sk_X509_ATTRIBUTE_num(x) <= (size_t) loc)
- return(NULL);
- ret=sk_X509_ATTRIBUTE_delete(x,loc);
- return(ret);
+ if (x == NULL || loc < 0 || sk_X509_ATTRIBUTE_num(x) <= (size_t)loc)
+ return (NULL);
+ ret = sk_X509_ATTRIBUTE_delete(x, loc);
+ return (ret);
}
STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x,
- X509_ATTRIBUTE *attr)
+ X509_ATTRIBUTE *attr)
{
- X509_ATTRIBUTE *new_attr=NULL;
- STACK_OF(X509_ATTRIBUTE) *sk=NULL;
-
- if (x == NULL)
- {
- OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER);
- goto err2;
- }
-
- if (*x == NULL)
- {
- if ((sk=sk_X509_ATTRIBUTE_new_null()) == NULL)
- goto err;
- }
- else
- sk= *x;
-
- if ((new_attr=X509_ATTRIBUTE_dup(attr)) == NULL)
- goto err2;
- if (!sk_X509_ATTRIBUTE_push(sk,new_attr))
- goto err;
- if (*x == NULL)
- *x=sk;
- return(sk);
-err:
- 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);
- return(NULL);
+ X509_ATTRIBUTE *new_attr = NULL;
+ STACK_OF(X509_ATTRIBUTE) *sk = NULL;
+
+ if (x == NULL) {
+ OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER);
+ goto err2;
+ }
+
+ if (*x == NULL) {
+ if ((sk = sk_X509_ATTRIBUTE_new_null()) == NULL)
+ goto err;
+ } else
+ sk = *x;
+
+ if ((new_attr = X509_ATTRIBUTE_dup(attr)) == NULL)
+ goto err2;
+ if (!sk_X509_ATTRIBUTE_push(sk, new_attr))
+ goto err;
+ if (*x == NULL)
+ *x = sk;
+ return (sk);
+ err:
+ 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);
+ return (NULL);
}
-STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE) **x,
- const ASN1_OBJECT *obj, int type,
- const unsigned char *bytes, int len)
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE)
+ **x, const ASN1_OBJECT *obj,
+ int type,
+ const unsigned char *bytes,
+ int len)
{
- X509_ATTRIBUTE *attr;
- STACK_OF(X509_ATTRIBUTE) *ret;
- attr = X509_ATTRIBUTE_create_by_OBJ(NULL, obj, type, bytes, len);
- if(!attr) return 0;
- ret = X509at_add1_attr(x, attr);
- X509_ATTRIBUTE_free(attr);
- return ret;
+ X509_ATTRIBUTE *attr;
+ STACK_OF(X509_ATTRIBUTE) *ret;
+ attr = X509_ATTRIBUTE_create_by_OBJ(NULL, obj, type, bytes, len);
+ if (!attr)
+ return 0;
+ ret = X509at_add1_attr(x, attr);
+ X509_ATTRIBUTE_free(attr);
+ return ret;
}
-STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) **x,
- int nid, int type,
- const unsigned char *bytes, int len)
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE)
+ **x, int nid, int type,
+ const unsigned char *bytes,
+ int len)
{
- X509_ATTRIBUTE *attr;
- STACK_OF(X509_ATTRIBUTE) *ret;
- attr = X509_ATTRIBUTE_create_by_NID(NULL, nid, type, bytes, len);
- if(!attr) return 0;
- ret = X509at_add1_attr(x, attr);
- X509_ATTRIBUTE_free(attr);
- return ret;
+ X509_ATTRIBUTE *attr;
+ STACK_OF(X509_ATTRIBUTE) *ret;
+ attr = X509_ATTRIBUTE_create_by_NID(NULL, nid, type, bytes, len);
+ if (!attr)
+ return 0;
+ ret = X509at_add1_attr(x, attr);
+ X509_ATTRIBUTE_free(attr);
+ return ret;
}
-STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) **x,
- const char *attrname, int type,
- const unsigned char *bytes, int len)
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE)
+ **x, const char *attrname,
+ int type,
+ const unsigned char *bytes,
+ int len)
{
- X509_ATTRIBUTE *attr;
- STACK_OF(X509_ATTRIBUTE) *ret;
- attr = X509_ATTRIBUTE_create_by_txt(NULL, attrname, type, bytes, len);
- if(!attr) return 0;
- ret = X509at_add1_attr(x, attr);
- X509_ATTRIBUTE_free(attr);
- return ret;
+ X509_ATTRIBUTE *attr;
+ STACK_OF(X509_ATTRIBUTE) *ret;
+ attr = X509_ATTRIBUTE_create_by_txt(NULL, attrname, type, bytes, len);
+ if (!attr)
+ return 0;
+ ret = X509at_add1_attr(x, attr);
+ X509_ATTRIBUTE_free(attr);
+ return ret;
}
void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x,
- ASN1_OBJECT *obj, int lastpos, int type)
+ ASN1_OBJECT *obj, int lastpos, int type)
{
- int i;
- X509_ATTRIBUTE *at;
- i = X509at_get_attr_by_OBJ(x, obj, lastpos);
- if (i == -1)
- return NULL;
- if ((lastpos <= -2) && (X509at_get_attr_by_OBJ(x, obj, i) != -1))
- return NULL;
- at = X509at_get_attr(x, i);
- if (lastpos <= -3 && (X509_ATTRIBUTE_count(at) != 1))
- return NULL;
- return X509_ATTRIBUTE_get0_data(at, 0, type, NULL);
+ int i;
+ X509_ATTRIBUTE *at;
+ i = X509at_get_attr_by_OBJ(x, obj, lastpos);
+ if (i == -1)
+ return NULL;
+ if ((lastpos <= -2) && (X509at_get_attr_by_OBJ(x, obj, i) != -1))
+ return NULL;
+ at = X509at_get_attr(x, i);
+ if (lastpos <= -3 && (X509_ATTRIBUTE_count(at) != 1))
+ return NULL;
+ return X509_ATTRIBUTE_get0_data(at, 0, type, NULL);
}
X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid,
- int atrtype, const void *data, int len)
+ int atrtype, const void *data,
+ int len)
{
- const ASN1_OBJECT *obj;
-
- obj=OBJ_nid2obj(nid);
- if (obj == NULL)
- {
- OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_NID);
- return(NULL);
- }
- return X509_ATTRIBUTE_create_by_OBJ(attr,obj,atrtype,data,len);
+ const ASN1_OBJECT *obj;
+
+ obj = OBJ_nid2obj(nid);
+ if (obj == NULL) {
+ OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_NID);
+ return (NULL);
+ }
+ return X509_ATTRIBUTE_create_by_OBJ(attr, obj, atrtype, data, len);
}
X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr,
- const ASN1_OBJECT *obj, int atrtype, const void *data, int len)
+ const ASN1_OBJECT *obj,
+ int atrtype, const void *data,
+ int len)
{
- X509_ATTRIBUTE *ret;
-
- if ((attr == NULL) || (*attr == NULL))
- {
- if ((ret=X509_ATTRIBUTE_new()) == NULL)
- {
- OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
- return(NULL);
- }
- }
- else
- ret= *attr;
-
- if (!X509_ATTRIBUTE_set1_object(ret,obj))
- goto err;
- if (!X509_ATTRIBUTE_set1_data(ret,atrtype,data,len))
- goto err;
-
- if ((attr != NULL) && (*attr == NULL)) *attr=ret;
- return(ret);
-err:
- if ((attr == NULL) || (ret != *attr))
- X509_ATTRIBUTE_free(ret);
- return(NULL);
+ X509_ATTRIBUTE *ret;
+
+ if ((attr == NULL) || (*attr == NULL)) {
+ if ((ret = X509_ATTRIBUTE_new()) == NULL) {
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+ } else
+ ret = *attr;
+
+ if (!X509_ATTRIBUTE_set1_object(ret, obj))
+ goto err;
+ if (!X509_ATTRIBUTE_set1_data(ret, atrtype, data, len))
+ goto err;
+
+ if ((attr != NULL) && (*attr == NULL))
+ *attr = ret;
+ return (ret);
+ err:
+ if ((attr == NULL) || (ret != *attr))
+ X509_ATTRIBUTE_free(ret);
+ return (NULL);
}
X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr,
- const char *atrname, int type, const unsigned char *bytes, int len)
- {
- ASN1_OBJECT *obj;
- X509_ATTRIBUTE *nattr;
-
- obj=OBJ_txt2obj(atrname, 0);
- if (obj == NULL)
- {
- OPENSSL_PUT_ERROR(X509, X509_R_INVALID_FIELD_NAME);
- ERR_add_error_data(2, "name=", atrname);
- return(NULL);
- }
- nattr = X509_ATTRIBUTE_create_by_OBJ(attr,obj,type,bytes,len);
- ASN1_OBJECT_free(obj);
- return nattr;
- }
+ const char *atrname, int type,
+ const unsigned char *bytes,
+ int len)
+{
+ ASN1_OBJECT *obj;
+ X509_ATTRIBUTE *nattr;
+
+ obj = OBJ_txt2obj(atrname, 0);
+ if (obj == NULL) {
+ OPENSSL_PUT_ERROR(X509, X509_R_INVALID_FIELD_NAME);
+ ERR_add_error_data(2, "name=", atrname);
+ return (NULL);
+ }
+ nattr = X509_ATTRIBUTE_create_by_OBJ(attr, obj, type, bytes, len);
+ ASN1_OBJECT_free(obj);
+ return nattr;
+}
int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj)
{
- if ((attr == NULL) || (obj == NULL))
- return(0);
- ASN1_OBJECT_free(attr->object);
- attr->object=OBJ_dup(obj);
- return attr->object != NULL;
+ if ((attr == NULL) || (obj == NULL))
+ return (0);
+ ASN1_OBJECT_free(attr->object);
+ attr->object = OBJ_dup(obj);
+ return attr->object != NULL;
}
-int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, const void *data, int len)
+int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype,
+ const void *data, int len)
{
- ASN1_TYPE *ttmp;
- ASN1_STRING *stmp = NULL;
- int atype = 0;
- if (!attr) return 0;
- if(attrtype & MBSTRING_FLAG) {
- stmp = ASN1_STRING_set_by_NID(NULL, data, len, attrtype,
- OBJ_obj2nid(attr->object));
- if(!stmp) {
- OPENSSL_PUT_ERROR(X509, ERR_R_ASN1_LIB);
- return 0;
- }
- atype = stmp->type;
- } else if (len != -1){
- if(!(stmp = ASN1_STRING_type_new(attrtype))) goto err;
- if(!ASN1_STRING_set(stmp, data, len)) goto err;
- atype = attrtype;
- }
- if(!(attr->value.set = sk_ASN1_TYPE_new_null())) goto err;
- attr->single = 0;
- /* This is a bit naughty because the attribute should really have
- * at least one value but some types use and zero length SET and
- * require this.
- */
- if (attrtype == 0)
- return 1;
- if(!(ttmp = ASN1_TYPE_new())) goto err;
- if ((len == -1) && !(attrtype & MBSTRING_FLAG))
- {
- if (!ASN1_TYPE_set1(ttmp, attrtype, data))
- goto err;
- }
- else
- ASN1_TYPE_set(ttmp, atype, stmp);
- if(!sk_ASN1_TYPE_push(attr->value.set, ttmp)) goto err;
- return 1;
- err:
- OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
- return 0;
+ ASN1_TYPE *ttmp;
+ ASN1_STRING *stmp = NULL;
+ int atype = 0;
+ if (!attr)
+ return 0;
+ if (attrtype & MBSTRING_FLAG) {
+ stmp = ASN1_STRING_set_by_NID(NULL, data, len, attrtype,
+ OBJ_obj2nid(attr->object));
+ if (!stmp) {
+ OPENSSL_PUT_ERROR(X509, ERR_R_ASN1_LIB);
+ return 0;
+ }
+ atype = stmp->type;
+ } else if (len != -1) {
+ if (!(stmp = ASN1_STRING_type_new(attrtype)))
+ goto err;
+ if (!ASN1_STRING_set(stmp, data, len))
+ goto err;
+ atype = attrtype;
+ }
+ if (!(attr->value.set = sk_ASN1_TYPE_new_null()))
+ goto err;
+ attr->single = 0;
+ /*
+ * This is a bit naughty because the attribute should really have at
+ * least one value but some types use and zero length SET and require
+ * this.
+ */
+ if (attrtype == 0)
+ return 1;
+ if (!(ttmp = ASN1_TYPE_new()))
+ goto err;
+ if ((len == -1) && !(attrtype & MBSTRING_FLAG)) {
+ if (!ASN1_TYPE_set1(ttmp, attrtype, data))
+ goto err;
+ } else
+ ASN1_TYPE_set(ttmp, atype, stmp);
+ if (!sk_ASN1_TYPE_push(attr->value.set, ttmp))
+ goto err;
+ return 1;
+ err:
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+ return 0;
}
int X509_ATTRIBUTE_count(X509_ATTRIBUTE *attr)
{
- if(!attr->single) return sk_ASN1_TYPE_num(attr->value.set);
- if(attr->value.single) return 1;
- return 0;
+ if (!attr->single)
+ return sk_ASN1_TYPE_num(attr->value.set);
+ if (attr->value.single)
+ return 1;
+ return 0;
}
ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr)
{
- if (attr == NULL) return(NULL);
- return(attr->object);
+ if (attr == NULL)
+ return (NULL);
+ return (attr->object);
}
void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx,
- int atrtype, void *data)
+ int atrtype, void *data)
{
- ASN1_TYPE *ttmp;
- ttmp = X509_ATTRIBUTE_get0_type(attr, idx);
- if(!ttmp) return NULL;
- if(atrtype != ASN1_TYPE_get(ttmp)){
- OPENSSL_PUT_ERROR(X509, X509_R_WRONG_TYPE);
- return NULL;
- }
- return ttmp->value.ptr;
+ ASN1_TYPE *ttmp;
+ ttmp = X509_ATTRIBUTE_get0_type(attr, idx);
+ if (!ttmp)
+ return NULL;
+ if (atrtype != ASN1_TYPE_get(ttmp)) {
+ OPENSSL_PUT_ERROR(X509, X509_R_WRONG_TYPE);
+ return NULL;
+ }
+ return ttmp->value.ptr;
}
ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx)
{
- if (attr == NULL) return(NULL);
- if(idx >= X509_ATTRIBUTE_count(attr)) return NULL;
- if(!attr->single) return sk_ASN1_TYPE_value(attr->value.set, idx);
- else return attr->value.single;
+ if (attr == NULL)
+ return (NULL);
+ if (idx >= X509_ATTRIBUTE_count(attr))
+ return NULL;
+ if (!attr->single)
+ return sk_ASN1_TYPE_value(attr->value.set, idx);
+ else
+ return attr->value.single;
}
diff --git a/src/crypto/x509/x509_cmp.c b/src/crypto/x509/x509_cmp.c
index 0e35f3ea..32862ebc 100644
--- a/src/crypto/x509/x509_cmp.c
+++ b/src/crypto/x509/x509_cmp.c
@@ -67,424 +67,408 @@
#include <openssl/x509.h>
#include <openssl/x509v3.h>
-
int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b)
- {
- int i;
- X509_CINF *ai,*bi;
-
- ai=a->cert_info;
- bi=b->cert_info;
- i=M_ASN1_INTEGER_cmp(ai->serialNumber,bi->serialNumber);
- if (i) return(i);
- return(X509_NAME_cmp(ai->issuer,bi->issuer));
- }
+{
+ int i;
+ X509_CINF *ai, *bi;
+
+ ai = a->cert_info;
+ bi = b->cert_info;
+ i = M_ASN1_INTEGER_cmp(ai->serialNumber, bi->serialNumber);
+ if (i)
+ return (i);
+ return (X509_NAME_cmp(ai->issuer, bi->issuer));
+}
unsigned long X509_issuer_and_serial_hash(X509 *a)
- {
- unsigned long ret=0;
- EVP_MD_CTX ctx;
- unsigned char md[16];
- char *f;
-
- EVP_MD_CTX_init(&ctx);
- f=X509_NAME_oneline(a->cert_info->issuer,NULL,0);
- if (!EVP_DigestInit_ex(&ctx, EVP_md5(), NULL))
- goto err;
- if (!EVP_DigestUpdate(&ctx,(unsigned char *)f,strlen(f)))
- goto err;
- OPENSSL_free(f);
- if(!EVP_DigestUpdate(&ctx,(unsigned char *)a->cert_info->serialNumber->data,
- (unsigned long)a->cert_info->serialNumber->length))
- goto err;
- if (!EVP_DigestFinal_ex(&ctx,&(md[0]),NULL))
- goto err;
- ret=( ((unsigned long)md[0] )|((unsigned long)md[1]<<8L)|
- ((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
- )&0xffffffffL;
- err:
- EVP_MD_CTX_cleanup(&ctx);
- return(ret);
- }
-
+{
+ unsigned long ret = 0;
+ EVP_MD_CTX ctx;
+ unsigned char md[16];
+ char *f;
+
+ EVP_MD_CTX_init(&ctx);
+ f = X509_NAME_oneline(a->cert_info->issuer, NULL, 0);
+ if (!EVP_DigestInit_ex(&ctx, EVP_md5(), NULL))
+ goto err;
+ if (!EVP_DigestUpdate(&ctx, (unsigned char *)f, strlen(f)))
+ goto err;
+ OPENSSL_free(f);
+ if (!EVP_DigestUpdate
+ (&ctx, (unsigned char *)a->cert_info->serialNumber->data,
+ (unsigned long)a->cert_info->serialNumber->length))
+ goto err;
+ if (!EVP_DigestFinal_ex(&ctx, &(md[0]), NULL))
+ goto err;
+ ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) |
+ ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L)
+ ) & 0xffffffffL;
+ err:
+ EVP_MD_CTX_cleanup(&ctx);
+ return (ret);
+}
+
int X509_issuer_name_cmp(const X509 *a, const X509 *b)
- {
- return(X509_NAME_cmp(a->cert_info->issuer,b->cert_info->issuer));
- }
+{
+ return (X509_NAME_cmp(a->cert_info->issuer, b->cert_info->issuer));
+}
int X509_subject_name_cmp(const X509 *a, const X509 *b)
- {
- return(X509_NAME_cmp(a->cert_info->subject,b->cert_info->subject));
- }
+{
+ return (X509_NAME_cmp(a->cert_info->subject, b->cert_info->subject));
+}
int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b)
- {
- return(X509_NAME_cmp(a->crl->issuer,b->crl->issuer));
- }
+{
+ return (X509_NAME_cmp(a->crl->issuer, b->crl->issuer));
+}
int X509_CRL_match(const X509_CRL *a, const X509_CRL *b)
- {
- return memcmp(a->sha1_hash, b->sha1_hash, 20);
- }
+{
+ return memcmp(a->sha1_hash, b->sha1_hash, 20);
+}
X509_NAME *X509_get_issuer_name(X509 *a)
- {
- return(a->cert_info->issuer);
- }
+{
+ return (a->cert_info->issuer);
+}
unsigned long X509_issuer_name_hash(X509 *x)
- {
- return(X509_NAME_hash(x->cert_info->issuer));
- }
+{
+ return (X509_NAME_hash(x->cert_info->issuer));
+}
unsigned long X509_issuer_name_hash_old(X509 *x)
- {
- return(X509_NAME_hash_old(x->cert_info->issuer));
- }
+{
+ return (X509_NAME_hash_old(x->cert_info->issuer));
+}
X509_NAME *X509_get_subject_name(X509 *a)
- {
- return(a->cert_info->subject);
- }
+{
+ return (a->cert_info->subject);
+}
ASN1_INTEGER *X509_get_serialNumber(X509 *a)
- {
- return(a->cert_info->serialNumber);
- }
+{
+ return (a->cert_info->serialNumber);
+}
unsigned long X509_subject_name_hash(X509 *x)
- {
- return(X509_NAME_hash(x->cert_info->subject));
- }
+{
+ return (X509_NAME_hash(x->cert_info->subject));
+}
unsigned long X509_subject_name_hash_old(X509 *x)
- {
- return(X509_NAME_hash_old(x->cert_info->subject));
- }
-
-/* Compare two certificates: they must be identical for
- * this to work. NB: Although "cmp" operations are generally
- * prototyped to take "const" arguments (eg. for use in
- * STACKs), the way X509 handling is - these operations may
- * involve ensuring the hashes are up-to-date and ensuring
- * certain cert information is cached. So this is the point
- * where the "depth-first" constification tree has to halt
- * with an evil cast.
+{
+ return (X509_NAME_hash_old(x->cert_info->subject));
+}
+
+/*
+ * Compare two certificates: they must be identical for this to work. NB:
+ * Although "cmp" operations are generally prototyped to take "const"
+ * arguments (eg. for use in STACKs), the way X509 handling is - these
+ * operations may involve ensuring the hashes are up-to-date and ensuring
+ * certain cert information is cached. So this is the point where the
+ * "depth-first" constification tree has to halt with an evil cast.
*/
int X509_cmp(const X509 *a, const X509 *b)
{
- int rv;
- /* ensure hash is valid */
- X509_check_purpose((X509 *)a, -1, 0);
- X509_check_purpose((X509 *)b, -1, 0);
-
- rv = memcmp(a->sha1_hash, b->sha1_hash, SHA_DIGEST_LENGTH);
- if (rv)
- return rv;
- /* Check for match against stored encoding too */
- if (!a->cert_info->enc.modified && !b->cert_info->enc.modified)
- {
- rv = (int)(a->cert_info->enc.len - b->cert_info->enc.len);
- if (rv)
- return rv;
- return memcmp(a->cert_info->enc.enc, b->cert_info->enc.enc,
- a->cert_info->enc.len);
- }
- return rv;
+ int rv;
+ /* ensure hash is valid */
+ X509_check_purpose((X509 *)a, -1, 0);
+ X509_check_purpose((X509 *)b, -1, 0);
+
+ rv = memcmp(a->sha1_hash, b->sha1_hash, SHA_DIGEST_LENGTH);
+ if (rv)
+ return rv;
+ /* Check for match against stored encoding too */
+ if (!a->cert_info->enc.modified && !b->cert_info->enc.modified) {
+ rv = (int)(a->cert_info->enc.len - b->cert_info->enc.len);
+ if (rv)
+ return rv;
+ return memcmp(a->cert_info->enc.enc, b->cert_info->enc.enc,
+ a->cert_info->enc.len);
+ }
+ return rv;
}
-
int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b)
- {
- int ret;
+{
+ int ret;
- /* Ensure canonical encoding is present and up to date */
+ /* Ensure canonical encoding is present and up to date */
- if (!a->canon_enc || a->modified)
- {
- ret = i2d_X509_NAME((X509_NAME *)a, NULL);
- if (ret < 0)
- return -2;
- }
+ if (!a->canon_enc || a->modified) {
+ ret = i2d_X509_NAME((X509_NAME *)a, NULL);
+ if (ret < 0)
+ return -2;
+ }
- if (!b->canon_enc || b->modified)
- {
- ret = i2d_X509_NAME((X509_NAME *)b, NULL);
- if (ret < 0)
- return -2;
- }
+ if (!b->canon_enc || b->modified) {
+ ret = i2d_X509_NAME((X509_NAME *)b, NULL);
+ if (ret < 0)
+ return -2;
+ }
- ret = a->canon_enclen - b->canon_enclen;
+ ret = a->canon_enclen - b->canon_enclen;
- if (ret)
- return ret;
+ if (ret)
+ return ret;
- return memcmp(a->canon_enc, b->canon_enc, a->canon_enclen);
+ return memcmp(a->canon_enc, b->canon_enc, a->canon_enclen);
- }
+}
unsigned long X509_NAME_hash(X509_NAME *x)
- {
- unsigned long ret=0;
- unsigned char md[SHA_DIGEST_LENGTH];
-
- /* Make sure X509_NAME structure contains valid cached encoding */
- i2d_X509_NAME(x,NULL);
- if (!EVP_Digest(x->canon_enc, x->canon_enclen, md, NULL, EVP_sha1(),
- NULL))
- return 0;
-
- ret=( ((unsigned long)md[0] )|((unsigned long)md[1]<<8L)|
- ((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
- )&0xffffffffL;
- return(ret);
- }
-
+{
+ unsigned long ret = 0;
+ unsigned char md[SHA_DIGEST_LENGTH];
+
+ /* Make sure X509_NAME structure contains valid cached encoding */
+ i2d_X509_NAME(x, NULL);
+ if (!EVP_Digest(x->canon_enc, x->canon_enclen, md, NULL, EVP_sha1(),
+ NULL))
+ return 0;
+
+ ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) |
+ ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L)
+ ) & 0xffffffffL;
+ return (ret);
+}
-/* I now DER encode the name and hash it. Since I cache the DER encoding,
- * this is reasonably efficient. */
+/*
+ * I now DER encode the name and hash it. Since I cache the DER encoding,
+ * this is reasonably efficient.
+ */
unsigned long X509_NAME_hash_old(X509_NAME *x)
- {
- EVP_MD_CTX md_ctx;
- unsigned long ret=0;
- unsigned char md[16];
-
- /* Make sure X509_NAME structure contains valid cached encoding */
- i2d_X509_NAME(x,NULL);
- EVP_MD_CTX_init(&md_ctx);
- /* EVP_MD_CTX_set_flags(&md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); */
- if (EVP_DigestInit_ex(&md_ctx, EVP_md5(), NULL)
- && EVP_DigestUpdate(&md_ctx, x->bytes->data, x->bytes->length)
- && EVP_DigestFinal_ex(&md_ctx,md,NULL))
- ret=(((unsigned long)md[0] )|((unsigned long)md[1]<<8L)|
- ((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
- )&0xffffffffL;
- EVP_MD_CTX_cleanup(&md_ctx);
-
- return(ret);
- }
+{
+ EVP_MD_CTX md_ctx;
+ unsigned long ret = 0;
+ unsigned char md[16];
+
+ /* Make sure X509_NAME structure contains valid cached encoding */
+ i2d_X509_NAME(x, NULL);
+ EVP_MD_CTX_init(&md_ctx);
+ /* EVP_MD_CTX_set_flags(&md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); */
+ if (EVP_DigestInit_ex(&md_ctx, EVP_md5(), NULL)
+ && EVP_DigestUpdate(&md_ctx, x->bytes->data, x->bytes->length)
+ && EVP_DigestFinal_ex(&md_ctx, md, NULL))
+ ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) |
+ ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L)
+ ) & 0xffffffffL;
+ EVP_MD_CTX_cleanup(&md_ctx);
+
+ return (ret);
+}
/* Search a stack of X509 for a match */
X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, X509_NAME *name,
- ASN1_INTEGER *serial)
- {
- size_t i;
- X509_CINF cinf;
- X509 x,*x509=NULL;
-
- if(!sk) return NULL;
-
- x.cert_info= &cinf;
- cinf.serialNumber=serial;
- cinf.issuer=name;
-
- for (i=0; i<sk_X509_num(sk); i++)
- {
- x509=sk_X509_value(sk,i);
- if (X509_issuer_and_serial_cmp(x509,&x) == 0)
- return(x509);
- }
- return(NULL);
- }
+ ASN1_INTEGER *serial)
+{
+ size_t i;
+ X509_CINF cinf;
+ X509 x, *x509 = NULL;
+
+ if (!sk)
+ return NULL;
+
+ x.cert_info = &cinf;
+ cinf.serialNumber = serial;
+ cinf.issuer = name;
+
+ for (i = 0; i < sk_X509_num(sk); i++) {
+ x509 = sk_X509_value(sk, i);
+ if (X509_issuer_and_serial_cmp(x509, &x) == 0)
+ return (x509);
+ }
+ return (NULL);
+}
X509 *X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name)
- {
- X509 *x509;
- size_t i;
-
- for (i=0; i<sk_X509_num(sk); i++)
- {
- x509=sk_X509_value(sk,i);
- if (X509_NAME_cmp(X509_get_subject_name(x509),name) == 0)
- return(x509);
- }
- return(NULL);
- }
+{
+ X509 *x509;
+ size_t i;
+
+ for (i = 0; i < sk_X509_num(sk); i++) {
+ x509 = sk_X509_value(sk, i);
+ if (X509_NAME_cmp(X509_get_subject_name(x509), name) == 0)
+ return (x509);
+ }
+ return (NULL);
+}
EVP_PKEY *X509_get_pubkey(X509 *x)
- {
- if ((x == NULL) || (x->cert_info == NULL))
- return(NULL);
- return(X509_PUBKEY_get(x->cert_info->key));
- }
+{
+ if ((x == NULL) || (x->cert_info == NULL))
+ return (NULL);
+ return (X509_PUBKEY_get(x->cert_info->key));
+}
ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x)
- {
- if(!x) return NULL;
- return x->cert_info->key->public_key;
- }
-
+{
+ if (!x)
+ return NULL;
+ return x->cert_info->key->public_key;
+}
int X509_check_private_key(X509 *x, EVP_PKEY *k)
- {
- EVP_PKEY *xk;
- int ret;
-
- xk=X509_get_pubkey(x);
-
- if (xk)
- ret = EVP_PKEY_cmp(xk, k);
- else
- ret = -2;
-
- switch (ret)
- {
- case 1:
- break;
- case 0:
- OPENSSL_PUT_ERROR(X509, X509_R_KEY_VALUES_MISMATCH);
- break;
- case -1:
- OPENSSL_PUT_ERROR(X509, X509_R_KEY_TYPE_MISMATCH);
- break;
- case -2:
- OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_KEY_TYPE);
- }
- if (xk)
- EVP_PKEY_free(xk);
- if (ret > 0)
- return 1;
- return 0;
- }
-
-/* Check a suite B algorithm is permitted: pass in a public key and
- * the NID of its signature (or 0 if no signature). The pflags is
- * a pointer to a flags field which must contain the suite B verification
- * flags.
- */
+{
+ EVP_PKEY *xk;
+ int ret;
+
+ xk = X509_get_pubkey(x);
+
+ if (xk)
+ ret = EVP_PKEY_cmp(xk, k);
+ else
+ ret = -2;
+
+ switch (ret) {
+ case 1:
+ break;
+ case 0:
+ OPENSSL_PUT_ERROR(X509, X509_R_KEY_VALUES_MISMATCH);
+ break;
+ case -1:
+ OPENSSL_PUT_ERROR(X509, X509_R_KEY_TYPE_MISMATCH);
+ break;
+ case -2:
+ OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_KEY_TYPE);
+ }
+ if (xk)
+ EVP_PKEY_free(xk);
+ if (ret > 0)
+ return 1;
+ return 0;
+}
+/*
+ * Check a suite B algorithm is permitted: pass in a public key and the NID
+ * of its signature (or 0 if no signature). The pflags is a pointer to a
+ * flags field which must contain the suite B verification flags.
+ */
static int check_suite_b(EVP_PKEY *pkey, int sign_nid, unsigned long *pflags)
- {
- const EC_GROUP *grp = NULL;
- int curve_nid;
- if (pkey && pkey->type == EVP_PKEY_EC)
- grp = EC_KEY_get0_group(pkey->pkey.ec);
- if (!grp)
- return X509_V_ERR_SUITE_B_INVALID_ALGORITHM;
- curve_nid = EC_GROUP_get_curve_name(grp);
- /* Check curve is consistent with LOS */
- if (curve_nid == NID_secp384r1) /* P-384 */
- {
- /* Check signature algorithm is consistent with
- * curve.
- */
- if (sign_nid != -1 && sign_nid != NID_ecdsa_with_SHA384)
- return X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM;
- if (!(*pflags & X509_V_FLAG_SUITEB_192_LOS))
- return X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED;
- /* If we encounter P-384 we cannot use P-256 later */
- *pflags &= ~X509_V_FLAG_SUITEB_128_LOS_ONLY;
- }
- else if (curve_nid == NID_X9_62_prime256v1) /* P-256 */
- {
- if (sign_nid != -1 && sign_nid != NID_ecdsa_with_SHA256)
- return X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM;
- if (!(*pflags & X509_V_FLAG_SUITEB_128_LOS_ONLY))
- return X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED;
- }
- else
- return X509_V_ERR_SUITE_B_INVALID_CURVE;
-
- return X509_V_OK;
- }
+{
+ const EC_GROUP *grp = NULL;
+ int curve_nid;
+ if (pkey && pkey->type == EVP_PKEY_EC)
+ grp = EC_KEY_get0_group(pkey->pkey.ec);
+ if (!grp)
+ return X509_V_ERR_SUITE_B_INVALID_ALGORITHM;
+ curve_nid = EC_GROUP_get_curve_name(grp);
+ /* Check curve is consistent with LOS */
+ if (curve_nid == NID_secp384r1) { /* P-384 */
+ /*
+ * Check signature algorithm is consistent with curve.
+ */
+ if (sign_nid != -1 && sign_nid != NID_ecdsa_with_SHA384)
+ return X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM;
+ if (!(*pflags & X509_V_FLAG_SUITEB_192_LOS))
+ return X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED;
+ /* If we encounter P-384 we cannot use P-256 later */
+ *pflags &= ~X509_V_FLAG_SUITEB_128_LOS_ONLY;
+ } else if (curve_nid == NID_X9_62_prime256v1) { /* P-256 */
+ if (sign_nid != -1 && sign_nid != NID_ecdsa_with_SHA256)
+ return X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM;
+ if (!(*pflags & X509_V_FLAG_SUITEB_128_LOS_ONLY))
+ return X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED;
+ } else
+ return X509_V_ERR_SUITE_B_INVALID_CURVE;
+
+ return X509_V_OK;
+}
int X509_chain_check_suiteb(int *perror_depth, X509 *x, STACK_OF(X509) *chain,
- unsigned long flags)
- {
- int rv, sign_nid;
- size_t i;
- EVP_PKEY *pk = NULL;
- unsigned long tflags;
- if (!(flags & X509_V_FLAG_SUITEB_128_LOS))
- return X509_V_OK;
- tflags = flags;
- /* If no EE certificate passed in must be first in chain */
- if (x == NULL)
- {
- x = sk_X509_value(chain, 0);
- i = 1;
- }
- else
- i = 0;
-
- if (X509_get_version(x) != 2)
- {
- rv = X509_V_ERR_SUITE_B_INVALID_VERSION;
- /* Correct error depth */
- i = 0;
- goto end;
- }
-
- pk = X509_get_pubkey(x);
- /* Check EE key only */
- rv = check_suite_b(pk, -1, &tflags);
- if (rv != X509_V_OK)
- {
- /* Correct error depth */
- i = 0;
- goto end;
- }
- for(; i < sk_X509_num(chain); i++)
- {
- sign_nid = X509_get_signature_nid(x);
- x = sk_X509_value(chain, i);
- if (X509_get_version(x) != 2)
- {
- rv = X509_V_ERR_SUITE_B_INVALID_VERSION;
- goto end;
- }
- EVP_PKEY_free(pk);
- pk = X509_get_pubkey(x);
- rv = check_suite_b(pk, sign_nid, &tflags);
- if (rv != X509_V_OK)
- goto end;
- }
-
- /* Final check: root CA signature */
- rv = check_suite_b(pk, X509_get_signature_nid(x), &tflags);
- end:
- if (pk)
- EVP_PKEY_free(pk);
- if (rv != X509_V_OK)
- {
- /* Invalid signature or LOS errors are for previous cert */
- if ((rv == X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM
- || rv == X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED) && i)
- i--;
- /* If we have LOS error and flags changed then we are signing
- * P-384 with P-256. Use more meaninggul error.
- */
- if (rv == X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED && flags != tflags)
- rv = X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256;
- if (perror_depth)
- *perror_depth = i;
- }
- return rv;
- }
+ unsigned long flags)
+{
+ int rv, sign_nid;
+ size_t i;
+ EVP_PKEY *pk = NULL;
+ unsigned long tflags;
+ if (!(flags & X509_V_FLAG_SUITEB_128_LOS))
+ return X509_V_OK;
+ tflags = flags;
+ /* If no EE certificate passed in must be first in chain */
+ if (x == NULL) {
+ x = sk_X509_value(chain, 0);
+ i = 1;
+ } else
+ i = 0;
+
+ if (X509_get_version(x) != 2) {
+ rv = X509_V_ERR_SUITE_B_INVALID_VERSION;
+ /* Correct error depth */
+ i = 0;
+ goto end;
+ }
+
+ pk = X509_get_pubkey(x);
+ /* Check EE key only */
+ rv = check_suite_b(pk, -1, &tflags);
+ if (rv != X509_V_OK) {
+ /* Correct error depth */
+ i = 0;
+ goto end;
+ }
+ for (; i < sk_X509_num(chain); i++) {
+ sign_nid = X509_get_signature_nid(x);
+ x = sk_X509_value(chain, i);
+ if (X509_get_version(x) != 2) {
+ rv = X509_V_ERR_SUITE_B_INVALID_VERSION;
+ goto end;
+ }
+ EVP_PKEY_free(pk);
+ pk = X509_get_pubkey(x);
+ rv = check_suite_b(pk, sign_nid, &tflags);
+ if (rv != X509_V_OK)
+ goto end;
+ }
+
+ /* Final check: root CA signature */
+ rv = check_suite_b(pk, X509_get_signature_nid(x), &tflags);
+ end:
+ if (pk)
+ EVP_PKEY_free(pk);
+ if (rv != X509_V_OK) {
+ /* Invalid signature or LOS errors are for previous cert */
+ if ((rv == X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM
+ || rv == X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED) && i)
+ i--;
+ /*
+ * If we have LOS error and flags changed then we are signing P-384
+ * with P-256. Use more meaninggul error.
+ */
+ if (rv == X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED && flags != tflags)
+ rv = X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256;
+ if (perror_depth)
+ *perror_depth = i;
+ }
+ return rv;
+}
int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags)
- {
- int sign_nid;
- if (!(flags & X509_V_FLAG_SUITEB_128_LOS))
- return X509_V_OK;
- sign_nid = OBJ_obj2nid(crl->crl->sig_alg->algorithm);
- return check_suite_b(pk, sign_nid, &flags);
- }
-
-/* Not strictly speaking an "up_ref" as a STACK doesn't have a reference
- * count but it has the same effect by duping the STACK and upping the ref
- * of each X509 structure.
+{
+ int sign_nid;
+ if (!(flags & X509_V_FLAG_SUITEB_128_LOS))
+ return X509_V_OK;
+ sign_nid = OBJ_obj2nid(crl->crl->sig_alg->algorithm);
+ return check_suite_b(pk, sign_nid, &flags);
+}
+
+/*
+ * Not strictly speaking an "up_ref" as a STACK doesn't have a reference
+ * count but it has the same effect by duping the STACK and upping the ref of
+ * each X509 structure.
*/
STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain)
- {
- STACK_OF(X509) *ret;
- size_t i;
- ret = sk_X509_dup(chain);
- for (i = 0; i < sk_X509_num(ret); i++)
- {
- X509_up_ref(sk_X509_value(ret, i));
- }
- return ret;
- }
+{
+ STACK_OF(X509) *ret;
+ size_t i;
+ ret = sk_X509_dup(chain);
+ for (i = 0; i < sk_X509_num(ret); i++) {
+ X509_up_ref(sk_X509_value(ret, i));
+ }
+ return ret;
+}
diff --git a/src/crypto/x509/x509_d2.c b/src/crypto/x509/x509_d2.c
index 2161d851..69ae54ed 100644
--- a/src/crypto/x509/x509_d2.c
+++ b/src/crypto/x509/x509_d2.c
@@ -58,48 +58,49 @@
#include <openssl/err.h>
#include <openssl/x509.h>
-
#ifndef OPENSSL_NO_STDIO
int X509_STORE_set_default_paths(X509_STORE *ctx)
- {
- X509_LOOKUP *lookup;
+{
+ X509_LOOKUP *lookup;
+
+ lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file());
+ if (lookup == NULL)
+ return (0);
+ X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT);
- lookup=X509_STORE_add_lookup(ctx,X509_LOOKUP_file());
- if (lookup == NULL) return(0);
- X509_LOOKUP_load_file(lookup,NULL,X509_FILETYPE_DEFAULT);
+ lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_hash_dir());
+ if (lookup == NULL)
+ return (0);
+ X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT);
- lookup=X509_STORE_add_lookup(ctx,X509_LOOKUP_hash_dir());
- if (lookup == NULL) return(0);
- X509_LOOKUP_add_dir(lookup,NULL,X509_FILETYPE_DEFAULT);
-
- /* clear any errors */
- ERR_clear_error();
+ /* clear any errors */
+ ERR_clear_error();
- return(1);
- }
+ return (1);
+}
int X509_STORE_load_locations(X509_STORE *ctx, const char *file,
- const char *path)
- {
- X509_LOOKUP *lookup;
+ const char *path)
+{
+ X509_LOOKUP *lookup;
- if (file != NULL)
- {
- lookup=X509_STORE_add_lookup(ctx,X509_LOOKUP_file());
- if (lookup == NULL) return(0);
- if (X509_LOOKUP_load_file(lookup,file,X509_FILETYPE_PEM) != 1)
- return(0);
- }
- if (path != NULL)
- {
- lookup=X509_STORE_add_lookup(ctx,X509_LOOKUP_hash_dir());
- if (lookup == NULL) return(0);
- if (X509_LOOKUP_add_dir(lookup,path,X509_FILETYPE_PEM) != 1)
- return(0);
- }
- if ((path == NULL) && (file == NULL))
- return(0);
- return(1);
- }
+ if (file != NULL) {
+ lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file());
+ if (lookup == NULL)
+ return (0);
+ if (X509_LOOKUP_load_file(lookup, file, X509_FILETYPE_PEM) != 1)
+ return (0);
+ }
+ if (path != NULL) {
+ lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_hash_dir());
+ if (lookup == NULL)
+ return (0);
+ if (X509_LOOKUP_add_dir(lookup, path, X509_FILETYPE_PEM) != 1)
+ return (0);
+ }
+ if ((path == NULL) && (file == NULL))
+ return (0);
+ return (1);
+}
#endif
diff --git a/src/crypto/x509/x509_def.c b/src/crypto/x509/x509_def.c
index dbae289f..2bf2240c 100644
--- a/src/crypto/x509/x509_def.c
+++ b/src/crypto/x509/x509_def.c
@@ -57,32 +57,42 @@
#include <openssl/x509.h>
-
/* TODO(fork): cleanup */
#define OPENSSLDIR "/etc/ssl"
-#define X509_CERT_AREA OPENSSLDIR
-#define X509_CERT_DIR OPENSSLDIR "/certs"
-#define X509_CERT_FILE OPENSSLDIR "/cert.pem"
-#define X509_PRIVATE_DIR OPENSSLDIR "/private"
+#define X509_CERT_AREA OPENSSLDIR
+#define X509_CERT_DIR OPENSSLDIR "/certs"
+#define X509_CERT_FILE OPENSSLDIR "/cert.pem"
+#define X509_PRIVATE_DIR OPENSSLDIR "/private"
#define X509_CERT_DIR_EVP "SSL_CERT_DIR"
#define X509_CERT_FILE_EVP "SSL_CERT_FILE"
const char *X509_get_default_private_dir(void)
- { return(X509_PRIVATE_DIR); }
-
+{
+ return (X509_PRIVATE_DIR);
+}
+
const char *X509_get_default_cert_area(void)
- { return(X509_CERT_AREA); }
+{
+ return (X509_CERT_AREA);
+}
const char *X509_get_default_cert_dir(void)
- { return(X509_CERT_DIR); }
+{
+ return (X509_CERT_DIR);
+}
const char *X509_get_default_cert_file(void)
- { return(X509_CERT_FILE); }
+{
+ return (X509_CERT_FILE);
+}
const char *X509_get_default_cert_dir_env(void)
- { return(X509_CERT_DIR_EVP); }
+{
+ return (X509_CERT_DIR_EVP);
+}
const char *X509_get_default_cert_file_env(void)
- { return(X509_CERT_FILE_EVP); }
-
+{
+ return (X509_CERT_FILE_EVP);
+}
diff --git a/src/crypto/x509/x509_ext.c b/src/crypto/x509/x509_ext.c
index 2f1e0c5a..a329f6fa 100644
--- a/src/crypto/x509/x509_ext.c
+++ b/src/crypto/x509/x509_ext.c
@@ -62,145 +62,145 @@
#include <openssl/x509.h>
#include <openssl/x509v3.h>
-
int X509_CRL_get_ext_count(X509_CRL *x)
- {
- return(X509v3_get_ext_count(x->crl->extensions));
- }
+{
+ return (X509v3_get_ext_count(x->crl->extensions));
+}
int X509_CRL_get_ext_by_NID(X509_CRL *x, int nid, int lastpos)
- {
- return(X509v3_get_ext_by_NID(x->crl->extensions,nid,lastpos));
- }
+{
+ return (X509v3_get_ext_by_NID(x->crl->extensions, nid, lastpos));
+}
int X509_CRL_get_ext_by_OBJ(X509_CRL *x, ASN1_OBJECT *obj, int lastpos)
- {
- return(X509v3_get_ext_by_OBJ(x->crl->extensions,obj,lastpos));
- }
+{
+ return (X509v3_get_ext_by_OBJ(x->crl->extensions, obj, lastpos));
+}
int X509_CRL_get_ext_by_critical(X509_CRL *x, int crit, int lastpos)
- {
- return(X509v3_get_ext_by_critical(x->crl->extensions,crit,lastpos));
- }
+{
+ return (X509v3_get_ext_by_critical(x->crl->extensions, crit, lastpos));
+}
X509_EXTENSION *X509_CRL_get_ext(X509_CRL *x, int loc)
- {
- return(X509v3_get_ext(x->crl->extensions,loc));
- }
+{
+ return (X509v3_get_ext(x->crl->extensions, loc));
+}
X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc)
- {
- return(X509v3_delete_ext(x->crl->extensions,loc));
- }
+{
+ return (X509v3_delete_ext(x->crl->extensions, loc));
+}
void *X509_CRL_get_ext_d2i(X509_CRL *x, int nid, int *crit, int *idx)
{
- return X509V3_get_d2i(x->crl->extensions, nid, crit, idx);
+ return X509V3_get_d2i(x->crl->extensions, nid, crit, idx);
}
int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit,
- unsigned long flags)
+ unsigned long flags)
{
- return X509V3_add1_i2d(&x->crl->extensions, nid, value, crit, flags);
+ return X509V3_add1_i2d(&x->crl->extensions, nid, value, crit, flags);
}
int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc)
- {
- return(X509v3_add_ext(&(x->crl->extensions),ex,loc) != NULL);
- }
+{
+ return (X509v3_add_ext(&(x->crl->extensions), ex, loc) != NULL);
+}
int X509_get_ext_count(X509 *x)
- {
- return(X509v3_get_ext_count(x->cert_info->extensions));
- }
+{
+ return (X509v3_get_ext_count(x->cert_info->extensions));
+}
int X509_get_ext_by_NID(X509 *x, int nid, int lastpos)
- {
- return(X509v3_get_ext_by_NID(x->cert_info->extensions,nid,lastpos));
- }
+{
+ return (X509v3_get_ext_by_NID(x->cert_info->extensions, nid, lastpos));
+}
int X509_get_ext_by_OBJ(X509 *x, ASN1_OBJECT *obj, int lastpos)
- {
- return(X509v3_get_ext_by_OBJ(x->cert_info->extensions,obj,lastpos));
- }
+{
+ return (X509v3_get_ext_by_OBJ(x->cert_info->extensions, obj, lastpos));
+}
int X509_get_ext_by_critical(X509 *x, int crit, int lastpos)
- {
- return(X509v3_get_ext_by_critical(x->cert_info->extensions,crit,lastpos));
- }
+{
+ return (X509v3_get_ext_by_critical
+ (x->cert_info->extensions, crit, lastpos));
+}
X509_EXTENSION *X509_get_ext(X509 *x, int loc)
- {
- return(X509v3_get_ext(x->cert_info->extensions,loc));
- }
+{
+ return (X509v3_get_ext(x->cert_info->extensions, loc));
+}
X509_EXTENSION *X509_delete_ext(X509 *x, int loc)
- {
- return(X509v3_delete_ext(x->cert_info->extensions,loc));
- }
+{
+ return (X509v3_delete_ext(x->cert_info->extensions, loc));
+}
int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc)
- {
- return(X509v3_add_ext(&(x->cert_info->extensions),ex,loc) != NULL);
- }
+{
+ return (X509v3_add_ext(&(x->cert_info->extensions), ex, loc) != NULL);
+}
void *X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx)
{
- return X509V3_get_d2i(x->cert_info->extensions, nid, crit, idx);
+ return X509V3_get_d2i(x->cert_info->extensions, nid, crit, idx);
}
int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit,
- unsigned long flags)
+ unsigned long flags)
{
- return X509V3_add1_i2d(&x->cert_info->extensions, nid, value, crit,
- flags);
+ return X509V3_add1_i2d(&x->cert_info->extensions, nid, value, crit,
+ flags);
}
int X509_REVOKED_get_ext_count(X509_REVOKED *x)
- {
- return(X509v3_get_ext_count(x->extensions));
- }
+{
+ return (X509v3_get_ext_count(x->extensions));
+}
int X509_REVOKED_get_ext_by_NID(X509_REVOKED *x, int nid, int lastpos)
- {
- return(X509v3_get_ext_by_NID(x->extensions,nid,lastpos));
- }
+{
+ return (X509v3_get_ext_by_NID(x->extensions, nid, lastpos));
+}
int X509_REVOKED_get_ext_by_OBJ(X509_REVOKED *x, ASN1_OBJECT *obj,
- int lastpos)
- {
- return(X509v3_get_ext_by_OBJ(x->extensions,obj,lastpos));
- }
+ int lastpos)
+{
+ return (X509v3_get_ext_by_OBJ(x->extensions, obj, lastpos));
+}
int X509_REVOKED_get_ext_by_critical(X509_REVOKED *x, int crit, int lastpos)
- {
- return(X509v3_get_ext_by_critical(x->extensions,crit,lastpos));
- }
+{
+ return (X509v3_get_ext_by_critical(x->extensions, crit, lastpos));
+}
X509_EXTENSION *X509_REVOKED_get_ext(X509_REVOKED *x, int loc)
- {
- return(X509v3_get_ext(x->extensions,loc));
- }
+{
+ return (X509v3_get_ext(x->extensions, loc));
+}
X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc)
- {
- return(X509v3_delete_ext(x->extensions,loc));
- }
+{
+ return (X509v3_delete_ext(x->extensions, loc));
+}
int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc)
- {
- return(X509v3_add_ext(&(x->extensions),ex,loc) != NULL);
- }
+{
+ return (X509v3_add_ext(&(x->extensions), ex, loc) != NULL);
+}
void *X509_REVOKED_get_ext_d2i(X509_REVOKED *x, int nid, int *crit, int *idx)
{
- return X509V3_get_d2i(x->extensions, nid, crit, idx);
+ return X509V3_get_d2i(x->extensions, nid, crit, idx);
}
int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit,
- unsigned long flags)
+ unsigned long flags)
{
- return X509V3_add1_i2d(&x->extensions, nid, value, crit, flags);
+ return X509V3_add1_i2d(&x->extensions, nid, value, crit, flags);
}
IMPLEMENT_ASN1_SET_OF(X509_EXTENSION)
diff --git a/src/crypto/x509/x509_lu.c b/src/crypto/x509/x509_lu.c
index 5751f758..ec3f300b 100644
--- a/src/crypto/x509/x509_lu.c
+++ b/src/crypto/x509/x509_lu.c
@@ -66,673 +66,640 @@
#include "../internal.h"
-
X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method)
- {
- X509_LOOKUP *ret;
-
- ret=(X509_LOOKUP *)OPENSSL_malloc(sizeof(X509_LOOKUP));
- if (ret == NULL) return NULL;
-
- ret->init=0;
- ret->skip=0;
- ret->method=method;
- ret->method_data=NULL;
- ret->store_ctx=NULL;
- if ((method->new_item != NULL) && !method->new_item(ret))
- {
- OPENSSL_free(ret);
- return NULL;
- }
- return ret;
- }
+{
+ X509_LOOKUP *ret;
+
+ ret = (X509_LOOKUP *)OPENSSL_malloc(sizeof(X509_LOOKUP));
+ if (ret == NULL)
+ return NULL;
+
+ ret->init = 0;
+ ret->skip = 0;
+ ret->method = method;
+ ret->method_data = NULL;
+ ret->store_ctx = NULL;
+ if ((method->new_item != NULL) && !method->new_item(ret)) {
+ OPENSSL_free(ret);
+ return NULL;
+ }
+ return ret;
+}
void X509_LOOKUP_free(X509_LOOKUP *ctx)
- {
- if (ctx == NULL) return;
- if ( (ctx->method != NULL) &&
- (ctx->method->free != NULL))
- (*ctx->method->free)(ctx);
- OPENSSL_free(ctx);
- }
+{
+ if (ctx == NULL)
+ return;
+ if ((ctx->method != NULL) && (ctx->method->free != NULL))
+ (*ctx->method->free) (ctx);
+ OPENSSL_free(ctx);
+}
int X509_LOOKUP_init(X509_LOOKUP *ctx)
- {
- if (ctx->method == NULL) return 0;
- if (ctx->method->init != NULL)
- return ctx->method->init(ctx);
- else
- return 1;
- }
+{
+ if (ctx->method == NULL)
+ return 0;
+ if (ctx->method->init != NULL)
+ return ctx->method->init(ctx);
+ else
+ return 1;
+}
int X509_LOOKUP_shutdown(X509_LOOKUP *ctx)
- {
- if (ctx->method == NULL) return 0;
- if (ctx->method->shutdown != NULL)
- return ctx->method->shutdown(ctx);
- else
- return 1;
- }
+{
+ if (ctx->method == NULL)
+ return 0;
+ if (ctx->method->shutdown != NULL)
+ return ctx->method->shutdown(ctx);
+ else
+ return 1;
+}
int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl,
- char **ret)
- {
- if (ctx->method == NULL) return -1;
- if (ctx->method->ctrl != NULL)
- return ctx->method->ctrl(ctx,cmd,argc,argl,ret);
- else
- return 1;
- }
+ char **ret)
+{
+ if (ctx->method == NULL)
+ return -1;
+ if (ctx->method->ctrl != NULL)
+ return ctx->method->ctrl(ctx, cmd, argc, argl, ret);
+ else
+ return 1;
+}
int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name,
- X509_OBJECT *ret)
- {
- if ((ctx->method == NULL) || (ctx->method->get_by_subject == NULL))
- return X509_LU_FAIL;
- if (ctx->skip) return 0;
- return ctx->method->get_by_subject(ctx,type,name,ret);
- }
+ X509_OBJECT *ret)
+{
+ if ((ctx->method == NULL) || (ctx->method->get_by_subject == NULL))
+ return X509_LU_FAIL;
+ if (ctx->skip)
+ return 0;
+ return ctx->method->get_by_subject(ctx, type, name, ret);
+}
int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name,
- ASN1_INTEGER *serial, X509_OBJECT *ret)
- {
- if ((ctx->method == NULL) ||
- (ctx->method->get_by_issuer_serial == NULL))
- return X509_LU_FAIL;
- return ctx->method->get_by_issuer_serial(ctx,type,name,serial,ret);
- }
+ ASN1_INTEGER *serial, X509_OBJECT *ret)
+{
+ if ((ctx->method == NULL) || (ctx->method->get_by_issuer_serial == NULL))
+ return X509_LU_FAIL;
+ return ctx->method->get_by_issuer_serial(ctx, type, name, serial, ret);
+}
int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type,
- unsigned char *bytes, int len, X509_OBJECT *ret)
- {
- if ((ctx->method == NULL) || (ctx->method->get_by_fingerprint == NULL))
- return X509_LU_FAIL;
- return ctx->method->get_by_fingerprint(ctx,type,bytes,len,ret);
- }
+ unsigned char *bytes, int len,
+ X509_OBJECT *ret)
+{
+ if ((ctx->method == NULL) || (ctx->method->get_by_fingerprint == NULL))
+ return X509_LU_FAIL;
+ return ctx->method->get_by_fingerprint(ctx, type, bytes, len, ret);
+}
int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str, int len,
- X509_OBJECT *ret)
- {
- if ((ctx->method == NULL) || (ctx->method->get_by_alias == NULL))
- return X509_LU_FAIL;
- return ctx->method->get_by_alias(ctx,type,str,len,ret);
- }
-
-
+ X509_OBJECT *ret)
+{
+ if ((ctx->method == NULL) || (ctx->method->get_by_alias == NULL))
+ return X509_LU_FAIL;
+ return ctx->method->get_by_alias(ctx, type, str, len, ret);
+}
+
static int x509_object_cmp(const X509_OBJECT **a, const X509_OBJECT **b)
- {
- int ret;
-
- ret=((*a)->type - (*b)->type);
- if (ret) return ret;
- switch ((*a)->type)
- {
- case X509_LU_X509:
- ret=X509_subject_name_cmp((*a)->data.x509,(*b)->data.x509);
- break;
- case X509_LU_CRL:
- ret=X509_CRL_cmp((*a)->data.crl,(*b)->data.crl);
- break;
- default:
- /* abort(); */
- return 0;
- }
- return ret;
- }
+{
+ int ret;
+
+ ret = ((*a)->type - (*b)->type);
+ if (ret)
+ return ret;
+ switch ((*a)->type) {
+ case X509_LU_X509:
+ ret = X509_subject_name_cmp((*a)->data.x509, (*b)->data.x509);
+ break;
+ case X509_LU_CRL:
+ ret = X509_CRL_cmp((*a)->data.crl, (*b)->data.crl);
+ break;
+ default:
+ /* abort(); */
+ return 0;
+ }
+ return ret;
+}
X509_STORE *X509_STORE_new(void)
- {
- X509_STORE *ret;
-
- if ((ret=(X509_STORE *)OPENSSL_malloc(sizeof(X509_STORE))) == NULL)
- return NULL;
- memset(ret, 0, sizeof(*ret));
- 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->get_cert_methods == NULL)
- goto err;
- ret->param = X509_VERIFY_PARAM_new();
- if (ret->param == NULL)
- goto err;
-
- ret->references = 1;
- return ret;
-err:
- if (ret)
- {
- CRYPTO_MUTEX_cleanup(&ret->objs_lock);
- if (ret->param)
- X509_VERIFY_PARAM_free(ret->param);
- if (ret->get_cert_methods)
- sk_X509_LOOKUP_free(ret->get_cert_methods);
- if (ret->objs)
- sk_X509_OBJECT_free(ret->objs);
- OPENSSL_free(ret);
- }
- return NULL;
- }
+{
+ X509_STORE *ret;
+
+ if ((ret = (X509_STORE *)OPENSSL_malloc(sizeof(X509_STORE))) == NULL)
+ return NULL;
+ memset(ret, 0, sizeof(*ret));
+ 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->get_cert_methods == NULL)
+ goto err;
+ ret->param = X509_VERIFY_PARAM_new();
+ if (ret->param == NULL)
+ goto err;
+
+ ret->references = 1;
+ return ret;
+ err:
+ if (ret) {
+ CRYPTO_MUTEX_cleanup(&ret->objs_lock);
+ if (ret->param)
+ X509_VERIFY_PARAM_free(ret->param);
+ if (ret->get_cert_methods)
+ sk_X509_LOOKUP_free(ret->get_cert_methods);
+ if (ret->objs)
+ sk_X509_OBJECT_free(ret->objs);
+ OPENSSL_free(ret);
+ }
+ return NULL;
+}
+
+void X509_STORE_up_ref(X509_STORE *store)
+{
+ CRYPTO_refcount_inc(&store->references);
+}
static void cleanup(X509_OBJECT *a)
- {
- if (a->type == X509_LU_X509)
- {
- X509_free(a->data.x509);
- }
- else if (a->type == X509_LU_CRL)
- {
- X509_CRL_free(a->data.crl);
- }
- else
- {
- /* abort(); */
- }
-
- OPENSSL_free(a);
- }
+{
+ if (a == NULL) {
+ return;
+ }
+ if (a->type == X509_LU_X509) {
+ X509_free(a->data.x509);
+ } else if (a->type == X509_LU_CRL) {
+ X509_CRL_free(a->data.crl);
+ } else {
+ /* abort(); */
+ }
+
+ OPENSSL_free(a);
+}
void X509_STORE_free(X509_STORE *vfy)
- {
- size_t j;
- STACK_OF(X509_LOOKUP) *sk;
- X509_LOOKUP *lu;
-
- if (vfy == NULL)
- return;
-
- if (!CRYPTO_refcount_dec_and_test_zero(&vfy->references)) {
- return;
- }
-
- CRYPTO_MUTEX_cleanup(&vfy->objs_lock);
-
- sk=vfy->get_cert_methods;
- for (j=0; j<sk_X509_LOOKUP_num(sk); j++)
- {
- lu=sk_X509_LOOKUP_value(sk,j);
- X509_LOOKUP_shutdown(lu);
- X509_LOOKUP_free(lu);
- }
- sk_X509_LOOKUP_free(sk);
- sk_X509_OBJECT_pop_free(vfy->objs, cleanup);
-
- if (vfy->param)
- X509_VERIFY_PARAM_free(vfy->param);
- OPENSSL_free(vfy);
- }
+{
+ size_t j;
+ STACK_OF(X509_LOOKUP) *sk;
+ X509_LOOKUP *lu;
+
+ if (vfy == NULL)
+ return;
+
+ if (!CRYPTO_refcount_dec_and_test_zero(&vfy->references)) {
+ return;
+ }
+
+ CRYPTO_MUTEX_cleanup(&vfy->objs_lock);
+
+ sk = vfy->get_cert_methods;
+ for (j = 0; j < sk_X509_LOOKUP_num(sk); j++) {
+ lu = sk_X509_LOOKUP_value(sk, j);
+ X509_LOOKUP_shutdown(lu);
+ X509_LOOKUP_free(lu);
+ }
+ sk_X509_LOOKUP_free(sk);
+ sk_X509_OBJECT_pop_free(vfy->objs, cleanup);
+
+ if (vfy->param)
+ X509_VERIFY_PARAM_free(vfy->param);
+ OPENSSL_free(vfy);
+}
X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m)
- {
- size_t i;
- STACK_OF(X509_LOOKUP) *sk;
- X509_LOOKUP *lu;
-
- sk=v->get_cert_methods;
- for (i=0; i<sk_X509_LOOKUP_num(sk); i++)
- {
- lu=sk_X509_LOOKUP_value(sk,i);
- if (m == lu->method)
- {
- return lu;
- }
- }
- /* a new one */
- lu=X509_LOOKUP_new(m);
- if (lu == NULL)
- return NULL;
- else
- {
- lu->store_ctx=v;
- if (sk_X509_LOOKUP_push(v->get_cert_methods,lu))
- return lu;
- else
- {
- X509_LOOKUP_free(lu);
- return NULL;
- }
- }
- }
+{
+ size_t i;
+ STACK_OF(X509_LOOKUP) *sk;
+ X509_LOOKUP *lu;
+
+ sk = v->get_cert_methods;
+ for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) {
+ lu = sk_X509_LOOKUP_value(sk, i);
+ if (m == lu->method) {
+ return lu;
+ }
+ }
+ /* a new one */
+ lu = X509_LOOKUP_new(m);
+ if (lu == NULL)
+ return NULL;
+ else {
+ lu->store_ctx = v;
+ if (sk_X509_LOOKUP_push(v->get_cert_methods, lu))
+ return lu;
+ else {
+ X509_LOOKUP_free(lu);
+ return NULL;
+ }
+ }
+}
int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name,
- X509_OBJECT *ret)
- {
- X509_STORE *ctx=vs->ctx;
- X509_LOOKUP *lu;
- X509_OBJECT stmp,*tmp;
- int i,j;
-
- CRYPTO_MUTEX_lock_write(&ctx->objs_lock);
- tmp=X509_OBJECT_retrieve_by_subject(ctx->objs,type,name);
- CRYPTO_MUTEX_unlock(&ctx->objs_lock);
-
- if (tmp == NULL || type == X509_LU_CRL)
- {
- for (i=vs->current_method; i<(int)sk_X509_LOOKUP_num(ctx->get_cert_methods); i++)
- {
- lu=sk_X509_LOOKUP_value(ctx->get_cert_methods,i);
- j=X509_LOOKUP_by_subject(lu,type,name,&stmp);
- if (j < 0)
- {
- vs->current_method=j;
- return j;
- }
- else if (j)
- {
- tmp= &stmp;
- break;
- }
- }
- vs->current_method=0;
- if (tmp == NULL)
- return 0;
- }
-
-/* if (ret->data.ptr != NULL)
- X509_OBJECT_free_contents(ret); */
-
- ret->type=tmp->type;
- ret->data.ptr=tmp->data.ptr;
-
- X509_OBJECT_up_ref_count(ret);
-
- return 1;
- }
+ X509_OBJECT *ret)
+{
+ X509_STORE *ctx = vs->ctx;
+ X509_LOOKUP *lu;
+ X509_OBJECT stmp, *tmp;
+ int i, j;
+
+ CRYPTO_MUTEX_lock_write(&ctx->objs_lock);
+ tmp = X509_OBJECT_retrieve_by_subject(ctx->objs, type, name);
+ CRYPTO_MUTEX_unlock(&ctx->objs_lock);
+
+ if (tmp == NULL || type == X509_LU_CRL) {
+ for (i = vs->current_method;
+ i < (int)sk_X509_LOOKUP_num(ctx->get_cert_methods); i++) {
+ lu = sk_X509_LOOKUP_value(ctx->get_cert_methods, i);
+ j = X509_LOOKUP_by_subject(lu, type, name, &stmp);
+ if (j < 0) {
+ vs->current_method = j;
+ return j;
+ } else if (j) {
+ tmp = &stmp;
+ break;
+ }
+ }
+ vs->current_method = 0;
+ if (tmp == NULL)
+ return 0;
+ }
+
+ /*
+ * if (ret->data.ptr != NULL) X509_OBJECT_free_contents(ret);
+ */
+
+ ret->type = tmp->type;
+ ret->data.ptr = tmp->data.ptr;
+
+ X509_OBJECT_up_ref_count(ret);
+
+ return 1;
+}
int X509_STORE_add_cert(X509_STORE *ctx, X509 *x)
- {
- X509_OBJECT *obj;
- int ret=1;
-
- if (x == NULL) return 0;
- obj=(X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT));
- if (obj == NULL)
- {
- OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
- return 0;
- }
- obj->type=X509_LU_X509;
- obj->data.x509=x;
-
- CRYPTO_MUTEX_lock_write(&ctx->objs_lock);
-
- X509_OBJECT_up_ref_count(obj);
-
- if (X509_OBJECT_retrieve_match(ctx->objs, obj))
- {
- X509_OBJECT_free_contents(obj);
- OPENSSL_free(obj);
- OPENSSL_PUT_ERROR(X509, X509_R_CERT_ALREADY_IN_HASH_TABLE);
- ret=0;
- }
- else sk_X509_OBJECT_push(ctx->objs, obj);
-
- CRYPTO_MUTEX_unlock(&ctx->objs_lock);
-
- return ret;
- }
+{
+ X509_OBJECT *obj;
+ int ret = 1;
+
+ if (x == NULL)
+ return 0;
+ obj = (X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT));
+ if (obj == NULL) {
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ obj->type = X509_LU_X509;
+ obj->data.x509 = x;
+
+ CRYPTO_MUTEX_lock_write(&ctx->objs_lock);
+
+ X509_OBJECT_up_ref_count(obj);
+
+ if (X509_OBJECT_retrieve_match(ctx->objs, obj)) {
+ X509_OBJECT_free_contents(obj);
+ OPENSSL_free(obj);
+ OPENSSL_PUT_ERROR(X509, X509_R_CERT_ALREADY_IN_HASH_TABLE);
+ ret = 0;
+ } else
+ sk_X509_OBJECT_push(ctx->objs, obj);
+
+ CRYPTO_MUTEX_unlock(&ctx->objs_lock);
+
+ return ret;
+}
int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x)
- {
- X509_OBJECT *obj;
- int ret=1;
-
- if (x == NULL) return 0;
- obj=(X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT));
- if (obj == NULL)
- {
- OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
- return 0;
- }
- obj->type=X509_LU_CRL;
- obj->data.crl=x;
-
- CRYPTO_MUTEX_lock_write(&ctx->objs_lock);
-
- X509_OBJECT_up_ref_count(obj);
-
- if (X509_OBJECT_retrieve_match(ctx->objs, obj))
- {
- X509_OBJECT_free_contents(obj);
- OPENSSL_free(obj);
- OPENSSL_PUT_ERROR(X509, X509_R_CERT_ALREADY_IN_HASH_TABLE);
- ret=0;
- }
- else sk_X509_OBJECT_push(ctx->objs, obj);
-
- CRYPTO_MUTEX_unlock(&ctx->objs_lock);
-
- return ret;
- }
+{
+ X509_OBJECT *obj;
+ int ret = 1;
+
+ if (x == NULL)
+ return 0;
+ obj = (X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT));
+ if (obj == NULL) {
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ obj->type = X509_LU_CRL;
+ obj->data.crl = x;
+
+ CRYPTO_MUTEX_lock_write(&ctx->objs_lock);
+
+ X509_OBJECT_up_ref_count(obj);
+
+ if (X509_OBJECT_retrieve_match(ctx->objs, obj)) {
+ X509_OBJECT_free_contents(obj);
+ OPENSSL_free(obj);
+ OPENSSL_PUT_ERROR(X509, X509_R_CERT_ALREADY_IN_HASH_TABLE);
+ ret = 0;
+ } else
+ sk_X509_OBJECT_push(ctx->objs, obj);
+
+ CRYPTO_MUTEX_unlock(&ctx->objs_lock);
+
+ return ret;
+}
void X509_OBJECT_up_ref_count(X509_OBJECT *a)
- {
- switch (a->type)
- {
- case X509_LU_X509:
- X509_up_ref(a->data.x509);
- break;
- case X509_LU_CRL:
- X509_CRL_up_ref(a->data.crl);
- break;
- }
- }
+{
+ switch (a->type) {
+ case X509_LU_X509:
+ X509_up_ref(a->data.x509);
+ break;
+ case X509_LU_CRL:
+ X509_CRL_up_ref(a->data.crl);
+ break;
+ }
+}
void X509_OBJECT_free_contents(X509_OBJECT *a)
- {
- switch (a->type)
- {
- case X509_LU_X509:
- X509_free(a->data.x509);
- break;
- case X509_LU_CRL:
- X509_CRL_free(a->data.crl);
- break;
- }
- }
+{
+ switch (a->type) {
+ case X509_LU_X509:
+ X509_free(a->data.x509);
+ break;
+ case X509_LU_CRL:
+ X509_CRL_free(a->data.crl);
+ break;
+ }
+}
static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type,
- X509_NAME *name, int *pnmatch)
- {
- X509_OBJECT stmp;
- X509 x509_s;
- X509_CINF cinf_s;
- X509_CRL crl_s;
- X509_CRL_INFO crl_info_s;
-
- stmp.type=type;
- switch (type)
- {
- case X509_LU_X509:
- stmp.data.x509= &x509_s;
- x509_s.cert_info= &cinf_s;
- cinf_s.subject=name;
- break;
- case X509_LU_CRL:
- stmp.data.crl= &crl_s;
- crl_s.crl= &crl_info_s;
- crl_info_s.issuer=name;
- break;
- default:
- /* abort(); */
- return -1;
- }
-
- size_t idx;
- if (!sk_X509_OBJECT_find(h, &idx, &stmp))
- return -1;
-
- if (pnmatch != NULL)
- {
- int tidx;
- const X509_OBJECT *tobj, *pstmp;
- *pnmatch = 1;
- pstmp = &stmp;
- for (tidx = idx + 1; tidx < (int)sk_X509_OBJECT_num(h); tidx++)
- {
- tobj = sk_X509_OBJECT_value(h, tidx);
- if (x509_object_cmp(&tobj, &pstmp))
- break;
- (*pnmatch)++;
- }
- }
-
- return idx;
- }
-
+ X509_NAME *name, int *pnmatch)
+{
+ X509_OBJECT stmp;
+ X509 x509_s;
+ X509_CINF cinf_s;
+ X509_CRL crl_s;
+ X509_CRL_INFO crl_info_s;
+
+ stmp.type = type;
+ switch (type) {
+ case X509_LU_X509:
+ stmp.data.x509 = &x509_s;
+ x509_s.cert_info = &cinf_s;
+ cinf_s.subject = name;
+ break;
+ case X509_LU_CRL:
+ stmp.data.crl = &crl_s;
+ crl_s.crl = &crl_info_s;
+ crl_info_s.issuer = name;
+ break;
+ default:
+ /* abort(); */
+ return -1;
+ }
+
+ size_t idx;
+ if (!sk_X509_OBJECT_find(h, &idx, &stmp))
+ return -1;
+
+ if (pnmatch != NULL) {
+ int tidx;
+ const X509_OBJECT *tobj, *pstmp;
+ *pnmatch = 1;
+ pstmp = &stmp;
+ for (tidx = idx + 1; tidx < (int)sk_X509_OBJECT_num(h); tidx++) {
+ tobj = sk_X509_OBJECT_value(h, tidx);
+ if (x509_object_cmp(&tobj, &pstmp))
+ break;
+ (*pnmatch)++;
+ }
+ }
+
+ return idx;
+}
int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type,
- X509_NAME *name)
- {
- return x509_object_idx_cnt(h, type, name, NULL);
- }
-
-X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, int type,
- X509_NAME *name)
- {
- int idx;
- idx = X509_OBJECT_idx_by_subject(h, type, name);
- if (idx==-1) return NULL;
- return sk_X509_OBJECT_value(h, idx);
- }
-
-STACK_OF(X509)* X509_STORE_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm)
- {
- int i, idx, cnt;
- STACK_OF(X509) *sk;
- 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)
- {
- /* Nothing found in cache: do lookup to possibly add new
- * objects to cache
- */
- X509_OBJECT xobj;
- CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock);
- if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, nm, &xobj))
- {
- sk_X509_free(sk);
- return NULL;
- }
- X509_OBJECT_free_contents(&xobj);
- CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock);
- idx = x509_object_idx_cnt(ctx->ctx->objs,X509_LU_X509,nm, &cnt);
- if (idx < 0)
- {
- CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock);
- sk_X509_free(sk);
- return NULL;
- }
- }
- for (i = 0; i < cnt; i++, idx++)
- {
- obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
- x = obj->data.x509;
- if (!sk_X509_push(sk, X509_up_ref(x)))
- {
- CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock);
- X509_free(x);
- sk_X509_pop_free(sk, X509_free);
- return NULL;
- }
- }
- CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock);
- return sk;
-
- }
-
-STACK_OF(X509_CRL)* X509_STORE_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm)
- {
- int i, idx, cnt;
- STACK_OF(X509_CRL) *sk;
- X509_CRL *x;
- X509_OBJECT *obj, xobj;
- sk = sk_X509_CRL_new_null();
- if (sk == NULL)
- return NULL;
-
- /* 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);
- return NULL;
- }
- X509_OBJECT_free_contents(&xobj);
- CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock);
- idx = x509_object_idx_cnt(ctx->ctx->objs,X509_LU_CRL, nm, &cnt);
- if (idx < 0)
- {
- CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock);
- sk_X509_CRL_free(sk);
- return NULL;
- }
-
- for (i = 0; i < cnt; i++, idx++)
- {
- obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
- x = obj->data.crl;
- X509_CRL_up_ref(x);
- if (!sk_X509_CRL_push(sk, x))
- {
- CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock);
- X509_CRL_free(x);
- sk_X509_CRL_pop_free(sk, X509_CRL_free);
- return NULL;
- }
- }
- CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock);
- return sk;
- }
-
-X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x)
- {
- size_t idx, i;
- X509_OBJECT *obj;
-
- if (!sk_X509_OBJECT_find(h, &idx, x)) {
- return NULL;
- }
- if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL))
- return sk_X509_OBJECT_value(h, idx);
- for (i = idx; i < sk_X509_OBJECT_num(h); i++)
- {
- obj = sk_X509_OBJECT_value(h, i);
- if (x509_object_cmp((const X509_OBJECT **)&obj, (const X509_OBJECT **)&x))
- return NULL;
- if (x->type == X509_LU_X509)
- {
- if (!X509_cmp(obj->data.x509, x->data.x509))
- return obj;
- }
- else if (x->type == X509_LU_CRL)
- {
- if (!X509_CRL_match(obj->data.crl, x->data.crl))
- return obj;
- }
- else
- return obj;
- }
- return NULL;
- }
-
-
-/* Try to get issuer certificate from store. Due to limitations
- * of the API this can only retrieve a single certificate matching
- * a given subject name. However it will fill the cache with all
- * matching certificates, so we can examine the cache for all
- * matches.
- *
- * Return values are:
- * 1 lookup successful.
- * 0 certificate not found.
- * -1 some other error.
+ X509_NAME *name)
+{
+ return x509_object_idx_cnt(h, type, name, NULL);
+}
+
+X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h,
+ int type, X509_NAME *name)
+{
+ int idx;
+ idx = X509_OBJECT_idx_by_subject(h, type, name);
+ if (idx == -1)
+ return NULL;
+ return sk_X509_OBJECT_value(h, idx);
+}
+
+STACK_OF (X509) * X509_STORE_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm)
+{
+ int i, idx, cnt;
+ STACK_OF(X509) *sk;
+ 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) {
+ /*
+ * Nothing found in cache: do lookup to possibly add new objects to
+ * cache
+ */
+ X509_OBJECT xobj;
+ CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock);
+ if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, nm, &xobj)) {
+ sk_X509_free(sk);
+ return NULL;
+ }
+ X509_OBJECT_free_contents(&xobj);
+ CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock);
+ idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt);
+ if (idx < 0) {
+ CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock);
+ sk_X509_free(sk);
+ return NULL;
+ }
+ }
+ for (i = 0; i < cnt; i++, idx++) {
+ obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
+ x = obj->data.x509;
+ if (!sk_X509_push(sk, X509_up_ref(x))) {
+ CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock);
+ X509_free(x);
+ sk_X509_pop_free(sk, X509_free);
+ return NULL;
+ }
+ }
+ CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock);
+ return sk;
+
+}
+
+STACK_OF (X509_CRL) * X509_STORE_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm)
+{
+ int i, idx, cnt;
+ STACK_OF(X509_CRL) *sk;
+ X509_CRL *x;
+ X509_OBJECT *obj, xobj;
+ sk = sk_X509_CRL_new_null();
+ if (sk == NULL)
+ return NULL;
+
+ /* 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);
+ return NULL;
+ }
+ X509_OBJECT_free_contents(&xobj);
+ CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock);
+ idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt);
+ if (idx < 0) {
+ CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock);
+ sk_X509_CRL_free(sk);
+ return NULL;
+ }
+
+ for (i = 0; i < cnt; i++, idx++) {
+ obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
+ x = obj->data.crl;
+ X509_CRL_up_ref(x);
+ if (!sk_X509_CRL_push(sk, x)) {
+ CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock);
+ X509_CRL_free(x);
+ sk_X509_CRL_pop_free(sk, X509_CRL_free);
+ return NULL;
+ }
+ }
+ CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock);
+ return sk;
+}
+
+X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h,
+ X509_OBJECT *x)
+{
+ size_t idx, i;
+ X509_OBJECT *obj;
+
+ if (!sk_X509_OBJECT_find(h, &idx, x)) {
+ return NULL;
+ }
+ if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL))
+ return sk_X509_OBJECT_value(h, idx);
+ for (i = idx; i < sk_X509_OBJECT_num(h); i++) {
+ obj = sk_X509_OBJECT_value(h, i);
+ if (x509_object_cmp
+ ((const X509_OBJECT **)&obj, (const X509_OBJECT **)&x))
+ return NULL;
+ if (x->type == X509_LU_X509) {
+ if (!X509_cmp(obj->data.x509, x->data.x509))
+ return obj;
+ } else if (x->type == X509_LU_CRL) {
+ if (!X509_CRL_match(obj->data.crl, x->data.crl))
+ return obj;
+ } else
+ return obj;
+ }
+ return NULL;
+}
+
+/*
+ * Try to get issuer certificate from store. Due to limitations of the API
+ * this can only retrieve a single certificate matching a given subject name.
+ * However it will fill the cache with all matching certificates, so we can
+ * examine the cache for all matches. Return values are: 1 lookup
+ * successful. 0 certificate not found. -1 some other error.
*/
int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
- {
- X509_NAME *xn;
- X509_OBJECT obj, *pobj;
- int ok, idx, ret;
- size_t i;
- xn=X509_get_issuer_name(x);
- ok=X509_STORE_get_by_subject(ctx,X509_LU_X509,xn,&obj);
- if (ok != X509_LU_X509)
- {
- if (ok == X509_LU_RETRY)
- {
- X509_OBJECT_free_contents(&obj);
- OPENSSL_PUT_ERROR(X509, X509_R_SHOULD_RETRY);
- return -1;
- }
- else if (ok != X509_LU_FAIL)
- {
- X509_OBJECT_free_contents(&obj);
- /* not good :-(, break anyway */
- return -1;
- }
- return 0;
- }
- /* If certificate matches all OK */
- if (ctx->check_issued(ctx, x, obj.data.x509))
- {
- *issuer = obj.data.x509;
- return 1;
- }
- X509_OBJECT_free_contents(&obj);
-
- /* Else find index of first cert accepted by 'check_issued' */
- ret = 0;
- CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock);
- idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn);
- if (idx != -1) /* should be true as we've had at least one match */
- {
- /* Look through all matching certs for suitable issuer */
- for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++)
- {
- pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i);
- /* See if we've run past the matches */
- if (pobj->type != X509_LU_X509)
- break;
- if (X509_NAME_cmp(xn, X509_get_subject_name(pobj->data.x509)))
- break;
- if (ctx->check_issued(ctx, x, pobj->data.x509))
- {
- *issuer = pobj->data.x509;
- X509_OBJECT_up_ref_count(pobj);
- ret = 1;
- break;
- }
- }
- }
- CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock);
- return ret;
- }
+{
+ X509_NAME *xn;
+ X509_OBJECT obj, *pobj;
+ int ok, idx, ret;
+ size_t i;
+ xn = X509_get_issuer_name(x);
+ ok = X509_STORE_get_by_subject(ctx, X509_LU_X509, xn, &obj);
+ if (ok != X509_LU_X509) {
+ if (ok == X509_LU_RETRY) {
+ X509_OBJECT_free_contents(&obj);
+ OPENSSL_PUT_ERROR(X509, X509_R_SHOULD_RETRY);
+ return -1;
+ } else if (ok != X509_LU_FAIL) {
+ X509_OBJECT_free_contents(&obj);
+ /* not good :-(, break anyway */
+ return -1;
+ }
+ return 0;
+ }
+ /* If certificate matches all OK */
+ if (ctx->check_issued(ctx, x, obj.data.x509)) {
+ *issuer = obj.data.x509;
+ return 1;
+ }
+ X509_OBJECT_free_contents(&obj);
+
+ /* Else find index of first cert accepted by 'check_issued' */
+ ret = 0;
+ CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock);
+ idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn);
+ if (idx != -1) { /* should be true as we've had at least one
+ * match */
+ /* Look through all matching certs for suitable issuer */
+ for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++) {
+ pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i);
+ /* See if we've run past the matches */
+ if (pobj->type != X509_LU_X509)
+ break;
+ if (X509_NAME_cmp(xn, X509_get_subject_name(pobj->data.x509)))
+ break;
+ if (ctx->check_issued(ctx, x, pobj->data.x509)) {
+ *issuer = pobj->data.x509;
+ X509_OBJECT_up_ref_count(pobj);
+ ret = 1;
+ break;
+ }
+ }
+ }
+ CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock);
+ return ret;
+}
int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags)
- {
- return X509_VERIFY_PARAM_set_flags(ctx->param, flags);
- }
+{
+ return X509_VERIFY_PARAM_set_flags(ctx->param, flags);
+}
int X509_STORE_set_depth(X509_STORE *ctx, int depth)
- {
- X509_VERIFY_PARAM_set_depth(ctx->param, depth);
- return 1;
- }
+{
+ X509_VERIFY_PARAM_set_depth(ctx->param, depth);
+ return 1;
+}
int X509_STORE_set_purpose(X509_STORE *ctx, int purpose)
- {
- return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose);
- }
+{
+ return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose);
+}
int X509_STORE_set_trust(X509_STORE *ctx, int trust)
- {
- return X509_VERIFY_PARAM_set_trust(ctx->param, trust);
- }
+{
+ return X509_VERIFY_PARAM_set_trust(ctx->param, trust);
+}
int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param)
- {
- return X509_VERIFY_PARAM_set1(ctx->param, param);
- }
+{
+ return X509_VERIFY_PARAM_set1(ctx->param, param);
+}
void X509_STORE_set_verify_cb(X509_STORE *ctx,
- int (*verify_cb)(int, X509_STORE_CTX *))
- {
- ctx->verify_cb = verify_cb;
- }
+ int (*verify_cb) (int, X509_STORE_CTX *))
+{
+ ctx->verify_cb = verify_cb;
+}
void X509_STORE_set_lookup_crls_cb(X509_STORE *ctx,
- STACK_OF(X509_CRL)* (*cb)(X509_STORE_CTX *ctx, X509_NAME *nm))
- {
- ctx->lookup_crls = cb;
- }
+ STACK_OF (X509_CRL) *
+ (*cb) (X509_STORE_CTX *ctx, X509_NAME *nm))
+{
+ ctx->lookup_crls = cb;
+}
X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx)
- {
- return ctx->ctx;
- }
+{
+ return ctx->ctx;
+}
diff --git a/src/crypto/x509/x509_obj.c b/src/crypto/x509/x509_obj.c
index b6f08164..641e308d 100644
--- a/src/crypto/x509/x509_obj.c
+++ b/src/crypto/x509/x509_obj.c
@@ -64,128 +64,117 @@
#include <openssl/obj.h>
#include <openssl/x509.h>
-
char *X509_NAME_oneline(X509_NAME *a, char *buf, int len)
- {
- X509_NAME_ENTRY *ne;
- size_t i;
- int n,lold,l,l1,l2,num,j,type;
- const char *s;
- char *p;
- unsigned char *q;
- BUF_MEM *b=NULL;
- static const char hex[17]="0123456789ABCDEF";
- int gs_doit[4];
- char tmp_buf[80];
-
- if (buf == NULL)
- {
- if ((b=BUF_MEM_new()) == NULL) goto err;
- if (!BUF_MEM_grow(b,200)) goto err;
- b->data[0]='\0';
- len=200;
- }
- if (a == NULL)
- {
- if(b)
- {
- buf=b->data;
- OPENSSL_free(b);
- }
- strncpy(buf,"NO X509_NAME",len);
- buf[len-1]='\0';
- return buf;
- }
+{
+ X509_NAME_ENTRY *ne;
+ size_t i;
+ int n, lold, l, l1, l2, num, j, type;
+ const char *s;
+ char *p;
+ unsigned char *q;
+ BUF_MEM *b = NULL;
+ static const char hex[17] = "0123456789ABCDEF";
+ int gs_doit[4];
+ char tmp_buf[80];
- len--; /* space for '\0' */
- l=0;
- for (i=0; i<sk_X509_NAME_ENTRY_num(a->entries); i++)
- {
- ne=sk_X509_NAME_ENTRY_value(a->entries,i);
- n=OBJ_obj2nid(ne->object);
- if ((n == NID_undef) || ((s=OBJ_nid2sn(n)) == NULL))
- {
- i2t_ASN1_OBJECT(tmp_buf,sizeof(tmp_buf),ne->object);
- s=tmp_buf;
- }
- l1=strlen(s);
+ if (buf == NULL) {
+ if ((b = BUF_MEM_new()) == NULL)
+ goto err;
+ if (!BUF_MEM_grow(b, 200))
+ goto err;
+ b->data[0] = '\0';
+ len = 200;
+ }
+ if (a == NULL) {
+ if (b) {
+ buf = b->data;
+ OPENSSL_free(b);
+ }
+ strncpy(buf, "NO X509_NAME", len);
+ buf[len - 1] = '\0';
+ return buf;
+ }
- type=ne->value->type;
- num=ne->value->length;
- q=ne->value->data;
+ len--; /* space for '\0' */
+ l = 0;
+ for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
+ ne = sk_X509_NAME_ENTRY_value(a->entries, i);
+ n = OBJ_obj2nid(ne->object);
+ if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
+ i2t_ASN1_OBJECT(tmp_buf, sizeof(tmp_buf), ne->object);
+ s = tmp_buf;
+ }
+ l1 = strlen(s);
- if ((type == V_ASN1_GENERALSTRING) && ((num%4) == 0))
- {
- gs_doit[0]=gs_doit[1]=gs_doit[2]=gs_doit[3]=0;
- for (j=0; j<num; j++)
- if (q[j] != 0) gs_doit[j&3]=1;
+ type = ne->value->type;
+ num = ne->value->length;
+ q = ne->value->data;
- if (gs_doit[0]|gs_doit[1]|gs_doit[2])
- gs_doit[0]=gs_doit[1]=gs_doit[2]=gs_doit[3]=1;
- else
- {
- gs_doit[0]=gs_doit[1]=gs_doit[2]=0;
- gs_doit[3]=1;
- }
- }
- else
- gs_doit[0]=gs_doit[1]=gs_doit[2]=gs_doit[3]=1;
+ if ((type == V_ASN1_GENERALSTRING) && ((num % 4) == 0)) {
+ gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 0;
+ for (j = 0; j < num; j++)
+ if (q[j] != 0)
+ gs_doit[j & 3] = 1;
- for (l2=j=0; j<num; j++)
- {
- if (!gs_doit[j&3]) continue;
- l2++;
- if ((q[j] < ' ') || (q[j] > '~')) l2+=3;
- }
+ if (gs_doit[0] | gs_doit[1] | gs_doit[2])
+ gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 1;
+ else {
+ gs_doit[0] = gs_doit[1] = gs_doit[2] = 0;
+ gs_doit[3] = 1;
+ }
+ } else
+ gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 1;
- lold=l;
- l+=1+l1+1+l2;
- if (b != NULL)
- {
- if (!BUF_MEM_grow(b,l+1)) goto err;
- p= &(b->data[lold]);
- }
- else if (l > len)
- {
- break;
- }
- else
- p= &(buf[lold]);
- *(p++)='/';
- memcpy(p,s,(unsigned int)l1); p+=l1;
- *(p++)='=';
+ for (l2 = j = 0; j < num; j++) {
+ if (!gs_doit[j & 3])
+ continue;
+ l2++;
+ if ((q[j] < ' ') || (q[j] > '~'))
+ l2 += 3;
+ }
- q=ne->value->data;
+ lold = l;
+ l += 1 + l1 + 1 + l2;
+ if (b != NULL) {
+ if (!BUF_MEM_grow(b, l + 1))
+ goto err;
+ p = &(b->data[lold]);
+ } else if (l > len) {
+ break;
+ } else
+ p = &(buf[lold]);
+ *(p++) = '/';
+ memcpy(p, s, (unsigned int)l1);
+ p += l1;
+ *(p++) = '=';
- for (j=0; j<num; j++)
- {
- if (!gs_doit[j&3]) continue;
- n=q[j];
- if ((n < ' ') || (n > '~'))
- {
- *(p++)='\\';
- *(p++)='x';
- *(p++)=hex[(n>>4)&0x0f];
- *(p++)=hex[n&0x0f];
- }
- else
- *(p++)=n;
- }
- *p='\0';
- }
- if (b != NULL)
- {
- p=b->data;
- OPENSSL_free(b);
- }
- else
- p=buf;
- if (i == 0)
- *p = '\0';
- return(p);
-err:
- OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
- if (b != NULL) BUF_MEM_free(b);
- return(NULL);
- }
+ q = ne->value->data;
+ for (j = 0; j < num; j++) {
+ if (!gs_doit[j & 3])
+ continue;
+ n = q[j];
+ if ((n < ' ') || (n > '~')) {
+ *(p++) = '\\';
+ *(p++) = 'x';
+ *(p++) = hex[(n >> 4) & 0x0f];
+ *(p++) = hex[n & 0x0f];
+ } else
+ *(p++) = n;
+ }
+ *p = '\0';
+ }
+ if (b != NULL) {
+ p = b->data;
+ OPENSSL_free(b);
+ } else
+ p = buf;
+ if (i == 0)
+ *p = '\0';
+ return (p);
+ err:
+ 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 85979ac0..83951a2e 100644
--- a/src/crypto/x509/x509_r2x.c
+++ b/src/crypto/x509/x509_r2x.c
@@ -63,51 +63,51 @@
#include <openssl/obj.h>
#include <openssl/x509.h>
-
X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey)
- {
- X509 *ret=NULL;
- X509_CINF *xi=NULL;
- X509_NAME *xn;
-
- if ((ret=X509_new()) == NULL)
- {
- OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
- goto err;
- }
+{
+ X509 *ret = NULL;
+ X509_CINF *xi = NULL;
+ X509_NAME *xn;
- /* duplicate the request */
- xi=ret->cert_info;
+ if ((ret = X509_new()) == NULL) {
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
- if (sk_X509_ATTRIBUTE_num(r->req_info->attributes) != 0)
- {
- if ((xi->version=M_ASN1_INTEGER_new()) == NULL) goto err;
- if (!ASN1_INTEGER_set(xi->version,2)) goto err;
-/* xi->extensions=ri->attributes; <- bad, should not ever be done
- ri->attributes=NULL; */
- }
+ /* duplicate the request */
+ xi = ret->cert_info;
- xn=X509_REQ_get_subject_name(r);
- if (X509_set_subject_name(ret,X509_NAME_dup(xn)) == 0)
- goto err;
- if (X509_set_issuer_name(ret,X509_NAME_dup(xn)) == 0)
- goto err;
+ if (sk_X509_ATTRIBUTE_num(r->req_info->attributes) != 0) {
+ if ((xi->version = M_ASN1_INTEGER_new()) == NULL)
+ goto err;
+ if (!ASN1_INTEGER_set(xi->version, 2))
+ goto err;
+ /*
+ * xi->extensions=ri->attributes; <- bad, should not ever be done
+ * ri->attributes=NULL;
+ */
+ }
- if (X509_gmtime_adj(xi->validity->notBefore,0) == NULL)
- goto err;
- if (X509_gmtime_adj(xi->validity->notAfter,(long)60*60*24*days) == NULL)
- goto err;
+ xn = X509_REQ_get_subject_name(r);
+ if (X509_set_subject_name(ret, X509_NAME_dup(xn)) == 0)
+ goto err;
+ if (X509_set_issuer_name(ret, X509_NAME_dup(xn)) == 0)
+ goto err;
- X509_set_pubkey(ret,X509_REQ_get_pubkey(r));
+ if (X509_gmtime_adj(xi->validity->notBefore, 0) == NULL)
+ goto err;
+ if (X509_gmtime_adj(xi->validity->notAfter, (long)60 * 60 * 24 * days) ==
+ NULL)
+ goto err;
- if (!X509_sign(ret,pkey,EVP_md5()))
- goto err;
- if (0)
- {
-err:
- X509_free(ret);
- ret=NULL;
- }
- return(ret);
- }
+ X509_set_pubkey(ret, X509_REQ_get_pubkey(r));
+ if (!X509_sign(ret, pkey, EVP_md5()))
+ goto err;
+ if (0) {
+ err:
+ X509_free(ret);
+ ret = NULL;
+ }
+ return (ret);
+}
diff --git a/src/crypto/x509/x509_req.c b/src/crypto/x509/x509_req.c
index 01c5113e..69bc6f11 100644
--- a/src/crypto/x509/x509_req.c
+++ b/src/crypto/x509/x509_req.c
@@ -66,250 +66,257 @@
#include <openssl/pem.h>
#include <openssl/x509.h>
-
X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md)
- {
- X509_REQ *ret;
- X509_REQ_INFO *ri;
- int i;
- EVP_PKEY *pktmp;
-
- ret=X509_REQ_new();
- if (ret == NULL)
- {
- OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
- goto err;
- }
-
- ri=ret->req_info;
-
- ri->version->length=1;
- ri->version->data=(unsigned char *)OPENSSL_malloc(1);
- if (ri->version->data == NULL) goto err;
- ri->version->data[0]=0; /* version == 0 */
-
- if (!X509_REQ_set_subject_name(ret,X509_get_subject_name(x)))
- goto err;
-
- pktmp = X509_get_pubkey(x);
- if (pktmp == NULL)
- goto err;
- i=X509_REQ_set_pubkey(ret,pktmp);
- EVP_PKEY_free(pktmp);
- if (!i) goto err;
-
- if (pkey != NULL)
- {
- if (!X509_REQ_sign(ret,pkey,md))
- goto err;
- }
- return(ret);
-err:
- X509_REQ_free(ret);
- return(NULL);
- }
+{
+ X509_REQ *ret;
+ X509_REQ_INFO *ri;
+ int i;
+ EVP_PKEY *pktmp;
+
+ ret = X509_REQ_new();
+ if (ret == NULL) {
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ ri = ret->req_info;
+
+ ri->version->length = 1;
+ ri->version->data = (unsigned char *)OPENSSL_malloc(1);
+ if (ri->version->data == NULL)
+ goto err;
+ ri->version->data[0] = 0; /* version == 0 */
+
+ if (!X509_REQ_set_subject_name(ret, X509_get_subject_name(x)))
+ goto err;
+
+ pktmp = X509_get_pubkey(x);
+ if (pktmp == NULL)
+ goto err;
+ i = X509_REQ_set_pubkey(ret, pktmp);
+ EVP_PKEY_free(pktmp);
+ if (!i)
+ goto err;
+
+ if (pkey != NULL) {
+ if (!X509_REQ_sign(ret, pkey, md))
+ goto err;
+ }
+ return (ret);
+ err:
+ X509_REQ_free(ret);
+ return (NULL);
+}
EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req)
- {
- if ((req == NULL) || (req->req_info == NULL))
- return(NULL);
- return(X509_PUBKEY_get(req->req_info->pubkey));
- }
+{
+ if ((req == NULL) || (req->req_info == NULL))
+ return (NULL);
+ return (X509_PUBKEY_get(req->req_info->pubkey));
+}
int X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k)
- {
- EVP_PKEY *xk=NULL;
- int ok=0;
-
- xk=X509_REQ_get_pubkey(x);
- switch (EVP_PKEY_cmp(xk, k))
- {
- case 1:
- ok=1;
- break;
- case 0:
- OPENSSL_PUT_ERROR(X509, X509_R_KEY_VALUES_MISMATCH);
- break;
- case -1:
- OPENSSL_PUT_ERROR(X509, X509_R_KEY_TYPE_MISMATCH);
- break;
- case -2:
- if (k->type == EVP_PKEY_EC)
- {
- OPENSSL_PUT_ERROR(X509, ERR_R_EC_LIB);
- break;
- }
- if (k->type == EVP_PKEY_DH)
- {
- /* No idea */
- OPENSSL_PUT_ERROR(X509, X509_R_CANT_CHECK_DH_KEY);
- break;
- }
- OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_KEY_TYPE);
- }
-
- EVP_PKEY_free(xk);
- return(ok);
- }
-
-/* It seems several organisations had the same idea of including a list of
+{
+ EVP_PKEY *xk = NULL;
+ int ok = 0;
+
+ xk = X509_REQ_get_pubkey(x);
+ switch (EVP_PKEY_cmp(xk, k)) {
+ case 1:
+ ok = 1;
+ break;
+ case 0:
+ OPENSSL_PUT_ERROR(X509, X509_R_KEY_VALUES_MISMATCH);
+ break;
+ case -1:
+ OPENSSL_PUT_ERROR(X509, X509_R_KEY_TYPE_MISMATCH);
+ break;
+ case -2:
+ if (k->type == EVP_PKEY_EC) {
+ OPENSSL_PUT_ERROR(X509, ERR_R_EC_LIB);
+ break;
+ }
+ if (k->type == EVP_PKEY_DH) {
+ /* No idea */
+ OPENSSL_PUT_ERROR(X509, X509_R_CANT_CHECK_DH_KEY);
+ break;
+ }
+ OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_KEY_TYPE);
+ }
+
+ EVP_PKEY_free(xk);
+ return (ok);
+}
+
+/*
+ * It seems several organisations had the same idea of including a list of
* extensions in a certificate request. There are at least two OIDs that are
* used and there may be more: so the list is configurable.
*/
-static const int ext_nid_list[] = { NID_ext_req, NID_ms_ext_req, NID_undef};
+static const int ext_nid_list[] = { NID_ext_req, NID_ms_ext_req, NID_undef };
static const int *ext_nids = ext_nid_list;
int X509_REQ_extension_nid(int req_nid)
{
- int i, nid;
- for(i = 0; ; i++) {
- nid = ext_nids[i];
- if(nid == NID_undef) return 0;
- else if (req_nid == nid) return 1;
- }
+ int i, nid;
+ for (i = 0;; i++) {
+ nid = ext_nids[i];
+ if (nid == NID_undef)
+ return 0;
+ else if (req_nid == nid)
+ return 1;
+ }
}
const int *X509_REQ_get_extension_nids(void)
{
- return ext_nids;
+ return ext_nids;
}
-
+
void X509_REQ_set_extension_nids(const int *nids)
{
- ext_nids = nids;
+ ext_nids = nids;
}
STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req)
- {
- X509_ATTRIBUTE *attr;
- ASN1_TYPE *ext = NULL;
- int idx;
- const int *pnid;
- const unsigned char *p;
-
- if ((req == NULL) || (req->req_info == NULL) || !ext_nids)
- return(NULL);
- for (pnid = ext_nids; *pnid != NID_undef; pnid++)
- {
- idx = X509_REQ_get_attr_by_NID(req, *pnid, -1);
- if (idx == -1)
- continue;
- attr = X509_REQ_get_attr(req, idx);
- if(attr->single) ext = attr->value.single;
- else if(sk_ASN1_TYPE_num(attr->value.set))
- ext = sk_ASN1_TYPE_value(attr->value.set, 0);
- break;
- }
- if(!ext || (ext->type != V_ASN1_SEQUENCE))
- return NULL;
- p = ext->value.sequence->data;
- return (STACK_OF(X509_EXTENSION) *)
- ASN1_item_d2i(NULL, &p, ext->value.sequence->length,
- ASN1_ITEM_rptr(X509_EXTENSIONS));
+{
+ X509_ATTRIBUTE *attr;
+ ASN1_TYPE *ext = NULL;
+ int idx;
+ const int *pnid;
+ const unsigned char *p;
+
+ if ((req == NULL) || (req->req_info == NULL) || !ext_nids)
+ return (NULL);
+ for (pnid = ext_nids; *pnid != NID_undef; pnid++) {
+ idx = X509_REQ_get_attr_by_NID(req, *pnid, -1);
+ if (idx == -1)
+ continue;
+ attr = X509_REQ_get_attr(req, idx);
+ if (attr->single)
+ ext = attr->value.single;
+ else if (sk_ASN1_TYPE_num(attr->value.set))
+ ext = sk_ASN1_TYPE_value(attr->value.set, 0);
+ break;
+ }
+ if (!ext || (ext->type != V_ASN1_SEQUENCE))
+ return NULL;
+ p = ext->value.sequence->data;
+ return (STACK_OF(X509_EXTENSION) *)
+ ASN1_item_d2i(NULL, &p, ext->value.sequence->length,
+ ASN1_ITEM_rptr(X509_EXTENSIONS));
}
-/* Add a STACK_OF extensions to a certificate request: allow alternative OIDs
+/*
+ * Add a STACK_OF extensions to a certificate request: allow alternative OIDs
* in case we want to create a non standard one.
*/
int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts,
- int nid)
+ int nid)
{
- ASN1_TYPE *at = NULL;
- X509_ATTRIBUTE *attr = NULL;
- if(!(at = ASN1_TYPE_new()) ||
- !(at->value.sequence = ASN1_STRING_new())) goto err;
-
- at->type = V_ASN1_SEQUENCE;
- /* Generate encoding of extensions */
- at->value.sequence->length =
- ASN1_item_i2d((ASN1_VALUE *)exts,
- &at->value.sequence->data,
- ASN1_ITEM_rptr(X509_EXTENSIONS));
- if(!(attr = X509_ATTRIBUTE_new())) goto err;
- if(!(attr->value.set = sk_ASN1_TYPE_new_null())) goto err;
- if(!sk_ASN1_TYPE_push(attr->value.set, at)) goto err;
- at = NULL;
- attr->single = 0;
- attr->object = (ASN1_OBJECT*) OBJ_nid2obj(nid);
- if (!req->req_info->attributes)
- {
- if (!(req->req_info->attributes = sk_X509_ATTRIBUTE_new_null()))
- goto err;
- }
- if(!sk_X509_ATTRIBUTE_push(req->req_info->attributes, attr)) goto err;
- return 1;
- err:
- X509_ATTRIBUTE_free(attr);
- ASN1_TYPE_free(at);
- return 0;
+ ASN1_TYPE *at = NULL;
+ X509_ATTRIBUTE *attr = NULL;
+ if (!(at = ASN1_TYPE_new()) || !(at->value.sequence = ASN1_STRING_new()))
+ goto err;
+
+ at->type = V_ASN1_SEQUENCE;
+ /* Generate encoding of extensions */
+ at->value.sequence->length =
+ ASN1_item_i2d((ASN1_VALUE *)exts,
+ &at->value.sequence->data,
+ ASN1_ITEM_rptr(X509_EXTENSIONS));
+ if (!(attr = X509_ATTRIBUTE_new()))
+ goto err;
+ if (!(attr->value.set = sk_ASN1_TYPE_new_null()))
+ goto err;
+ if (!sk_ASN1_TYPE_push(attr->value.set, at))
+ goto err;
+ at = NULL;
+ attr->single = 0;
+ attr->object = (ASN1_OBJECT *)OBJ_nid2obj(nid);
+ if (!req->req_info->attributes) {
+ if (!(req->req_info->attributes = sk_X509_ATTRIBUTE_new_null()))
+ goto err;
+ }
+ if (!sk_X509_ATTRIBUTE_push(req->req_info->attributes, attr))
+ goto err;
+ return 1;
+ err:
+ X509_ATTRIBUTE_free(attr);
+ ASN1_TYPE_free(at);
+ return 0;
}
+
/* This is the normal usage: use the "official" OID */
int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts)
{
- return X509_REQ_add_extensions_nid(req, exts, NID_ext_req);
+ return X509_REQ_add_extensions_nid(req, exts, NID_ext_req);
}
/* Request attribute functions */
int X509_REQ_get_attr_count(const X509_REQ *req)
{
- return X509at_get_attr_count(req->req_info->attributes);
+ return X509at_get_attr_count(req->req_info->attributes);
}
-int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid,
- int lastpos)
+int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos)
{
- return X509at_get_attr_by_NID(req->req_info->attributes, nid, lastpos);
+ return X509at_get_attr_by_NID(req->req_info->attributes, nid, lastpos);
}
int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, ASN1_OBJECT *obj,
- int lastpos)
+ int lastpos)
{
- return X509at_get_attr_by_OBJ(req->req_info->attributes, obj, lastpos);
+ return X509at_get_attr_by_OBJ(req->req_info->attributes, obj, lastpos);
}
X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc)
{
- return X509at_get_attr(req->req_info->attributes, loc);
+ return X509at_get_attr(req->req_info->attributes, loc);
}
X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc)
{
- return X509at_delete_attr(req->req_info->attributes, loc);
+ return X509at_delete_attr(req->req_info->attributes, loc);
}
int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr)
{
- if(X509at_add1_attr(&req->req_info->attributes, attr)) return 1;
- return 0;
+ if (X509at_add1_attr(&req->req_info->attributes, attr))
+ return 1;
+ return 0;
}
int X509_REQ_add1_attr_by_OBJ(X509_REQ *req,
- const ASN1_OBJECT *obj, int type,
- const unsigned char *bytes, int len)
+ const ASN1_OBJECT *obj, int type,
+ const unsigned char *bytes, int len)
{
- if(X509at_add1_attr_by_OBJ(&req->req_info->attributes, obj,
- type, bytes, len)) return 1;
- return 0;
+ if (X509at_add1_attr_by_OBJ(&req->req_info->attributes, obj,
+ type, bytes, len))
+ return 1;
+ return 0;
}
int X509_REQ_add1_attr_by_NID(X509_REQ *req,
- int nid, int type,
- const unsigned char *bytes, int len)
+ int nid, int type,
+ const unsigned char *bytes, int len)
{
- if(X509at_add1_attr_by_NID(&req->req_info->attributes, nid,
- type, bytes, len)) return 1;
- return 0;
+ if (X509at_add1_attr_by_NID(&req->req_info->attributes, nid,
+ type, bytes, len))
+ return 1;
+ return 0;
}
int X509_REQ_add1_attr_by_txt(X509_REQ *req,
- const char *attrname, int type,
- const unsigned char *bytes, int len)
+ const char *attrname, int type,
+ const unsigned char *bytes, int len)
{
- if(X509at_add1_attr_by_txt(&req->req_info->attributes, attrname,
- type, bytes, len)) return 1;
- return 0;
+ if (X509at_add1_attr_by_txt(&req->req_info->attributes, attrname,
+ type, bytes, len))
+ return 1;
+ return 0;
}
diff --git a/src/crypto/x509/x509_set.c b/src/crypto/x509/x509_set.c
index 06658b07..42e9cf0f 100644
--- a/src/crypto/x509/x509_set.c
+++ b/src/crypto/x509/x509_set.c
@@ -60,95 +60,90 @@
#include <openssl/obj.h>
#include <openssl/x509.h>
-
int X509_set_version(X509 *x, long version)
- {
- if (x == NULL) return(0);
- if (version == 0)
- {
- M_ASN1_INTEGER_free(x->cert_info->version);
- x->cert_info->version = NULL;
- return(1);
- }
- if (x->cert_info->version == NULL)
- {
- if ((x->cert_info->version=M_ASN1_INTEGER_new()) == NULL)
- return(0);
- }
- return(ASN1_INTEGER_set(x->cert_info->version,version));
- }
+{
+ if (x == NULL)
+ return (0);
+ if (version == 0) {
+ M_ASN1_INTEGER_free(x->cert_info->version);
+ x->cert_info->version = NULL;
+ return (1);
+ }
+ if (x->cert_info->version == NULL) {
+ if ((x->cert_info->version = M_ASN1_INTEGER_new()) == NULL)
+ return (0);
+ }
+ return (ASN1_INTEGER_set(x->cert_info->version, version));
+}
int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial)
- {
- ASN1_INTEGER *in;
+{
+ ASN1_INTEGER *in;
- if (x == NULL) return(0);
- in=x->cert_info->serialNumber;
- if (in != serial)
- {
- in=M_ASN1_INTEGER_dup(serial);
- if (in != NULL)
- {
- M_ASN1_INTEGER_free(x->cert_info->serialNumber);
- x->cert_info->serialNumber=in;
- }
- }
- return(in != NULL);
- }
+ if (x == NULL)
+ return (0);
+ in = x->cert_info->serialNumber;
+ if (in != serial) {
+ in = M_ASN1_INTEGER_dup(serial);
+ if (in != NULL) {
+ M_ASN1_INTEGER_free(x->cert_info->serialNumber);
+ x->cert_info->serialNumber = in;
+ }
+ }
+ return (in != NULL);
+}
int X509_set_issuer_name(X509 *x, X509_NAME *name)
- {
- if ((x == NULL) || (x->cert_info == NULL)) return(0);
- return(X509_NAME_set(&x->cert_info->issuer,name));
- }
+{
+ if ((x == NULL) || (x->cert_info == NULL))
+ return (0);
+ return (X509_NAME_set(&x->cert_info->issuer, name));
+}
int X509_set_subject_name(X509 *x, X509_NAME *name)
- {
- if ((x == NULL) || (x->cert_info == NULL)) return(0);
- return(X509_NAME_set(&x->cert_info->subject,name));
- }
+{
+ if ((x == NULL) || (x->cert_info == NULL))
+ return (0);
+ return (X509_NAME_set(&x->cert_info->subject, name));
+}
int X509_set_notBefore(X509 *x, const ASN1_TIME *tm)
- {
- ASN1_TIME *in;
+{
+ ASN1_TIME *in;
- if ((x == NULL) || (x->cert_info->validity == NULL)) return(0);
- in=x->cert_info->validity->notBefore;
- if (in != tm)
- {
- in=M_ASN1_TIME_dup(tm);
- if (in != NULL)
- {
- M_ASN1_TIME_free(x->cert_info->validity->notBefore);
- x->cert_info->validity->notBefore=in;
- }
- }
- return(in != NULL);
- }
+ if ((x == NULL) || (x->cert_info->validity == NULL))
+ return (0);
+ in = x->cert_info->validity->notBefore;
+ if (in != tm) {
+ in = M_ASN1_TIME_dup(tm);
+ if (in != NULL) {
+ M_ASN1_TIME_free(x->cert_info->validity->notBefore);
+ x->cert_info->validity->notBefore = in;
+ }
+ }
+ return (in != NULL);
+}
int X509_set_notAfter(X509 *x, const ASN1_TIME *tm)
- {
- ASN1_TIME *in;
+{
+ ASN1_TIME *in;
- if ((x == NULL) || (x->cert_info->validity == NULL)) return(0);
- in=x->cert_info->validity->notAfter;
- if (in != tm)
- {
- in=M_ASN1_TIME_dup(tm);
- if (in != NULL)
- {
- M_ASN1_TIME_free(x->cert_info->validity->notAfter);
- x->cert_info->validity->notAfter=in;
- }
- }
- return(in != NULL);
- }
+ if ((x == NULL) || (x->cert_info->validity == NULL))
+ return (0);
+ in = x->cert_info->validity->notAfter;
+ if (in != tm) {
+ in = M_ASN1_TIME_dup(tm);
+ if (in != NULL) {
+ M_ASN1_TIME_free(x->cert_info->validity->notAfter);
+ x->cert_info->validity->notAfter = in;
+ }
+ }
+ return (in != NULL);
+}
int X509_set_pubkey(X509 *x, EVP_PKEY *pkey)
- {
- if ((x == NULL) || (x->cert_info == NULL)) return(0);
- return(X509_PUBKEY_set(&(x->cert_info->key),pkey));
- }
-
-
-
+{
+ if ((x == NULL) || (x->cert_info == NULL))
+ return (0);
+ return (X509_PUBKEY_set(&(x->cert_info->key), pkey));
+}
diff --git a/src/crypto/x509/x509_test.cc b/src/crypto/x509/x509_test.cc
new file mode 100644
index 00000000..650163a8
--- /dev/null
+++ b/src/crypto/x509/x509_test.cc
@@ -0,0 +1,472 @@
+/* Copyright (c) 2016, 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 <vector>
+
+#include <assert.h>
+#include <string.h>
+
+#include <openssl/crypto.h>
+#include <openssl/digest.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/pem.h>
+#include <openssl/x509.h>
+
+#include "../test/scoped_types.h"
+
+
+static const char kCrossSigningRootPEM[] =
+"-----BEGIN CERTIFICATE-----\n"
+"MIICcTCCAdqgAwIBAgIIagJHiPvE0MowDQYJKoZIhvcNAQELBQAwPDEaMBgGA1UE\n"
+"ChMRQm9yaW5nU1NMIFRFU1RJTkcxHjAcBgNVBAMTFUNyb3NzLXNpZ25pbmcgUm9v\n"
+"dCBDQTAgFw0xNTAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowPDEaMBgGA1UE\n"
+"ChMRQm9yaW5nU1NMIFRFU1RJTkcxHjAcBgNVBAMTFUNyb3NzLXNpZ25pbmcgUm9v\n"
+"dCBDQTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwo3qFvSB9Zmlbpzn9wJp\n"
+"ikI75Rxkatez8VkLqyxbOhPYl2Haz8F5p1gDG96dCI6jcLGgu3AKT9uhEQyyUko5\n"
+"EKYasazSeA9CQrdyhPg0mkTYVETnPM1W/ebid1YtqQbq1CMWlq2aTDoSGAReGFKP\n"
+"RTdXAbuAXzpCfi/d8LqV13UCAwEAAaN6MHgwDgYDVR0PAQH/BAQDAgIEMB0GA1Ud\n"
+"JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAPBgNVHRMBAf8EBTADAQH/MBkGA1Ud\n"
+"DgQSBBBHKHC7V3Z/3oLvEZx0RZRwMBsGA1UdIwQUMBKAEEcocLtXdn/egu8RnHRF\n"
+"lHAwDQYJKoZIhvcNAQELBQADgYEAnglibsy6mGtpIXivtlcz4zIEnHw/lNW+r/eC\n"
+"CY7evZTmOoOuC/x9SS3MF9vawt1HFUummWM6ZgErqVBOXIB4//ykrcCgf5ZbF5Hr\n"
+"+3EFprKhBqYiXdD8hpBkrBoXwn85LPYWNd2TceCrx0YtLIprE2R5MB2RIq8y4Jk3\n"
+"YFXvkME=\n"
+"-----END CERTIFICATE-----\n";
+
+static const char kRootCAPEM[] =
+"-----BEGIN CERTIFICATE-----\n"
+"MIICVTCCAb6gAwIBAgIIAj5CwoHlWuYwDQYJKoZIhvcNAQELBQAwLjEaMBgGA1UE\n"
+"ChMRQm9yaW5nU1NMIFRFU1RJTkcxEDAOBgNVBAMTB1Jvb3QgQ0EwIBcNMTUwMTAx\n"
+"MDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMC4xGjAYBgNVBAoTEUJvcmluZ1NTTCBU\n"
+"RVNUSU5HMRAwDgYDVQQDEwdSb290IENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB\n"
+"iQKBgQDpDn8RDOZa5oaDcPZRBy4CeBH1siSSOO4mYgLHlPE+oXdqwI/VImi2XeJM\n"
+"2uCFETXCknJJjYG0iJdrt/yyRFvZTQZw+QzGj+mz36NqhGxDWb6dstB2m8PX+plZ\n"
+"w7jl81MDvUnWs8yiQ/6twgu5AbhWKZQDJKcNKCEpqa6UW0r5nwIDAQABo3oweDAO\n"
+"BgNVHQ8BAf8EBAMCAgQwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA8G\n"
+"A1UdEwEB/wQFMAMBAf8wGQYDVR0OBBIEEEA31wH7QC+4HH5UBCeMWQEwGwYDVR0j\n"
+"BBQwEoAQQDfXAftAL7gcflQEJ4xZATANBgkqhkiG9w0BAQsFAAOBgQDXylEK77Za\n"
+"kKeY6ZerrScWyZhrjIGtHFu09qVpdJEzrk87k2G7iHHR9CAvSofCgEExKtWNS9dN\n"
+"+9WiZp/U48iHLk7qaYXdEuO07No4BYtXn+lkOykE+FUxmA4wvOF1cTd2tdj3MzX2\n"
+"kfGIBAYhzGZWhY3JbhIfTEfY1PNM1pWChQ==\n"
+"-----END CERTIFICATE-----\n";
+
+static const char kRootCrossSignedPEM[] =
+"-----BEGIN CERTIFICATE-----\n"
+"MIICYzCCAcygAwIBAgIIAj5CwoHlWuYwDQYJKoZIhvcNAQELBQAwPDEaMBgGA1UE\n"
+"ChMRQm9yaW5nU1NMIFRFU1RJTkcxHjAcBgNVBAMTFUNyb3NzLXNpZ25pbmcgUm9v\n"
+"dCBDQTAgFw0xNTAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowLjEaMBgGA1UE\n"
+"ChMRQm9yaW5nU1NMIFRFU1RJTkcxEDAOBgNVBAMTB1Jvb3QgQ0EwgZ8wDQYJKoZI\n"
+"hvcNAQEBBQADgY0AMIGJAoGBAOkOfxEM5lrmhoNw9lEHLgJ4EfWyJJI47iZiAseU\n"
+"8T6hd2rAj9UiaLZd4kza4IURNcKSckmNgbSIl2u3/LJEW9lNBnD5DMaP6bPfo2qE\n"
+"bENZvp2y0Habw9f6mVnDuOXzUwO9SdazzKJD/q3CC7kBuFYplAMkpw0oISmprpRb\n"
+"SvmfAgMBAAGjejB4MA4GA1UdDwEB/wQEAwICBDAdBgNVHSUEFjAUBggrBgEFBQcD\n"
+"AQYIKwYBBQUHAwIwDwYDVR0TAQH/BAUwAwEB/zAZBgNVHQ4EEgQQQDfXAftAL7gc\n"
+"flQEJ4xZATAbBgNVHSMEFDASgBBHKHC7V3Z/3oLvEZx0RZRwMA0GCSqGSIb3DQEB\n"
+"CwUAA4GBAErTxYJ0en9HVRHAAr5OO5wuk5Iq3VMc79TMyQLCXVL8YH8Uk7KEwv+q\n"
+"9MEKZv2eR/Vfm4HlXlUuIqfgUXbwrAYC/YVVX86Wnbpy/jc73NYVCq8FEZeO+0XU\n"
+"90SWAPDdp+iL7aZdimnMtG1qlM1edmz8AKbrhN/R3IbA2CL0nCWV\n"
+"-----END CERTIFICATE-----\n";
+
+static const char kIntermediatePEM[] =
+"-----BEGIN CERTIFICATE-----\n"
+"MIICXjCCAcegAwIBAgIJAKJMH+7rscPcMA0GCSqGSIb3DQEBCwUAMC4xGjAYBgNV\n"
+"BAoTEUJvcmluZ1NTTCBURVNUSU5HMRAwDgYDVQQDEwdSb290IENBMCAXDTE1MDEw\n"
+"MTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjA2MRowGAYDVQQKExFCb3JpbmdTU0wg\n"
+"VEVTVElORzEYMBYGA1UEAxMPSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEB\n"
+"AQUAA4GNADCBiQKBgQC7YtI0l8ocTYJ0gKyXTtPL4iMJCNY4OcxXl48jkncVG1Hl\n"
+"blicgNUa1r9m9YFtVkxvBinb8dXiUpEGhVg4awRPDcatlsBSEBuJkiZGYbRcAmSu\n"
+"CmZYnf6u3aYQ18SU8WqVERPpE4cwVVs+6kwlzRw0+XDoZAczu8ZezVhCUc6NbQID\n"
+"AQABo3oweDAOBgNVHQ8BAf8EBAMCAgQwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsG\n"
+"AQUFBwMCMA8GA1UdEwEB/wQFMAMBAf8wGQYDVR0OBBIEEIwaaKi1dttdV3sfjRSy\n"
+"BqMwGwYDVR0jBBQwEoAQQDfXAftAL7gcflQEJ4xZATANBgkqhkiG9w0BAQsFAAOB\n"
+"gQCvnolNWEHuQS8PFVVyuLR+FKBeUUdrVbSfHSzTqNAqQGp0C9fk5oCzDq6ZgTfY\n"
+"ESXM4cJhb3IAnW0UM0NFsYSKQJ50JZL2L3z5ZLQhHdbs4RmODGoC40BVdnJ4/qgB\n"
+"aGSh09eQRvAVmbVCviDK2ipkWNegdyI19jFfNP5uIkGlYg==\n"
+"-----END CERTIFICATE-----\n";
+
+static const char kIntermediateSelfSignedPEM[] =
+"-----BEGIN CERTIFICATE-----\n"
+"MIICZjCCAc+gAwIBAgIJAKJMH+7rscPcMA0GCSqGSIb3DQEBCwUAMDYxGjAYBgNV\n"
+"BAoTEUJvcmluZ1NTTCBURVNUSU5HMRgwFgYDVQQDEw9JbnRlcm1lZGlhdGUgQ0Ew\n"
+"IBcNMTUwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMDYxGjAYBgNVBAoTEUJv\n"
+"cmluZ1NTTCBURVNUSU5HMRgwFgYDVQQDEw9JbnRlcm1lZGlhdGUgQ0EwgZ8wDQYJ\n"
+"KoZIhvcNAQEBBQADgY0AMIGJAoGBALti0jSXyhxNgnSArJdO08viIwkI1jg5zFeX\n"
+"jyOSdxUbUeVuWJyA1RrWv2b1gW1WTG8GKdvx1eJSkQaFWDhrBE8Nxq2WwFIQG4mS\n"
+"JkZhtFwCZK4KZlid/q7dphDXxJTxapURE+kThzBVWz7qTCXNHDT5cOhkBzO7xl7N\n"
+"WEJRzo1tAgMBAAGjejB4MA4GA1UdDwEB/wQEAwICBDAdBgNVHSUEFjAUBggrBgEF\n"
+"BQcDAQYIKwYBBQUHAwIwDwYDVR0TAQH/BAUwAwEB/zAZBgNVHQ4EEgQQjBpoqLV2\n"
+"211Xex+NFLIGozAbBgNVHSMEFDASgBCMGmiotXbbXVd7H40UsgajMA0GCSqGSIb3\n"
+"DQEBCwUAA4GBALcccSrAQ0/EqQBsx0ZDTUydHXXNP2DrUkpUKmAXIe8McqIVSlkT\n"
+"6H4xz7z8VRKBo9j+drjjtCw2i0CQc8aOLxRb5WJ8eVLnaW2XRlUqAzhF0CrulfVI\n"
+"E4Vs6ZLU+fra1WAuIj6qFiigRja+3YkZArG8tMA9vtlhTX/g7YBZIkqH\n"
+"-----END CERTIFICATE-----\n";
+
+static const char kLeafPEM[] =
+"-----BEGIN CERTIFICATE-----\n"
+"MIICXjCCAcegAwIBAgIIWjO48ufpunYwDQYJKoZIhvcNAQELBQAwNjEaMBgGA1UE\n"
+"ChMRQm9yaW5nU1NMIFRFU1RJTkcxGDAWBgNVBAMTD0ludGVybWVkaWF0ZSBDQTAg\n"
+"Fw0xNTAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowMjEaMBgGA1UEChMRQm9y\n"
+"aW5nU1NMIFRFU1RJTkcxFDASBgNVBAMTC2V4YW1wbGUuY29tMIGfMA0GCSqGSIb3\n"
+"DQEBAQUAA4GNADCBiQKBgQDD0U0ZYgqShJ7oOjsyNKyVXEHqeafmk/bAoPqY/h1c\n"
+"oPw2E8KmeqiUSoTPjG5IXSblOxcqpbAXgnjPzo8DI3GNMhAf8SYNYsoH7gc7Uy7j\n"
+"5x8bUrisGnuTHqkqH6d4/e7ETJ7i3CpR8bvK16DggEvQTudLipz8FBHtYhFakfdh\n"
+"TwIDAQABo3cwdTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEG\n"
+"CCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwGQYDVR0OBBIEEKN5pvbur7mlXjeMEYA0\n"
+"4nUwGwYDVR0jBBQwEoAQjBpoqLV2211Xex+NFLIGozANBgkqhkiG9w0BAQsFAAOB\n"
+"gQBj/p+JChp//LnXWC1k121LM/ii7hFzQzMrt70bny406SGz9jAjaPOX4S3gt38y\n"
+"rhjpPukBlSzgQXFg66y6q5qp1nQTD1Cw6NkKBe9WuBlY3iYfmsf7WT8nhlT1CttU\n"
+"xNCwyMX9mtdXdQicOfNjIGUCD5OLV5PgHFPRKiHHioBAhg==\n"
+"-----END CERTIFICATE-----\n";
+
+static const char kLeafNoKeyUsagePEM[] =
+"-----BEGIN CERTIFICATE-----\n"
+"MIICNTCCAZ6gAwIBAgIJAIFQGaLQ0G2mMA0GCSqGSIb3DQEBCwUAMDYxGjAYBgNV\n"
+"BAoTEUJvcmluZ1NTTCBURVNUSU5HMRgwFgYDVQQDEw9JbnRlcm1lZGlhdGUgQ0Ew\n"
+"IBcNMTUwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMDcxGjAYBgNVBAoTEUJv\n"
+"cmluZ1NTTCBURVNUSU5HMRkwFwYDVQQDExBldmlsLmV4YW1wbGUuY29tMIGfMA0G\n"
+"CSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOKoZe75NPz77EOaMMl4/0s3PyQw++zJvp\n"
+"ejHAxZiTPCJgMbEHLrSzNoHdopg+CLUH5bE4wTXM8w9Inv5P8OAFJt7gJuPUunmk\n"
+"j+NoU3QfzOR6BroePcz1vXX9jyVHRs087M/sLqWRHu9IR+/A+UTcBaWaFiDVUxtJ\n"
+"YOwFMwjNPQIDAQABo0gwRjAMBgNVHRMBAf8EAjAAMBkGA1UdDgQSBBBJfLEUWHq1\n"
+"27rZ1AVx2J5GMBsGA1UdIwQUMBKAEIwaaKi1dttdV3sfjRSyBqMwDQYJKoZIhvcN\n"
+"AQELBQADgYEALVKN2Y3LZJOtu6SxFIYKxbLaXhTGTdIjxipZhmbBRDFjbZjZZOTe\n"
+"6Oo+VDNPYco4rBexK7umYXJyfTqoY0E8dbiImhTcGTEj7OAB3DbBomgU1AYe+t2D\n"
+"uwBqh4Y3Eto+Zn4pMVsxGEfUpjzjZDel7bN1/oU/9KWPpDfywfUmjgk=\n"
+"-----END CERTIFICATE-----\n";
+
+static const char kForgeryPEM[] =
+"-----BEGIN CERTIFICATE-----\n"
+"MIICZzCCAdCgAwIBAgIIdTlMzQoKkeMwDQYJKoZIhvcNAQELBQAwNzEaMBgGA1UE\n"
+"ChMRQm9yaW5nU1NMIFRFU1RJTkcxGTAXBgNVBAMTEGV2aWwuZXhhbXBsZS5jb20w\n"
+"IBcNMTUwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMDoxGjAYBgNVBAoTEUJv\n"
+"cmluZ1NTTCBURVNUSU5HMRwwGgYDVQQDExNmb3JnZXJ5LmV4YW1wbGUuY29tMIGf\n"
+"MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDADTwruBQZGb7Ay6s9HiYv5d1lwtEy\n"
+"xQdA2Sy8Rn8uA20Q4KgqwVY7wzIZ+z5Butrsmwb70gdG1XU+yRaDeE7XVoW6jSpm\n"
+"0sw35/5vJbTcL4THEFbnX0OPZnvpuZDFUkvVtq5kxpDWsVyM24G8EEq7kPih3Sa3\n"
+"OMhXVXF8kso6UQIDAQABo3cwdTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYI\n"
+"KwYBBQUHAwEGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwGQYDVR0OBBIEEEYJ/WHM\n"
+"8p64erPWIg4/liwwGwYDVR0jBBQwEoAQSXyxFFh6tdu62dQFcdieRjANBgkqhkiG\n"
+"9w0BAQsFAAOBgQA+zH7bHPElWRWJvjxDqRexmYLn+D3Aivs8XgXQJsM94W0EzSUf\n"
+"DSLfRgaQwcb2gg2xpDFoG+W0vc6O651uF23WGt5JaFFJJxqjII05IexfCNhuPmp4\n"
+"4UZAXPttuJXpn74IY1tuouaM06B3vXKZR+/ityKmfJvSwxacmFcK+2ziAg==\n"
+"-----END CERTIFICATE-----\n";
+
+// kExamplePSSCert is an example RSA-PSS self-signed certificate, signed with
+// the default hash functions.
+static const char kExamplePSSCert[] =
+"-----BEGIN CERTIFICATE-----\n"
+"MIICYjCCAcagAwIBAgIJAI3qUyT6SIfzMBIGCSqGSIb3DQEBCjAFogMCAWowRTEL\n"
+"MAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVy\n"
+"bmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0xNDEwMDkxOTA5NTVaFw0xNTEwMDkxOTA5\n"
+"NTVaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQK\n"
+"DBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A\n"
+"MIGJAoGBAPi4bIO0vNmoV8CltFl2jFQdeesiUgR+0zfrQf2D+fCmhRU0dXFahKg8\n"
+"0u9aTtPel4rd/7vPCqqGkr64UOTNb4AzMHYTj8p73OxaymPHAyXvqIqDWHYg+hZ3\n"
+"13mSYwFIGth7Z/FSVUlO1m5KXNd6NzYM3t2PROjCpywrta9kS2EHAgMBAAGjUDBO\n"
+"MB0GA1UdDgQWBBTQQfuJQR6nrVrsNF1JEflVgXgfEzAfBgNVHSMEGDAWgBTQQfuJ\n"
+"QR6nrVrsNF1JEflVgXgfEzAMBgNVHRMEBTADAQH/MBIGCSqGSIb3DQEBCjAFogMC\n"
+"AWoDgYEASUy2RZcgNbNQZA0/7F+V1YTLEXwD16bm+iSVnzGwtexmQVEYIZG74K/w\n"
+"xbdZQdTbpNJkp1QPjPfh0zsatw6dmt5QoZ8K8No0DjR9dgf+Wvv5WJvJUIQBoAVN\n"
+"Z0IL+OQFz6+LcTHxD27JJCebrATXZA0wThGTQDm7crL+a+SujBY=\n"
+"-----END CERTIFICATE-----\n";
+
+// kBadPSSCertPEM is a self-signed RSA-PSS certificate with bad parameters.
+static const char kBadPSSCertPEM[] =
+"-----BEGIN CERTIFICATE-----\n"
+"MIIDdjCCAjqgAwIBAgIJANcwZLyfEv7DMD4GCSqGSIb3DQEBCjAxoA0wCwYJYIZI\n"
+"AWUDBAIBoRowGAYJKoZIhvcNAQEIMAsGCWCGSAFlAwQCAaIEAgIA3jAnMSUwIwYD\n"
+"VQQDDBxUZXN0IEludmFsaWQgUFNTIGNlcnRpZmljYXRlMB4XDTE1MTEwNDE2MDIz\n"
+"NVoXDTE1MTIwNDE2MDIzNVowJzElMCMGA1UEAwwcVGVzdCBJbnZhbGlkIFBTUyBj\n"
+"ZXJ0aWZpY2F0ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMTaM7WH\n"
+"qVCAGAIA+zL1KWvvASTrhlq+1ePdO7wsrWX2KiYoTYrJYTnxhLnn0wrHqApt79nL\n"
+"IBG7cfShyZqFHOY/IzlYPMVt+gPo293gw96Fds5JBsjhjkyGnOyr9OUntFqvxDbT\n"
+"IIFU7o9IdxD4edaqjRv+fegVE+B79pDk4s0ujsk6dULtCg9Rst0ucGFo19mr+b7k\n"
+"dbfn8pZ72ZNDJPueVdrUAWw9oll61UcYfk75XdrLk6JlL41GrYHc8KlfXf43gGQq\n"
+"QfrpHkg4Ih2cI6Wt2nhFGAzrlcorzLliQIUJRIhM8h4IgDfpBpaPdVQLqS2pFbXa\n"
+"5eQjqiyJwak2vJ8CAwEAAaNQME4wHQYDVR0OBBYEFCt180N4oGUt5LbzBwQ4Ia+2\n"
+"4V97MB8GA1UdIwQYMBaAFCt180N4oGUt5LbzBwQ4Ia+24V97MAwGA1UdEwQFMAMB\n"
+"Af8wMQYJKoZIhvcNAQEKMCSgDTALBglghkgBZQMEAgGhDTALBgkqhkiG9w0BAQii\n"
+"BAICAN4DggEBAAjBtm90lGxgddjc4Xu/nbXXFHVs2zVcHv/mqOZoQkGB9r/BVgLb\n"
+"xhHrFZ2pHGElbUYPfifdS9ztB73e1d4J+P29o0yBqfd4/wGAc/JA8qgn6AAEO/Xn\n"
+"plhFeTRJQtLZVl75CkHXgUGUd3h+ADvKtcBuW9dSUncaUrgNKR8u/h/2sMG38RWY\n"
+"DzBddC/66YTa3r7KkVUfW7yqRQfELiGKdcm+bjlTEMsvS+EhHup9CzbpoCx2Fx9p\n"
+"NPtFY3yEObQhmL1JyoCRWqBE75GzFPbRaiux5UpEkns+i3trkGssZzsOuVqHNTNZ\n"
+"lC9+9hPHIoc9UMmAQNo1vGIW3NWVoeGbaJ8=\n"
+"-----END CERTIFICATE-----\n";
+
+static const char kRSAKey[] =
+"-----BEGIN RSA PRIVATE KEY-----\n"
+"MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
+"kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
+"KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
+"AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
+"i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
+"WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
+"m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
+"QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
+"aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
+"LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
+"104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
+"tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
+"moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
+"-----END RSA PRIVATE KEY-----\n";
+
+
+// CertFromPEM parses the given, NUL-terminated pem block and returns an
+// |X509*|.
+static ScopedX509 CertFromPEM(const char *pem) {
+ ScopedBIO bio(BIO_new_mem_buf(pem, strlen(pem)));
+ return ScopedX509(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
+}
+
+// PrivateKeyFromPEM parses the given, NUL-terminated pem block and returns an
+// |EVP_PKEY*|.
+static ScopedEVP_PKEY PrivateKeyFromPEM(const char *pem) {
+ ScopedBIO bio(BIO_new_mem_buf(const_cast<char *>(pem), strlen(pem)));
+ return ScopedEVP_PKEY(
+ PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
+}
+
+// CertsToStack converts a vector of |X509*| to an OpenSSL STACK_OF(X509*),
+// bumping the reference counts for each certificate in question.
+static STACK_OF(X509)* CertsToStack(const std::vector<X509*> &certs) {
+ ScopedX509Stack stack(sk_X509_new_null());
+ if (!stack) {
+ return nullptr;
+ }
+ for (auto cert : certs) {
+ if (!sk_X509_push(stack.get(), cert)) {
+ return nullptr;
+ }
+ X509_up_ref(cert);
+ }
+
+ return stack.release();
+}
+
+static bool Verify(X509 *leaf, const std::vector<X509 *> &roots,
+ const std::vector<X509 *> &intermediates,
+ unsigned long flags = 0) {
+ ScopedX509Stack roots_stack(CertsToStack(roots));
+ ScopedX509Stack intermediates_stack(CertsToStack(intermediates));
+ if (!roots_stack ||
+ !intermediates_stack) {
+ return false;
+ }
+
+ ScopedX509_STORE_CTX ctx(X509_STORE_CTX_new());
+ if (!ctx) {
+ return false;
+ }
+ if (!X509_STORE_CTX_init(ctx.get(), nullptr /* no X509_STORE */, leaf,
+ intermediates_stack.get())) {
+ return false;
+ }
+
+ X509_STORE_CTX_trusted_stack(ctx.get(), roots_stack.get());
+
+ X509_VERIFY_PARAM *param = X509_VERIFY_PARAM_new();
+ if (param == nullptr) {
+ return false;
+ }
+ X509_VERIFY_PARAM_set_time(param, 1452807555 /* Jan 14th, 2016 */);
+ X509_VERIFY_PARAM_set_depth(param, 16);
+ if (flags) {
+ X509_VERIFY_PARAM_set_flags(param, flags);
+ }
+ X509_STORE_CTX_set0_param(ctx.get(), param);
+
+ ERR_clear_error();
+ return X509_verify_cert(ctx.get()) == 1;
+}
+
+static bool TestVerify() {
+ ScopedX509 cross_signing_root(CertFromPEM(kCrossSigningRootPEM));
+ ScopedX509 root(CertFromPEM(kRootCAPEM));
+ ScopedX509 root_cross_signed(CertFromPEM(kRootCrossSignedPEM));
+ ScopedX509 intermediate(CertFromPEM(kIntermediatePEM));
+ ScopedX509 intermediate_self_signed(CertFromPEM(kIntermediateSelfSignedPEM));
+ ScopedX509 leaf(CertFromPEM(kLeafPEM));
+ ScopedX509 leaf_no_key_usage(CertFromPEM(kLeafNoKeyUsagePEM));
+ ScopedX509 forgery(CertFromPEM(kForgeryPEM));
+
+ if (!cross_signing_root ||
+ !root ||
+ !root_cross_signed ||
+ !intermediate ||
+ !intermediate_self_signed ||
+ !leaf ||
+ !leaf_no_key_usage ||
+ !forgery) {
+ fprintf(stderr, "Failed to parse certificates\n");
+ return false;
+ }
+
+ std::vector<X509*> empty;
+ if (Verify(leaf.get(), empty, empty)) {
+ fprintf(stderr, "Leaf verified with no roots!\n");
+ return false;
+ }
+
+ if (Verify(leaf.get(), empty, {intermediate.get()})) {
+ fprintf(stderr, "Leaf verified with no roots!\n");
+ return false;
+ }
+
+ if (!Verify(leaf.get(), {root.get()}, {intermediate.get()})) {
+ ERR_print_errors_fp(stderr);
+ fprintf(stderr, "Basic chain didn't verify.\n");
+ return false;
+ }
+
+ if (!Verify(leaf.get(), {cross_signing_root.get()},
+ {intermediate.get(), root_cross_signed.get()})) {
+ ERR_print_errors_fp(stderr);
+ fprintf(stderr, "Cross-signed chain didn't verify.\n");
+ return false;
+ }
+
+ if (!Verify(leaf.get(), {cross_signing_root.get(), root.get()},
+ {intermediate.get(), root_cross_signed.get()})) {
+ ERR_print_errors_fp(stderr);
+ fprintf(stderr, "Cross-signed chain with root didn't verify.\n");
+ return false;
+ }
+
+ /* This is the “altchains” test – we remove the cross-signing CA but include
+ * the cross-sign in the intermediates. */
+ if (!Verify(leaf.get(), {root.get()},
+ {intermediate.get(), root_cross_signed.get()})) {
+ ERR_print_errors_fp(stderr);
+ fprintf(stderr, "Chain with cross-sign didn't backtrack to find root.\n");
+ return false;
+ }
+
+ if (Verify(leaf.get(), {root.get()},
+ {intermediate.get(), root_cross_signed.get()},
+ X509_V_FLAG_NO_ALT_CHAINS)) {
+ fprintf(stderr, "Altchains test still passed when disabled.\n");
+ return false;
+ }
+
+ if (Verify(forgery.get(), {intermediate_self_signed.get()},
+ {leaf_no_key_usage.get()})) {
+ fprintf(stderr, "Basic constraints weren't checked.\n");
+ return false;
+ }
+
+ /* Test that one cannot skip Basic Constraints checking with a contorted set
+ * of roots and intermediates. This is a regression test for CVE-2015-1793. */
+ if (Verify(forgery.get(),
+ {intermediate_self_signed.get(), root_cross_signed.get()},
+ {leaf_no_key_usage.get(), intermediate.get()})) {
+ fprintf(stderr, "Basic constraints weren't checked.\n");
+ return false;
+ }
+
+ return true;
+}
+
+static bool TestPSS() {
+ ScopedX509 cert(CertFromPEM(kExamplePSSCert));
+ if (!cert) {
+ return false;
+ }
+
+ ScopedEVP_PKEY pkey(X509_get_pubkey(cert.get()));
+ if (!pkey) {
+ return false;
+ }
+
+ if (!X509_verify(cert.get(), pkey.get())) {
+ fprintf(stderr, "Could not verify certificate.\n");
+ return false;
+ }
+ return true;
+}
+
+static bool TestBadPSSParameters() {
+ ScopedX509 cert(CertFromPEM(kBadPSSCertPEM));
+ if (!cert) {
+ return false;
+ }
+
+ ScopedEVP_PKEY pkey(X509_get_pubkey(cert.get()));
+ if (!pkey) {
+ return false;
+ }
+
+ if (X509_verify(cert.get(), pkey.get())) {
+ fprintf(stderr, "Unexpectedly verified bad certificate.\n");
+ return false;
+ }
+ ERR_clear_error();
+ return true;
+}
+
+static bool SignatureRoundTrips(EVP_MD_CTX *md_ctx, EVP_PKEY *pkey) {
+ // Make a certificate like signed with |md_ctx|'s settings.'
+ ScopedX509 cert(CertFromPEM(kLeafPEM));
+ if (!cert || !X509_sign_ctx(cert.get(), md_ctx)) {
+ return false;
+ }
+
+ // Ensure that |pkey| may still be used to verify the resulting signature. All
+ // settings in |md_ctx| must have been serialized appropriately.
+ return !!X509_verify(cert.get(), pkey);
+}
+
+static bool TestSignCtx() {
+ ScopedEVP_PKEY pkey(PrivateKeyFromPEM(kRSAKey));
+ if (!pkey) {
+ return false;
+ }
+
+ // Test PKCS#1 v1.5.
+ ScopedEVP_MD_CTX md_ctx;
+ if (!EVP_DigestSignInit(md_ctx.get(), NULL, EVP_sha256(), NULL, pkey.get()) ||
+ !SignatureRoundTrips(md_ctx.get(), pkey.get())) {
+ fprintf(stderr, "RSA PKCS#1 with SHA-256 failed\n");
+ return false;
+ }
+
+ // Test RSA-PSS with custom parameters.
+ md_ctx.Reset();
+ EVP_PKEY_CTX *pkey_ctx;
+ if (!EVP_DigestSignInit(md_ctx.get(), &pkey_ctx, EVP_sha256(), NULL,
+ pkey.get()) ||
+ !EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) ||
+ !EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, EVP_sha512()) ||
+ !SignatureRoundTrips(md_ctx.get(), pkey.get())) {
+ fprintf(stderr, "RSA-PSS failed\n");
+ return false;
+ }
+
+ return true;
+}
+
+int main(int argc, char **argv) {
+ CRYPTO_library_init();
+
+ if (!TestVerify() ||
+ !TestPSS() ||
+ !TestBadPSSParameters() ||
+ !TestSignCtx()) {
+ return 1;
+ }
+
+ printf("PASS\n");
+ return 0;
+}
diff --git a/src/crypto/x509/x509_trs.c b/src/crypto/x509/x509_trs.c
index 820e6052..c7dfcad6 100644
--- a/src/crypto/x509/x509_trs.c
+++ b/src/crypto/x509/x509_trs.c
@@ -1,5 +1,7 @@
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999. */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
*
@@ -8,7 +10,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -58,9 +60,7 @@
#include <openssl/obj.h>
#include <openssl/x509v3.h>
-
-static int tr_cmp(const X509_TRUST **a,
- const X509_TRUST **b);
+static int tr_cmp(const X509_TRUST **a, const X509_TRUST **b);
static void trtable_free(X509_TRUST *p);
static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags);
@@ -68,237 +68,259 @@ static int trust_1oid(X509_TRUST *trust, X509 *x, int flags);
static int trust_compat(X509_TRUST *trust, X509 *x, int flags);
static int obj_trust(int id, X509 *x, int flags);
-static int (*default_trust)(int id, X509 *x, int flags) = obj_trust;
+static int (*default_trust) (int id, X509 *x, int flags) = obj_trust;
-/* WARNING: the following table should be kept in order of trust
- * and without any gaps so we can just subtract the minimum trust
- * value to get an index into the table
+/*
+ * WARNING: the following table should be kept in order of trust and without
+ * any gaps so we can just subtract the minimum trust value to get an index
+ * into the table
*/
static X509_TRUST trstandard[] = {
-{X509_TRUST_COMPAT, 0, trust_compat, (char *) "compatible", 0, NULL},
-{X509_TRUST_SSL_CLIENT, 0, trust_1oidany, (char *) "SSL Client", NID_client_auth, NULL},
-{X509_TRUST_SSL_SERVER, 0, trust_1oidany, (char *) "SSL Server", NID_server_auth, NULL},
-{X509_TRUST_EMAIL, 0, trust_1oidany, (char *) "S/MIME email", NID_email_protect, NULL},
-{X509_TRUST_OBJECT_SIGN, 0, trust_1oidany, (char *) "Object Signer", NID_code_sign, NULL},
-{X509_TRUST_OCSP_SIGN, 0, trust_1oid, (char *) "OCSP responder", NID_OCSP_sign, NULL},
-{X509_TRUST_OCSP_REQUEST, 0, trust_1oid, (char *) "OCSP request", NID_ad_OCSP, NULL},
-{X509_TRUST_TSA, 0, trust_1oidany, (char *) "TSA server", NID_time_stamp, NULL}
+ {X509_TRUST_COMPAT, 0, trust_compat, (char *)"compatible", 0, NULL},
+ {X509_TRUST_SSL_CLIENT, 0, trust_1oidany, (char *)"SSL Client",
+ NID_client_auth, NULL},
+ {X509_TRUST_SSL_SERVER, 0, trust_1oidany, (char *)"SSL Server",
+ NID_server_auth, NULL},
+ {X509_TRUST_EMAIL, 0, trust_1oidany, (char *)"S/MIME email",
+ NID_email_protect, NULL},
+ {X509_TRUST_OBJECT_SIGN, 0, trust_1oidany, (char *)"Object Signer",
+ NID_code_sign, NULL},
+ {X509_TRUST_OCSP_SIGN, 0, trust_1oid, (char *)"OCSP responder",
+ NID_OCSP_sign, NULL},
+ {X509_TRUST_OCSP_REQUEST, 0, trust_1oid, (char *)"OCSP request",
+ NID_ad_OCSP, NULL},
+ {X509_TRUST_TSA, 0, trust_1oidany, (char *)"TSA server", NID_time_stamp,
+ NULL}
};
-#define X509_TRUST_COUNT (sizeof(trstandard)/sizeof(X509_TRUST))
+#define X509_TRUST_COUNT (sizeof(trstandard)/sizeof(X509_TRUST))
static STACK_OF(X509_TRUST) *trtable = NULL;
-static int tr_cmp(const X509_TRUST **a,
- const X509_TRUST **b)
+static int tr_cmp(const X509_TRUST **a, const X509_TRUST **b)
{
- return (*a)->trust - (*b)->trust;
+ return (*a)->trust - (*b)->trust;
}
-int (*X509_TRUST_set_default(int (*trust)(int , X509 *, int)))(int, X509 *, int)
-{
- int (*oldtrust)(int , X509 *, int);
- oldtrust = default_trust;
- default_trust = trust;
- return oldtrust;
+int (*X509_TRUST_set_default(int (*trust) (int, X509 *, int))) (int, X509 *,
+ int) {
+ int (*oldtrust) (int, X509 *, int);
+ oldtrust = default_trust;
+ default_trust = trust;
+ return oldtrust;
}
-
int X509_check_trust(X509 *x, int id, int flags)
{
- X509_TRUST *pt;
- int idx;
- if(id == -1) return 1;
- /* We get this as a default value */
- if (id == 0)
- {
- int rv;
- rv = obj_trust(NID_anyExtendedKeyUsage, x, 0);
- if (rv != X509_TRUST_UNTRUSTED)
- return rv;
- return trust_compat(NULL, x, 0);
- }
- idx = X509_TRUST_get_by_id(id);
- if(idx == -1) return default_trust(id, x, flags);
- pt = X509_TRUST_get0(idx);
- return pt->check_trust(pt, x, flags);
+ X509_TRUST *pt;
+ int idx;
+ if (id == -1)
+ return 1;
+ /* We get this as a default value */
+ if (id == 0) {
+ int rv;
+ rv = obj_trust(NID_anyExtendedKeyUsage, x, 0);
+ if (rv != X509_TRUST_UNTRUSTED)
+ return rv;
+ return trust_compat(NULL, x, 0);
+ }
+ idx = X509_TRUST_get_by_id(id);
+ if (idx == -1)
+ return default_trust(id, x, flags);
+ pt = X509_TRUST_get0(idx);
+ return pt->check_trust(pt, x, flags);
}
int X509_TRUST_get_count(void)
{
- if(!trtable) return X509_TRUST_COUNT;
- return sk_X509_TRUST_num(trtable) + X509_TRUST_COUNT;
+ if (!trtable)
+ return X509_TRUST_COUNT;
+ return sk_X509_TRUST_num(trtable) + X509_TRUST_COUNT;
}
-X509_TRUST * X509_TRUST_get0(int idx)
+X509_TRUST *X509_TRUST_get0(int idx)
{
- if(idx < 0) return NULL;
- if(idx < (int)X509_TRUST_COUNT) return trstandard + idx;
- return sk_X509_TRUST_value(trtable, idx - X509_TRUST_COUNT);
+ if (idx < 0)
+ return NULL;
+ if (idx < (int)X509_TRUST_COUNT)
+ return trstandard + idx;
+ return sk_X509_TRUST_value(trtable, idx - X509_TRUST_COUNT);
}
int X509_TRUST_get_by_id(int id)
{
- X509_TRUST tmp;
- size_t idx;
-
- if((id >= X509_TRUST_MIN) && (id <= X509_TRUST_MAX))
- return id - X509_TRUST_MIN;
- tmp.trust = id;
- if(!trtable) return -1;
- if (!sk_X509_TRUST_find(trtable, &idx, &tmp)) {
- return -1;
- }
- return idx + X509_TRUST_COUNT;
+ X509_TRUST tmp;
+ size_t idx;
+
+ if ((id >= X509_TRUST_MIN) && (id <= X509_TRUST_MAX))
+ return id - X509_TRUST_MIN;
+ tmp.trust = id;
+ if (!trtable)
+ return -1;
+ if (!sk_X509_TRUST_find(trtable, &idx, &tmp)) {
+ return -1;
+ }
+ return idx + X509_TRUST_COUNT;
}
int X509_TRUST_set(int *t, int trust)
{
- if(X509_TRUST_get_by_id(trust) == -1) {
- OPENSSL_PUT_ERROR(X509, X509_R_INVALID_TRUST);
- return 0;
- }
- *t = trust;
- return 1;
+ if (X509_TRUST_get_by_id(trust) == -1) {
+ OPENSSL_PUT_ERROR(X509, X509_R_INVALID_TRUST);
+ return 0;
+ }
+ *t = trust;
+ return 1;
}
-int X509_TRUST_add(int id, int flags, int (*ck)(X509_TRUST *, X509 *, int),
- char *name, int arg1, void *arg2)
+int X509_TRUST_add(int id, int flags, int (*ck) (X509_TRUST *, X509 *, int),
+ char *name, int arg1, void *arg2)
{
- int idx;
- X509_TRUST *trtmp;
- char *name_dup;
-
- /* This is set according to what we change: application can't set it */
- flags &= ~X509_TRUST_DYNAMIC;
- /* This will always be set for application modified trust entries */
- flags |= X509_TRUST_DYNAMIC_NAME;
- /* Get existing entry if any */
- idx = X509_TRUST_get_by_id(id);
- /* Need a new entry */
- if(idx == -1) {
- if(!(trtmp = OPENSSL_malloc(sizeof(X509_TRUST)))) {
- OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
- return 0;
- }
- trtmp->flags = X509_TRUST_DYNAMIC;
- } else trtmp = X509_TRUST_get0(idx);
-
- /* Duplicate the supplied name. */
- name_dup = BUF_strdup(name);
- if (name_dup == NULL) {
- OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
- if (idx == -1)
- OPENSSL_free(trtmp);
- return 0;
- }
-
- /* OPENSSL_free existing name if dynamic */
- if (trtmp->flags & X509_TRUST_DYNAMIC_NAME) OPENSSL_free(trtmp->name);
- trtmp->name = name_dup;
- /* Keep the dynamic flag of existing entry */
- trtmp->flags &= X509_TRUST_DYNAMIC;
- /* Set all other flags */
- trtmp->flags |= flags;
-
- trtmp->trust = id;
- trtmp->check_trust = ck;
- trtmp->arg1 = arg1;
- trtmp->arg2 = arg2;
-
- /* 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, ERR_R_MALLOC_FAILURE);
- trtable_free(trtmp);
- return 0;
- }
- if (!sk_X509_TRUST_push(trtable, trtmp)) {
- OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
- trtable_free(trtmp);
- return 0;
- }
- }
- return 1;
+ int idx;
+ X509_TRUST *trtmp;
+ char *name_dup;
+
+ /*
+ * This is set according to what we change: application can't set it
+ */
+ flags &= ~X509_TRUST_DYNAMIC;
+ /* This will always be set for application modified trust entries */
+ flags |= X509_TRUST_DYNAMIC_NAME;
+ /* Get existing entry if any */
+ idx = X509_TRUST_get_by_id(id);
+ /* Need a new entry */
+ if (idx == -1) {
+ if (!(trtmp = OPENSSL_malloc(sizeof(X509_TRUST)))) {
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ trtmp->flags = X509_TRUST_DYNAMIC;
+ } else
+ trtmp = X509_TRUST_get0(idx);
+
+ /* Duplicate the supplied name. */
+ name_dup = BUF_strdup(name);
+ if (name_dup == NULL) {
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+ if (idx == -1)
+ OPENSSL_free(trtmp);
+ return 0;
+ }
+
+ /* OPENSSL_free existing name if dynamic */
+ if (trtmp->flags & X509_TRUST_DYNAMIC_NAME)
+ OPENSSL_free(trtmp->name);
+ trtmp->name = name_dup;
+ /* Keep the dynamic flag of existing entry */
+ trtmp->flags &= X509_TRUST_DYNAMIC;
+ /* Set all other flags */
+ trtmp->flags |= flags;
+
+ trtmp->trust = id;
+ trtmp->check_trust = ck;
+ trtmp->arg1 = arg1;
+ trtmp->arg2 = arg2;
+
+ /* 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, ERR_R_MALLOC_FAILURE);
+ trtable_free(trtmp);
+ return 0;
+ }
+ if (!sk_X509_TRUST_push(trtable, trtmp)) {
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+ trtable_free(trtmp);
+ return 0;
+ }
+ }
+ return 1;
}
static void trtable_free(X509_TRUST *p)
- {
- if(!p) return;
- if (p->flags & X509_TRUST_DYNAMIC)
- {
- if (p->flags & X509_TRUST_DYNAMIC_NAME)
- OPENSSL_free(p->name);
- OPENSSL_free(p);
- }
- }
+{
+ if (!p)
+ return;
+ if (p->flags & X509_TRUST_DYNAMIC) {
+ if (p->flags & X509_TRUST_DYNAMIC_NAME)
+ OPENSSL_free(p->name);
+ OPENSSL_free(p);
+ }
+}
void X509_TRUST_cleanup(void)
{
- unsigned int i;
- for(i = 0; i < X509_TRUST_COUNT; i++) trtable_free(trstandard + i);
- sk_X509_TRUST_pop_free(trtable, trtable_free);
- trtable = NULL;
+ unsigned int i;
+ for (i = 0; i < X509_TRUST_COUNT; i++)
+ trtable_free(trstandard + i);
+ sk_X509_TRUST_pop_free(trtable, trtable_free);
+ trtable = NULL;
}
int X509_TRUST_get_flags(X509_TRUST *xp)
{
- return xp->flags;
+ return xp->flags;
}
char *X509_TRUST_get0_name(X509_TRUST *xp)
{
- return xp->name;
+ return xp->name;
}
int X509_TRUST_get_trust(X509_TRUST *xp)
{
- return xp->trust;
+ return xp->trust;
}
static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags)
{
- if(x->aux && (x->aux->trust || x->aux->reject))
- return obj_trust(trust->arg1, x, flags);
- /* we don't have any trust settings: for compatibility
- * we return trusted if it is self signed
- */
- return trust_compat(trust, x, flags);
+ if (x->aux && (x->aux->trust || x->aux->reject))
+ return obj_trust(trust->arg1, x, flags);
+ /*
+ * we don't have any trust settings: for compatibility we return trusted
+ * if it is self signed
+ */
+ return trust_compat(trust, x, flags);
}
static int trust_1oid(X509_TRUST *trust, X509 *x, int flags)
{
- if(x->aux) return obj_trust(trust->arg1, x, flags);
- return X509_TRUST_UNTRUSTED;
+ if (x->aux)
+ return obj_trust(trust->arg1, x, flags);
+ return X509_TRUST_UNTRUSTED;
}
static int trust_compat(X509_TRUST *trust, X509 *x, int flags)
{
- X509_check_purpose(x, -1, 0);
- if(x->ex_flags & EXFLAG_SS) return X509_TRUST_TRUSTED;
- else return X509_TRUST_UNTRUSTED;
+ X509_check_purpose(x, -1, 0);
+ if (x->ex_flags & EXFLAG_SS)
+ return X509_TRUST_TRUSTED;
+ else
+ return X509_TRUST_UNTRUSTED;
}
static int obj_trust(int id, X509 *x, int flags)
{
- ASN1_OBJECT *obj;
- size_t i;
- X509_CERT_AUX *ax;
- ax = x->aux;
- if(!ax) return X509_TRUST_UNTRUSTED;
- if(ax->reject) {
- for(i = 0; i < sk_ASN1_OBJECT_num(ax->reject); i++) {
- obj = sk_ASN1_OBJECT_value(ax->reject, i);
- if(OBJ_obj2nid(obj) == id) return X509_TRUST_REJECTED;
- }
- }
- if(ax->trust) {
- for(i = 0; i < sk_ASN1_OBJECT_num(ax->trust); i++) {
- obj = sk_ASN1_OBJECT_value(ax->trust, i);
- if(OBJ_obj2nid(obj) == id) return X509_TRUST_TRUSTED;
- }
- }
- return X509_TRUST_UNTRUSTED;
+ ASN1_OBJECT *obj;
+ size_t i;
+ X509_CERT_AUX *ax;
+ ax = x->aux;
+ if (!ax)
+ return X509_TRUST_UNTRUSTED;
+ if (ax->reject) {
+ for (i = 0; i < sk_ASN1_OBJECT_num(ax->reject); i++) {
+ obj = sk_ASN1_OBJECT_value(ax->reject, i);
+ if (OBJ_obj2nid(obj) == id)
+ return X509_TRUST_REJECTED;
+ }
+ }
+ if (ax->trust) {
+ for (i = 0; i < sk_ASN1_OBJECT_num(ax->trust); i++) {
+ obj = sk_ASN1_OBJECT_value(ax->trust, i);
+ if (OBJ_obj2nid(obj) == id)
+ return X509_TRUST_TRUSTED;
+ }
+ }
+ return X509_TRUST_UNTRUSTED;
}
-
diff --git a/src/crypto/x509/x509_txt.c b/src/crypto/x509/x509_txt.c
index c2867102..86af3fec 100644
--- a/src/crypto/x509/x509_txt.c
+++ b/src/crypto/x509/x509_txt.c
@@ -63,147 +63,144 @@
#include <openssl/obj.h>
#include <openssl/x509.h>
-
const char *X509_verify_cert_error_string(long n)
- {
- static char buf[100];
-
- switch ((int)n)
- {
- case X509_V_OK:
- return("ok");
- case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
- return("unable to get issuer certificate");
- case X509_V_ERR_UNABLE_TO_GET_CRL:
- return("unable to get certificate CRL");
- case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
- return("unable to decrypt certificate's signature");
- case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
- return("unable to decrypt CRL's signature");
- case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
- return("unable to decode issuer public key");
- case X509_V_ERR_CERT_SIGNATURE_FAILURE:
- return("certificate signature failure");
- case X509_V_ERR_CRL_SIGNATURE_FAILURE:
- return("CRL signature failure");
- case X509_V_ERR_CERT_NOT_YET_VALID:
- return("certificate is not yet valid");
- case X509_V_ERR_CRL_NOT_YET_VALID:
- return("CRL is not yet valid");
- case X509_V_ERR_CERT_HAS_EXPIRED:
- return("certificate has expired");
- case X509_V_ERR_CRL_HAS_EXPIRED:
- return("CRL has expired");
- case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
- return("format error in certificate's notBefore field");
- case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
- return("format error in certificate's notAfter field");
- case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
- return("format error in CRL's lastUpdate field");
- case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
- return("format error in CRL's nextUpdate field");
- case X509_V_ERR_OUT_OF_MEM:
- return("out of memory");
- case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
- return("self signed certificate");
- case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
- return("self signed certificate in certificate chain");
- case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
- return("unable to get local issuer certificate");
- case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
- return("unable to verify the first certificate");
- case X509_V_ERR_CERT_CHAIN_TOO_LONG:
- return("certificate chain too long");
- case X509_V_ERR_CERT_REVOKED:
- return("certificate revoked");
- case X509_V_ERR_INVALID_CA:
- return ("invalid CA certificate");
- case X509_V_ERR_INVALID_NON_CA:
- return ("invalid non-CA certificate (has CA markings)");
- case X509_V_ERR_PATH_LENGTH_EXCEEDED:
- return ("path length constraint exceeded");
- case X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED:
- return("proxy path length constraint exceeded");
- case X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED:
- return("proxy certificates not allowed, please set the appropriate flag");
- case X509_V_ERR_INVALID_PURPOSE:
- return ("unsupported certificate purpose");
- case X509_V_ERR_CERT_UNTRUSTED:
- return ("certificate not trusted");
- case X509_V_ERR_CERT_REJECTED:
- return ("certificate rejected");
- case X509_V_ERR_APPLICATION_VERIFICATION:
- return("application verification failure");
- case X509_V_ERR_SUBJECT_ISSUER_MISMATCH:
- return("subject issuer mismatch");
- case X509_V_ERR_AKID_SKID_MISMATCH:
- return("authority and subject key identifier mismatch");
- case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH:
- return("authority and issuer serial number mismatch");
- case X509_V_ERR_KEYUSAGE_NO_CERTSIGN:
- return("key usage does not include certificate signing");
- case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
- return("unable to get CRL issuer certificate");
- case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION:
- return("unhandled critical extension");
- case X509_V_ERR_KEYUSAGE_NO_CRL_SIGN:
- return("key usage does not include CRL signing");
- case X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE:
- return("key usage does not include digital signature");
- case X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION:
- return("unhandled critical CRL extension");
- case X509_V_ERR_INVALID_EXTENSION:
- return("invalid or inconsistent certificate extension");
- case X509_V_ERR_INVALID_POLICY_EXTENSION:
- return("invalid or inconsistent certificate policy extension");
- case X509_V_ERR_NO_EXPLICIT_POLICY:
- return("no explicit policy");
- case X509_V_ERR_DIFFERENT_CRL_SCOPE:
- return("Different CRL scope");
- case X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE:
- return("Unsupported extension feature");
- case X509_V_ERR_UNNESTED_RESOURCE:
- return("RFC 3779 resource not subset of parent's resources");
-
- case X509_V_ERR_PERMITTED_VIOLATION:
- return("permitted subtree violation");
- case X509_V_ERR_EXCLUDED_VIOLATION:
- return("excluded subtree violation");
- case X509_V_ERR_SUBTREE_MINMAX:
- return("name constraints minimum and maximum not supported");
- case X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE:
- return("unsupported name constraint type");
- case X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX:
- return("unsupported or invalid name constraint syntax");
- case X509_V_ERR_UNSUPPORTED_NAME_SYNTAX:
- return("unsupported or invalid name syntax");
- case X509_V_ERR_CRL_PATH_VALIDATION_ERROR:
- return("CRL path validation error");
+{
+ static char buf[100];
- case X509_V_ERR_SUITE_B_INVALID_VERSION:
- return("Suite B: certificate version invalid");
- case X509_V_ERR_SUITE_B_INVALID_ALGORITHM:
- return("Suite B: invalid public key algorithm");
- case X509_V_ERR_SUITE_B_INVALID_CURVE:
- return("Suite B: invalid ECC curve");
- case X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM:
- return("Suite B: invalid signature algorithm");
- case X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED:
- return("Suite B: curve not allowed for this LOS");
- case X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256:
- return("Suite B: cannot sign P-384 with P-256");
+ switch ((int)n) {
+ case X509_V_OK:
+ return ("ok");
+ case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
+ return ("unable to get issuer certificate");
+ case X509_V_ERR_UNABLE_TO_GET_CRL:
+ return ("unable to get certificate CRL");
+ case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
+ return ("unable to decrypt certificate's signature");
+ case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
+ return ("unable to decrypt CRL's signature");
+ case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
+ return ("unable to decode issuer public key");
+ case X509_V_ERR_CERT_SIGNATURE_FAILURE:
+ return ("certificate signature failure");
+ case X509_V_ERR_CRL_SIGNATURE_FAILURE:
+ return ("CRL signature failure");
+ case X509_V_ERR_CERT_NOT_YET_VALID:
+ return ("certificate is not yet valid");
+ case X509_V_ERR_CRL_NOT_YET_VALID:
+ return ("CRL is not yet valid");
+ case X509_V_ERR_CERT_HAS_EXPIRED:
+ return ("certificate has expired");
+ case X509_V_ERR_CRL_HAS_EXPIRED:
+ return ("CRL has expired");
+ case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
+ return ("format error in certificate's notBefore field");
+ case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
+ return ("format error in certificate's notAfter field");
+ case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
+ return ("format error in CRL's lastUpdate field");
+ case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
+ return ("format error in CRL's nextUpdate field");
+ case X509_V_ERR_OUT_OF_MEM:
+ return ("out of memory");
+ case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
+ return ("self signed certificate");
+ case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
+ return ("self signed certificate in certificate chain");
+ case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
+ return ("unable to get local issuer certificate");
+ case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
+ return ("unable to verify the first certificate");
+ case X509_V_ERR_CERT_CHAIN_TOO_LONG:
+ return ("certificate chain too long");
+ case X509_V_ERR_CERT_REVOKED:
+ return ("certificate revoked");
+ case X509_V_ERR_INVALID_CA:
+ return ("invalid CA certificate");
+ case X509_V_ERR_INVALID_NON_CA:
+ return ("invalid non-CA certificate (has CA markings)");
+ case X509_V_ERR_PATH_LENGTH_EXCEEDED:
+ return ("path length constraint exceeded");
+ case X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED:
+ return ("proxy path length constraint exceeded");
+ case X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED:
+ return
+ ("proxy certificates not allowed, please set the appropriate flag");
+ case X509_V_ERR_INVALID_PURPOSE:
+ return ("unsupported certificate purpose");
+ case X509_V_ERR_CERT_UNTRUSTED:
+ return ("certificate not trusted");
+ case X509_V_ERR_CERT_REJECTED:
+ return ("certificate rejected");
+ case X509_V_ERR_APPLICATION_VERIFICATION:
+ return ("application verification failure");
+ case X509_V_ERR_SUBJECT_ISSUER_MISMATCH:
+ return ("subject issuer mismatch");
+ case X509_V_ERR_AKID_SKID_MISMATCH:
+ return ("authority and subject key identifier mismatch");
+ case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH:
+ return ("authority and issuer serial number mismatch");
+ case X509_V_ERR_KEYUSAGE_NO_CERTSIGN:
+ return ("key usage does not include certificate signing");
+ case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
+ return ("unable to get CRL issuer certificate");
+ case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION:
+ return ("unhandled critical extension");
+ case X509_V_ERR_KEYUSAGE_NO_CRL_SIGN:
+ return ("key usage does not include CRL signing");
+ case X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE:
+ return ("key usage does not include digital signature");
+ case X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION:
+ return ("unhandled critical CRL extension");
+ case X509_V_ERR_INVALID_EXTENSION:
+ return ("invalid or inconsistent certificate extension");
+ case X509_V_ERR_INVALID_POLICY_EXTENSION:
+ return ("invalid or inconsistent certificate policy extension");
+ case X509_V_ERR_NO_EXPLICIT_POLICY:
+ return ("no explicit policy");
+ case X509_V_ERR_DIFFERENT_CRL_SCOPE:
+ return ("Different CRL scope");
+ case X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE:
+ return ("Unsupported extension feature");
+ case X509_V_ERR_UNNESTED_RESOURCE:
+ return ("RFC 3779 resource not subset of parent's resources");
- case X509_V_ERR_HOSTNAME_MISMATCH:
- return("Hostname mismatch");
- case X509_V_ERR_EMAIL_MISMATCH:
- return("Email address mismatch");
- case X509_V_ERR_IP_ADDRESS_MISMATCH:
- return("IP address mismatch");
+ case X509_V_ERR_PERMITTED_VIOLATION:
+ return ("permitted subtree violation");
+ case X509_V_ERR_EXCLUDED_VIOLATION:
+ return ("excluded subtree violation");
+ case X509_V_ERR_SUBTREE_MINMAX:
+ return ("name constraints minimum and maximum not supported");
+ case X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE:
+ return ("unsupported name constraint type");
+ case X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX:
+ return ("unsupported or invalid name constraint syntax");
+ case X509_V_ERR_UNSUPPORTED_NAME_SYNTAX:
+ return ("unsupported or invalid name syntax");
+ case X509_V_ERR_CRL_PATH_VALIDATION_ERROR:
+ return ("CRL path validation error");
- default:
- BIO_snprintf(buf,sizeof buf,"error number %ld",n);
- return(buf);
- }
- }
+ case X509_V_ERR_SUITE_B_INVALID_VERSION:
+ return ("Suite B: certificate version invalid");
+ case X509_V_ERR_SUITE_B_INVALID_ALGORITHM:
+ return ("Suite B: invalid public key algorithm");
+ case X509_V_ERR_SUITE_B_INVALID_CURVE:
+ return ("Suite B: invalid ECC curve");
+ case X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM:
+ return ("Suite B: invalid signature algorithm");
+ case X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED:
+ return ("Suite B: curve not allowed for this LOS");
+ case X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256:
+ return ("Suite B: cannot sign P-384 with P-256");
+ case X509_V_ERR_HOSTNAME_MISMATCH:
+ return ("Hostname mismatch");
+ case X509_V_ERR_EMAIL_MISMATCH:
+ return ("Email address mismatch");
+ case X509_V_ERR_IP_ADDRESS_MISMATCH:
+ return ("IP address mismatch");
+ default:
+ BIO_snprintf(buf, sizeof buf, "error number %ld", n);
+ return (buf);
+ }
+}
diff --git a/src/crypto/x509/x509_v3.c b/src/crypto/x509/x509_v3.c
index b0429851..ecbc0ddc 100644
--- a/src/crypto/x509/x509_v3.c
+++ b/src/crypto/x509/x509_v3.c
@@ -62,210 +62,217 @@
#include <openssl/x509.h>
#include <openssl/x509v3.h>
-
int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x)
- {
- if (x == NULL) return(0);
- return(sk_X509_EXTENSION_num(x));
- }
+{
+ if (x == NULL)
+ return (0);
+ return (sk_X509_EXTENSION_num(x));
+}
int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, int nid,
- int lastpos)
- {
- const ASN1_OBJECT *obj;
+ int lastpos)
+{
+ const ASN1_OBJECT *obj;
- obj=OBJ_nid2obj(nid);
- if (obj == NULL) return(-2);
- return(X509v3_get_ext_by_OBJ(x,obj,lastpos));
- }
+ obj = OBJ_nid2obj(nid);
+ if (obj == NULL)
+ return (-2);
+ return (X509v3_get_ext_by_OBJ(x, obj, lastpos));
+}
-int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *sk, const ASN1_OBJECT *obj,
- int lastpos)
- {
- int n;
- X509_EXTENSION *ex;
+int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *sk,
+ const ASN1_OBJECT *obj, int lastpos)
+{
+ int n;
+ X509_EXTENSION *ex;
- if (sk == NULL) return(-1);
- lastpos++;
- if (lastpos < 0)
- lastpos=0;
- n=sk_X509_EXTENSION_num(sk);
- for ( ; lastpos < n; lastpos++)
- {
- ex=sk_X509_EXTENSION_value(sk,lastpos);
- if (OBJ_cmp(ex->object,obj) == 0)
- return(lastpos);
- }
- return(-1);
- }
+ if (sk == NULL)
+ return (-1);
+ lastpos++;
+ if (lastpos < 0)
+ lastpos = 0;
+ n = sk_X509_EXTENSION_num(sk);
+ for (; lastpos < n; lastpos++) {
+ ex = sk_X509_EXTENSION_value(sk, lastpos);
+ if (OBJ_cmp(ex->object, obj) == 0)
+ return (lastpos);
+ }
+ return (-1);
+}
int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *sk, int crit,
- int lastpos)
- {
- int n;
- X509_EXTENSION *ex;
+ int lastpos)
+{
+ int n;
+ X509_EXTENSION *ex;
- if (sk == NULL) return(-1);
- lastpos++;
- if (lastpos < 0)
- lastpos=0;
- n=sk_X509_EXTENSION_num(sk);
- for ( ; lastpos < n; lastpos++)
- {
- ex=sk_X509_EXTENSION_value(sk,lastpos);
- if ( ((ex->critical > 0) && crit) ||
- ((ex->critical <= 0) && !crit))
- return(lastpos);
- }
- return(-1);
- }
+ if (sk == NULL)
+ return (-1);
+ lastpos++;
+ if (lastpos < 0)
+ lastpos = 0;
+ n = sk_X509_EXTENSION_num(sk);
+ for (; lastpos < n; lastpos++) {
+ ex = sk_X509_EXTENSION_value(sk, lastpos);
+ if (((ex->critical > 0) && crit) || ((ex->critical <= 0) && !crit))
+ return (lastpos);
+ }
+ return (-1);
+}
X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc)
- {
- if (x == NULL || loc < 0 || sk_X509_EXTENSION_num(x) <= (size_t) loc)
- return NULL;
- else
- return sk_X509_EXTENSION_value(x,loc);
- }
+{
+ if (x == NULL || loc < 0 || sk_X509_EXTENSION_num(x) <= (size_t)loc)
+ return NULL;
+ else
+ return sk_X509_EXTENSION_value(x, loc);
+}
X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc)
- {
- X509_EXTENSION *ret;
+{
+ X509_EXTENSION *ret;
- if (x == NULL || loc < 0 || sk_X509_EXTENSION_num(x) <= (size_t) loc)
- return(NULL);
- ret=sk_X509_EXTENSION_delete(x,loc);
- return(ret);
- }
+ if (x == NULL || loc < 0 || sk_X509_EXTENSION_num(x) <= (size_t)loc)
+ return (NULL);
+ ret = sk_X509_EXTENSION_delete(x, loc);
+ return (ret);
+}
STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x,
- X509_EXTENSION *ex, int loc)
- {
- X509_EXTENSION *new_ex=NULL;
- int n;
- STACK_OF(X509_EXTENSION) *sk=NULL;
+ X509_EXTENSION *ex, int loc)
+{
+ X509_EXTENSION *new_ex = NULL;
+ int n;
+ STACK_OF(X509_EXTENSION) *sk = NULL;
- if (x == NULL)
- {
- OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER);
- goto err2;
- }
+ if (x == NULL) {
+ OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER);
+ goto err2;
+ }
- if (*x == NULL)
- {
- if ((sk=sk_X509_EXTENSION_new_null()) == NULL)
- goto err;
- }
- else
- sk= *x;
+ if (*x == NULL) {
+ if ((sk = sk_X509_EXTENSION_new_null()) == NULL)
+ goto err;
+ } else
+ sk = *x;
- n=sk_X509_EXTENSION_num(sk);
- if (loc > n) loc=n;
- else if (loc < 0) loc=n;
+ n = sk_X509_EXTENSION_num(sk);
+ if (loc > n)
+ loc = n;
+ else if (loc < 0)
+ loc = n;
- if ((new_ex=X509_EXTENSION_dup(ex)) == NULL)
- goto err2;
- if (!sk_X509_EXTENSION_insert(sk,new_ex,loc))
- goto err;
- if (*x == NULL)
- *x=sk;
- return(sk);
-err:
- 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);
- return(NULL);
- }
+ if ((new_ex = X509_EXTENSION_dup(ex)) == NULL)
+ goto err2;
+ if (!sk_X509_EXTENSION_insert(sk, new_ex, loc))
+ goto err;
+ if (*x == NULL)
+ *x = sk;
+ return (sk);
+ err:
+ 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);
+ return (NULL);
+}
X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, int nid,
- int crit, ASN1_OCTET_STRING *data)
- {
- const ASN1_OBJECT *obj;
- X509_EXTENSION *ret;
+ int crit,
+ ASN1_OCTET_STRING *data)
+{
+ const ASN1_OBJECT *obj;
+ X509_EXTENSION *ret;
- obj=OBJ_nid2obj(nid);
- if (obj == NULL)
- {
- OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_NID);
- return(NULL);
- }
- ret=X509_EXTENSION_create_by_OBJ(ex,obj,crit,data);
- return(ret);
- }
+ obj = OBJ_nid2obj(nid);
+ if (obj == NULL) {
+ OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_NID);
+ return (NULL);
+ }
+ ret = X509_EXTENSION_create_by_OBJ(ex, obj, crit, data);
+ return (ret);
+}
X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex,
- const ASN1_OBJECT *obj, int crit, ASN1_OCTET_STRING *data)
- {
- X509_EXTENSION *ret;
+ const ASN1_OBJECT *obj, int crit,
+ ASN1_OCTET_STRING *data)
+{
+ X509_EXTENSION *ret;
+
+ if ((ex == NULL) || (*ex == NULL)) {
+ if ((ret = X509_EXTENSION_new()) == NULL) {
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+ } else
+ ret = *ex;
- if ((ex == NULL) || (*ex == NULL))
- {
- if ((ret=X509_EXTENSION_new()) == NULL)
- {
- OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
- return(NULL);
- }
- }
- else
- ret= *ex;
+ if (!X509_EXTENSION_set_object(ret, obj))
+ goto err;
+ if (!X509_EXTENSION_set_critical(ret, crit))
+ goto err;
+ if (!X509_EXTENSION_set_data(ret, data))
+ goto err;
- if (!X509_EXTENSION_set_object(ret,obj))
- goto err;
- if (!X509_EXTENSION_set_critical(ret,crit))
- goto err;
- if (!X509_EXTENSION_set_data(ret,data))
- goto err;
-
- if ((ex != NULL) && (*ex == NULL)) *ex=ret;
- return(ret);
-err:
- if ((ex == NULL) || (ret != *ex))
- X509_EXTENSION_free(ret);
- return(NULL);
- }
+ if ((ex != NULL) && (*ex == NULL))
+ *ex = ret;
+ return (ret);
+ err:
+ if ((ex == NULL) || (ret != *ex))
+ X509_EXTENSION_free(ret);
+ return (NULL);
+}
int X509_EXTENSION_set_object(X509_EXTENSION *ex, const ASN1_OBJECT *obj)
- {
- if ((ex == NULL) || (obj == NULL))
- return(0);
- ASN1_OBJECT_free(ex->object);
- ex->object=OBJ_dup(obj);
- return ex->object != NULL;
- }
+{
+ if ((ex == NULL) || (obj == NULL))
+ return (0);
+ ASN1_OBJECT_free(ex->object);
+ ex->object = OBJ_dup(obj);
+ return ex->object != NULL;
+}
int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit)
- {
- if (ex == NULL) return(0);
- ex->critical=(crit)?0xFF:-1;
- return(1);
- }
+{
+ if (ex == NULL)
+ return (0);
+ ex->critical = (crit) ? 0xFF : -1;
+ return (1);
+}
int X509_EXTENSION_set_data(X509_EXTENSION *ex, ASN1_OCTET_STRING *data)
- {
- int i;
+{
+ int i;
- if (ex == NULL) return(0);
- i=M_ASN1_OCTET_STRING_set(ex->value,data->data,data->length);
- if (!i) return(0);
- return(1);
- }
+ if (ex == NULL)
+ return (0);
+ i = M_ASN1_OCTET_STRING_set(ex->value, data->data, data->length);
+ if (!i)
+ return (0);
+ return (1);
+}
ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *ex)
- {
- if (ex == NULL) return(NULL);
- return(ex->object);
- }
+{
+ if (ex == NULL)
+ return (NULL);
+ return (ex->object);
+}
ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ex)
- {
- if (ex == NULL) return(NULL);
- return(ex->value);
- }
+{
+ if (ex == NULL)
+ return (NULL);
+ return (ex->value);
+}
int X509_EXTENSION_get_critical(X509_EXTENSION *ex)
- {
- if (ex == NULL) return(0);
- if(ex->critical > 0) return 1;
- return 0;
- }
+{
+ if (ex == NULL)
+ return (0);
+ if (ex->critical > 0)
+ return 1;
+ return 0;
+}
diff --git a/src/crypto/x509/x509_vfy.c b/src/crypto/x509/x509_vfy.c
index c62a6f58..2ed2f03e 100644
--- a/src/crypto/x509/x509_vfy.c
+++ b/src/crypto/x509/x509_vfy.c
@@ -71,27 +71,26 @@
#include "vpm_int.h"
#include "../internal.h"
-
static CRYPTO_EX_DATA_CLASS g_ex_data_class =
- CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA;
+ CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA;
/* CRL score values */
/* No unhandled critical extensions */
-#define CRL_SCORE_NOCRITICAL 0x100
+#define CRL_SCORE_NOCRITICAL 0x100
/* certificate is within CRL scope */
-#define CRL_SCORE_SCOPE 0x080
+#define CRL_SCORE_SCOPE 0x080
/* CRL times valid */
-#define CRL_SCORE_TIME 0x040
+#define CRL_SCORE_TIME 0x040
/* Issuer name matches certificate */
-#define CRL_SCORE_ISSUER_NAME 0x020
+#define CRL_SCORE_ISSUER_NAME 0x020
/* If this score or above CRL is probably valid */
@@ -99,21 +98,21 @@ static CRYPTO_EX_DATA_CLASS g_ex_data_class =
/* CRL issuer is certificate issuer */
-#define CRL_SCORE_ISSUER_CERT 0x018
+#define CRL_SCORE_ISSUER_CERT 0x018
/* CRL issuer is on certificate path */
-#define CRL_SCORE_SAME_PATH 0x008
+#define CRL_SCORE_SAME_PATH 0x008
/* CRL issuer matches CRL AKID */
-#define CRL_SCORE_AKID 0x004
+#define CRL_SCORE_AKID 0x004
/* Have a delta CRL with valid times */
-#define CRL_SCORE_TIME_DELTA 0x002
+#define CRL_SCORE_TIME_DELTA 0x002
-static int null_callback(int ok,X509_STORE_CTX *e);
+static int null_callback(int ok, X509_STORE_CTX *e);
static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer);
static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x);
static int check_chain_extensions(X509_STORE_CTX *ctx);
@@ -125,2336 +124,2284 @@ static int check_cert(X509_STORE_CTX *ctx);
static int check_policy(X509_STORE_CTX *ctx);
static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer,
- unsigned int *preasons,
- X509_CRL *crl, X509 *x);
+ unsigned int *preasons, X509_CRL *crl, X509 *x);
static int get_crl_delta(X509_STORE_CTX *ctx,
- X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x);
-static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pcrl_score,
- X509_CRL *base, STACK_OF(X509_CRL) *crls);
-static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl,
- X509 **pissuer, int *pcrl_score);
+ X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x);
+static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl,
+ int *pcrl_score, X509_CRL *base,
+ STACK_OF(X509_CRL) *crls);
+static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, X509 **pissuer,
+ int *pcrl_score);
static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score,
- unsigned int *preasons);
+ unsigned int *preasons);
static int check_crl_path(X509_STORE_CTX *ctx, X509 *x);
static int check_crl_chain(X509_STORE_CTX *ctx,
- STACK_OF(X509) *cert_path,
- STACK_OF(X509) *crl_path);
+ STACK_OF(X509) *cert_path,
+ STACK_OF(X509) *crl_path);
static int internal_verify(X509_STORE_CTX *ctx);
-
static int null_callback(int ok, X509_STORE_CTX *e)
- {
- return ok;
- }
+{
+ return ok;
+}
#if 0
static int x509_subject_cmp(X509 **a, X509 **b)
- {
- return X509_subject_name_cmp(*a,*b);
- }
+{
+ return X509_subject_name_cmp(*a, *b);
+}
#endif
/* Return 1 is a certificate is self signed */
static int cert_self_signed(X509 *x)
- {
- X509_check_purpose(x, -1, 0);
- if (x->ex_flags & EXFLAG_SS)
- return 1;
- else
- return 0;
- }
+{
+ X509_check_purpose(x, -1, 0);
+ if (x->ex_flags & EXFLAG_SS)
+ return 1;
+ else
+ return 0;
+}
/* Given a certificate try and find an exact match in the store */
static X509 *lookup_cert_match(X509_STORE_CTX *ctx, X509 *x)
- {
- STACK_OF(X509) *certs;
- X509 *xtmp = NULL;
- size_t i;
- /* Lookup all certs with matching subject name */
- certs = ctx->lookup_certs(ctx, X509_get_subject_name(x));
- if (certs == NULL)
- return NULL;
- /* Look for exact match */
- for (i = 0; i < sk_X509_num(certs); i++)
- {
- xtmp = sk_X509_value(certs, i);
- if (!X509_cmp(xtmp, x))
- break;
- }
- if (i < sk_X509_num(certs))
- X509_up_ref(xtmp);
- else
- xtmp = NULL;
- sk_X509_pop_free(certs, X509_free);
- return xtmp;
- }
+{
+ STACK_OF(X509) *certs;
+ X509 *xtmp = NULL;
+ size_t i;
+ /* Lookup all certs with matching subject name */
+ certs = ctx->lookup_certs(ctx, X509_get_subject_name(x));
+ if (certs == NULL)
+ return NULL;
+ /* Look for exact match */
+ for (i = 0; i < sk_X509_num(certs); i++) {
+ xtmp = sk_X509_value(certs, i);
+ if (!X509_cmp(xtmp, x))
+ break;
+ }
+ if (i < sk_X509_num(certs))
+ X509_up_ref(xtmp);
+ else
+ xtmp = NULL;
+ sk_X509_pop_free(certs, X509_free);
+ return xtmp;
+}
int X509_verify_cert(X509_STORE_CTX *ctx)
- {
- X509 *x,*xtmp,*chain_ss=NULL;
- int bad_chain = 0;
- X509_VERIFY_PARAM *param = ctx->param;
- int depth,i,ok=0;
- int num;
- int (*cb)(int xok,X509_STORE_CTX *xctx);
- STACK_OF(X509) *sktmp=NULL;
- if (ctx->cert == NULL)
- {
- OPENSSL_PUT_ERROR(X509, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY);
- return -1;
- }
- if (ctx->chain != NULL)
- {
- /* This X509_STORE_CTX has already been used to verify a
- * cert. We cannot do another one. */
- OPENSSL_PUT_ERROR(X509, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return -1;
- }
-
- cb=ctx->verify_cb;
-
- /* first we make sure the chain we are going to build is
- * present and that the first entry is in place */
- ctx->chain = sk_X509_new_null();
- if (ctx->chain == NULL || !sk_X509_push(ctx->chain, ctx->cert))
- {
- OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
- goto end;
- }
- X509_up_ref(ctx->cert);
- ctx->last_untrusted = 1;
-
- /* 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, ERR_R_MALLOC_FAILURE);
- goto end;
- }
-
- num=sk_X509_num(ctx->chain);
- x=sk_X509_value(ctx->chain,num-1);
- depth=param->depth;
-
-
- for (;;)
- {
- /* If we have enough, we break */
- if (depth < num) break; /* FIXME: If this happens, we should take
- * note of it and, if appropriate, use the
- * X509_V_ERR_CERT_CHAIN_TOO_LONG error
- * code later.
- */
-
- /* If we are self signed, we break */
- if (cert_self_signed(x))
- break;
- /* If asked see if we can find issuer in trusted store first */
- if (ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST)
- {
- ok = ctx->get_issuer(&xtmp, ctx, x);
- if (ok < 0)
- goto end;
- /* If successful for now free up cert so it
- * will be picked up again later.
- */
- if (ok > 0)
- {
- X509_free(xtmp);
- break;
- }
- }
-
- /* If we were passed a cert chain, use it first */
- if (ctx->untrusted != NULL)
- {
- xtmp=find_issuer(ctx, sktmp,x);
- if (xtmp != NULL)
- {
- if (!sk_X509_push(ctx->chain,xtmp))
- {
- OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
- goto end;
- }
- X509_up_ref(xtmp);
- (void)sk_X509_delete_ptr(sktmp,xtmp);
- ctx->last_untrusted++;
- x=xtmp;
- num++;
- /* reparse the full chain for
- * the next one */
- continue;
- }
- }
- break;
- }
-
- /* at this point, chain should contain a list of untrusted
- * certificates. We now need to add at least one trusted one,
- * if possible, otherwise we complain. */
-
- /* Examine last certificate in chain and see if it
- * is self signed.
- */
-
- i=sk_X509_num(ctx->chain);
- x=sk_X509_value(ctx->chain,i-1);
- if (cert_self_signed(x))
- {
- /* we have a self signed certificate */
- if (sk_X509_num(ctx->chain) == 1)
- {
- /* We have a single self signed certificate: see if
- * we can find it in the store. We must have an exact
- * match to avoid possible impersonation.
- */
- ok = ctx->get_issuer(&xtmp, ctx, x);
- if ((ok <= 0) || X509_cmp(x, xtmp))
- {
- ctx->error=X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT;
- ctx->current_cert=x;
- ctx->error_depth=i-1;
- if (ok == 1) X509_free(xtmp);
- bad_chain = 1;
- ok=cb(0,ctx);
- if (!ok) goto end;
- }
- else
- {
- /* We have a match: replace certificate with store version
- * so we get any trust settings.
- */
- X509_free(x);
- x = xtmp;
- (void)sk_X509_set(ctx->chain, i - 1, x);
- ctx->last_untrusted=0;
- }
- }
- else
- {
- /* extract and save self signed certificate for later use */
- chain_ss=sk_X509_pop(ctx->chain);
- ctx->last_untrusted--;
- num--;
- x=sk_X509_value(ctx->chain,num-1);
- }
- }
-
- /* We now lookup certs from the certificate store */
- for (;;)
- {
- /* If we have enough, we break */
- if (depth < num) break;
-
- /* If we are self signed, we break */
- if (cert_self_signed(x))
- break;
-
- ok = ctx->get_issuer(&xtmp, ctx, x);
-
- 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, ERR_R_MALLOC_FAILURE);
- ok = 0;
- goto end;
- }
- num++;
- }
-
- /* we now have our chain, lets check it... */
-
- i = check_trust(ctx);
-
- /* If explicitly rejected error */
- if (i == X509_TRUST_REJECTED)
- goto end;
- /* If not explicitly trusted then indicate error unless it's
- * a single self signed certificate in which case we've indicated
- * an error already and set bad_chain == 1
- */
- if (i != X509_TRUST_TRUSTED && !bad_chain)
- {
- if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss))
- {
- if (ctx->last_untrusted >= num)
- ctx->error=X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;
- else
- ctx->error=X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT;
- ctx->current_cert=x;
- }
- else
- {
-
- sk_X509_push(ctx->chain,chain_ss);
- num++;
- ctx->last_untrusted=num;
- ctx->current_cert=chain_ss;
- ctx->error=X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN;
- chain_ss=NULL;
- }
-
- ctx->error_depth=num-1;
- bad_chain = 1;
- ok=cb(0,ctx);
- if (!ok) goto end;
- }
-
- /* We have the chain complete: now we need to check its purpose */
- ok = check_chain_extensions(ctx);
-
- if (!ok) goto end;
-
- /* Check name constraints */
-
- ok = check_name_constraints(ctx);
-
- if (!ok) goto end;
-
- ok = check_id(ctx);
-
- if (!ok) goto end;
-
- /* Check revocation status: we do this after copying parameters
- * because they may be needed for CRL signature verification.
- */
-
- ok = ctx->check_revocation(ctx);
- if(!ok) goto end;
-
- i = X509_chain_check_suiteb(&ctx->error_depth, NULL, ctx->chain,
- ctx->param->flags);
- if (i != X509_V_OK)
- {
- ctx->error = i;
- ctx->current_cert = sk_X509_value(ctx->chain, ctx->error_depth);
- ok = cb(0, ctx);
- if (!ok)
- goto end;
- }
-
- /* At this point, we have a chain and need to verify it */
- if (ctx->verify != NULL)
- ok=ctx->verify(ctx);
- else
- ok=internal_verify(ctx);
- if(!ok) goto end;
-
- /* If we get this far evaluate policies */
- if (!bad_chain && (ctx->param->flags & X509_V_FLAG_POLICY_CHECK))
- ok = ctx->check_policy(ctx);
-
-end:
- if (sktmp != NULL) sk_X509_free(sktmp);
- if (chain_ss != NULL) X509_free(chain_ss);
- return ok;
- }
-
-
-/* Given a STACK_OF(X509) find the issuer of cert (if any)
+{
+ X509 *x, *xtmp, *xtmp2, *chain_ss = NULL;
+ int bad_chain = 0;
+ X509_VERIFY_PARAM *param = ctx->param;
+ int depth, i, ok = 0;
+ int num, j, retry, trust;
+ int (*cb) (int xok, X509_STORE_CTX *xctx);
+ STACK_OF(X509) *sktmp = NULL;
+ if (ctx->cert == NULL) {
+ OPENSSL_PUT_ERROR(X509, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY);
+ return -1;
+ }
+ if (ctx->chain != NULL) {
+ /*
+ * This X509_STORE_CTX has already been used to verify a cert. We
+ * cannot do another one.
+ */
+ OPENSSL_PUT_ERROR(X509, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return -1;
+ }
+
+ cb = ctx->verify_cb;
+
+ /*
+ * first we make sure the chain we are going to build is present and that
+ * the first entry is in place
+ */
+ ctx->chain = sk_X509_new_null();
+ if (ctx->chain == NULL || !sk_X509_push(ctx->chain, ctx->cert)) {
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+ goto end;
+ }
+ X509_up_ref(ctx->cert);
+ ctx->last_untrusted = 1;
+
+ /* 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, ERR_R_MALLOC_FAILURE);
+ goto end;
+ }
+
+ num = sk_X509_num(ctx->chain);
+ x = sk_X509_value(ctx->chain, num - 1);
+ depth = param->depth;
+
+ for (;;) {
+ /* If we have enough, we break */
+ if (depth < num)
+ break; /* FIXME: If this happens, we should take
+ * note of it and, if appropriate, use the
+ * X509_V_ERR_CERT_CHAIN_TOO_LONG error code
+ * later. */
+
+ /* If we are self signed, we break */
+ if (cert_self_signed(x))
+ break;
+ /*
+ * If asked see if we can find issuer in trusted store first
+ */
+ if (ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST) {
+ ok = ctx->get_issuer(&xtmp, ctx, x);
+ if (ok < 0)
+ goto end;
+ /*
+ * If successful for now free up cert so it will be picked up
+ * again later.
+ */
+ if (ok > 0) {
+ X509_free(xtmp);
+ break;
+ }
+ }
+
+ /* If we were passed a cert chain, use it first */
+ if (ctx->untrusted != NULL) {
+ xtmp = find_issuer(ctx, sktmp, x);
+ if (xtmp != NULL) {
+ if (!sk_X509_push(ctx->chain, xtmp)) {
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+ ok = 0;
+ goto end;
+ }
+ X509_up_ref(xtmp);
+ (void)sk_X509_delete_ptr(sktmp, xtmp);
+ ctx->last_untrusted++;
+ x = xtmp;
+ num++;
+ /*
+ * reparse the full chain for the next one
+ */
+ continue;
+ }
+ }
+ break;
+ }
+
+ /* Remember how many untrusted certs we have */
+ j = num;
+ /*
+ * at this point, chain should contain a list of untrusted certificates.
+ * We now need to add at least one trusted one, if possible, otherwise we
+ * complain.
+ */
+
+ do {
+ /*
+ * Examine last certificate in chain and see if it is self signed.
+ */
+ i = sk_X509_num(ctx->chain);
+ x = sk_X509_value(ctx->chain, i - 1);
+ if (cert_self_signed(x)) {
+ /* we have a self signed certificate */
+ if (sk_X509_num(ctx->chain) == 1) {
+ /*
+ * We have a single self signed certificate: see if we can
+ * find it in the store. We must have an exact match to avoid
+ * possible impersonation.
+ */
+ ok = ctx->get_issuer(&xtmp, ctx, x);
+ if ((ok <= 0) || X509_cmp(x, xtmp)) {
+ ctx->error = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT;
+ ctx->current_cert = x;
+ ctx->error_depth = i - 1;
+ if (ok == 1)
+ X509_free(xtmp);
+ bad_chain = 1;
+ ok = cb(0, ctx);
+ if (!ok)
+ goto end;
+ } else {
+ /*
+ * We have a match: replace certificate with store
+ * version so we get any trust settings.
+ */
+ X509_free(x);
+ x = xtmp;
+ (void)sk_X509_set(ctx->chain, i - 1, x);
+ ctx->last_untrusted = 0;
+ }
+ } else {
+ /*
+ * extract and save self signed certificate for later use
+ */
+ chain_ss = sk_X509_pop(ctx->chain);
+ ctx->last_untrusted--;
+ num--;
+ j--;
+ x = sk_X509_value(ctx->chain, num - 1);
+ }
+ }
+ /* We now lookup certs from the certificate store */
+ for (;;) {
+ /* If we have enough, we break */
+ if (depth < num)
+ break;
+ /* If we are self signed, we break */
+ if (cert_self_signed(x))
+ break;
+ ok = ctx->get_issuer(&xtmp, ctx, x);
+
+ 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, ERR_R_MALLOC_FAILURE);
+ ok = 0;
+ goto end;
+ }
+ num++;
+ }
+
+ /* we now have our chain, lets check it... */
+ trust = check_trust(ctx);
+
+ /* If explicitly rejected error */
+ if (trust == X509_TRUST_REJECTED) {
+ ok = 0;
+ goto end;
+ }
+ /*
+ * If it's not explicitly trusted then check if there is an alternative
+ * chain that could be used. We only do this if we haven't already
+ * checked via TRUSTED_FIRST and the user hasn't switched off alternate
+ * chain checking
+ */
+ retry = 0;
+ if (trust != X509_TRUST_TRUSTED
+ && !(ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST)
+ && !(ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS)) {
+ while (j-- > 1) {
+ xtmp2 = sk_X509_value(ctx->chain, j - 1);
+ ok = ctx->get_issuer(&xtmp, ctx, xtmp2);
+ if (ok < 0)
+ goto end;
+ /* Check if we found an alternate chain */
+ if (ok > 0) {
+ /*
+ * Free up the found cert we'll add it again later
+ */
+ X509_free(xtmp);
+
+ /*
+ * Dump all the certs above this point - we've found an
+ * alternate chain
+ */
+ while (num > j) {
+ xtmp = sk_X509_pop(ctx->chain);
+ X509_free(xtmp);
+ num--;
+ }
+ ctx->last_untrusted = sk_X509_num(ctx->chain);
+ retry = 1;
+ break;
+ }
+ }
+ }
+ } while (retry);
+
+ /*
+ * If not explicitly trusted then indicate error unless it's a single
+ * self signed certificate in which case we've indicated an error already
+ * and set bad_chain == 1
+ */
+ if (trust != X509_TRUST_TRUSTED && !bad_chain) {
+ if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss)) {
+ if (ctx->last_untrusted >= num)
+ ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;
+ else
+ ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT;
+ ctx->current_cert = x;
+ } else {
+
+ sk_X509_push(ctx->chain, chain_ss);
+ num++;
+ ctx->last_untrusted = num;
+ ctx->current_cert = chain_ss;
+ ctx->error = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN;
+ chain_ss = NULL;
+ }
+
+ ctx->error_depth = num - 1;
+ bad_chain = 1;
+ ok = cb(0, ctx);
+ if (!ok)
+ goto end;
+ }
+
+ /* We have the chain complete: now we need to check its purpose */
+ ok = check_chain_extensions(ctx);
+
+ if (!ok)
+ goto end;
+
+ /* Check name constraints */
+
+ ok = check_name_constraints(ctx);
+
+ if (!ok)
+ goto end;
+
+ ok = check_id(ctx);
+
+ if (!ok)
+ goto end;
+
+ /*
+ * Check revocation status: we do this after copying parameters because
+ * they may be needed for CRL signature verification.
+ */
+
+ ok = ctx->check_revocation(ctx);
+ if (!ok)
+ goto end;
+
+ int err = X509_chain_check_suiteb(&ctx->error_depth, NULL, ctx->chain,
+ ctx->param->flags);
+ if (err != X509_V_OK) {
+ ctx->error = err;
+ ctx->current_cert = sk_X509_value(ctx->chain, ctx->error_depth);
+ ok = cb(0, ctx);
+ if (!ok)
+ goto end;
+ }
+
+ /* At this point, we have a chain and need to verify it */
+ if (ctx->verify != NULL)
+ ok = ctx->verify(ctx);
+ else
+ ok = internal_verify(ctx);
+ if (!ok)
+ goto end;
+
+ /* If we get this far evaluate policies */
+ if (!bad_chain && (ctx->param->flags & X509_V_FLAG_POLICY_CHECK))
+ ok = ctx->check_policy(ctx);
+
+ end:
+ if (sktmp != NULL)
+ sk_X509_free(sktmp);
+ if (chain_ss != NULL)
+ X509_free(chain_ss);
+ return ok;
+}
+
+/*
+ * Given a STACK_OF(X509) find the issuer of cert (if any)
*/
static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x)
{
- size_t i;
- X509 *issuer;
- for (i = 0; i < sk_X509_num(sk); i++)
- {
- issuer = sk_X509_value(sk, i);
- if (ctx->check_issued(ctx, x, issuer))
- return issuer;
- }
- return NULL;
+ size_t i;
+ X509 *issuer;
+ for (i = 0; i < sk_X509_num(sk); i++) {
+ issuer = sk_X509_value(sk, i);
+ if (ctx->check_issued(ctx, x, issuer))
+ return issuer;
+ }
+ return NULL;
}
/* Given a possible certificate and issuer check them */
static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer)
{
- int ret;
- ret = X509_check_issued(issuer, x);
- if (ret == X509_V_OK)
- return 1;
- /* If we haven't asked for issuer errors don't set ctx */
- if (!(ctx->param->flags & X509_V_FLAG_CB_ISSUER_CHECK))
- return 0;
-
- ctx->error = ret;
- ctx->current_cert = x;
- ctx->current_issuer = issuer;
- return ctx->verify_cb(0, ctx);
+ int ret;
+ ret = X509_check_issued(issuer, x);
+ if (ret == X509_V_OK)
+ return 1;
+ /* If we haven't asked for issuer errors don't set ctx */
+ if (!(ctx->param->flags & X509_V_FLAG_CB_ISSUER_CHECK))
+ return 0;
+
+ ctx->error = ret;
+ ctx->current_cert = x;
+ ctx->current_issuer = issuer;
+ return ctx->verify_cb(0, ctx);
}
/* Alternative lookup method: look from a STACK stored in other_ctx */
static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
{
- *issuer = find_issuer(ctx, ctx->other_ctx, x);
- if (*issuer)
- {
- X509_up_ref(*issuer);
- return 1;
- }
- else
- return 0;
+ *issuer = find_issuer(ctx, ctx->other_ctx, x);
+ if (*issuer) {
+ X509_up_ref(*issuer);
+ return 1;
+ } else
+ return 0;
}
-
-/* Check a certificate chains extensions for consistency
- * with the supplied purpose
+/*
+ * Check a certificate chains extensions for consistency with the supplied
+ * purpose
*/
static int check_chain_extensions(X509_STORE_CTX *ctx)
{
- int i, ok=0, must_be_ca, plen = 0;
- X509 *x;
- int (*cb)(int xok,X509_STORE_CTX *xctx);
- int proxy_path_length = 0;
- int purpose;
- int allow_proxy_certs;
- cb=ctx->verify_cb;
-
- /* must_be_ca can have 1 of 3 values:
- -1: we accept both CA and non-CA certificates, to allow direct
- use of self-signed certificates (which are marked as CA).
- 0: we only accept non-CA certificates. This is currently not
- used, but the possibility is present for future extensions.
- 1: we only accept CA certificates. This is currently used for
- all certificates in the chain except the leaf certificate.
- */
- must_be_ca = -1;
-
- /* CRL path validation */
- if (ctx->parent)
- {
- allow_proxy_certs = 0;
- purpose = X509_PURPOSE_CRL_SIGN;
- }
- else
- {
- allow_proxy_certs =
- !!(ctx->param->flags & X509_V_FLAG_ALLOW_PROXY_CERTS);
- /* A hack to keep people who don't want to modify their
- software happy */
- if (getenv("OPENSSL_ALLOW_PROXY_CERTS"))
- allow_proxy_certs = 1;
- purpose = ctx->param->purpose;
- }
-
- /* Check all untrusted certificates */
- for (i = 0; i < ctx->last_untrusted; i++)
- {
- int ret;
- x = sk_X509_value(ctx->chain, i);
- if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
- && (x->ex_flags & EXFLAG_CRITICAL))
- {
- ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION;
- ctx->error_depth = i;
- ctx->current_cert = x;
- ok=cb(0,ctx);
- if (!ok) goto end;
- }
- if (!allow_proxy_certs && (x->ex_flags & EXFLAG_PROXY))
- {
- ctx->error = X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED;
- ctx->error_depth = i;
- ctx->current_cert = x;
- ok=cb(0,ctx);
- if (!ok) goto end;
- }
- ret = X509_check_ca(x);
- switch(must_be_ca)
- {
- case -1:
- if ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
- && (ret != 1) && (ret != 0))
- {
- ret = 0;
- ctx->error = X509_V_ERR_INVALID_CA;
- }
- else
- ret = 1;
- break;
- case 0:
- if (ret != 0)
- {
- ret = 0;
- ctx->error = X509_V_ERR_INVALID_NON_CA;
- }
- else
- ret = 1;
- break;
- default:
- if ((ret == 0)
- || ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
- && (ret != 1)))
- {
- ret = 0;
- ctx->error = X509_V_ERR_INVALID_CA;
- }
- else
- ret = 1;
- break;
- }
- if (ret == 0)
- {
- ctx->error_depth = i;
- ctx->current_cert = x;
- ok=cb(0,ctx);
- if (!ok) goto end;
- }
- if (ctx->param->purpose > 0)
- {
- ret = X509_check_purpose(x, purpose, must_be_ca > 0);
- if ((ret == 0)
- || ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
- && (ret != 1)))
- {
- ctx->error = X509_V_ERR_INVALID_PURPOSE;
- ctx->error_depth = i;
- ctx->current_cert = x;
- ok=cb(0,ctx);
- if (!ok) goto end;
- }
- }
- /* Check pathlen if not self issued */
- if ((i > 1) && !(x->ex_flags & EXFLAG_SI)
- && (x->ex_pathlen != -1)
- && (plen > (x->ex_pathlen + proxy_path_length + 1)))
- {
- ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED;
- ctx->error_depth = i;
- ctx->current_cert = x;
- ok=cb(0,ctx);
- if (!ok) goto end;
- }
- /* Increment path length if not self issued */
- if (!(x->ex_flags & EXFLAG_SI))
- plen++;
- /* If this certificate is a proxy certificate, the next
- certificate must be another proxy certificate or a EE
- certificate. If not, the next certificate must be a
- CA certificate. */
- if (x->ex_flags & EXFLAG_PROXY)
- {
- if (x->ex_pcpathlen != -1 && i > x->ex_pcpathlen)
- {
- ctx->error =
- X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED;
- ctx->error_depth = i;
- ctx->current_cert = x;
- ok=cb(0,ctx);
- if (!ok) goto end;
- }
- proxy_path_length++;
- must_be_ca = 0;
- }
- else
- must_be_ca = 1;
- }
- ok = 1;
+ int i, ok = 0, must_be_ca, plen = 0;
+ X509 *x;
+ int (*cb) (int xok, X509_STORE_CTX *xctx);
+ int proxy_path_length = 0;
+ int purpose;
+ int allow_proxy_certs;
+ cb = ctx->verify_cb;
+
+ /*
+ * must_be_ca can have 1 of 3 values: -1: we accept both CA and non-CA
+ * certificates, to allow direct use of self-signed certificates (which
+ * are marked as CA). 0: we only accept non-CA certificates. This is
+ * currently not used, but the possibility is present for future
+ * extensions. 1: we only accept CA certificates. This is currently used
+ * for all certificates in the chain except the leaf certificate.
+ */
+ must_be_ca = -1;
+
+ /* CRL path validation */
+ if (ctx->parent) {
+ allow_proxy_certs = 0;
+ purpose = X509_PURPOSE_CRL_SIGN;
+ } else {
+ allow_proxy_certs =
+ ! !(ctx->param->flags & X509_V_FLAG_ALLOW_PROXY_CERTS);
+ /*
+ * A hack to keep people who don't want to modify their software
+ * happy
+ */
+ if (getenv("OPENSSL_ALLOW_PROXY_CERTS"))
+ allow_proxy_certs = 1;
+ purpose = ctx->param->purpose;
+ }
+
+ /* Check all untrusted certificates */
+ for (i = 0; i < ctx->last_untrusted; i++) {
+ int ret;
+ x = sk_X509_value(ctx->chain, i);
+ if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
+ && (x->ex_flags & EXFLAG_CRITICAL)) {
+ ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION;
+ ctx->error_depth = i;
+ ctx->current_cert = x;
+ ok = cb(0, ctx);
+ if (!ok)
+ goto end;
+ }
+ if (!allow_proxy_certs && (x->ex_flags & EXFLAG_PROXY)) {
+ ctx->error = X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED;
+ ctx->error_depth = i;
+ ctx->current_cert = x;
+ ok = cb(0, ctx);
+ if (!ok)
+ goto end;
+ }
+ ret = X509_check_ca(x);
+ switch (must_be_ca) {
+ case -1:
+ if ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
+ && (ret != 1) && (ret != 0)) {
+ ret = 0;
+ ctx->error = X509_V_ERR_INVALID_CA;
+ } else
+ ret = 1;
+ break;
+ case 0:
+ if (ret != 0) {
+ ret = 0;
+ ctx->error = X509_V_ERR_INVALID_NON_CA;
+ } else
+ ret = 1;
+ break;
+ default:
+ if ((ret == 0)
+ || ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
+ && (ret != 1))) {
+ ret = 0;
+ ctx->error = X509_V_ERR_INVALID_CA;
+ } else
+ ret = 1;
+ break;
+ }
+ if (ret == 0) {
+ ctx->error_depth = i;
+ ctx->current_cert = x;
+ ok = cb(0, ctx);
+ if (!ok)
+ goto end;
+ }
+ if (ctx->param->purpose > 0) {
+ ret = X509_check_purpose(x, purpose, must_be_ca > 0);
+ if ((ret == 0)
+ || ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
+ && (ret != 1))) {
+ ctx->error = X509_V_ERR_INVALID_PURPOSE;
+ ctx->error_depth = i;
+ ctx->current_cert = x;
+ ok = cb(0, ctx);
+ if (!ok)
+ goto end;
+ }
+ }
+ /* Check pathlen if not self issued */
+ if ((i > 1) && !(x->ex_flags & EXFLAG_SI)
+ && (x->ex_pathlen != -1)
+ && (plen > (x->ex_pathlen + proxy_path_length + 1))) {
+ ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED;
+ ctx->error_depth = i;
+ ctx->current_cert = x;
+ ok = cb(0, ctx);
+ if (!ok)
+ goto end;
+ }
+ /* Increment path length if not self issued */
+ if (!(x->ex_flags & EXFLAG_SI))
+ plen++;
+ /*
+ * If this certificate is a proxy certificate, the next certificate
+ * must be another proxy certificate or a EE certificate. If not,
+ * the next certificate must be a CA certificate.
+ */
+ if (x->ex_flags & EXFLAG_PROXY) {
+ if (x->ex_pcpathlen != -1 && i > x->ex_pcpathlen) {
+ ctx->error = X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED;
+ ctx->error_depth = i;
+ ctx->current_cert = x;
+ ok = cb(0, ctx);
+ if (!ok)
+ goto end;
+ }
+ proxy_path_length++;
+ must_be_ca = 0;
+ } else
+ must_be_ca = 1;
+ }
+ ok = 1;
end:
- return ok;
+ return ok;
}
static int check_name_constraints(X509_STORE_CTX *ctx)
- {
- X509 *x;
- int i, j, rv;
- /* Check name constraints for all certificates */
- for (i = sk_X509_num(ctx->chain) - 1; i >= 0; i--)
- {
- x = sk_X509_value(ctx->chain, i);
- /* Ignore self issued certs unless last in chain */
- if (i && (x->ex_flags & EXFLAG_SI))
- continue;
- /* Check against constraints for all certificates higher in
- * chain including trust anchor. Trust anchor not strictly
- * speaking needed but if it includes constraints it is to be
- * assumed it expects them to be obeyed.
- */
- for (j = sk_X509_num(ctx->chain) - 1; j > i; j--)
- {
- NAME_CONSTRAINTS *nc = sk_X509_value(ctx->chain, j)->nc;
- if (nc)
- {
- rv = NAME_CONSTRAINTS_check(x, nc);
- if (rv != X509_V_OK)
- {
- ctx->error = rv;
- ctx->error_depth = i;
- ctx->current_cert = x;
- if (!ctx->verify_cb(0,ctx))
- return 0;
- }
- }
- }
- }
- return 1;
- }
+{
+ X509 *x;
+ int i, j, rv;
+ /* Check name constraints for all certificates */
+ for (i = sk_X509_num(ctx->chain) - 1; i >= 0; i--) {
+ x = sk_X509_value(ctx->chain, i);
+ /* Ignore self issued certs unless last in chain */
+ if (i && (x->ex_flags & EXFLAG_SI))
+ continue;
+ /*
+ * Check against constraints for all certificates higher in chain
+ * including trust anchor. Trust anchor not strictly speaking needed
+ * but if it includes constraints it is to be assumed it expects them
+ * to be obeyed.
+ */
+ for (j = sk_X509_num(ctx->chain) - 1; j > i; j--) {
+ NAME_CONSTRAINTS *nc = sk_X509_value(ctx->chain, j)->nc;
+ if (nc) {
+ rv = NAME_CONSTRAINTS_check(x, nc);
+ if (rv != X509_V_OK) {
+ ctx->error = rv;
+ ctx->error_depth = i;
+ ctx->current_cert = x;
+ if (!ctx->verify_cb(0, ctx))
+ return 0;
+ }
+ }
+ }
+ }
+ return 1;
+}
static int check_id_error(X509_STORE_CTX *ctx, int errcode)
- {
- ctx->error = errcode;
- ctx->current_cert = ctx->cert;
- ctx->error_depth = 0;
- return ctx->verify_cb(0, ctx);
- }
+{
+ ctx->error = errcode;
+ ctx->current_cert = ctx->cert;
+ ctx->error_depth = 0;
+ return ctx->verify_cb(0, ctx);
+}
static int check_hosts(X509 *x, X509_VERIFY_PARAM_ID *id)
- {
- size_t i;
- size_t n = sk_OPENSSL_STRING_num(id->hosts);
- char *name;
-
- for (i = 0; i < n; ++i)
- {
- name = sk_OPENSSL_STRING_value(id->hosts, i);
- if (X509_check_host(x, name, strlen(name), id->hostflags,
- &id->peername) > 0)
- return 1;
- }
- return n == 0;
- }
+{
+ size_t i;
+ size_t n = sk_OPENSSL_STRING_num(id->hosts);
+ char *name;
+
+ if (id->peername != NULL) {
+ OPENSSL_free(id->peername);
+ id->peername = NULL;
+ }
+ for (i = 0; i < n; ++i) {
+ name = sk_OPENSSL_STRING_value(id->hosts, i);
+ if (X509_check_host(x, name, strlen(name), id->hostflags,
+ &id->peername) > 0)
+ return 1;
+ }
+ return n == 0;
+}
static int check_id(X509_STORE_CTX *ctx)
- {
- X509_VERIFY_PARAM *vpm = ctx->param;
- X509_VERIFY_PARAM_ID *id = vpm->id;
- X509 *x = ctx->cert;
- if (id->hosts && check_hosts(x, id) <= 0)
- {
- if (!check_id_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH))
- return 0;
- }
- if (id->email && X509_check_email(x, id->email, id->emaillen, 0) <= 0)
- {
- if (!check_id_error(ctx, X509_V_ERR_EMAIL_MISMATCH))
- return 0;
- }
- if (id->ip && X509_check_ip(x, id->ip, id->iplen, 0) <= 0)
- {
- if (!check_id_error(ctx, X509_V_ERR_IP_ADDRESS_MISMATCH))
- return 0;
- }
- return 1;
- }
+{
+ X509_VERIFY_PARAM *vpm = ctx->param;
+ X509_VERIFY_PARAM_ID *id = vpm->id;
+ X509 *x = ctx->cert;
+ if (id->hosts && check_hosts(x, id) <= 0) {
+ if (!check_id_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH))
+ return 0;
+ }
+ if (id->email && X509_check_email(x, id->email, id->emaillen, 0) <= 0) {
+ if (!check_id_error(ctx, X509_V_ERR_EMAIL_MISMATCH))
+ return 0;
+ }
+ if (id->ip && X509_check_ip(x, id->ip, id->iplen, 0) <= 0) {
+ if (!check_id_error(ctx, X509_V_ERR_IP_ADDRESS_MISMATCH))
+ return 0;
+ }
+ return 1;
+}
static int check_trust(X509_STORE_CTX *ctx)
{
- size_t i;
- int ok;
- X509 *x = NULL;
- int (*cb)(int xok,X509_STORE_CTX *xctx);
- cb=ctx->verify_cb;
- /* Check all trusted certificates in chain */
- for (i = ctx->last_untrusted; i < sk_X509_num(ctx->chain); i++)
- {
- x = sk_X509_value(ctx->chain, i);
- ok = X509_check_trust(x, ctx->param->trust, 0);
- /* If explicitly trusted return trusted */
- if (ok == X509_TRUST_TRUSTED)
- return X509_TRUST_TRUSTED;
- /* If explicitly rejected notify callback and reject if
- * not overridden.
- */
- if (ok == X509_TRUST_REJECTED)
- {
- ctx->error_depth = i;
- ctx->current_cert = x;
- ctx->error = X509_V_ERR_CERT_REJECTED;
- ok = cb(0, ctx);
- if (!ok)
- return X509_TRUST_REJECTED;
- }
- }
- /* If we accept partial chains and have at least one trusted
- * certificate return success.
- */
- if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN)
- {
- X509 *mx;
- if (ctx->last_untrusted < (int) sk_X509_num(ctx->chain))
- return X509_TRUST_TRUSTED;
- x = sk_X509_value(ctx->chain, 0);
- mx = lookup_cert_match(ctx, x);
- if (mx)
- {
- (void)sk_X509_set(ctx->chain, 0, mx);
- X509_free(x);
- ctx->last_untrusted = 0;
- return X509_TRUST_TRUSTED;
- }
- }
-
- /* If no trusted certs in chain at all return untrusted and
- * allow standard (no issuer cert) etc errors to be indicated.
- */
- return X509_TRUST_UNTRUSTED;
+ size_t i;
+ int ok;
+ X509 *x = NULL;
+ int (*cb) (int xok, X509_STORE_CTX *xctx);
+ cb = ctx->verify_cb;
+ /* Check all trusted certificates in chain */
+ for (i = ctx->last_untrusted; i < sk_X509_num(ctx->chain); i++) {
+ x = sk_X509_value(ctx->chain, i);
+ ok = X509_check_trust(x, ctx->param->trust, 0);
+ /* If explicitly trusted return trusted */
+ if (ok == X509_TRUST_TRUSTED)
+ return X509_TRUST_TRUSTED;
+ /*
+ * If explicitly rejected notify callback and reject if not
+ * overridden.
+ */
+ if (ok == X509_TRUST_REJECTED) {
+ ctx->error_depth = i;
+ ctx->current_cert = x;
+ ctx->error = X509_V_ERR_CERT_REJECTED;
+ ok = cb(0, ctx);
+ if (!ok)
+ return X509_TRUST_REJECTED;
+ }
+ }
+ /*
+ * If we accept partial chains and have at least one trusted certificate
+ * return success.
+ */
+ if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) {
+ X509 *mx;
+ if (ctx->last_untrusted < (int)sk_X509_num(ctx->chain))
+ return X509_TRUST_TRUSTED;
+ x = sk_X509_value(ctx->chain, 0);
+ mx = lookup_cert_match(ctx, x);
+ if (mx) {
+ (void)sk_X509_set(ctx->chain, 0, mx);
+ X509_free(x);
+ ctx->last_untrusted = 0;
+ return X509_TRUST_TRUSTED;
+ }
+ }
+
+ /*
+ * If no trusted certs in chain at all return untrusted and allow
+ * standard (no issuer cert) etc errors to be indicated.
+ */
+ return X509_TRUST_UNTRUSTED;
}
static int check_revocation(X509_STORE_CTX *ctx)
- {
- int i, last, ok;
- if (!(ctx->param->flags & X509_V_FLAG_CRL_CHECK))
- return 1;
- if (ctx->param->flags & X509_V_FLAG_CRL_CHECK_ALL)
- last = sk_X509_num(ctx->chain) - 1;
- else
- {
- /* If checking CRL paths this isn't the EE certificate */
- if (ctx->parent)
- return 1;
- last = 0;
- }
- for(i = 0; i <= last; i++)
- {
- ctx->error_depth = i;
- ok = check_cert(ctx);
- if (!ok) return ok;
- }
- return 1;
- }
+{
+ int i, last, ok;
+ if (!(ctx->param->flags & X509_V_FLAG_CRL_CHECK))
+ return 1;
+ if (ctx->param->flags & X509_V_FLAG_CRL_CHECK_ALL)
+ last = sk_X509_num(ctx->chain) - 1;
+ else {
+ /* If checking CRL paths this isn't the EE certificate */
+ if (ctx->parent)
+ return 1;
+ last = 0;
+ }
+ for (i = 0; i <= last; i++) {
+ ctx->error_depth = i;
+ ok = check_cert(ctx);
+ if (!ok)
+ return ok;
+ }
+ return 1;
+}
static int check_cert(X509_STORE_CTX *ctx)
- OPENSSL_SUPPRESS_POTENTIALLY_UNINITIALIZED_WARNINGS
- {
- X509_CRL *crl = NULL, *dcrl = NULL;
- X509 *x;
- int ok, cnum;
- unsigned int last_reasons;
- cnum = ctx->error_depth;
- x = sk_X509_value(ctx->chain, cnum);
- ctx->current_cert = x;
- ctx->current_issuer = NULL;
- ctx->current_crl_score = 0;
- ctx->current_reasons = 0;
- while (ctx->current_reasons != CRLDP_ALL_REASONS)
- {
- last_reasons = ctx->current_reasons;
- /* Try to retrieve relevant CRL */
- if (ctx->get_crl)
- ok = ctx->get_crl(ctx, &crl, x);
- else
- ok = get_crl_delta(ctx, &crl, &dcrl, x);
- /* If error looking up CRL, nothing we can do except
- * notify callback
- */
- if(!ok)
- {
- ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL;
- ok = ctx->verify_cb(0, ctx);
- goto err;
- }
- ctx->current_crl = crl;
- ok = ctx->check_crl(ctx, crl);
- if (!ok)
- goto err;
-
- if (dcrl)
- {
- ok = ctx->check_crl(ctx, dcrl);
- if (!ok)
- goto err;
- ok = ctx->cert_crl(ctx, dcrl, x);
- if (!ok)
- goto err;
- }
- else
- ok = 1;
-
- /* Don't look in full CRL if delta reason is removefromCRL */
- if (ok != 2)
- {
- ok = ctx->cert_crl(ctx, crl, x);
- if (!ok)
- goto err;
- }
-
- X509_CRL_free(crl);
- X509_CRL_free(dcrl);
- crl = NULL;
- dcrl = NULL;
- /* If reasons not updated we wont get anywhere by
- * another iteration, so exit loop.
- */
- if (last_reasons == ctx->current_reasons)
- {
- ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL;
- ok = ctx->verify_cb(0, ctx);
- goto err;
- }
- }
- err:
- X509_CRL_free(crl);
- X509_CRL_free(dcrl);
-
- ctx->current_crl = NULL;
- return ok;
-
- }
+{
+ X509_CRL *crl = NULL, *dcrl = NULL;
+ X509 *x;
+ int ok = 0, cnum;
+ unsigned int last_reasons;
+ cnum = ctx->error_depth;
+ x = sk_X509_value(ctx->chain, cnum);
+ ctx->current_cert = x;
+ ctx->current_issuer = NULL;
+ ctx->current_crl_score = 0;
+ ctx->current_reasons = 0;
+ while (ctx->current_reasons != CRLDP_ALL_REASONS) {
+ last_reasons = ctx->current_reasons;
+ /* Try to retrieve relevant CRL */
+ if (ctx->get_crl)
+ ok = ctx->get_crl(ctx, &crl, x);
+ else
+ ok = get_crl_delta(ctx, &crl, &dcrl, x);
+ /*
+ * If error looking up CRL, nothing we can do except notify callback
+ */
+ if (!ok) {
+ ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL;
+ ok = ctx->verify_cb(0, ctx);
+ goto err;
+ }
+ ctx->current_crl = crl;
+ ok = ctx->check_crl(ctx, crl);
+ if (!ok)
+ goto err;
+
+ if (dcrl) {
+ ok = ctx->check_crl(ctx, dcrl);
+ if (!ok)
+ goto err;
+ ok = ctx->cert_crl(ctx, dcrl, x);
+ if (!ok)
+ goto err;
+ } else
+ ok = 1;
+
+ /* Don't look in full CRL if delta reason is removefromCRL */
+ if (ok != 2) {
+ ok = ctx->cert_crl(ctx, crl, x);
+ if (!ok)
+ goto err;
+ }
+
+ X509_CRL_free(crl);
+ X509_CRL_free(dcrl);
+ crl = NULL;
+ dcrl = NULL;
+ /*
+ * If reasons not updated we wont get anywhere by another iteration,
+ * so exit loop.
+ */
+ if (last_reasons == ctx->current_reasons) {
+ ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL;
+ ok = ctx->verify_cb(0, ctx);
+ goto err;
+ }
+ }
+ err:
+ X509_CRL_free(crl);
+ X509_CRL_free(dcrl);
+
+ ctx->current_crl = NULL;
+ return ok;
+
+}
/* Check CRL times against values in X509_STORE_CTX */
static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify)
- {
- time_t *ptime;
- int i;
- if (notify)
- ctx->current_crl = crl;
- if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
- ptime = &ctx->param->check_time;
- else
- ptime = NULL;
-
- i=X509_cmp_time(X509_CRL_get_lastUpdate(crl), ptime);
- if (i == 0)
- {
- if (!notify)
- return 0;
- ctx->error=X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD;
- if (!ctx->verify_cb(0, ctx))
- return 0;
- }
-
- if (i > 0)
- {
- if (!notify)
- return 0;
- ctx->error=X509_V_ERR_CRL_NOT_YET_VALID;
- if (!ctx->verify_cb(0, ctx))
- return 0;
- }
-
- if(X509_CRL_get_nextUpdate(crl))
- {
- i=X509_cmp_time(X509_CRL_get_nextUpdate(crl), ptime);
-
- if (i == 0)
- {
- if (!notify)
- return 0;
- ctx->error=X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD;
- if (!ctx->verify_cb(0, ctx))
- return 0;
- }
- /* Ignore expiry of base CRL is delta is valid */
- if ((i < 0) && !(ctx->current_crl_score & CRL_SCORE_TIME_DELTA))
- {
- if (!notify)
- return 0;
- ctx->error=X509_V_ERR_CRL_HAS_EXPIRED;
- if (!ctx->verify_cb(0, ctx))
- return 0;
- }
- }
-
- if (notify)
- ctx->current_crl = NULL;
-
- return 1;
- }
+{
+ time_t *ptime;
+ int i;
+ if (notify)
+ ctx->current_crl = crl;
+ if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
+ ptime = &ctx->param->check_time;
+ else
+ ptime = NULL;
+
+ i = X509_cmp_time(X509_CRL_get_lastUpdate(crl), ptime);
+ if (i == 0) {
+ if (!notify)
+ return 0;
+ ctx->error = X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD;
+ if (!ctx->verify_cb(0, ctx))
+ return 0;
+ }
+
+ if (i > 0) {
+ if (!notify)
+ return 0;
+ ctx->error = X509_V_ERR_CRL_NOT_YET_VALID;
+ if (!ctx->verify_cb(0, ctx))
+ return 0;
+ }
+
+ if (X509_CRL_get_nextUpdate(crl)) {
+ i = X509_cmp_time(X509_CRL_get_nextUpdate(crl), ptime);
+
+ if (i == 0) {
+ if (!notify)
+ return 0;
+ ctx->error = X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD;
+ if (!ctx->verify_cb(0, ctx))
+ return 0;
+ }
+ /* Ignore expiry of base CRL is delta is valid */
+ if ((i < 0) && !(ctx->current_crl_score & CRL_SCORE_TIME_DELTA)) {
+ if (!notify)
+ return 0;
+ ctx->error = X509_V_ERR_CRL_HAS_EXPIRED;
+ if (!ctx->verify_cb(0, ctx))
+ return 0;
+ }
+ }
+
+ if (notify)
+ ctx->current_crl = NULL;
+
+ return 1;
+}
static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl,
- X509 **pissuer, int *pscore, unsigned int *preasons,
- STACK_OF(X509_CRL) *crls)
- {
- int crl_score, best_score = *pscore;
- size_t i;
- unsigned int reasons, best_reasons = 0;
- X509 *x = ctx->current_cert;
- X509_CRL *crl, *best_crl = NULL;
- X509 *crl_issuer = NULL, *best_crl_issuer = NULL;
-
- for (i = 0; i < sk_X509_CRL_num(crls); i++)
- {
- crl = sk_X509_CRL_value(crls, i);
- reasons = *preasons;
- crl_score = get_crl_score(ctx, &crl_issuer, &reasons, crl, x);
-
- if (crl_score > best_score)
- {
- best_crl = crl;
- best_crl_issuer = crl_issuer;
- best_score = crl_score;
- best_reasons = reasons;
- }
- }
-
- if (best_crl)
- {
- if (*pcrl)
- X509_CRL_free(*pcrl);
- *pcrl = best_crl;
- *pissuer = best_crl_issuer;
- *pscore = best_score;
- *preasons = best_reasons;
- X509_CRL_up_ref(best_crl);
- if (*pdcrl)
- {
- X509_CRL_free(*pdcrl);
- *pdcrl = NULL;
- }
- get_delta_sk(ctx, pdcrl, pscore, best_crl, crls);
- }
-
- if (best_score >= CRL_SCORE_VALID)
- return 1;
-
- return 0;
- }
-
-/* Compare two CRL extensions for delta checking purposes. They should be
+ X509 **pissuer, int *pscore, unsigned int *preasons,
+ STACK_OF(X509_CRL) *crls)
+{
+ int crl_score, best_score = *pscore;
+ size_t i;
+ unsigned int reasons, best_reasons = 0;
+ X509 *x = ctx->current_cert;
+ X509_CRL *crl, *best_crl = NULL;
+ X509 *crl_issuer = NULL, *best_crl_issuer = NULL;
+
+ for (i = 0; i < sk_X509_CRL_num(crls); i++) {
+ crl = sk_X509_CRL_value(crls, i);
+ reasons = *preasons;
+ crl_score = get_crl_score(ctx, &crl_issuer, &reasons, crl, x);
+
+ if (crl_score > best_score) {
+ best_crl = crl;
+ best_crl_issuer = crl_issuer;
+ best_score = crl_score;
+ best_reasons = reasons;
+ }
+ }
+
+ if (best_crl) {
+ if (*pcrl)
+ X509_CRL_free(*pcrl);
+ *pcrl = best_crl;
+ *pissuer = best_crl_issuer;
+ *pscore = best_score;
+ *preasons = best_reasons;
+ X509_CRL_up_ref(best_crl);
+ if (*pdcrl) {
+ X509_CRL_free(*pdcrl);
+ *pdcrl = NULL;
+ }
+ get_delta_sk(ctx, pdcrl, pscore, best_crl, crls);
+ }
+
+ if (best_score >= CRL_SCORE_VALID)
+ return 1;
+
+ return 0;
+}
+
+/*
+ * Compare two CRL extensions for delta checking purposes. They should be
* both present or both absent. If both present all fields must be identical.
*/
static int crl_extension_match(X509_CRL *a, X509_CRL *b, int nid)
- {
- ASN1_OCTET_STRING *exta, *extb;
- int i;
- i = X509_CRL_get_ext_by_NID(a, nid, -1);
- if (i >= 0)
- {
- /* Can't have multiple occurrences */
- if (X509_CRL_get_ext_by_NID(a, nid, i) != -1)
- return 0;
- exta = X509_EXTENSION_get_data(X509_CRL_get_ext(a, i));
- }
- else
- exta = NULL;
-
- i = X509_CRL_get_ext_by_NID(b, nid, -1);
+{
+ ASN1_OCTET_STRING *exta, *extb;
+ int i;
+ i = X509_CRL_get_ext_by_NID(a, nid, -1);
+ if (i >= 0) {
+ /* Can't have multiple occurrences */
+ if (X509_CRL_get_ext_by_NID(a, nid, i) != -1)
+ return 0;
+ exta = X509_EXTENSION_get_data(X509_CRL_get_ext(a, i));
+ } else
+ exta = NULL;
- if (i >= 0)
- {
+ i = X509_CRL_get_ext_by_NID(b, nid, -1);
- if (X509_CRL_get_ext_by_NID(b, nid, i) != -1)
- return 0;
- extb = X509_EXTENSION_get_data(X509_CRL_get_ext(b, i));
- }
- else
- extb = NULL;
+ if (i >= 0) {
- if (!exta && !extb)
- return 1;
+ if (X509_CRL_get_ext_by_NID(b, nid, i) != -1)
+ return 0;
+ extb = X509_EXTENSION_get_data(X509_CRL_get_ext(b, i));
+ } else
+ extb = NULL;
- if (!exta || !extb)
- return 0;
+ if (!exta && !extb)
+ return 1;
+ if (!exta || !extb)
+ return 0;
- if (ASN1_OCTET_STRING_cmp(exta, extb))
- return 0;
+ if (ASN1_OCTET_STRING_cmp(exta, extb))
+ return 0;
- return 1;
- }
+ return 1;
+}
/* See if a base and delta are compatible */
static int check_delta_base(X509_CRL *delta, X509_CRL *base)
- {
- /* Delta CRL must be a delta */
- if (!delta->base_crl_number)
- return 0;
- /* Base must have a CRL number */
- if (!base->crl_number)
- return 0;
- /* Issuer names must match */
- if (X509_NAME_cmp(X509_CRL_get_issuer(base),
- X509_CRL_get_issuer(delta)))
- return 0;
- /* AKID and IDP must match */
- if (!crl_extension_match(delta, base, NID_authority_key_identifier))
- return 0;
- if (!crl_extension_match(delta, base, NID_issuing_distribution_point))
- return 0;
- /* Delta CRL base number must not exceed Full CRL number. */
- if (ASN1_INTEGER_cmp(delta->base_crl_number, base->crl_number) > 0)
- return 0;
- /* Delta CRL number must exceed full CRL number */
- if (ASN1_INTEGER_cmp(delta->crl_number, base->crl_number) > 0)
- return 1;
- return 0;
- }
-
-/* For a given base CRL find a delta... maybe extend to delta scoring
- * or retrieve a chain of deltas...
+{
+ /* Delta CRL must be a delta */
+ if (!delta->base_crl_number)
+ return 0;
+ /* Base must have a CRL number */
+ if (!base->crl_number)
+ return 0;
+ /* Issuer names must match */
+ if (X509_NAME_cmp(X509_CRL_get_issuer(base), X509_CRL_get_issuer(delta)))
+ return 0;
+ /* AKID and IDP must match */
+ if (!crl_extension_match(delta, base, NID_authority_key_identifier))
+ return 0;
+ if (!crl_extension_match(delta, base, NID_issuing_distribution_point))
+ return 0;
+ /* Delta CRL base number must not exceed Full CRL number. */
+ if (ASN1_INTEGER_cmp(delta->base_crl_number, base->crl_number) > 0)
+ return 0;
+ /* Delta CRL number must exceed full CRL number */
+ if (ASN1_INTEGER_cmp(delta->crl_number, base->crl_number) > 0)
+ return 1;
+ return 0;
+}
+
+/*
+ * For a given base CRL find a delta... maybe extend to delta scoring or
+ * retrieve a chain of deltas...
*/
static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pscore,
- X509_CRL *base, STACK_OF(X509_CRL) *crls)
- {
- X509_CRL *delta;
- size_t i;
- if (!(ctx->param->flags & X509_V_FLAG_USE_DELTAS))
- return;
- if (!((ctx->current_cert->ex_flags | base->flags) & EXFLAG_FRESHEST))
- return;
- for (i = 0; i < sk_X509_CRL_num(crls); i++)
- {
- delta = sk_X509_CRL_value(crls, i);
- if (check_delta_base(delta, base))
- {
- if (check_crl_time(ctx, delta, 0))
- *pscore |= CRL_SCORE_TIME_DELTA;
- X509_CRL_up_ref(delta);
- *dcrl = delta;
- return;
- }
- }
- *dcrl = NULL;
- }
-
-/* For a given CRL return how suitable it is for the supplied certificate 'x'.
- * The return value is a mask of several criteria.
- * If the issuer is not the certificate issuer this is returned in *pissuer.
- * The reasons mask is also used to determine if the CRL is suitable: if
- * no new reasons the CRL is rejected, otherwise reasons is updated.
+ X509_CRL *base, STACK_OF(X509_CRL) *crls)
+{
+ X509_CRL *delta;
+ size_t i;
+ if (!(ctx->param->flags & X509_V_FLAG_USE_DELTAS))
+ return;
+ if (!((ctx->current_cert->ex_flags | base->flags) & EXFLAG_FRESHEST))
+ return;
+ for (i = 0; i < sk_X509_CRL_num(crls); i++) {
+ delta = sk_X509_CRL_value(crls, i);
+ if (check_delta_base(delta, base)) {
+ if (check_crl_time(ctx, delta, 0))
+ *pscore |= CRL_SCORE_TIME_DELTA;
+ X509_CRL_up_ref(delta);
+ *dcrl = delta;
+ return;
+ }
+ }
+ *dcrl = NULL;
+}
+
+/*
+ * For a given CRL return how suitable it is for the supplied certificate
+ * 'x'. The return value is a mask of several criteria. If the issuer is not
+ * the certificate issuer this is returned in *pissuer. The reasons mask is
+ * also used to determine if the CRL is suitable: if no new reasons the CRL
+ * is rejected, otherwise reasons is updated.
*/
static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer,
- unsigned int *preasons,
- X509_CRL *crl, X509 *x)
- {
-
- int crl_score = 0;
- unsigned int tmp_reasons = *preasons, crl_reasons;
-
- /* First see if we can reject CRL straight away */
-
- /* Invalid IDP cannot be processed */
- if (crl->idp_flags & IDP_INVALID)
- return 0;
- /* Reason codes or indirect CRLs need extended CRL support */
- if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT))
- {
- if (crl->idp_flags & (IDP_INDIRECT | IDP_REASONS))
- return 0;
- }
- else if (crl->idp_flags & IDP_REASONS)
- {
- /* If no new reasons reject */
- if (!(crl->idp_reasons & ~tmp_reasons))
- return 0;
- }
- /* Don't process deltas at this stage */
- else if (crl->base_crl_number)
- return 0;
- /* If issuer name doesn't match certificate need indirect CRL */
- if (X509_NAME_cmp(X509_get_issuer_name(x), X509_CRL_get_issuer(crl)))
- {
- if (!(crl->idp_flags & IDP_INDIRECT))
- return 0;
- }
- else
- crl_score |= CRL_SCORE_ISSUER_NAME;
-
- if (!(crl->flags & EXFLAG_CRITICAL))
- crl_score |= CRL_SCORE_NOCRITICAL;
-
- /* Check expiry */
- if (check_crl_time(ctx, crl, 0))
- crl_score |= CRL_SCORE_TIME;
-
- /* Check authority key ID and locate certificate issuer */
- crl_akid_check(ctx, crl, pissuer, &crl_score);
-
- /* If we can't locate certificate issuer at this point forget it */
-
- if (!(crl_score & CRL_SCORE_AKID))
- return 0;
-
- /* Check cert for matching CRL distribution points */
-
- if (crl_crldp_check(x, crl, crl_score, &crl_reasons))
- {
- /* If no new reasons reject */
- if (!(crl_reasons & ~tmp_reasons))
- return 0;
- tmp_reasons |= crl_reasons;
- crl_score |= CRL_SCORE_SCOPE;
- }
-
- *preasons = tmp_reasons;
-
- return crl_score;
-
- }
+ unsigned int *preasons, X509_CRL *crl, X509 *x)
+{
+
+ int crl_score = 0;
+ unsigned int tmp_reasons = *preasons, crl_reasons;
+
+ /* First see if we can reject CRL straight away */
+
+ /* Invalid IDP cannot be processed */
+ if (crl->idp_flags & IDP_INVALID)
+ return 0;
+ /* Reason codes or indirect CRLs need extended CRL support */
+ if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT)) {
+ if (crl->idp_flags & (IDP_INDIRECT | IDP_REASONS))
+ return 0;
+ } else if (crl->idp_flags & IDP_REASONS) {
+ /* If no new reasons reject */
+ if (!(crl->idp_reasons & ~tmp_reasons))
+ return 0;
+ }
+ /* Don't process deltas at this stage */
+ else if (crl->base_crl_number)
+ return 0;
+ /* If issuer name doesn't match certificate need indirect CRL */
+ if (X509_NAME_cmp(X509_get_issuer_name(x), X509_CRL_get_issuer(crl))) {
+ if (!(crl->idp_flags & IDP_INDIRECT))
+ return 0;
+ } else
+ crl_score |= CRL_SCORE_ISSUER_NAME;
+
+ if (!(crl->flags & EXFLAG_CRITICAL))
+ crl_score |= CRL_SCORE_NOCRITICAL;
+
+ /* Check expiry */
+ if (check_crl_time(ctx, crl, 0))
+ crl_score |= CRL_SCORE_TIME;
+
+ /* Check authority key ID and locate certificate issuer */
+ crl_akid_check(ctx, crl, pissuer, &crl_score);
+
+ /* If we can't locate certificate issuer at this point forget it */
+
+ if (!(crl_score & CRL_SCORE_AKID))
+ return 0;
+
+ /* Check cert for matching CRL distribution points */
+
+ if (crl_crldp_check(x, crl, crl_score, &crl_reasons)) {
+ /* If no new reasons reject */
+ if (!(crl_reasons & ~tmp_reasons))
+ return 0;
+ tmp_reasons |= crl_reasons;
+ crl_score |= CRL_SCORE_SCOPE;
+ }
+
+ *preasons = tmp_reasons;
+
+ return crl_score;
+
+}
static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl,
- X509 **pissuer, int *pcrl_score)
- {
- X509 *crl_issuer = NULL;
- X509_NAME *cnm = X509_CRL_get_issuer(crl);
- int cidx = ctx->error_depth;
- size_t i;
-
- if ((size_t) cidx != sk_X509_num(ctx->chain) - 1)
- cidx++;
-
- crl_issuer = sk_X509_value(ctx->chain, cidx);
-
- if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK)
- {
- if (*pcrl_score & CRL_SCORE_ISSUER_NAME)
- {
- *pcrl_score |= CRL_SCORE_AKID|CRL_SCORE_ISSUER_CERT;
- *pissuer = crl_issuer;
- return;
- }
- }
-
- for (cidx++; cidx < (int) sk_X509_num(ctx->chain); cidx++)
- {
- crl_issuer = sk_X509_value(ctx->chain, cidx);
- if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm))
- continue;
- if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK)
- {
- *pcrl_score |= CRL_SCORE_AKID|CRL_SCORE_SAME_PATH;
- *pissuer = crl_issuer;
- return;
- }
- }
-
- /* Anything else needs extended CRL support */
-
- if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT))
- return;
-
- /* Otherwise the CRL issuer is not on the path. Look for it in the
- * set of untrusted certificates.
- */
- for (i = 0; i < sk_X509_num(ctx->untrusted); i++)
- {
- crl_issuer = sk_X509_value(ctx->untrusted, i);
- if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm))
- continue;
- if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK)
- {
- *pissuer = crl_issuer;
- *pcrl_score |= CRL_SCORE_AKID;
- return;
- }
- }
- }
-
-/* Check the path of a CRL issuer certificate. This creates a new
+ X509 **pissuer, int *pcrl_score)
+{
+ X509 *crl_issuer = NULL;
+ X509_NAME *cnm = X509_CRL_get_issuer(crl);
+ int cidx = ctx->error_depth;
+ size_t i;
+
+ if ((size_t)cidx != sk_X509_num(ctx->chain) - 1)
+ cidx++;
+
+ crl_issuer = sk_X509_value(ctx->chain, cidx);
+
+ if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) {
+ if (*pcrl_score & CRL_SCORE_ISSUER_NAME) {
+ *pcrl_score |= CRL_SCORE_AKID | CRL_SCORE_ISSUER_CERT;
+ *pissuer = crl_issuer;
+ return;
+ }
+ }
+
+ for (cidx++; cidx < (int)sk_X509_num(ctx->chain); cidx++) {
+ crl_issuer = sk_X509_value(ctx->chain, cidx);
+ if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm))
+ continue;
+ if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) {
+ *pcrl_score |= CRL_SCORE_AKID | CRL_SCORE_SAME_PATH;
+ *pissuer = crl_issuer;
+ return;
+ }
+ }
+
+ /* Anything else needs extended CRL support */
+
+ if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT))
+ return;
+
+ /*
+ * Otherwise the CRL issuer is not on the path. Look for it in the set of
+ * untrusted certificates.
+ */
+ for (i = 0; i < sk_X509_num(ctx->untrusted); i++) {
+ crl_issuer = sk_X509_value(ctx->untrusted, i);
+ if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm))
+ continue;
+ if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) {
+ *pissuer = crl_issuer;
+ *pcrl_score |= CRL_SCORE_AKID;
+ return;
+ }
+ }
+}
+
+/*
+ * Check the path of a CRL issuer certificate. This creates a new
* X509_STORE_CTX and populates it with most of the parameters from the
- * parent. This could be optimised somewhat since a lot of path checking
- * will be duplicated by the parent, but this will rarely be used in
- * practice.
+ * parent. This could be optimised somewhat since a lot of path checking will
+ * be duplicated by the parent, but this will rarely be used in practice.
*/
static int check_crl_path(X509_STORE_CTX *ctx, X509 *x)
- {
- X509_STORE_CTX crl_ctx;
- int ret;
- /* Don't allow recursive CRL path validation */
- if (ctx->parent)
- return 0;
- if (!X509_STORE_CTX_init(&crl_ctx, ctx->ctx, x, ctx->untrusted))
- return -1;
-
- crl_ctx.crls = ctx->crls;
- /* Copy verify params across */
- X509_STORE_CTX_set0_param(&crl_ctx, ctx->param);
-
- crl_ctx.parent = ctx;
- crl_ctx.verify_cb = ctx->verify_cb;
-
- /* Verify CRL issuer */
- ret = X509_verify_cert(&crl_ctx);
-
- if (ret <= 0)
- goto err;
-
- /* Check chain is acceptable */
-
- ret = check_crl_chain(ctx, ctx->chain, crl_ctx.chain);
- err:
- X509_STORE_CTX_cleanup(&crl_ctx);
- return ret;
- }
-
-/* RFC3280 says nothing about the relationship between CRL path
- * and certificate path, which could lead to situations where a
- * certificate could be revoked or validated by a CA not authorised
- * to do so. RFC5280 is more strict and states that the two paths must
- * end in the same trust anchor, though some discussions remain...
- * until this is resolved we use the RFC5280 version
+{
+ X509_STORE_CTX crl_ctx;
+ int ret;
+ /* Don't allow recursive CRL path validation */
+ if (ctx->parent)
+ return 0;
+ if (!X509_STORE_CTX_init(&crl_ctx, ctx->ctx, x, ctx->untrusted))
+ return -1;
+
+ crl_ctx.crls = ctx->crls;
+ /* Copy verify params across */
+ X509_STORE_CTX_set0_param(&crl_ctx, ctx->param);
+
+ crl_ctx.parent = ctx;
+ crl_ctx.verify_cb = ctx->verify_cb;
+
+ /* Verify CRL issuer */
+ ret = X509_verify_cert(&crl_ctx);
+
+ if (ret <= 0)
+ goto err;
+
+ /* Check chain is acceptable */
+
+ ret = check_crl_chain(ctx, ctx->chain, crl_ctx.chain);
+ err:
+ X509_STORE_CTX_cleanup(&crl_ctx);
+ return ret;
+}
+
+/*
+ * RFC3280 says nothing about the relationship between CRL path and
+ * certificate path, which could lead to situations where a certificate could
+ * be revoked or validated by a CA not authorised to do so. RFC5280 is more
+ * strict and states that the two paths must end in the same trust anchor,
+ * though some discussions remain... until this is resolved we use the
+ * RFC5280 version
*/
static int check_crl_chain(X509_STORE_CTX *ctx,
- STACK_OF(X509) *cert_path,
- STACK_OF(X509) *crl_path)
- {
- X509 *cert_ta, *crl_ta;
- cert_ta = sk_X509_value(cert_path, sk_X509_num(cert_path) - 1);
- crl_ta = sk_X509_value(crl_path, sk_X509_num(crl_path) - 1);
- if (!X509_cmp(cert_ta, crl_ta))
- return 1;
- return 0;
- }
-
-/* Check for match between two dist point names: three separate cases.
- * 1. Both are relative names and compare X509_NAME types.
- * 2. One full, one relative. Compare X509_NAME to GENERAL_NAMES.
- * 3. Both are full names and compare two GENERAL_NAMES.
- * 4. One is NULL: automatic match.
- */
+ STACK_OF(X509) *cert_path,
+ STACK_OF(X509) *crl_path)
+{
+ X509 *cert_ta, *crl_ta;
+ cert_ta = sk_X509_value(cert_path, sk_X509_num(cert_path) - 1);
+ crl_ta = sk_X509_value(crl_path, sk_X509_num(crl_path) - 1);
+ if (!X509_cmp(cert_ta, crl_ta))
+ return 1;
+ return 0;
+}
+/*
+ * Check for match between two dist point names: three separate cases. 1.
+ * Both are relative names and compare X509_NAME types. 2. One full, one
+ * relative. Compare X509_NAME to GENERAL_NAMES. 3. Both are full names and
+ * compare two GENERAL_NAMES. 4. One is NULL: automatic match.
+ */
static int idp_check_dp(DIST_POINT_NAME *a, DIST_POINT_NAME *b)
- {
- X509_NAME *nm = NULL;
- GENERAL_NAMES *gens = NULL;
- GENERAL_NAME *gena, *genb;
- size_t i, j;
- if (!a || !b)
- return 1;
- if (a->type == 1)
- {
- if (!a->dpname)
- return 0;
- /* Case 1: two X509_NAME */
- if (b->type == 1)
- {
- if (!b->dpname)
- return 0;
- if (!X509_NAME_cmp(a->dpname, b->dpname))
- return 1;
- else
- return 0;
- }
- /* Case 2: set name and GENERAL_NAMES appropriately */
- nm = a->dpname;
- gens = b->name.fullname;
- }
- else if (b->type == 1)
- {
- if (!b->dpname)
- return 0;
- /* Case 2: set name and GENERAL_NAMES appropriately */
- gens = a->name.fullname;
- nm = b->dpname;
- }
-
- /* Handle case 2 with one GENERAL_NAMES and one X509_NAME */
- if (nm)
- {
- for (i = 0; i < sk_GENERAL_NAME_num(gens); i++)
- {
- gena = sk_GENERAL_NAME_value(gens, i);
- if (gena->type != GEN_DIRNAME)
- continue;
- if (!X509_NAME_cmp(nm, gena->d.directoryName))
- return 1;
- }
- return 0;
- }
-
- /* Else case 3: two GENERAL_NAMES */
-
- for (i = 0; i < sk_GENERAL_NAME_num(a->name.fullname); i++)
- {
- gena = sk_GENERAL_NAME_value(a->name.fullname, i);
- for (j = 0; j < sk_GENERAL_NAME_num(b->name.fullname); j++)
- {
- genb = sk_GENERAL_NAME_value(b->name.fullname, j);
- if (!GENERAL_NAME_cmp(gena, genb))
- return 1;
- }
- }
-
- return 0;
-
- }
+{
+ X509_NAME *nm = NULL;
+ GENERAL_NAMES *gens = NULL;
+ GENERAL_NAME *gena, *genb;
+ size_t i, j;
+ if (!a || !b)
+ return 1;
+ if (a->type == 1) {
+ if (!a->dpname)
+ return 0;
+ /* Case 1: two X509_NAME */
+ if (b->type == 1) {
+ if (!b->dpname)
+ return 0;
+ if (!X509_NAME_cmp(a->dpname, b->dpname))
+ return 1;
+ else
+ return 0;
+ }
+ /* Case 2: set name and GENERAL_NAMES appropriately */
+ nm = a->dpname;
+ gens = b->name.fullname;
+ } else if (b->type == 1) {
+ if (!b->dpname)
+ return 0;
+ /* Case 2: set name and GENERAL_NAMES appropriately */
+ gens = a->name.fullname;
+ nm = b->dpname;
+ }
+
+ /* Handle case 2 with one GENERAL_NAMES and one X509_NAME */
+ if (nm) {
+ for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
+ gena = sk_GENERAL_NAME_value(gens, i);
+ if (gena->type != GEN_DIRNAME)
+ continue;
+ if (!X509_NAME_cmp(nm, gena->d.directoryName))
+ return 1;
+ }
+ return 0;
+ }
+
+ /* Else case 3: two GENERAL_NAMES */
+
+ for (i = 0; i < sk_GENERAL_NAME_num(a->name.fullname); i++) {
+ gena = sk_GENERAL_NAME_value(a->name.fullname, i);
+ for (j = 0; j < sk_GENERAL_NAME_num(b->name.fullname); j++) {
+ genb = sk_GENERAL_NAME_value(b->name.fullname, j);
+ if (!GENERAL_NAME_cmp(gena, genb))
+ return 1;
+ }
+ }
+
+ return 0;
+
+}
static int crldp_check_crlissuer(DIST_POINT *dp, X509_CRL *crl, int crl_score)
- {
- size_t i;
- X509_NAME *nm = X509_CRL_get_issuer(crl);
- /* If no CRLissuer return is successful iff don't need a match */
- if (!dp->CRLissuer)
- return !!(crl_score & CRL_SCORE_ISSUER_NAME);
- for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++)
- {
- GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i);
- if (gen->type != GEN_DIRNAME)
- continue;
- if (!X509_NAME_cmp(gen->d.directoryName, nm))
- return 1;
- }
- return 0;
- }
+{
+ size_t i;
+ X509_NAME *nm = X509_CRL_get_issuer(crl);
+ /* If no CRLissuer return is successful iff don't need a match */
+ if (!dp->CRLissuer)
+ return ! !(crl_score & CRL_SCORE_ISSUER_NAME);
+ for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) {
+ GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i);
+ if (gen->type != GEN_DIRNAME)
+ continue;
+ if (!X509_NAME_cmp(gen->d.directoryName, nm))
+ return 1;
+ }
+ return 0;
+}
/* Check CRLDP and IDP */
static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score,
- unsigned int *preasons)
- {
- size_t i;
- if (crl->idp_flags & IDP_ONLYATTR)
- return 0;
- if (x->ex_flags & EXFLAG_CA)
- {
- if (crl->idp_flags & IDP_ONLYUSER)
- return 0;
- }
- else
- {
- if (crl->idp_flags & IDP_ONLYCA)
- return 0;
- }
- *preasons = crl->idp_reasons;
- for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++)
- {
- DIST_POINT *dp = sk_DIST_POINT_value(x->crldp, i);
- if (crldp_check_crlissuer(dp, crl, crl_score))
- {
- if (!crl->idp ||
- idp_check_dp(dp->distpoint, crl->idp->distpoint))
- {
- *preasons &= dp->dp_reasons;
- return 1;
- }
- }
- }
- if ((!crl->idp || !crl->idp->distpoint) && (crl_score & CRL_SCORE_ISSUER_NAME))
- return 1;
- return 0;
- }
-
-/* Retrieve CRL corresponding to current certificate.
- * If deltas enabled try to find a delta CRL too
+ unsigned int *preasons)
+{
+ size_t i;
+ if (crl->idp_flags & IDP_ONLYATTR)
+ return 0;
+ if (x->ex_flags & EXFLAG_CA) {
+ if (crl->idp_flags & IDP_ONLYUSER)
+ return 0;
+ } else {
+ if (crl->idp_flags & IDP_ONLYCA)
+ return 0;
+ }
+ *preasons = crl->idp_reasons;
+ for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++) {
+ DIST_POINT *dp = sk_DIST_POINT_value(x->crldp, i);
+ if (crldp_check_crlissuer(dp, crl, crl_score)) {
+ if (!crl->idp || idp_check_dp(dp->distpoint, crl->idp->distpoint)) {
+ *preasons &= dp->dp_reasons;
+ return 1;
+ }
+ }
+ }
+ if ((!crl->idp || !crl->idp->distpoint)
+ && (crl_score & CRL_SCORE_ISSUER_NAME))
+ return 1;
+ return 0;
+}
+
+/*
+ * Retrieve CRL corresponding to current certificate. If deltas enabled try
+ * to find a delta CRL too
*/
-
+
static int get_crl_delta(X509_STORE_CTX *ctx,
- X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x)
- {
- int ok;
- X509 *issuer = NULL;
- int crl_score = 0;
- unsigned int reasons;
- X509_CRL *crl = NULL, *dcrl = NULL;
- STACK_OF(X509_CRL) *skcrl;
- X509_NAME *nm = X509_get_issuer_name(x);
- reasons = ctx->current_reasons;
- ok = get_crl_sk(ctx, &crl, &dcrl,
- &issuer, &crl_score, &reasons, ctx->crls);
-
- if (ok)
- goto done;
-
- /* Lookup CRLs from store */
-
- skcrl = ctx->lookup_crls(ctx, nm);
-
- /* If no CRLs found and a near match from get_crl_sk use that */
- if (!skcrl && crl)
- goto done;
-
- get_crl_sk(ctx, &crl, &dcrl, &issuer, &crl_score, &reasons, skcrl);
-
- sk_X509_CRL_pop_free(skcrl, X509_CRL_free);
-
- done:
-
- /* If we got any kind of CRL use it and return success */
- if (crl)
- {
- ctx->current_issuer = issuer;
- ctx->current_crl_score = crl_score;
- ctx->current_reasons = reasons;
- *pcrl = crl;
- *pdcrl = dcrl;
- return 1;
- }
-
- return 0;
- }
+ X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x)
+{
+ int ok;
+ X509 *issuer = NULL;
+ int crl_score = 0;
+ unsigned int reasons;
+ X509_CRL *crl = NULL, *dcrl = NULL;
+ STACK_OF(X509_CRL) *skcrl;
+ X509_NAME *nm = X509_get_issuer_name(x);
+ reasons = ctx->current_reasons;
+ ok = get_crl_sk(ctx, &crl, &dcrl,
+ &issuer, &crl_score, &reasons, ctx->crls);
+
+ if (ok)
+ goto done;
+
+ /* Lookup CRLs from store */
+
+ skcrl = ctx->lookup_crls(ctx, nm);
+
+ /* If no CRLs found and a near match from get_crl_sk use that */
+ if (!skcrl && crl)
+ goto done;
+
+ get_crl_sk(ctx, &crl, &dcrl, &issuer, &crl_score, &reasons, skcrl);
+
+ sk_X509_CRL_pop_free(skcrl, X509_CRL_free);
+
+ done:
+
+ /* If we got any kind of CRL use it and return success */
+ if (crl) {
+ ctx->current_issuer = issuer;
+ ctx->current_crl_score = crl_score;
+ ctx->current_reasons = reasons;
+ *pcrl = crl;
+ *pdcrl = dcrl;
+ return 1;
+ }
+
+ return 0;
+}
/* Check CRL validity */
static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl)
- {
- X509 *issuer = NULL;
- EVP_PKEY *ikey = NULL;
- int ok = 0, chnum, cnum;
- cnum = ctx->error_depth;
- chnum = sk_X509_num(ctx->chain) - 1;
- /* if we have an alternative CRL issuer cert use that */
- if (ctx->current_issuer)
- issuer = ctx->current_issuer;
-
- /* Else find CRL issuer: if not last certificate then issuer
- * is next certificate in chain.
- */
- else if (cnum < chnum)
- issuer = sk_X509_value(ctx->chain, cnum + 1);
- else
- {
- issuer = sk_X509_value(ctx->chain, chnum);
- /* If not self signed, can't check signature */
- if(!ctx->check_issued(ctx, issuer, issuer))
- {
- ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER;
- ok = ctx->verify_cb(0, ctx);
- if(!ok) goto err;
- }
- }
-
- if(issuer)
- {
- /* Skip most tests for deltas because they have already
- * been done
- */
- if (!crl->base_crl_number)
- {
- /* Check for cRLSign bit if keyUsage present */
- if ((issuer->ex_flags & EXFLAG_KUSAGE) &&
- !(issuer->ex_kusage & KU_CRL_SIGN))
- {
- ctx->error = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN;
- ok = ctx->verify_cb(0, ctx);
- if(!ok) goto err;
- }
-
- if (!(ctx->current_crl_score & CRL_SCORE_SCOPE))
- {
- ctx->error = X509_V_ERR_DIFFERENT_CRL_SCOPE;
- ok = ctx->verify_cb(0, ctx);
- if(!ok) goto err;
- }
-
- if (!(ctx->current_crl_score & CRL_SCORE_SAME_PATH))
- {
- if (check_crl_path(ctx, ctx->current_issuer) <= 0)
- {
- ctx->error = X509_V_ERR_CRL_PATH_VALIDATION_ERROR;
- ok = ctx->verify_cb(0, ctx);
- if(!ok) goto err;
- }
- }
-
- if (crl->idp_flags & IDP_INVALID)
- {
- ctx->error = X509_V_ERR_INVALID_EXTENSION;
- ok = ctx->verify_cb(0, ctx);
- if(!ok) goto err;
- }
-
-
- }
-
- if (!(ctx->current_crl_score & CRL_SCORE_TIME))
- {
- ok = check_crl_time(ctx, crl, 1);
- if (!ok)
- goto err;
- }
-
- /* Attempt to get issuer certificate public key */
- ikey = X509_get_pubkey(issuer);
-
- if(!ikey)
- {
- ctx->error=X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
- ok = ctx->verify_cb(0, ctx);
- if (!ok) goto err;
- }
- else
- {
- int rv;
- rv = X509_CRL_check_suiteb(crl, ikey, ctx->param->flags);
- if (rv != X509_V_OK)
- {
- ctx->error=rv;
- ok = ctx->verify_cb(0, ctx);
- if (!ok)
- goto err;
- }
- /* Verify CRL signature */
- if(X509_CRL_verify(crl, ikey) <= 0)
- {
- ctx->error=X509_V_ERR_CRL_SIGNATURE_FAILURE;
- ok = ctx->verify_cb(0, ctx);
- if (!ok) goto err;
- }
- }
- }
-
- ok = 1;
-
- err:
- EVP_PKEY_free(ikey);
- return ok;
- }
+{
+ X509 *issuer = NULL;
+ EVP_PKEY *ikey = NULL;
+ int ok = 0, chnum, cnum;
+ cnum = ctx->error_depth;
+ chnum = sk_X509_num(ctx->chain) - 1;
+ /* if we have an alternative CRL issuer cert use that */
+ if (ctx->current_issuer)
+ issuer = ctx->current_issuer;
+
+ /*
+ * Else find CRL issuer: if not last certificate then issuer is next
+ * certificate in chain.
+ */
+ else if (cnum < chnum)
+ issuer = sk_X509_value(ctx->chain, cnum + 1);
+ else {
+ issuer = sk_X509_value(ctx->chain, chnum);
+ /* If not self signed, can't check signature */
+ if (!ctx->check_issued(ctx, issuer, issuer)) {
+ ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER;
+ ok = ctx->verify_cb(0, ctx);
+ if (!ok)
+ goto err;
+ }
+ }
+
+ if (issuer) {
+ /*
+ * Skip most tests for deltas because they have already been done
+ */
+ if (!crl->base_crl_number) {
+ /* Check for cRLSign bit if keyUsage present */
+ if ((issuer->ex_flags & EXFLAG_KUSAGE) &&
+ !(issuer->ex_kusage & KU_CRL_SIGN)) {
+ ctx->error = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN;
+ ok = ctx->verify_cb(0, ctx);
+ if (!ok)
+ goto err;
+ }
+
+ if (!(ctx->current_crl_score & CRL_SCORE_SCOPE)) {
+ ctx->error = X509_V_ERR_DIFFERENT_CRL_SCOPE;
+ ok = ctx->verify_cb(0, ctx);
+ if (!ok)
+ goto err;
+ }
+
+ if (!(ctx->current_crl_score & CRL_SCORE_SAME_PATH)) {
+ if (check_crl_path(ctx, ctx->current_issuer) <= 0) {
+ ctx->error = X509_V_ERR_CRL_PATH_VALIDATION_ERROR;
+ ok = ctx->verify_cb(0, ctx);
+ if (!ok)
+ goto err;
+ }
+ }
+
+ if (crl->idp_flags & IDP_INVALID) {
+ ctx->error = X509_V_ERR_INVALID_EXTENSION;
+ ok = ctx->verify_cb(0, ctx);
+ if (!ok)
+ goto err;
+ }
+
+ }
+
+ if (!(ctx->current_crl_score & CRL_SCORE_TIME)) {
+ ok = check_crl_time(ctx, crl, 1);
+ if (!ok)
+ goto err;
+ }
+
+ /* Attempt to get issuer certificate public key */
+ ikey = X509_get_pubkey(issuer);
+
+ if (!ikey) {
+ ctx->error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
+ ok = ctx->verify_cb(0, ctx);
+ if (!ok)
+ goto err;
+ } else {
+ int rv;
+ rv = X509_CRL_check_suiteb(crl, ikey, ctx->param->flags);
+ if (rv != X509_V_OK) {
+ ctx->error = rv;
+ ok = ctx->verify_cb(0, ctx);
+ if (!ok)
+ goto err;
+ }
+ /* Verify CRL signature */
+ if (X509_CRL_verify(crl, ikey) <= 0) {
+ ctx->error = X509_V_ERR_CRL_SIGNATURE_FAILURE;
+ ok = ctx->verify_cb(0, ctx);
+ if (!ok)
+ goto err;
+ }
+ }
+ }
+
+ ok = 1;
+
+ err:
+ EVP_PKEY_free(ikey);
+ return ok;
+}
/* Check certificate against CRL */
static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x)
- {
- int ok;
- X509_REVOKED *rev;
- /* The rules changed for this... previously if a CRL contained
- * unhandled critical extensions it could still be used to indicate
- * a certificate was revoked. This has since been changed since
- * critical extension can change the meaning of CRL entries.
- */
- if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
- && (crl->flags & EXFLAG_CRITICAL))
- {
- ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION;
- ok = ctx->verify_cb(0, ctx);
- if(!ok)
- return 0;
- }
- /* Look for serial number of certificate in CRL
- * If found make sure reason is not removeFromCRL.
- */
- if (X509_CRL_get0_by_cert(crl, &rev, x))
- {
- if (rev->reason == CRL_REASON_REMOVE_FROM_CRL)
- return 2;
- ctx->error = X509_V_ERR_CERT_REVOKED;
- ok = ctx->verify_cb(0, ctx);
- if (!ok)
- return 0;
- }
-
- return 1;
- }
+{
+ int ok;
+ X509_REVOKED *rev;
+ /*
+ * The rules changed for this... previously if a CRL contained unhandled
+ * critical extensions it could still be used to indicate a certificate
+ * was revoked. This has since been changed since critical extension can
+ * change the meaning of CRL entries.
+ */
+ if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
+ && (crl->flags & EXFLAG_CRITICAL)) {
+ ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION;
+ ok = ctx->verify_cb(0, ctx);
+ if (!ok)
+ return 0;
+ }
+ /*
+ * Look for serial number of certificate in CRL If found make sure reason
+ * is not removeFromCRL.
+ */
+ if (X509_CRL_get0_by_cert(crl, &rev, x)) {
+ if (rev->reason == CRL_REASON_REMOVE_FROM_CRL)
+ return 2;
+ ctx->error = X509_V_ERR_CERT_REVOKED;
+ ok = ctx->verify_cb(0, ctx);
+ if (!ok)
+ return 0;
+ }
+
+ return 1;
+}
static int check_policy(X509_STORE_CTX *ctx)
- {
- int ret;
- if (ctx->parent)
- return 1;
- ret = X509_policy_check(&ctx->tree, &ctx->explicit_policy, ctx->chain,
- ctx->param->policies, ctx->param->flags);
- if (ret == 0)
- {
- OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
- return 0;
- }
- /* Invalid or inconsistent extensions */
- if (ret == -1)
- {
- /* Locate certificates with bad extensions and notify
- * callback.
- */
- X509 *x;
- size_t i;
- for (i = 1; i < sk_X509_num(ctx->chain); i++)
- {
- x = sk_X509_value(ctx->chain, i);
- if (!(x->ex_flags & EXFLAG_INVALID_POLICY))
- continue;
- ctx->current_cert = x;
- ctx->error = X509_V_ERR_INVALID_POLICY_EXTENSION;
- if(!ctx->verify_cb(0, ctx))
- return 0;
- }
- return 1;
- }
- if (ret == -2)
- {
- ctx->current_cert = NULL;
- ctx->error = X509_V_ERR_NO_EXPLICIT_POLICY;
- return ctx->verify_cb(0, ctx);
- }
-
- if (ctx->param->flags & X509_V_FLAG_NOTIFY_POLICY)
- {
- ctx->current_cert = NULL;
- ctx->error = X509_V_OK;
- if (!ctx->verify_cb(2, ctx))
- return 0;
- }
-
- return 1;
- }
+{
+ int ret;
+ if (ctx->parent)
+ return 1;
+ ret = X509_policy_check(&ctx->tree, &ctx->explicit_policy, ctx->chain,
+ ctx->param->policies, ctx->param->flags);
+ if (ret == 0) {
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ /* Invalid or inconsistent extensions */
+ if (ret == -1) {
+ /*
+ * Locate certificates with bad extensions and notify callback.
+ */
+ X509 *x;
+ size_t i;
+ for (i = 1; i < sk_X509_num(ctx->chain); i++) {
+ x = sk_X509_value(ctx->chain, i);
+ if (!(x->ex_flags & EXFLAG_INVALID_POLICY))
+ continue;
+ ctx->current_cert = x;
+ ctx->error = X509_V_ERR_INVALID_POLICY_EXTENSION;
+ if (!ctx->verify_cb(0, ctx))
+ return 0;
+ }
+ return 1;
+ }
+ if (ret == -2) {
+ ctx->current_cert = NULL;
+ ctx->error = X509_V_ERR_NO_EXPLICIT_POLICY;
+ return ctx->verify_cb(0, ctx);
+ }
+
+ if (ctx->param->flags & X509_V_FLAG_NOTIFY_POLICY) {
+ ctx->current_cert = NULL;
+ ctx->error = X509_V_OK;
+ if (!ctx->verify_cb(2, ctx))
+ return 0;
+ }
+
+ return 1;
+}
static int check_cert_time(X509_STORE_CTX *ctx, X509 *x)
- {
- time_t *ptime;
- int i;
-
- if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
- ptime = &ctx->param->check_time;
- else
- ptime = NULL;
-
- i=X509_cmp_time(X509_get_notBefore(x), ptime);
- if (i == 0)
- {
- ctx->error=X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD;
- ctx->current_cert=x;
- if (!ctx->verify_cb(0, ctx))
- return 0;
- }
-
- if (i > 0)
- {
- ctx->error=X509_V_ERR_CERT_NOT_YET_VALID;
- ctx->current_cert=x;
- if (!ctx->verify_cb(0, ctx))
- return 0;
- }
-
- i=X509_cmp_time(X509_get_notAfter(x), ptime);
- if (i == 0)
- {
- ctx->error=X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD;
- ctx->current_cert=x;
- if (!ctx->verify_cb(0, ctx))
- return 0;
- }
-
- if (i < 0)
- {
- ctx->error=X509_V_ERR_CERT_HAS_EXPIRED;
- ctx->current_cert=x;
- if (!ctx->verify_cb(0, ctx))
- return 0;
- }
-
- return 1;
- }
+{
+ time_t *ptime;
+ int i;
+
+ if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
+ ptime = &ctx->param->check_time;
+ else
+ ptime = NULL;
+
+ i = X509_cmp_time(X509_get_notBefore(x), ptime);
+ if (i == 0) {
+ ctx->error = X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD;
+ ctx->current_cert = x;
+ if (!ctx->verify_cb(0, ctx))
+ return 0;
+ }
+
+ if (i > 0) {
+ ctx->error = X509_V_ERR_CERT_NOT_YET_VALID;
+ ctx->current_cert = x;
+ if (!ctx->verify_cb(0, ctx))
+ return 0;
+ }
+
+ i = X509_cmp_time(X509_get_notAfter(x), ptime);
+ if (i == 0) {
+ ctx->error = X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD;
+ ctx->current_cert = x;
+ if (!ctx->verify_cb(0, ctx))
+ return 0;
+ }
+
+ if (i < 0) {
+ ctx->error = X509_V_ERR_CERT_HAS_EXPIRED;
+ ctx->current_cert = x;
+ if (!ctx->verify_cb(0, ctx))
+ return 0;
+ }
+
+ return 1;
+}
static int internal_verify(X509_STORE_CTX *ctx)
- {
- int ok=0,n;
- X509 *xs,*xi;
- EVP_PKEY *pkey=NULL;
- int (*cb)(int xok,X509_STORE_CTX *xctx);
-
- cb=ctx->verify_cb;
-
- n=sk_X509_num(ctx->chain);
- ctx->error_depth=n-1;
- n--;
- xi=sk_X509_value(ctx->chain,n);
-
- if (ctx->check_issued(ctx, xi, xi))
- xs=xi;
- else
- {
- if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN)
- {
- xs = xi;
- goto check_cert;
- }
- if (n <= 0)
- {
- ctx->error=X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE;
- ctx->current_cert=xi;
- ok=cb(0,ctx);
- goto end;
- }
- else
- {
- n--;
- ctx->error_depth=n;
- xs=sk_X509_value(ctx->chain,n);
- }
- }
-
-/* ctx->error=0; not needed */
- while (n >= 0)
- {
- ctx->error_depth=n;
-
- /* Skip signature check for self signed certificates unless
- * explicitly asked for. It doesn't add any security and
- * just wastes time.
- */
- if (!xs->valid && (xs != xi || (ctx->param->flags & X509_V_FLAG_CHECK_SS_SIGNATURE)))
- {
- if ((pkey=X509_get_pubkey(xi)) == NULL)
- {
- ctx->error=X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
- ctx->current_cert=xi;
- ok=(*cb)(0,ctx);
- if (!ok) goto end;
- }
- else if (X509_verify(xs,pkey) <= 0)
- {
- ctx->error=X509_V_ERR_CERT_SIGNATURE_FAILURE;
- ctx->current_cert=xs;
- ok=(*cb)(0,ctx);
- if (!ok)
- {
- EVP_PKEY_free(pkey);
- goto end;
- }
- }
- EVP_PKEY_free(pkey);
- pkey=NULL;
- }
-
- xs->valid = 1;
-
- check_cert:
- ok = check_cert_time(ctx, xs);
- if (!ok)
- goto end;
-
- /* The last error (if any) is still in the error value */
- ctx->current_issuer=xi;
- ctx->current_cert=xs;
- ok=(*cb)(1,ctx);
- if (!ok) goto end;
-
- n--;
- if (n >= 0)
- {
- xi=xs;
- xs=sk_X509_value(ctx->chain,n);
- }
- }
- ok=1;
-end:
- return ok;
- }
+{
+ int ok = 0, n;
+ X509 *xs, *xi;
+ EVP_PKEY *pkey = NULL;
+ int (*cb) (int xok, X509_STORE_CTX *xctx);
+
+ cb = ctx->verify_cb;
+
+ n = sk_X509_num(ctx->chain);
+ ctx->error_depth = n - 1;
+ n--;
+ xi = sk_X509_value(ctx->chain, n);
+
+ if (ctx->check_issued(ctx, xi, xi))
+ xs = xi;
+ else {
+ if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) {
+ xs = xi;
+ goto check_cert;
+ }
+ if (n <= 0) {
+ ctx->error = X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE;
+ ctx->current_cert = xi;
+ ok = cb(0, ctx);
+ goto end;
+ } else {
+ n--;
+ ctx->error_depth = n;
+ xs = sk_X509_value(ctx->chain, n);
+ }
+ }
+
+/* ctx->error=0; not needed */
+ while (n >= 0) {
+ ctx->error_depth = n;
+
+ /*
+ * Skip signature check for self signed certificates unless
+ * explicitly asked for. It doesn't add any security and just wastes
+ * time.
+ */
+ if (!xs->valid
+ && (xs != xi
+ || (ctx->param->flags & X509_V_FLAG_CHECK_SS_SIGNATURE))) {
+ if ((pkey = X509_get_pubkey(xi)) == NULL) {
+ ctx->error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
+ ctx->current_cert = xi;
+ ok = (*cb) (0, ctx);
+ if (!ok)
+ goto end;
+ } else if (X509_verify(xs, pkey) <= 0) {
+ ctx->error = X509_V_ERR_CERT_SIGNATURE_FAILURE;
+ ctx->current_cert = xs;
+ ok = (*cb) (0, ctx);
+ if (!ok) {
+ EVP_PKEY_free(pkey);
+ goto end;
+ }
+ }
+ EVP_PKEY_free(pkey);
+ pkey = NULL;
+ }
+
+ xs->valid = 1;
+
+ check_cert:
+ ok = check_cert_time(ctx, xs);
+ if (!ok)
+ goto end;
+
+ /* The last error (if any) is still in the error value */
+ ctx->current_issuer = xi;
+ ctx->current_cert = xs;
+ ok = (*cb) (1, ctx);
+ if (!ok)
+ goto end;
+
+ n--;
+ if (n >= 0) {
+ xi = xs;
+ xs = sk_X509_value(ctx->chain, n);
+ }
+ }
+ ok = 1;
+ end:
+ return ok;
+}
int X509_cmp_current_time(const ASN1_TIME *ctm)
{
- return X509_cmp_time(ctm, NULL);
+ return X509_cmp_time(ctm, NULL);
}
int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time)
- {
- char *str;
- ASN1_TIME atm;
- long offset;
- char buff1[24],buff2[24],*p;
- int i, j, remaining;
-
- p=buff1;
- 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)
- {
- /* 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
- {
- /* 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++);
- 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++;
- 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 == '-')
- offset= -offset;
- }
- atm.type=ctm->type;
- atm.flags = 0;
- atm.length=sizeof(buff2);
- atm.data=(unsigned char *)buff2;
-
- if (X509_time_adj(&atm, offset*60, cmp_time) == NULL)
- return 0;
-
- if (ctm->type == V_ASN1_UTCTIME)
- {
- i=(buff1[0]-'0')*10+(buff1[1]-'0');
- if (i < 50) i+=100; /* cf. RFC 2459 */
- j=(buff2[0]-'0')*10+(buff2[1]-'0');
- if (j < 50) j+=100;
-
- if (i < j) return -1;
- if (i > j) return 1;
- }
- i=strcmp(buff1,buff2);
- if (i == 0) /* wait a second then return younger :-) */
- return -1;
- else
- return i;
- }
+{
+ char *str;
+ ASN1_TIME atm;
+ long offset;
+ char buff1[24], buff2[24], *p;
+ int i, j, remaining;
+
+ p = buff1;
+ 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) {
+ /* 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 {
+ /*
+ * 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++);
+ 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++;
+ 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 == '-')
+ offset = -offset;
+ }
+ atm.type = ctm->type;
+ atm.flags = 0;
+ atm.length = sizeof(buff2);
+ atm.data = (unsigned char *)buff2;
+
+ if (X509_time_adj(&atm, offset * 60, cmp_time) == NULL)
+ return 0;
+
+ if (ctm->type == V_ASN1_UTCTIME) {
+ i = (buff1[0] - '0') * 10 + (buff1[1] - '0');
+ if (i < 50)
+ i += 100; /* cf. RFC 2459 */
+ j = (buff2[0] - '0') * 10 + (buff2[1] - '0');
+ if (j < 50)
+ j += 100;
+
+ if (i < j)
+ return -1;
+ if (i > j)
+ return 1;
+ }
+ i = strcmp(buff1, buff2);
+ if (i == 0) /* wait a second then return younger :-) */
+ return -1;
+ else
+ return i;
+}
ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj)
{
- return X509_time_adj(s, adj, NULL);
+ return X509_time_adj(s, adj, NULL);
}
ASN1_TIME *X509_time_adj(ASN1_TIME *s, long offset_sec, time_t *in_tm)
- {
- return X509_time_adj_ex(s, 0, offset_sec, in_tm);
- }
+{
+ return X509_time_adj_ex(s, 0, offset_sec, in_tm);
+}
ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s,
- int offset_day, long offset_sec, time_t *in_tm)
- {
- time_t t = 0;
-
- if (in_tm) t = *in_tm;
- else time(&t);
-
- if (s && !(s->flags & ASN1_STRING_FLAG_MSTRING))
- {
- if (s->type == V_ASN1_UTCTIME)
- return ASN1_UTCTIME_adj(s,t, offset_day, offset_sec);
- if (s->type == V_ASN1_GENERALIZEDTIME)
- return ASN1_GENERALIZEDTIME_adj(s, t, offset_day,
- offset_sec);
- }
- return ASN1_TIME_adj(s, t, offset_day, offset_sec);
- }
+ int offset_day, long offset_sec, time_t *in_tm)
+{
+ time_t t = 0;
+
+ if (in_tm)
+ t = *in_tm;
+ else
+ time(&t);
+
+ if (s && !(s->flags & ASN1_STRING_FLAG_MSTRING)) {
+ if (s->type == V_ASN1_UTCTIME)
+ return ASN1_UTCTIME_adj(s, t, offset_day, offset_sec);
+ if (s->type == V_ASN1_GENERALIZEDTIME)
+ return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec);
+ }
+ return ASN1_TIME_adj(s, t, offset_day, offset_sec);
+}
/* Make a delta CRL as the diff between two full CRLs */
X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer,
- EVP_PKEY *skey, const EVP_MD *md, unsigned int flags)
- {
- X509_CRL *crl = NULL;
- int i;
- size_t j;
- STACK_OF(X509_REVOKED) *revs = NULL;
- /* CRLs can't be delta already */
- if (base->base_crl_number || newer->base_crl_number)
- {
- 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_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_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_R_AKID_MISMATCH);
- return NULL;
- }
- if (!crl_extension_match(base, newer, NID_issuing_distribution_point))
- {
- 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_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_R_CRL_VERIFY_FAILURE);
- return NULL;
- }
- /* Create new CRL */
- crl = X509_CRL_new();
- if (!crl || !X509_CRL_set_version(crl, 1))
- goto memerr;
- /* Set issuer name */
- if (!X509_CRL_set_issuer_name(crl, X509_CRL_get_issuer(newer)))
- goto memerr;
-
- if (!X509_CRL_set_lastUpdate(crl, X509_CRL_get_lastUpdate(newer)))
- goto memerr;
- if (!X509_CRL_set_nextUpdate(crl, X509_CRL_get_nextUpdate(newer)))
- goto memerr;
-
- /* Set base CRL number: must be critical */
-
- if (!X509_CRL_add1_ext_i2d(crl, NID_delta_crl, base->crl_number, 1, 0))
- goto memerr;
-
- /* Copy extensions across from newest CRL to delta: this will set
- * CRL number to correct value too.
- */
-
- for (i = 0; i < X509_CRL_get_ext_count(newer); i++)
- {
- X509_EXTENSION *ext;
- ext = X509_CRL_get_ext(newer, i);
- if (!X509_CRL_add_ext(crl, ext, -1))
- goto memerr;
- }
-
- /* Go through revoked entries, copying as needed */
-
- revs = X509_CRL_get_REVOKED(newer);
-
- for (j = 0; j < sk_X509_REVOKED_num(revs); j++)
- {
- X509_REVOKED *rvn, *rvtmp;
- rvn = sk_X509_REVOKED_value(revs, j);
- /* Add only if not also in base.
- * TODO: need something cleverer here for some more complex
- * CRLs covering multiple CAs.
- */
- if (!X509_CRL_get0_by_serial(base, &rvtmp, rvn->serialNumber))
- {
- rvtmp = X509_REVOKED_dup(rvn);
- if (!rvtmp)
- goto memerr;
- if (!X509_CRL_add0_revoked(crl, rvtmp))
- {
- X509_REVOKED_free(rvtmp);
- goto memerr;
- }
- }
- }
- /* TODO: optionally prune deleted entries */
-
- if (skey && md && !X509_CRL_sign(crl, skey, md))
- goto memerr;
-
- return crl;
-
- memerr:
- 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_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,
- dup_func, free_func))
- {
- return -1;
- }
- return index;
- }
+ EVP_PKEY *skey, const EVP_MD *md, unsigned int flags)
+{
+ X509_CRL *crl = NULL;
+ int i;
+ size_t j;
+ STACK_OF(X509_REVOKED) *revs = NULL;
+ /* CRLs can't be delta already */
+ if (base->base_crl_number || newer->base_crl_number) {
+ 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_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_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_R_AKID_MISMATCH);
+ return NULL;
+ }
+ if (!crl_extension_match(base, newer, NID_issuing_distribution_point)) {
+ 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_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_R_CRL_VERIFY_FAILURE);
+ return NULL;
+ }
+ /* Create new CRL */
+ crl = X509_CRL_new();
+ if (!crl || !X509_CRL_set_version(crl, 1))
+ goto memerr;
+ /* Set issuer name */
+ if (!X509_CRL_set_issuer_name(crl, X509_CRL_get_issuer(newer)))
+ goto memerr;
+
+ if (!X509_CRL_set_lastUpdate(crl, X509_CRL_get_lastUpdate(newer)))
+ goto memerr;
+ if (!X509_CRL_set_nextUpdate(crl, X509_CRL_get_nextUpdate(newer)))
+ goto memerr;
+
+ /* Set base CRL number: must be critical */
+
+ if (!X509_CRL_add1_ext_i2d(crl, NID_delta_crl, base->crl_number, 1, 0))
+ goto memerr;
+
+ /*
+ * Copy extensions across from newest CRL to delta: this will set CRL
+ * number to correct value too.
+ */
+
+ for (i = 0; i < X509_CRL_get_ext_count(newer); i++) {
+ X509_EXTENSION *ext;
+ ext = X509_CRL_get_ext(newer, i);
+ if (!X509_CRL_add_ext(crl, ext, -1))
+ goto memerr;
+ }
+
+ /* Go through revoked entries, copying as needed */
+
+ revs = X509_CRL_get_REVOKED(newer);
+
+ for (j = 0; j < sk_X509_REVOKED_num(revs); j++) {
+ X509_REVOKED *rvn, *rvtmp;
+ rvn = sk_X509_REVOKED_value(revs, j);
+ /*
+ * Add only if not also in base. TODO: need something cleverer here
+ * for some more complex CRLs covering multiple CAs.
+ */
+ if (!X509_CRL_get0_by_serial(base, &rvtmp, rvn->serialNumber)) {
+ rvtmp = X509_REVOKED_dup(rvn);
+ if (!rvtmp)
+ goto memerr;
+ if (!X509_CRL_add0_revoked(crl, rvtmp)) {
+ X509_REVOKED_free(rvtmp);
+ goto memerr;
+ }
+ }
+ }
+ /* TODO: optionally prune deleted entries */
+
+ if (skey && md && !X509_CRL_sign(crl, skey, md))
+ goto memerr;
+
+ return crl;
+
+ memerr:
+ 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_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,
+ dup_func, free_func)) {
+ return -1;
+ }
+ return index;
+}
int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data)
- {
- return CRYPTO_set_ex_data(&ctx->ex_data,idx,data);
- }
+{
+ return CRYPTO_set_ex_data(&ctx->ex_data, idx, data);
+}
void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx)
- {
- return CRYPTO_get_ex_data(&ctx->ex_data,idx);
- }
+{
+ return CRYPTO_get_ex_data(&ctx->ex_data, idx);
+}
int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx)
- {
- return ctx->error;
- }
+{
+ return ctx->error;
+}
void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int err)
- {
- ctx->error=err;
- }
+{
+ ctx->error = err;
+}
int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx)
- {
- return ctx->error_depth;
- }
+{
+ return ctx->error_depth;
+}
X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx)
- {
- return ctx->current_cert;
- }
+{
+ return ctx->current_cert;
+}
STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx)
- {
- return ctx->chain;
- }
+{
+ return ctx->chain;
+}
STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx)
- {
- if (!ctx->chain)
- return NULL;
- return X509_chain_up_ref(ctx->chain);
- }
+{
+ if (!ctx->chain)
+ return NULL;
+ return X509_chain_up_ref(ctx->chain);
+}
X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx)
- {
- return ctx->current_issuer;
- }
+{
+ return ctx->current_issuer;
+}
X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx)
- {
- return ctx->current_crl;
- }
+{
+ return ctx->current_crl;
+}
X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx)
- {
- return ctx->parent;
- }
+{
+ return ctx->parent;
+}
void X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx, X509 *x)
- {
- ctx->cert=x;
- }
+{
+ ctx->cert = x;
+}
void X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
- {
- ctx->untrusted=sk;
- }
+{
+ ctx->untrusted = sk;
+}
void X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk)
- {
- ctx->crls=sk;
- }
+{
+ ctx->crls = sk;
+}
int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose)
- {
- return X509_STORE_CTX_purpose_inherit(ctx, 0, purpose, 0);
- }
+{
+ return X509_STORE_CTX_purpose_inherit(ctx, 0, purpose, 0);
+}
int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust)
- {
- return X509_STORE_CTX_purpose_inherit(ctx, 0, 0, trust);
- }
-
-/* This function is used to set the X509_STORE_CTX purpose and trust
- * values. This is intended to be used when another structure has its
- * own trust and purpose values which (if set) will be inherited by
- * the ctx. If they aren't set then we will usually have a default
- * purpose in mind which should then be used to set the trust value.
- * An example of this is SSL use: an SSL structure will have its own
- * purpose and trust settings which the application can set: if they
- * aren't set then we use the default of SSL client/server.
+{
+ return X509_STORE_CTX_purpose_inherit(ctx, 0, 0, trust);
+}
+
+/*
+ * This function is used to set the X509_STORE_CTX purpose and trust values.
+ * This is intended to be used when another structure has its own trust and
+ * purpose values which (if set) will be inherited by the ctx. If they aren't
+ * set then we will usually have a default purpose in mind which should then
+ * be used to set the trust value. An example of this is SSL use: an SSL
+ * structure will have its own purpose and trust settings which the
+ * application can set: if they aren't set then we use the default of SSL
+ * client/server.
*/
int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
- int purpose, int trust)
-{
- int idx;
- /* If purpose not set use default */
- if (!purpose) purpose = def_purpose;
- /* If we have a purpose then check it is valid */
- if (purpose)
- {
- X509_PURPOSE *ptmp;
- idx = X509_PURPOSE_get_by_id(purpose);
- if (idx == -1)
- {
- OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_PURPOSE_ID);
- return 0;
- }
- ptmp = X509_PURPOSE_get0(idx);
- if (ptmp->trust == X509_TRUST_DEFAULT)
- {
- idx = X509_PURPOSE_get_by_id(def_purpose);
- if (idx == -1)
- {
- OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_PURPOSE_ID);
- return 0;
- }
- ptmp = X509_PURPOSE_get0(idx);
- }
- /* If trust not set then get from purpose default */
- if (!trust) trust = ptmp->trust;
- }
- if (trust)
- {
- idx = X509_TRUST_get_by_id(trust);
- if (idx == -1)
- {
- OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_TRUST_ID);
- return 0;
- }
- }
-
- if (purpose && !ctx->param->purpose) ctx->param->purpose = purpose;
- if (trust && !ctx->param->trust) ctx->param->trust = trust;
- return 1;
+ int purpose, int trust)
+{
+ int idx;
+ /* If purpose not set use default */
+ if (!purpose)
+ purpose = def_purpose;
+ /* If we have a purpose then check it is valid */
+ if (purpose) {
+ X509_PURPOSE *ptmp;
+ idx = X509_PURPOSE_get_by_id(purpose);
+ if (idx == -1) {
+ OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_PURPOSE_ID);
+ return 0;
+ }
+ ptmp = X509_PURPOSE_get0(idx);
+ if (ptmp->trust == X509_TRUST_DEFAULT) {
+ idx = X509_PURPOSE_get_by_id(def_purpose);
+ if (idx == -1) {
+ OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_PURPOSE_ID);
+ return 0;
+ }
+ ptmp = X509_PURPOSE_get0(idx);
+ }
+ /* If trust not set then get from purpose default */
+ if (!trust)
+ trust = ptmp->trust;
+ }
+ if (trust) {
+ idx = X509_TRUST_get_by_id(trust);
+ if (idx == -1) {
+ OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_TRUST_ID);
+ return 0;
+ }
+ }
+
+ if (purpose && !ctx->param->purpose)
+ ctx->param->purpose = purpose;
+ if (trust && !ctx->param->trust)
+ ctx->param->trust = trust;
+ return 1;
}
X509_STORE_CTX *X509_STORE_CTX_new(void)
{
- X509_STORE_CTX *ctx;
- ctx = (X509_STORE_CTX *)OPENSSL_malloc(sizeof(X509_STORE_CTX));
- if (!ctx)
- {
- OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
- memset(ctx, 0, sizeof(X509_STORE_CTX));
- return ctx;
+ X509_STORE_CTX *ctx;
+ ctx = (X509_STORE_CTX *)OPENSSL_malloc(sizeof(X509_STORE_CTX));
+ if (!ctx) {
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ memset(ctx, 0, sizeof(X509_STORE_CTX));
+ return ctx;
}
void X509_STORE_CTX_free(X509_STORE_CTX *ctx)
{
- X509_STORE_CTX_cleanup(ctx);
- OPENSSL_free(ctx);
+ if (ctx == NULL) {
+ return;
+ }
+ X509_STORE_CTX_cleanup(ctx);
+ OPENSSL_free(ctx);
}
int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
- STACK_OF(X509) *chain)
- {
- int ret = 1;
-
- memset(ctx, 0, sizeof(X509_STORE_CTX));
- ctx->ctx=store;
- ctx->cert=x509;
- ctx->untrusted=chain;
-
- CRYPTO_new_ex_data(&ctx->ex_data);
-
- ctx->param = X509_VERIFY_PARAM_new();
- if (!ctx->param)
- goto err;
-
- /* Inherit callbacks and flags from X509_STORE if not set
- * use defaults. */
-
- if (store)
- ret = X509_VERIFY_PARAM_inherit(ctx->param, store->param);
- else
- ctx->param->inh_flags |= X509_VP_FLAG_DEFAULT|X509_VP_FLAG_ONCE;
-
- if (store)
- {
- ctx->verify_cb = store->verify_cb;
- ctx->cleanup = store->cleanup;
- }
- else
- ctx->cleanup = 0;
-
- if (ret)
- ret = X509_VERIFY_PARAM_inherit(ctx->param,
- X509_VERIFY_PARAM_lookup("default"));
-
- if (ret == 0)
- goto err;
-
- if (store && store->check_issued)
- ctx->check_issued = store->check_issued;
- else
- ctx->check_issued = check_issued;
-
- if (store && store->get_issuer)
- ctx->get_issuer = store->get_issuer;
- else
- ctx->get_issuer = X509_STORE_CTX_get1_issuer;
-
- if (store && store->verify_cb)
- ctx->verify_cb = store->verify_cb;
- else
- ctx->verify_cb = null_callback;
-
- if (store && store->verify)
- ctx->verify = store->verify;
- else
- ctx->verify = internal_verify;
-
- if (store && store->check_revocation)
- ctx->check_revocation = store->check_revocation;
- else
- ctx->check_revocation = check_revocation;
-
- if (store && store->get_crl)
- ctx->get_crl = store->get_crl;
- else
- ctx->get_crl = NULL;
-
- if (store && store->check_crl)
- ctx->check_crl = store->check_crl;
- else
- ctx->check_crl = check_crl;
-
- if (store && store->cert_crl)
- ctx->cert_crl = store->cert_crl;
- else
- ctx->cert_crl = cert_crl;
-
- if (store && store->lookup_certs)
- ctx->lookup_certs = store->lookup_certs;
- else
- ctx->lookup_certs = X509_STORE_get1_certs;
-
- if (store && store->lookup_crls)
- ctx->lookup_crls = store->lookup_crls;
- else
- ctx->lookup_crls = X509_STORE_get1_crls;
-
- ctx->check_policy = check_policy;
-
- return 1;
-
-err:
- 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, ERR_R_MALLOC_FAILURE);
- return 0;
- }
-
-/* Set alternative lookup method: just a STACK of trusted certificates.
- * This avoids X509_STORE nastiness where it isn't needed.
+ STACK_OF(X509) *chain)
+{
+ int ret = 1;
+
+ memset(ctx, 0, sizeof(X509_STORE_CTX));
+ ctx->ctx = store;
+ ctx->cert = x509;
+ ctx->untrusted = chain;
+
+ CRYPTO_new_ex_data(&ctx->ex_data);
+
+ ctx->param = X509_VERIFY_PARAM_new();
+ if (!ctx->param)
+ goto err;
+
+ /*
+ * Inherit callbacks and flags from X509_STORE if not set use defaults.
+ */
+
+ if (store)
+ ret = X509_VERIFY_PARAM_inherit(ctx->param, store->param);
+ else
+ ctx->param->inh_flags |= X509_VP_FLAG_DEFAULT | X509_VP_FLAG_ONCE;
+
+ if (store) {
+ ctx->verify_cb = store->verify_cb;
+ ctx->cleanup = store->cleanup;
+ } else
+ ctx->cleanup = 0;
+
+ if (ret)
+ ret = X509_VERIFY_PARAM_inherit(ctx->param,
+ X509_VERIFY_PARAM_lookup("default"));
+
+ if (ret == 0)
+ goto err;
+
+ if (store && store->check_issued)
+ ctx->check_issued = store->check_issued;
+ else
+ ctx->check_issued = check_issued;
+
+ if (store && store->get_issuer)
+ ctx->get_issuer = store->get_issuer;
+ else
+ ctx->get_issuer = X509_STORE_CTX_get1_issuer;
+
+ if (store && store->verify_cb)
+ ctx->verify_cb = store->verify_cb;
+ else
+ ctx->verify_cb = null_callback;
+
+ if (store && store->verify)
+ ctx->verify = store->verify;
+ else
+ ctx->verify = internal_verify;
+
+ if (store && store->check_revocation)
+ ctx->check_revocation = store->check_revocation;
+ else
+ ctx->check_revocation = check_revocation;
+
+ if (store && store->get_crl)
+ ctx->get_crl = store->get_crl;
+ else
+ ctx->get_crl = NULL;
+
+ if (store && store->check_crl)
+ ctx->check_crl = store->check_crl;
+ else
+ ctx->check_crl = check_crl;
+
+ if (store && store->cert_crl)
+ ctx->cert_crl = store->cert_crl;
+ else
+ ctx->cert_crl = cert_crl;
+
+ if (store && store->lookup_certs)
+ ctx->lookup_certs = store->lookup_certs;
+ else
+ ctx->lookup_certs = X509_STORE_get1_certs;
+
+ if (store && store->lookup_crls)
+ ctx->lookup_crls = store->lookup_crls;
+ else
+ ctx->lookup_crls = X509_STORE_get1_crls;
+
+ ctx->check_policy = check_policy;
+
+ return 1;
+
+ err:
+ 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, ERR_R_MALLOC_FAILURE);
+ return 0;
+}
+
+/*
+ * Set alternative lookup method: just a STACK of trusted certificates. This
+ * avoids X509_STORE nastiness where it isn't needed.
*/
void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
{
- ctx->other_ctx = sk;
- ctx->get_issuer = get_issuer_sk;
+ ctx->other_ctx = sk;
+ ctx->get_issuer = get_issuer_sk;
}
void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx)
- {
- if (ctx->cleanup) ctx->cleanup(ctx);
- if (ctx->param != NULL)
- {
- if (ctx->parent == NULL)
- X509_VERIFY_PARAM_free(ctx->param);
- ctx->param=NULL;
- }
- if (ctx->tree != NULL)
- {
- X509_policy_tree_free(ctx->tree);
- ctx->tree=NULL;
- }
- if (ctx->chain != NULL)
- {
- sk_X509_pop_free(ctx->chain,X509_free);
- ctx->chain=NULL;
- }
- CRYPTO_free_ex_data(&g_ex_data_class, ctx, &(ctx->ex_data));
- memset(&ctx->ex_data,0,sizeof(CRYPTO_EX_DATA));
- }
+{
+ /* We need to be idempotent because, unfortunately, |X509_STORE_CTX_free|
+ * also calls this function. */
+ if (ctx->cleanup != NULL) {
+ ctx->cleanup(ctx);
+ ctx->cleanup = NULL;
+ }
+ if (ctx->param != NULL) {
+ if (ctx->parent == NULL)
+ X509_VERIFY_PARAM_free(ctx->param);
+ ctx->param = NULL;
+ }
+ if (ctx->tree != NULL) {
+ X509_policy_tree_free(ctx->tree);
+ ctx->tree = NULL;
+ }
+ if (ctx->chain != NULL) {
+ sk_X509_pop_free(ctx->chain, X509_free);
+ ctx->chain = NULL;
+ }
+ CRYPTO_free_ex_data(&g_ex_data_class, ctx, &(ctx->ex_data));
+ memset(&ctx->ex_data, 0, sizeof(CRYPTO_EX_DATA));
+}
void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth)
- {
- X509_VERIFY_PARAM_set_depth(ctx->param, depth);
- }
+{
+ X509_VERIFY_PARAM_set_depth(ctx->param, depth);
+}
void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags)
- {
- X509_VERIFY_PARAM_set_flags(ctx->param, flags);
- }
+{
+ X509_VERIFY_PARAM_set_flags(ctx->param, flags);
+}
-void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, time_t t)
- {
- X509_VERIFY_PARAM_set_time(ctx->param, t);
- }
+void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags,
+ time_t t)
+{
+ X509_VERIFY_PARAM_set_time(ctx->param, t);
+}
void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx,
- int (*verify_cb)(int, X509_STORE_CTX *))
- {
- ctx->verify_cb=verify_cb;
- }
+ int (*verify_cb) (int, X509_STORE_CTX *))
+{
+ ctx->verify_cb = verify_cb;
+}
X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx)
- {
- return ctx->tree;
- }
+{
+ return ctx->tree;
+}
int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx)
- {
- return ctx->explicit_policy;
- }
+{
+ return ctx->explicit_policy;
+}
int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name)
- {
- const X509_VERIFY_PARAM *param;
- param = X509_VERIFY_PARAM_lookup(name);
- if (!param)
- return 0;
- return X509_VERIFY_PARAM_inherit(ctx->param, param);
- }
+{
+ const X509_VERIFY_PARAM *param;
+ param = X509_VERIFY_PARAM_lookup(name);
+ if (!param)
+ return 0;
+ return X509_VERIFY_PARAM_inherit(ctx->param, param);
+}
X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx)
- {
- return ctx->param;
- }
+{
+ return ctx->param;
+}
void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param)
- {
- if (ctx->param)
- X509_VERIFY_PARAM_free(ctx->param);
- ctx->param = param;
- }
+{
+ if (ctx->param)
+ X509_VERIFY_PARAM_free(ctx->param);
+ ctx->param = param;
+}
IMPLEMENT_ASN1_SET_OF(X509)
+
IMPLEMENT_ASN1_SET_OF(X509_ATTRIBUTE)
diff --git a/src/crypto/x509/x509_vpm.c b/src/crypto/x509/x509_vpm.c
index 8c8f98ea..b51bc176 100644
--- a/src/crypto/x509/x509_vpm.c
+++ b/src/crypto/x509/x509_vpm.c
@@ -1,5 +1,7 @@
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2004. */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2004.
+ */
/* ====================================================================
* Copyright (c) 2004 The OpenSSL Project. All rights reserved.
*
@@ -8,7 +10,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -64,609 +66,571 @@
#include "vpm_int.h"
-
/* X509_VERIFY_PARAM functions */
#define SET_HOST 0
#define ADD_HOST 1
-static char *str_copy(char *s) { return OPENSSL_strdup(s); }
-static void str_free(char *s) { OPENSSL_free(s); }
+static char *str_copy(char *s)
+{
+ return OPENSSL_strdup(s);
+}
+
+static void str_free(char *s)
+{
+ OPENSSL_free(s);
+}
#define string_stack_free(sk) sk_OPENSSL_STRING_pop_free(sk, str_free)
static int int_x509_param_set_hosts(X509_VERIFY_PARAM_ID *id, int mode,
- const char *name, size_t namelen)
- {
- char *copy;
-
- /*
- * Refuse names with embedded NUL bytes.
- * XXX: Do we need to push an error onto the error stack?
- */
- if (name && memchr(name, '\0', namelen))
- return 0;
-
- if (mode == SET_HOST && id->hosts)
- {
- string_stack_free(id->hosts);
- id->hosts = NULL;
- }
- if (name == NULL || namelen == 0)
- return 1;
-
- copy = BUF_strndup(name, namelen);
- if (copy == NULL)
- return 0;
-
- if (id->hosts == NULL &&
- (id->hosts = sk_OPENSSL_STRING_new_null()) == NULL)
- {
- OPENSSL_free(copy);
- return 0;
- }
-
- if (!sk_OPENSSL_STRING_push(id->hosts, copy))
- {
- OPENSSL_free(copy);
- if (sk_OPENSSL_STRING_num(id->hosts) == 0)
- {
- sk_OPENSSL_STRING_free(id->hosts);
- id->hosts = NULL;
- }
- return 0;
- }
-
- return 1;
- }
+ const char *name, size_t namelen)
+{
+ char *copy;
+
+ /*
+ * Refuse names with embedded NUL bytes.
+ * XXX: Do we need to push an error onto the error stack?
+ */
+ if (name && memchr(name, '\0', namelen))
+ return 0;
+
+ if (mode == SET_HOST && id->hosts) {
+ string_stack_free(id->hosts);
+ id->hosts = NULL;
+ }
+ if (name == NULL || namelen == 0)
+ return 1;
+
+ copy = BUF_strndup(name, namelen);
+ if (copy == NULL)
+ return 0;
+
+ if (id->hosts == NULL &&
+ (id->hosts = sk_OPENSSL_STRING_new_null()) == NULL) {
+ OPENSSL_free(copy);
+ return 0;
+ }
+
+ if (!sk_OPENSSL_STRING_push(id->hosts, copy)) {
+ OPENSSL_free(copy);
+ if (sk_OPENSSL_STRING_num(id->hosts) == 0) {
+ sk_OPENSSL_STRING_free(id->hosts);
+ id->hosts = NULL;
+ }
+ return 0;
+ }
+
+ return 1;
+}
static void x509_verify_param_zero(X509_VERIFY_PARAM *param)
- {
- X509_VERIFY_PARAM_ID *paramid;
- if (!param)
- return;
- param->name = NULL;
- param->purpose = 0;
- param->trust = 0;
- /*param->inh_flags = X509_VP_FLAG_DEFAULT;*/
- param->inh_flags = 0;
- param->flags = 0;
- param->depth = -1;
- if (param->policies)
- {
- sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free);
- param->policies = NULL;
- }
- paramid = param->id;
- if (paramid->hosts)
- {
- string_stack_free(paramid->hosts);
- paramid->hosts = NULL;
- }
- if (paramid->peername)
- {
- OPENSSL_free(paramid->peername);
- paramid->peername = NULL;
- }
- if (paramid->email)
- {
- OPENSSL_free(paramid->email);
- paramid->email = NULL;
- paramid->emaillen = 0;
- }
- if (paramid->ip)
- {
- OPENSSL_free(paramid->ip);
- paramid->ip = NULL;
- paramid->iplen = 0;
- }
-
- }
+{
+ X509_VERIFY_PARAM_ID *paramid;
+ if (!param)
+ return;
+ param->name = NULL;
+ param->purpose = 0;
+ param->trust = 0;
+ /*
+ * param->inh_flags = X509_VP_FLAG_DEFAULT;
+ */
+ param->inh_flags = 0;
+ param->flags = 0;
+ param->depth = -1;
+ if (param->policies) {
+ sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free);
+ param->policies = NULL;
+ }
+ paramid = param->id;
+ if (paramid->hosts) {
+ string_stack_free(paramid->hosts);
+ paramid->hosts = NULL;
+ }
+ if (paramid->peername) {
+ OPENSSL_free(paramid->peername);
+ paramid->peername = NULL;
+ }
+ if (paramid->email) {
+ OPENSSL_free(paramid->email);
+ paramid->email = NULL;
+ paramid->emaillen = 0;
+ }
+ if (paramid->ip) {
+ OPENSSL_free(paramid->ip);
+ paramid->ip = NULL;
+ paramid->iplen = 0;
+ }
+
+}
X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void)
- {
- X509_VERIFY_PARAM *param;
- X509_VERIFY_PARAM_ID *paramid;
- param = OPENSSL_malloc(sizeof(X509_VERIFY_PARAM));
- if (!param)
- return NULL;
- paramid = OPENSSL_malloc(sizeof(X509_VERIFY_PARAM_ID));
- if (!paramid)
- {
- OPENSSL_free(param);
- return NULL;
- }
- memset(param, 0, sizeof(X509_VERIFY_PARAM));
- memset(paramid, 0, sizeof(X509_VERIFY_PARAM_ID));
- param->id = paramid;
- x509_verify_param_zero(param);
- return param;
- }
+{
+ X509_VERIFY_PARAM *param;
+ X509_VERIFY_PARAM_ID *paramid;
+ param = OPENSSL_malloc(sizeof(X509_VERIFY_PARAM));
+ if (!param)
+ return NULL;
+ paramid = OPENSSL_malloc(sizeof(X509_VERIFY_PARAM_ID));
+ if (!paramid) {
+ OPENSSL_free(param);
+ return NULL;
+ }
+ memset(param, 0, sizeof(X509_VERIFY_PARAM));
+ memset(paramid, 0, sizeof(X509_VERIFY_PARAM_ID));
+ param->id = paramid;
+ x509_verify_param_zero(param);
+ return param;
+}
void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param)
- {
- if (param == NULL)
- return;
- x509_verify_param_zero(param);
- OPENSSL_free(param->id);
- OPENSSL_free(param);
- }
-
-/* This function determines how parameters are "inherited" from one structure
- * to another. There are several different ways this can happen.
- *
- * 1. If a child structure needs to have its values initialized from a parent
- * they are simply copied across. For example SSL_CTX copied to SSL.
- * 2. If the structure should take on values only if they are currently unset.
- * For example the values in an SSL structure will take appropriate value
- * for SSL servers or clients but only if the application has not set new
- * ones.
- *
- * The "inh_flags" field determines how this function behaves.
- *
- * Normally any values which are set in the default are not copied from the
- * destination and verify flags are ORed together.
- *
- * If X509_VP_FLAG_DEFAULT is set then anything set in the source is copied
- * to the destination. Effectively the values in "to" become default values
- * which will be used only if nothing new is set in "from".
- *
- * If X509_VP_FLAG_OVERWRITE is set then all value are copied across whether
- * they are set or not. Flags is still Ored though.
- *
- * If X509_VP_FLAG_RESET_FLAGS is set then the flags value is copied instead
- * of ORed.
- *
- * If X509_VP_FLAG_LOCKED is set then no values are copied.
- *
- * If X509_VP_FLAG_ONCE is set then the current inh_flags setting is zeroed
- * after the next call.
+{
+ if (param == NULL)
+ return;
+ x509_verify_param_zero(param);
+ OPENSSL_free(param->id);
+ OPENSSL_free(param);
+}
+
+/*
+ * This function determines how parameters are "inherited" from one structure
+ * to another. There are several different ways this can happen. 1. If a
+ * child structure needs to have its values initialized from a parent they are
+ * simply copied across. For example SSL_CTX copied to SSL. 2. If the
+ * structure should take on values only if they are currently unset. For
+ * example the values in an SSL structure will take appropriate value for SSL
+ * servers or clients but only if the application has not set new ones. The
+ * "inh_flags" field determines how this function behaves. Normally any
+ * values which are set in the default are not copied from the destination and
+ * verify flags are ORed together. If X509_VP_FLAG_DEFAULT is set then
+ * anything set in the source is copied to the destination. Effectively the
+ * values in "to" become default values which will be used only if nothing new
+ * is set in "from". If X509_VP_FLAG_OVERWRITE is set then all value are
+ * copied across whether they are set or not. Flags is still Ored though. If
+ * X509_VP_FLAG_RESET_FLAGS is set then the flags value is copied instead of
+ * ORed. If X509_VP_FLAG_LOCKED is set then no values are copied. If
+ * X509_VP_FLAG_ONCE is set then the current inh_flags setting is zeroed after
+ * the next call.
*/
/* Macro to test if a field should be copied from src to dest */
#define test_x509_verify_param_copy(field, def) \
- (to_overwrite || \
- ((src->field != def) && (to_default || (dest->field == def))))
+ (to_overwrite || \
+ ((src->field != def) && (to_default || (dest->field == def))))
/* As above but for ID fields */
#define test_x509_verify_param_copy_id(idf, def) \
- test_x509_verify_param_copy(id->idf, def)
+ test_x509_verify_param_copy(id->idf, def)
/* Macro to test and copy a field if necessary */
#define x509_verify_param_copy(field, def) \
- if (test_x509_verify_param_copy(field, def)) \
- dest->field = src->field
-
+ if (test_x509_verify_param_copy(field, def)) \
+ dest->field = src->field
int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest,
- const X509_VERIFY_PARAM *src)
- {
- unsigned long inh_flags;
- int to_default, to_overwrite;
- X509_VERIFY_PARAM_ID *id;
- if (!src)
- return 1;
- id = src->id;
- inh_flags = dest->inh_flags | src->inh_flags;
-
- if (inh_flags & X509_VP_FLAG_ONCE)
- dest->inh_flags = 0;
-
- if (inh_flags & X509_VP_FLAG_LOCKED)
- return 1;
-
- if (inh_flags & X509_VP_FLAG_DEFAULT)
- to_default = 1;
- else
- to_default = 0;
-
- if (inh_flags & X509_VP_FLAG_OVERWRITE)
- to_overwrite = 1;
- else
- to_overwrite = 0;
-
- x509_verify_param_copy(purpose, 0);
- x509_verify_param_copy(trust, 0);
- x509_verify_param_copy(depth, -1);
-
- /* If overwrite or check time not set, copy across */
-
- if (to_overwrite || !(dest->flags & X509_V_FLAG_USE_CHECK_TIME))
- {
- dest->check_time = src->check_time;
- dest->flags &= ~X509_V_FLAG_USE_CHECK_TIME;
- /* Don't need to copy flag: that is done below */
- }
-
- if (inh_flags & X509_VP_FLAG_RESET_FLAGS)
- dest->flags = 0;
-
- dest->flags |= src->flags;
-
- if (test_x509_verify_param_copy(policies, NULL))
- {
- if (!X509_VERIFY_PARAM_set1_policies(dest, src->policies))
- return 0;
- }
-
- /* Copy the host flags if and only if we're copying the host list */
- if (test_x509_verify_param_copy_id(hosts, NULL))
- {
- if (dest->id->hosts)
- {
- string_stack_free(dest->id->hosts);
- dest->id->hosts = NULL;
- }
- if (id->hosts)
- {
- dest->id->hosts =
- sk_OPENSSL_STRING_deep_copy(id->hosts,
- str_copy, str_free);
- if (dest->id->hosts == NULL)
- return 0;
- dest->id->hostflags = id->hostflags;
- }
- }
-
- if (test_x509_verify_param_copy_id(email, NULL))
- {
- if (!X509_VERIFY_PARAM_set1_email(dest, id->email, id->emaillen))
- return 0;
- }
-
- if (test_x509_verify_param_copy_id(ip, NULL))
- {
- if (!X509_VERIFY_PARAM_set1_ip(dest, id->ip, id->iplen))
- return 0;
- }
-
- return 1;
- }
+ const X509_VERIFY_PARAM *src)
+{
+ unsigned long inh_flags;
+ int to_default, to_overwrite;
+ X509_VERIFY_PARAM_ID *id;
+ if (!src)
+ return 1;
+ id = src->id;
+ inh_flags = dest->inh_flags | src->inh_flags;
+
+ if (inh_flags & X509_VP_FLAG_ONCE)
+ dest->inh_flags = 0;
+
+ if (inh_flags & X509_VP_FLAG_LOCKED)
+ return 1;
+
+ if (inh_flags & X509_VP_FLAG_DEFAULT)
+ to_default = 1;
+ else
+ to_default = 0;
+
+ if (inh_flags & X509_VP_FLAG_OVERWRITE)
+ to_overwrite = 1;
+ else
+ to_overwrite = 0;
+
+ x509_verify_param_copy(purpose, 0);
+ x509_verify_param_copy(trust, 0);
+ x509_verify_param_copy(depth, -1);
+
+ /* If overwrite or check time not set, copy across */
+
+ if (to_overwrite || !(dest->flags & X509_V_FLAG_USE_CHECK_TIME)) {
+ dest->check_time = src->check_time;
+ dest->flags &= ~X509_V_FLAG_USE_CHECK_TIME;
+ /* Don't need to copy flag: that is done below */
+ }
+
+ if (inh_flags & X509_VP_FLAG_RESET_FLAGS)
+ dest->flags = 0;
+
+ dest->flags |= src->flags;
+
+ if (test_x509_verify_param_copy(policies, NULL)) {
+ if (!X509_VERIFY_PARAM_set1_policies(dest, src->policies))
+ return 0;
+ }
+
+ /* Copy the host flags if and only if we're copying the host list */
+ if (test_x509_verify_param_copy_id(hosts, NULL)) {
+ if (dest->id->hosts) {
+ string_stack_free(dest->id->hosts);
+ dest->id->hosts = NULL;
+ }
+ if (id->hosts) {
+ dest->id->hosts =
+ sk_OPENSSL_STRING_deep_copy(id->hosts, str_copy, str_free);
+ if (dest->id->hosts == NULL)
+ return 0;
+ dest->id->hostflags = id->hostflags;
+ }
+ }
+
+ if (test_x509_verify_param_copy_id(email, NULL)) {
+ if (!X509_VERIFY_PARAM_set1_email(dest, id->email, id->emaillen))
+ return 0;
+ }
+
+ if (test_x509_verify_param_copy_id(ip, NULL)) {
+ if (!X509_VERIFY_PARAM_set1_ip(dest, id->ip, id->iplen))
+ return 0;
+ }
+
+ return 1;
+}
int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to,
- const X509_VERIFY_PARAM *from)
- {
- unsigned long save_flags = to->inh_flags;
- int ret;
- to->inh_flags |= X509_VP_FLAG_DEFAULT;
- ret = X509_VERIFY_PARAM_inherit(to, from);
- to->inh_flags = save_flags;
- return ret;
- }
+ const X509_VERIFY_PARAM *from)
+{
+ unsigned long save_flags = to->inh_flags;
+ int ret;
+ to->inh_flags |= X509_VP_FLAG_DEFAULT;
+ ret = X509_VERIFY_PARAM_inherit(to, from);
+ to->inh_flags = save_flags;
+ return ret;
+}
static int int_x509_param_set1(char **pdest, size_t *pdestlen,
- const char *src, size_t srclen)
- {
- void *tmp;
- if (src)
- {
- if (srclen == 0)
- {
- tmp = BUF_strdup(src);
- srclen = strlen(src);
- }
- else
- tmp = BUF_memdup(src, srclen);
- if (!tmp)
- return 0;
- }
- else
- {
- tmp = NULL;
- srclen = 0;
- }
- if (*pdest)
- OPENSSL_free(*pdest);
- *pdest = tmp;
- if (pdestlen)
- *pdestlen = srclen;
- return 1;
- }
+ const char *src, size_t srclen)
+{
+ void *tmp;
+ if (src) {
+ if (srclen == 0) {
+ tmp = BUF_strdup(src);
+ srclen = strlen(src);
+ } else
+ tmp = BUF_memdup(src, srclen);
+ if (!tmp)
+ return 0;
+ } else {
+ tmp = NULL;
+ srclen = 0;
+ }
+ if (*pdest)
+ OPENSSL_free(*pdest);
+ *pdest = tmp;
+ if (pdestlen)
+ *pdestlen = srclen;
+ return 1;
+}
int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name)
- {
- if (param->name)
- OPENSSL_free(param->name);
- param->name = BUF_strdup(name);
- if (param->name)
- return 1;
- return 0;
- }
+{
+ if (param->name)
+ OPENSSL_free(param->name);
+ param->name = BUF_strdup(name);
+ if (param->name)
+ return 1;
+ return 0;
+}
int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags)
- {
- param->flags |= flags;
- if (flags & X509_V_FLAG_POLICY_MASK)
- param->flags |= X509_V_FLAG_POLICY_CHECK;
- return 1;
- }
-
-int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, unsigned long flags)
- {
- param->flags &= ~flags;
- return 1;
- }
+{
+ param->flags |= flags;
+ if (flags & X509_V_FLAG_POLICY_MASK)
+ param->flags |= X509_V_FLAG_POLICY_CHECK;
+ return 1;
+}
+
+int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param,
+ unsigned long flags)
+{
+ param->flags &= ~flags;
+ return 1;
+}
unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param)
- {
- return param->flags;
- }
+{
+ return param->flags;
+}
int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose)
- {
- return X509_PURPOSE_set(&param->purpose, purpose);
- }
+{
+ return X509_PURPOSE_set(&param->purpose, purpose);
+}
int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust)
- {
- return X509_TRUST_set(&param->trust, trust);
- }
+{
+ return X509_TRUST_set(&param->trust, trust);
+}
void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth)
- {
- param->depth = depth;
- }
+{
+ param->depth = depth;
+}
void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t)
- {
- param->check_time = t;
- param->flags |= X509_V_FLAG_USE_CHECK_TIME;
- }
-
-int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, ASN1_OBJECT *policy)
- {
- if (!param->policies)
- {
- param->policies = sk_ASN1_OBJECT_new_null();
- if (!param->policies)
- return 0;
- }
- if (!sk_ASN1_OBJECT_push(param->policies, policy))
- return 0;
- return 1;
- }
-
-int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param,
- STACK_OF(ASN1_OBJECT) *policies)
- {
- size_t i;
- ASN1_OBJECT *oid, *doid;
- if (!param)
- return 0;
- if (param->policies)
- sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free);
-
- if (!policies)
- {
- param->policies = NULL;
- return 1;
- }
-
- param->policies = sk_ASN1_OBJECT_new_null();
- if (!param->policies)
- return 0;
-
- for (i = 0; i < sk_ASN1_OBJECT_num(policies); i++)
- {
- oid = sk_ASN1_OBJECT_value(policies, i);
- doid = OBJ_dup(oid);
- if (!doid)
- return 0;
- if (!sk_ASN1_OBJECT_push(param->policies, doid))
- {
- ASN1_OBJECT_free(doid);
- return 0;
- }
- }
- param->flags |= X509_V_FLAG_POLICY_CHECK;
- return 1;
- }
+{
+ param->check_time = t;
+ param->flags |= X509_V_FLAG_USE_CHECK_TIME;
+}
+
+int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param,
+ ASN1_OBJECT *policy)
+{
+ if (!param->policies) {
+ param->policies = sk_ASN1_OBJECT_new_null();
+ if (!param->policies)
+ return 0;
+ }
+ if (!sk_ASN1_OBJECT_push(param->policies, policy))
+ return 0;
+ return 1;
+}
+
+int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param,
+ STACK_OF(ASN1_OBJECT) *policies)
+{
+ size_t i;
+ ASN1_OBJECT *oid, *doid;
+ if (!param)
+ return 0;
+ if (param->policies)
+ sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free);
+
+ if (!policies) {
+ param->policies = NULL;
+ return 1;
+ }
+
+ param->policies = sk_ASN1_OBJECT_new_null();
+ if (!param->policies)
+ return 0;
+
+ for (i = 0; i < sk_ASN1_OBJECT_num(policies); i++) {
+ oid = sk_ASN1_OBJECT_value(policies, i);
+ doid = OBJ_dup(oid);
+ if (!doid)
+ return 0;
+ if (!sk_ASN1_OBJECT_push(param->policies, doid)) {
+ ASN1_OBJECT_free(doid);
+ return 0;
+ }
+ }
+ param->flags |= X509_V_FLAG_POLICY_CHECK;
+ return 1;
+}
int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param,
- const char *name, size_t namelen)
- {
- return int_x509_param_set_hosts(param->id, SET_HOST, name, namelen);
- }
+ const char *name, size_t namelen)
+{
+ return int_x509_param_set_hosts(param->id, SET_HOST, name, namelen);
+}
int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param,
- const char *name, size_t namelen)
- {
- return int_x509_param_set_hosts(param->id, ADD_HOST, name, namelen);
- }
+ const char *name, size_t namelen)
+{
+ return int_x509_param_set_hosts(param->id, ADD_HOST, name, namelen);
+}
void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param,
- unsigned int flags)
- {
- param->id->hostflags = flags;
- }
+ unsigned int flags)
+{
+ param->id->hostflags = flags;
+}
char *X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *param)
- {
- return param->id->peername;
- }
+{
+ return param->id->peername;
+}
int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param,
- const char *email, size_t emaillen)
- {
- return int_x509_param_set1(&param->id->email, &param->id->emaillen,
- email, emaillen);
- }
+ const char *email, size_t emaillen)
+{
+ return int_x509_param_set1(&param->id->email, &param->id->emaillen,
+ email, emaillen);
+}
int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param,
- const unsigned char *ip, size_t iplen)
- {
- if (iplen != 0 && iplen != 4 && iplen != 16)
- return 0;
- return int_x509_param_set1((char **)&param->id->ip, &param->id->iplen,
- (char *)ip, iplen);
- }
+ const unsigned char *ip, size_t iplen)
+{
+ if (iplen != 0 && iplen != 4 && iplen != 16)
+ return 0;
+ return int_x509_param_set1((char **)&param->id->ip, &param->id->iplen,
+ (char *)ip, iplen);
+}
int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, const char *ipasc)
- {
- unsigned char ipout[16];
- size_t iplen;
+{
+ unsigned char ipout[16];
+ size_t iplen;
- iplen = (size_t) a2i_ipadd(ipout, ipasc);
- if (iplen == 0)
- return 0;
- return X509_VERIFY_PARAM_set1_ip(param, ipout, iplen);
- }
+ iplen = (size_t)a2i_ipadd(ipout, ipasc);
+ if (iplen == 0)
+ return 0;
+ return X509_VERIFY_PARAM_set1_ip(param, ipout, iplen);
+}
int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param)
- {
- return param->depth;
- }
+{
+ return param->depth;
+}
const char *X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param)
- {
- return param->name;
- }
+{
+ return param->name;
+}
-static const X509_VERIFY_PARAM_ID _empty_id = {NULL, 0U, NULL, NULL, 0, NULL, 0};
+static const X509_VERIFY_PARAM_ID _empty_id =
+ { NULL, 0U, NULL, NULL, 0, NULL, 0 };
#define vpm_empty_id (X509_VERIFY_PARAM_ID *)&_empty_id
-/* Default verify parameters: these are used for various
- * applications and can be overridden by the user specified table.
- * NB: the 'name' field *must* be in alphabetical order because it
- * will be searched using OBJ_search.
+/*
+ * Default verify parameters: these are used for various applications and can
+ * be overridden by the user specified table. NB: the 'name' field *must* be
+ * in alphabetical order because it will be searched using OBJ_search.
*/
static const X509_VERIFY_PARAM default_table[] = {
- {
- (char *) "default", /* X509 default parameters */
- 0, /* Check time */
- 0, /* internal flags */
- 0, /* flags */
- 0, /* purpose */
- 0, /* trust */
- 100, /* depth */
- NULL, /* policies */
- vpm_empty_id
- },
- {
- (char *) "pkcs7", /* S/MIME sign parameters */
- 0, /* Check time */
- 0, /* internal flags */
- 0, /* flags */
- X509_PURPOSE_SMIME_SIGN, /* purpose */
- X509_TRUST_EMAIL, /* trust */
- -1, /* depth */
- NULL, /* policies */
- vpm_empty_id
- },
- {
- (char *) "smime_sign", /* S/MIME sign parameters */
- 0, /* Check time */
- 0, /* internal flags */
- 0, /* flags */
- X509_PURPOSE_SMIME_SIGN, /* purpose */
- X509_TRUST_EMAIL, /* trust */
- -1, /* depth */
- NULL, /* policies */
- vpm_empty_id
- },
- {
- (char *) "ssl_client", /* SSL/TLS client parameters */
- 0, /* Check time */
- 0, /* internal flags */
- 0, /* flags */
- X509_PURPOSE_SSL_CLIENT, /* purpose */
- X509_TRUST_SSL_CLIENT, /* trust */
- -1, /* depth */
- NULL, /* policies */
- vpm_empty_id
- },
- {
- (char *) "ssl_server", /* SSL/TLS server parameters */
- 0, /* Check time */
- 0, /* internal flags */
- 0, /* flags */
- X509_PURPOSE_SSL_SERVER, /* purpose */
- X509_TRUST_SSL_SERVER, /* trust */
- -1, /* depth */
- NULL, /* policies */
- vpm_empty_id
- }};
+ {
+ (char *)"default", /* X509 default parameters */
+ 0, /* Check time */
+ 0, /* internal flags */
+ 0, /* flags */
+ 0, /* purpose */
+ 0, /* trust */
+ 100, /* depth */
+ NULL, /* policies */
+ vpm_empty_id},
+ {
+ (char *)"pkcs7", /* S/MIME sign parameters */
+ 0, /* Check time */
+ 0, /* internal flags */
+ 0, /* flags */
+ X509_PURPOSE_SMIME_SIGN, /* purpose */
+ X509_TRUST_EMAIL, /* trust */
+ -1, /* depth */
+ NULL, /* policies */
+ vpm_empty_id},
+ {
+ (char *)"smime_sign", /* S/MIME sign parameters */
+ 0, /* Check time */
+ 0, /* internal flags */
+ 0, /* flags */
+ X509_PURPOSE_SMIME_SIGN, /* purpose */
+ X509_TRUST_EMAIL, /* trust */
+ -1, /* depth */
+ NULL, /* policies */
+ vpm_empty_id},
+ {
+ (char *)"ssl_client", /* SSL/TLS client parameters */
+ 0, /* Check time */
+ 0, /* internal flags */
+ 0, /* flags */
+ X509_PURPOSE_SSL_CLIENT, /* purpose */
+ X509_TRUST_SSL_CLIENT, /* trust */
+ -1, /* depth */
+ NULL, /* policies */
+ vpm_empty_id},
+ {
+ (char *)"ssl_server", /* SSL/TLS server parameters */
+ 0, /* Check time */
+ 0, /* internal flags */
+ 0, /* flags */
+ X509_PURPOSE_SSL_SERVER, /* purpose */
+ X509_TRUST_SSL_SERVER, /* trust */
+ -1, /* depth */
+ NULL, /* policies */
+ vpm_empty_id}
+};
static STACK_OF(X509_VERIFY_PARAM) *param_table = NULL;
-static int param_cmp(const X509_VERIFY_PARAM **a,
- const X509_VERIFY_PARAM **b)
- {
- return strcmp((*a)->name, (*b)->name);
- }
+static int param_cmp(const X509_VERIFY_PARAM **a, const X509_VERIFY_PARAM **b)
+{
+ return strcmp((*a)->name, (*b)->name);
+}
int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param)
- {
- X509_VERIFY_PARAM *ptmp;
- if (!param_table)
- {
- param_table = sk_X509_VERIFY_PARAM_new(param_cmp);
- if (!param_table)
- return 0;
- }
- else
- {
- size_t idx;
-
- if (sk_X509_VERIFY_PARAM_find(param_table, &idx, param))
- {
- ptmp = sk_X509_VERIFY_PARAM_value(param_table, idx);
- X509_VERIFY_PARAM_free(ptmp);
- (void)sk_X509_VERIFY_PARAM_delete(param_table, idx);
- }
- }
- if (!sk_X509_VERIFY_PARAM_push(param_table, param))
- return 0;
- return 1;
- }
+{
+ X509_VERIFY_PARAM *ptmp;
+ if (!param_table) {
+ param_table = sk_X509_VERIFY_PARAM_new(param_cmp);
+ if (!param_table)
+ return 0;
+ } else {
+ size_t idx;
+
+ if (sk_X509_VERIFY_PARAM_find(param_table, &idx, param)) {
+ ptmp = sk_X509_VERIFY_PARAM_value(param_table, idx);
+ X509_VERIFY_PARAM_free(ptmp);
+ (void)sk_X509_VERIFY_PARAM_delete(param_table, idx);
+ }
+ }
+ if (!sk_X509_VERIFY_PARAM_push(param_table, param))
+ return 0;
+ return 1;
+}
int X509_VERIFY_PARAM_get_count(void)
- {
- int num = sizeof(default_table)/sizeof(X509_VERIFY_PARAM);
- if (param_table)
- num += sk_X509_VERIFY_PARAM_num(param_table);
- return num;
- }
+{
+ int num = sizeof(default_table) / sizeof(X509_VERIFY_PARAM);
+ if (param_table)
+ num += sk_X509_VERIFY_PARAM_num(param_table);
+ return num;
+}
const X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id)
- {
- int num = sizeof(default_table)/sizeof(X509_VERIFY_PARAM);
- if (id < num)
- return default_table + id;
- return sk_X509_VERIFY_PARAM_value(param_table, id - num);
- }
+{
+ int num = sizeof(default_table) / sizeof(X509_VERIFY_PARAM);
+ if (id < num)
+ return default_table + id;
+ return sk_X509_VERIFY_PARAM_value(param_table, id - num);
+}
const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name)
- {
- X509_VERIFY_PARAM pm;
- unsigned i, limit;
-
- pm.name = (char *)name;
- if (param_table)
- {
- size_t idx;
- if (sk_X509_VERIFY_PARAM_find(param_table, &idx, &pm))
- return sk_X509_VERIFY_PARAM_value(param_table, idx);
- }
-
- limit = sizeof(default_table)/sizeof(X509_VERIFY_PARAM);
- for (i = 0; i < limit; i++) {
- if (strcmp(default_table[i].name, name) == 0) {
- return &default_table[i];
- }
- }
- return NULL;
- }
+{
+ X509_VERIFY_PARAM pm;
+ unsigned i, limit;
+
+ pm.name = (char *)name;
+ if (param_table) {
+ size_t idx;
+ if (sk_X509_VERIFY_PARAM_find(param_table, &idx, &pm))
+ return sk_X509_VERIFY_PARAM_value(param_table, idx);
+ }
+
+ limit = sizeof(default_table) / sizeof(X509_VERIFY_PARAM);
+ for (i = 0; i < limit; i++) {
+ if (strcmp(default_table[i].name, name) == 0) {
+ return &default_table[i];
+ }
+ }
+ return NULL;
+}
void X509_VERIFY_PARAM_table_cleanup(void)
- {
- if (param_table)
- sk_X509_VERIFY_PARAM_pop_free(param_table,
- X509_VERIFY_PARAM_free);
- param_table = NULL;
- }
+{
+ if (param_table)
+ sk_X509_VERIFY_PARAM_pop_free(param_table, X509_VERIFY_PARAM_free);
+ param_table = NULL;
+}
diff --git a/src/crypto/x509/x509cset.c b/src/crypto/x509/x509cset.c
index 82d61d06..a292710e 100644
--- a/src/crypto/x509/x509cset.c
+++ b/src/crypto/x509/x509cset.c
@@ -1,5 +1,7 @@
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2001. */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2001.
+ */
/* ====================================================================
* Copyright (c) 2001 The OpenSSL Project. All rights reserved.
*
@@ -8,7 +10,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -59,114 +61,109 @@
#include "../internal.h"
-
int X509_CRL_set_version(X509_CRL *x, long version)
- {
- if (x == NULL) return(0);
- if (x->crl->version == NULL)
- {
- if ((x->crl->version=M_ASN1_INTEGER_new()) == NULL)
- return(0);
- }
- return(ASN1_INTEGER_set(x->crl->version,version));
- }
+{
+ if (x == NULL)
+ return (0);
+ if (x->crl->version == NULL) {
+ if ((x->crl->version = M_ASN1_INTEGER_new()) == NULL)
+ return (0);
+ }
+ return (ASN1_INTEGER_set(x->crl->version, version));
+}
int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name)
- {
- if ((x == NULL) || (x->crl == NULL)) return(0);
- return(X509_NAME_set(&x->crl->issuer,name));
- }
-
+{
+ if ((x == NULL) || (x->crl == NULL))
+ return (0);
+ return (X509_NAME_set(&x->crl->issuer, name));
+}
int X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm)
- {
- ASN1_TIME *in;
-
- if (x == NULL) return(0);
- in=x->crl->lastUpdate;
- if (in != tm)
- {
- in=M_ASN1_TIME_dup(tm);
- if (in != NULL)
- {
- M_ASN1_TIME_free(x->crl->lastUpdate);
- x->crl->lastUpdate=in;
- }
- }
- return(in != NULL);
- }
+{
+ ASN1_TIME *in;
+
+ if (x == NULL)
+ return (0);
+ in = x->crl->lastUpdate;
+ if (in != tm) {
+ in = M_ASN1_TIME_dup(tm);
+ if (in != NULL) {
+ M_ASN1_TIME_free(x->crl->lastUpdate);
+ x->crl->lastUpdate = in;
+ }
+ }
+ return (in != NULL);
+}
int X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm)
- {
- ASN1_TIME *in;
-
- if (x == NULL) return(0);
- in=x->crl->nextUpdate;
- if (in != tm)
- {
- in=M_ASN1_TIME_dup(tm);
- if (in != NULL)
- {
- M_ASN1_TIME_free(x->crl->nextUpdate);
- x->crl->nextUpdate=in;
- }
- }
- return(in != NULL);
- }
+{
+ ASN1_TIME *in;
+
+ if (x == NULL)
+ return (0);
+ in = x->crl->nextUpdate;
+ if (in != tm) {
+ in = M_ASN1_TIME_dup(tm);
+ if (in != NULL) {
+ M_ASN1_TIME_free(x->crl->nextUpdate);
+ x->crl->nextUpdate = in;
+ }
+ }
+ return (in != NULL);
+}
int X509_CRL_sort(X509_CRL *c)
- {
- size_t i;
- X509_REVOKED *r;
- /* sort the data so it will be written in serial
- * number order */
- sk_X509_REVOKED_sort(c->crl->revoked);
- for (i=0; i<sk_X509_REVOKED_num(c->crl->revoked); i++)
- {
- r=sk_X509_REVOKED_value(c->crl->revoked,i);
- r->sequence=i;
- }
- c->crl->enc.modified = 1;
- return 1;
- }
+{
+ size_t i;
+ X509_REVOKED *r;
+ /*
+ * sort the data so it will be written in serial number order
+ */
+ sk_X509_REVOKED_sort(c->crl->revoked);
+ for (i = 0; i < sk_X509_REVOKED_num(c->crl->revoked); i++) {
+ r = sk_X509_REVOKED_value(c->crl->revoked, i);
+ r->sequence = i;
+ }
+ c->crl->enc.modified = 1;
+ return 1;
+}
void X509_CRL_up_ref(X509_CRL *crl)
- {
- CRYPTO_refcount_inc(&crl->references);
- }
+{
+ CRYPTO_refcount_inc(&crl->references);
+}
int X509_REVOKED_set_revocationDate(X509_REVOKED *x, ASN1_TIME *tm)
- {
- ASN1_TIME *in;
-
- if (x == NULL) return(0);
- in=x->revocationDate;
- if (in != tm)
- {
- in=M_ASN1_TIME_dup(tm);
- if (in != NULL)
- {
- M_ASN1_TIME_free(x->revocationDate);
- x->revocationDate=in;
- }
- }
- return(in != NULL);
- }
+{
+ ASN1_TIME *in;
+
+ if (x == NULL)
+ return (0);
+ in = x->revocationDate;
+ if (in != tm) {
+ in = M_ASN1_TIME_dup(tm);
+ if (in != NULL) {
+ M_ASN1_TIME_free(x->revocationDate);
+ x->revocationDate = in;
+ }
+ }
+ return (in != NULL);
+}
int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial)
- {
- ASN1_INTEGER *in;
-
- if (x == NULL) return(0);
- in=x->serialNumber;
- if (in != serial)
- {
- in=M_ASN1_INTEGER_dup(serial);
- if (in != NULL)
- {
- M_ASN1_INTEGER_free(x->serialNumber);
- x->serialNumber=in;
- }
- }
- return(in != NULL);
- }
+{
+ ASN1_INTEGER *in;
+
+ if (x == NULL)
+ return (0);
+ in = x->serialNumber;
+ if (in != serial) {
+ in = M_ASN1_INTEGER_dup(serial);
+ if (in != NULL) {
+ M_ASN1_INTEGER_free(x->serialNumber);
+ x->serialNumber = in;
+ }
+ }
+ return (in != NULL);
+}
diff --git a/src/crypto/x509/x509name.c b/src/crypto/x509/x509name.c
index 8b10fa27..050e16a8 100644
--- a/src/crypto/x509/x509name.c
+++ b/src/crypto/x509/x509name.c
@@ -63,313 +63,324 @@
#include <openssl/stack.h>
#include <openssl/x509.h>
-
int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len)
- {
- const ASN1_OBJECT *obj;
-
- obj=OBJ_nid2obj(nid);
- if (obj == NULL) return(-1);
- return(X509_NAME_get_text_by_OBJ(name,obj,buf,len));
- }
-
-int X509_NAME_get_text_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, char *buf,
- int len)
- {
- int i;
- ASN1_STRING *data;
-
- i=X509_NAME_get_index_by_OBJ(name,obj,-1);
- if (i < 0) return(-1);
- data=X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name,i));
- i=(data->length > (len-1))?(len-1):data->length;
- if (buf == NULL) return(data->length);
- memcpy(buf,data->data,i);
- buf[i]='\0';
- return(i);
- }
+{
+ const ASN1_OBJECT *obj;
+
+ obj = OBJ_nid2obj(nid);
+ if (obj == NULL)
+ return (-1);
+ return (X509_NAME_get_text_by_OBJ(name, obj, buf, len));
+}
+
+int X509_NAME_get_text_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj,
+ char *buf, int len)
+{
+ int i;
+ ASN1_STRING *data;
+
+ i = X509_NAME_get_index_by_OBJ(name, obj, -1);
+ if (i < 0)
+ return (-1);
+ data = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i));
+ i = (data->length > (len - 1)) ? (len - 1) : data->length;
+ if (buf == NULL)
+ return (data->length);
+ memcpy(buf, data->data, i);
+ buf[i] = '\0';
+ return (i);
+}
int X509_NAME_entry_count(X509_NAME *name)
- {
- if (name == NULL) return(0);
- return(sk_X509_NAME_ENTRY_num(name->entries));
- }
+{
+ if (name == NULL)
+ return (0);
+ return (sk_X509_NAME_ENTRY_num(name->entries));
+}
int X509_NAME_get_index_by_NID(X509_NAME *name, int nid, int lastpos)
- {
- const ASN1_OBJECT *obj;
+{
+ const ASN1_OBJECT *obj;
- obj=OBJ_nid2obj(nid);
- if (obj == NULL) return(-2);
- return(X509_NAME_get_index_by_OBJ(name,obj,lastpos));
- }
+ obj = OBJ_nid2obj(nid);
+ if (obj == NULL)
+ return (-2);
+ return (X509_NAME_get_index_by_OBJ(name, obj, lastpos));
+}
/* NOTE: you should be passsing -1, not 0 as lastpos */
int X509_NAME_get_index_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj,
- int lastpos)
- {
- int n;
- X509_NAME_ENTRY *ne;
- STACK_OF(X509_NAME_ENTRY) *sk;
-
- if (name == NULL) return(-1);
- if (lastpos < 0)
- lastpos= -1;
- sk=name->entries;
- n=sk_X509_NAME_ENTRY_num(sk);
- for (lastpos++; lastpos < n; lastpos++)
- {
- ne=sk_X509_NAME_ENTRY_value(sk,lastpos);
- if (OBJ_cmp(ne->object,obj) == 0)
- return(lastpos);
- }
- return(-1);
- }
+ int lastpos)
+{
+ int n;
+ X509_NAME_ENTRY *ne;
+ STACK_OF(X509_NAME_ENTRY) *sk;
+
+ if (name == NULL)
+ return (-1);
+ if (lastpos < 0)
+ lastpos = -1;
+ sk = name->entries;
+ n = sk_X509_NAME_ENTRY_num(sk);
+ for (lastpos++; lastpos < n; lastpos++) {
+ ne = sk_X509_NAME_ENTRY_value(sk, lastpos);
+ if (OBJ_cmp(ne->object, obj) == 0)
+ return (lastpos);
+ }
+ return (-1);
+}
X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc)
- {
- if(name == NULL || loc < 0 || sk_X509_NAME_ENTRY_num(name->entries) <= (size_t) loc)
- return(NULL);
- else
- return(sk_X509_NAME_ENTRY_value(name->entries,loc));
- }
+{
+ if (name == NULL || loc < 0
+ || sk_X509_NAME_ENTRY_num(name->entries) <= (size_t)loc)
+ return (NULL);
+ else
+ return (sk_X509_NAME_ENTRY_value(name->entries, loc));
+}
X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc)
- {
- X509_NAME_ENTRY *ret;
- int i,n,set_prev,set_next;
- STACK_OF(X509_NAME_ENTRY) *sk;
-
- if (name == NULL || loc < 0 || sk_X509_NAME_ENTRY_num(name->entries) <= (size_t) loc)
- return(NULL);
- sk=name->entries;
- ret=sk_X509_NAME_ENTRY_delete(sk,loc);
- n=sk_X509_NAME_ENTRY_num(sk);
- name->modified=1;
- if (loc == n) return(ret);
-
- /* else we need to fixup the set field */
- if (loc != 0)
- set_prev=(sk_X509_NAME_ENTRY_value(sk,loc-1))->set;
- else
- set_prev=ret->set-1;
- set_next=sk_X509_NAME_ENTRY_value(sk,loc)->set;
-
- /* set_prev is the previous set
- * set is the current set
- * set_next is the following
- * prev 1 1 1 1 1 1 1 1
- * set 1 1 2 2
- * next 1 1 2 2 2 2 3 2
- * so basically only if prev and next differ by 2, then
- * re-number down by 1 */
- if (set_prev+1 < set_next)
- for (i=loc; i<n; i++)
- sk_X509_NAME_ENTRY_value(sk,i)->set--;
- return(ret);
- }
+{
+ X509_NAME_ENTRY *ret;
+ int i, n, set_prev, set_next;
+ STACK_OF(X509_NAME_ENTRY) *sk;
+
+ if (name == NULL || loc < 0
+ || sk_X509_NAME_ENTRY_num(name->entries) <= (size_t)loc)
+ return (NULL);
+ sk = name->entries;
+ ret = sk_X509_NAME_ENTRY_delete(sk, loc);
+ n = sk_X509_NAME_ENTRY_num(sk);
+ name->modified = 1;
+ if (loc == n)
+ return (ret);
+
+ /* else we need to fixup the set field */
+ if (loc != 0)
+ set_prev = (sk_X509_NAME_ENTRY_value(sk, loc - 1))->set;
+ else
+ set_prev = ret->set - 1;
+ set_next = sk_X509_NAME_ENTRY_value(sk, loc)->set;
+
+ /*
+ * set_prev is the previous set set is the current set set_next is the
+ * following prev 1 1 1 1 1 1 1 1 set 1 1 2 2 next 1 1 2 2 2 2 3 2 so
+ * basically only if prev and next differ by 2, then re-number down by 1
+ */
+ if (set_prev + 1 < set_next)
+ for (i = loc; i < n; i++)
+ sk_X509_NAME_ENTRY_value(sk, i)->set--;
+ return (ret);
+}
int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type,
- unsigned char *bytes, int len, int loc, int set)
+ unsigned char *bytes, int len, int loc,
+ int set)
{
- X509_NAME_ENTRY *ne;
- int ret;
- ne = X509_NAME_ENTRY_create_by_OBJ(NULL, obj, type, bytes, len);
- if(!ne) return 0;
- ret = X509_NAME_add_entry(name, ne, loc, set);
- X509_NAME_ENTRY_free(ne);
- return ret;
+ X509_NAME_ENTRY *ne;
+ int ret;
+ ne = X509_NAME_ENTRY_create_by_OBJ(NULL, obj, type, bytes, len);
+ if (!ne)
+ return 0;
+ ret = X509_NAME_add_entry(name, ne, loc, set);
+ X509_NAME_ENTRY_free(ne);
+ return ret;
}
int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type,
- unsigned char *bytes, int len, int loc, int set)
+ unsigned char *bytes, int len, int loc,
+ int set)
{
- X509_NAME_ENTRY *ne;
- int ret;
- ne = X509_NAME_ENTRY_create_by_NID(NULL, nid, type, bytes, len);
- if(!ne) return 0;
- ret = X509_NAME_add_entry(name, ne, loc, set);
- X509_NAME_ENTRY_free(ne);
- return ret;
+ X509_NAME_ENTRY *ne;
+ int ret;
+ ne = X509_NAME_ENTRY_create_by_NID(NULL, nid, type, bytes, len);
+ if (!ne)
+ return 0;
+ ret = X509_NAME_add_entry(name, ne, loc, set);
+ X509_NAME_ENTRY_free(ne);
+ return ret;
}
int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type,
- const unsigned char *bytes, int len, int loc, int set)
+ const unsigned char *bytes, int len, int loc,
+ int set)
{
- X509_NAME_ENTRY *ne;
- int ret;
- ne = X509_NAME_ENTRY_create_by_txt(NULL, field, type, bytes, len);
- if(!ne) return 0;
- ret = X509_NAME_add_entry(name, ne, loc, set);
- X509_NAME_ENTRY_free(ne);
- return ret;
+ X509_NAME_ENTRY *ne;
+ int ret;
+ ne = X509_NAME_ENTRY_create_by_txt(NULL, field, type, bytes, len);
+ if (!ne)
+ return 0;
+ ret = X509_NAME_add_entry(name, ne, loc, set);
+ X509_NAME_ENTRY_free(ne);
+ return ret;
}
-/* if set is -1, append to previous set, 0 'a new one', and 1,
- * prepend to the guy we are about to stomp on. */
+/*
+ * if set is -1, append to previous set, 0 'a new one', and 1, prepend to the
+ * guy we are about to stomp on.
+ */
int X509_NAME_add_entry(X509_NAME *name, X509_NAME_ENTRY *ne, int loc,
- int set)
- {
- X509_NAME_ENTRY *new_name=NULL;
- int n,i,inc;
- STACK_OF(X509_NAME_ENTRY) *sk;
-
- if (name == NULL) return(0);
- sk=name->entries;
- n=sk_X509_NAME_ENTRY_num(sk);
- if (loc > n) loc=n;
- else if (loc < 0) loc=n;
-
- name->modified=1;
-
- if (set == -1)
- {
- if (loc == 0)
- {
- set=0;
- inc=1;
- }
- else
- {
- set=sk_X509_NAME_ENTRY_value(sk,loc-1)->set;
- inc=0;
- }
- }
- else /* if (set >= 0) */
- {
- if (loc >= n)
- {
- if (loc != 0)
- set=sk_X509_NAME_ENTRY_value(sk,loc-1)->set+1;
- else
- set=0;
- }
- else
- set=sk_X509_NAME_ENTRY_value(sk,loc)->set;
- inc=(set == 0)?1:0;
- }
-
- if ((new_name=X509_NAME_ENTRY_dup(ne)) == NULL)
- goto err;
- new_name->set=set;
- if (!sk_X509_NAME_ENTRY_insert(sk,new_name,loc))
- {
- OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- if (inc)
- {
- n=sk_X509_NAME_ENTRY_num(sk);
- for (i=loc+1; i<n; i++)
- sk_X509_NAME_ENTRY_value(sk,i-1)->set+=1;
- }
- return(1);
-err:
- if (new_name != NULL)
- X509_NAME_ENTRY_free(new_name);
- return(0);
- }
+ int set)
+{
+ X509_NAME_ENTRY *new_name = NULL;
+ int n, i, inc;
+ STACK_OF(X509_NAME_ENTRY) *sk;
+
+ if (name == NULL)
+ return (0);
+ sk = name->entries;
+ n = sk_X509_NAME_ENTRY_num(sk);
+ if (loc > n)
+ loc = n;
+ else if (loc < 0)
+ loc = n;
+
+ name->modified = 1;
+
+ if (set == -1) {
+ if (loc == 0) {
+ set = 0;
+ inc = 1;
+ } else {
+ set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set;
+ inc = 0;
+ }
+ } else { /* if (set >= 0) */
+
+ if (loc >= n) {
+ if (loc != 0)
+ set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set + 1;
+ else
+ set = 0;
+ } else
+ set = sk_X509_NAME_ENTRY_value(sk, loc)->set;
+ inc = (set == 0) ? 1 : 0;
+ }
+
+ if ((new_name = X509_NAME_ENTRY_dup(ne)) == NULL)
+ goto err;
+ new_name->set = set;
+ if (!sk_X509_NAME_ENTRY_insert(sk, new_name, loc)) {
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if (inc) {
+ n = sk_X509_NAME_ENTRY_num(sk);
+ for (i = loc + 1; i < n; i++)
+ sk_X509_NAME_ENTRY_value(sk, i - 1)->set += 1;
+ }
+ return (1);
+ err:
+ if (new_name != NULL)
+ X509_NAME_ENTRY_free(new_name);
+ return (0);
+}
X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne,
- const char *field, int type, const unsigned char *bytes, int len)
- {
- ASN1_OBJECT *obj;
- X509_NAME_ENTRY *nentry;
-
- obj=OBJ_txt2obj(field, 0);
- if (obj == NULL)
- {
- OPENSSL_PUT_ERROR(X509, X509_R_INVALID_FIELD_NAME);
- ERR_add_error_data(2, "name=", field);
- return(NULL);
- }
- nentry = X509_NAME_ENTRY_create_by_OBJ(ne,obj,type,bytes,len);
- ASN1_OBJECT_free(obj);
- return nentry;
- }
+ const char *field, int type,
+ const unsigned char *bytes,
+ int len)
+{
+ ASN1_OBJECT *obj;
+ X509_NAME_ENTRY *nentry;
+
+ obj = OBJ_txt2obj(field, 0);
+ if (obj == NULL) {
+ OPENSSL_PUT_ERROR(X509, X509_R_INVALID_FIELD_NAME);
+ ERR_add_error_data(2, "name=", field);
+ return (NULL);
+ }
+ nentry = X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len);
+ ASN1_OBJECT_free(obj);
+ return nentry;
+}
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 = OBJ_nid2obj(nid);
- if (obj == NULL)
- {
- OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_NID);
- return NULL;
- }
- return X509_NAME_ENTRY_create_by_OBJ(ne,obj,type,bytes,len);
- }
+ int type, unsigned char *bytes,
+ int len)
+{
+ const ASN1_OBJECT *obj = OBJ_nid2obj(nid);
+ if (obj == NULL) {
+ OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_NID);
+ return NULL;
+ }
+ 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,
- const ASN1_OBJECT *obj, int type, const unsigned char *bytes, int len)
- {
- X509_NAME_ENTRY *ret;
-
- if ((ne == NULL) || (*ne == NULL))
- {
- if ((ret=X509_NAME_ENTRY_new()) == NULL)
- return(NULL);
- }
- else
- ret= *ne;
-
- if (!X509_NAME_ENTRY_set_object(ret,obj))
- goto err;
- if (!X509_NAME_ENTRY_set_data(ret,type,bytes,len))
- goto err;
-
- if ((ne != NULL) && (*ne == NULL)) *ne=ret;
- return(ret);
-err:
- if ((ne == NULL) || (ret != *ne))
- X509_NAME_ENTRY_free(ret);
- return(NULL);
- }
+ const ASN1_OBJECT *obj,
+ int type,
+ const unsigned char *bytes,
+ int len)
+{
+ X509_NAME_ENTRY *ret;
+
+ if ((ne == NULL) || (*ne == NULL)) {
+ if ((ret = X509_NAME_ENTRY_new()) == NULL)
+ return (NULL);
+ } else
+ ret = *ne;
+
+ if (!X509_NAME_ENTRY_set_object(ret, obj))
+ goto err;
+ if (!X509_NAME_ENTRY_set_data(ret, type, bytes, len))
+ goto err;
+
+ if ((ne != NULL) && (*ne == NULL))
+ *ne = ret;
+ return (ret);
+ err:
+ if ((ne == NULL) || (ret != *ne))
+ X509_NAME_ENTRY_free(ret);
+ return (NULL);
+}
int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, const ASN1_OBJECT *obj)
- {
- if ((ne == NULL) || (obj == NULL))
- {
- OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER);
- return(0);
- }
- ASN1_OBJECT_free(ne->object);
- ne->object=OBJ_dup(obj);
- return((ne->object == NULL)?0:1);
- }
+{
+ if ((ne == NULL) || (obj == NULL)) {
+ OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER);
+ return (0);
+ }
+ ASN1_OBJECT_free(ne->object);
+ ne->object = OBJ_dup(obj);
+ return ((ne->object == NULL) ? 0 : 1);
+}
int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type,
- const unsigned char *bytes, int len)
- {
- int i;
-
- if ((ne == NULL) || ((bytes == NULL) && (len != 0))) return(0);
- if((type > 0) && (type & MBSTRING_FLAG))
- return ASN1_STRING_set_by_NID(&ne->value, bytes,
- len, type,
- OBJ_obj2nid(ne->object)) ? 1 : 0;
- if (len < 0) len=strlen((const char *)bytes);
- i=ASN1_STRING_set(ne->value,bytes,len);
- if (!i) return(0);
- if (type != V_ASN1_UNDEF)
- {
- if (type == V_ASN1_APP_CHOOSE)
- ne->value->type=ASN1_PRINTABLE_type(bytes,len);
- else
- ne->value->type=type;
- }
- return(1);
- }
+ const unsigned char *bytes, int len)
+{
+ int i;
+
+ if ((ne == NULL) || ((bytes == NULL) && (len != 0)))
+ return (0);
+ if ((type > 0) && (type & MBSTRING_FLAG))
+ return ASN1_STRING_set_by_NID(&ne->value, bytes,
+ len, type,
+ OBJ_obj2nid(ne->object)) ? 1 : 0;
+ if (len < 0)
+ len = strlen((const char *)bytes);
+ i = ASN1_STRING_set(ne->value, bytes, len);
+ if (!i)
+ return (0);
+ if (type != V_ASN1_UNDEF) {
+ if (type == V_ASN1_APP_CHOOSE)
+ ne->value->type = ASN1_PRINTABLE_type(bytes, len);
+ else
+ ne->value->type = type;
+ }
+ return (1);
+}
ASN1_OBJECT *X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne)
- {
- if (ne == NULL) return(NULL);
- return(ne->object);
- }
+{
+ if (ne == NULL)
+ return (NULL);
+ return (ne->object);
+}
ASN1_STRING *X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne)
- {
- if (ne == NULL) return(NULL);
- return(ne->value);
- }
-
+{
+ if (ne == NULL)
+ return (NULL);
+ return (ne->value);
+}
diff --git a/src/crypto/x509/x509rset.c b/src/crypto/x509/x509rset.c
index dbab555d..c4e6683d 100644
--- a/src/crypto/x509/x509rset.c
+++ b/src/crypto/x509/x509rset.c
@@ -59,22 +59,23 @@
#include <openssl/obj.h>
#include <openssl/x509.h>
-
int X509_REQ_set_version(X509_REQ *x, long version)
- {
- if (x == NULL) return(0);
- return(ASN1_INTEGER_set(x->req_info->version,version));
- }
+{
+ if (x == NULL)
+ return (0);
+ return (ASN1_INTEGER_set(x->req_info->version, version));
+}
int X509_REQ_set_subject_name(X509_REQ *x, X509_NAME *name)
- {
- if ((x == NULL) || (x->req_info == NULL)) return(0);
- return(X509_NAME_set(&x->req_info->subject,name));
- }
+{
+ if ((x == NULL) || (x->req_info == NULL))
+ return (0);
+ return (X509_NAME_set(&x->req_info->subject, name));
+}
int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey)
- {
- if ((x == NULL) || (x->req_info == NULL)) return(0);
- return(X509_PUBKEY_set(&x->req_info->pubkey,pkey));
- }
-
+{
+ if ((x == NULL) || (x->req_info == NULL))
+ return (0);
+ return (X509_PUBKEY_set(&x->req_info->pubkey, pkey));
+}
diff --git a/src/crypto/x509/x509spki.c b/src/crypto/x509/x509spki.c
index ccf93e06..4a9b95e7 100644
--- a/src/crypto/x509/x509spki.c
+++ b/src/crypto/x509/x509spki.c
@@ -1,5 +1,7 @@
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999. */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
*
@@ -8,7 +10,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -59,77 +61,77 @@
#include <openssl/mem.h>
#include <openssl/x509.h>
-
int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey)
{
- if ((x == NULL) || (x->spkac == NULL)) return(0);
- return(X509_PUBKEY_set(&(x->spkac->pubkey),pkey));
+ if ((x == NULL) || (x->spkac == NULL))
+ return (0);
+ return (X509_PUBKEY_set(&(x->spkac->pubkey), pkey));
}
EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x)
{
- if ((x == NULL) || (x->spkac == NULL))
- return(NULL);
- return(X509_PUBKEY_get(x->spkac->pubkey));
+ if ((x == NULL) || (x->spkac == NULL))
+ return (NULL);
+ return (X509_PUBKEY_get(x->spkac->pubkey));
}
/* Load a Netscape SPKI from a base64 encoded string */
-NETSCAPE_SPKI * NETSCAPE_SPKI_b64_decode(const char *str, int len)
+NETSCAPE_SPKI *NETSCAPE_SPKI_b64_decode(const char *str, int len)
{
- unsigned char *spki_der;
- const unsigned char *p;
- size_t spki_len;
- NETSCAPE_SPKI *spki;
- if (len <= 0)
- len = strlen(str);
- if (!EVP_DecodedLength(&spki_len, len)) {
- OPENSSL_PUT_ERROR(X509, X509_R_BASE64_DECODE_ERROR);
- return NULL;
- }
- if (!(spki_der = OPENSSL_malloc(spki_len))) {
- 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, X509_R_BASE64_DECODE_ERROR);
- OPENSSL_free(spki_der);
- return NULL;
- }
- p = spki_der;
- spki = d2i_NETSCAPE_SPKI(NULL, &p, spki_len);
- OPENSSL_free(spki_der);
- return spki;
+ unsigned char *spki_der;
+ const unsigned char *p;
+ size_t spki_len;
+ NETSCAPE_SPKI *spki;
+ if (len <= 0)
+ len = strlen(str);
+ if (!EVP_DecodedLength(&spki_len, len)) {
+ OPENSSL_PUT_ERROR(X509, X509_R_BASE64_DECODE_ERROR);
+ return NULL;
+ }
+ if (!(spki_der = OPENSSL_malloc(spki_len))) {
+ 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, X509_R_BASE64_DECODE_ERROR);
+ OPENSSL_free(spki_der);
+ return NULL;
+ }
+ p = spki_der;
+ spki = d2i_NETSCAPE_SPKI(NULL, &p, spki_len);
+ OPENSSL_free(spki_der);
+ return spki;
}
/* Generate a base64 encoded string from an SPKI */
-char * NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *spki)
+char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *spki)
{
- unsigned char *der_spki, *p;
- char *b64_str;
- size_t b64_len;
- int der_len;
- der_len = i2d_NETSCAPE_SPKI(spki, NULL);
- if (!EVP_EncodedLength(&b64_len, der_len))
- {
- OPENSSL_PUT_ERROR(X509, ERR_R_OVERFLOW);
- return NULL;
- }
- der_spki = OPENSSL_malloc(der_len);
- if (der_spki == NULL) {
- 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, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
- p = der_spki;
- i2d_NETSCAPE_SPKI(spki, &p);
- EVP_EncodeBlock((unsigned char *)b64_str, der_spki, der_len);
- OPENSSL_free(der_spki);
- return b64_str;
+ unsigned char *der_spki, *p;
+ char *b64_str;
+ size_t b64_len;
+ int der_len;
+ der_len = i2d_NETSCAPE_SPKI(spki, NULL);
+ if (!EVP_EncodedLength(&b64_len, der_len)) {
+ OPENSSL_PUT_ERROR(X509, ERR_R_OVERFLOW);
+ return NULL;
+ }
+ der_spki = OPENSSL_malloc(der_len);
+ if (der_spki == NULL) {
+ 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, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ p = der_spki;
+ i2d_NETSCAPE_SPKI(spki, &p);
+ EVP_EncodeBlock((unsigned char *)b64_str, der_spki, der_len);
+ OPENSSL_free(der_spki);
+ return b64_str;
}
diff --git a/src/crypto/x509/x509type.c b/src/crypto/x509/x509type.c
index e7c79354..d4f5a4dc 100644
--- a/src/crypto/x509/x509type.c
+++ b/src/crypto/x509/x509type.c
@@ -58,71 +58,69 @@
#include <openssl/obj.h>
#include <openssl/x509.h>
-
int X509_certificate_type(X509 *x, EVP_PKEY *pkey)
- {
- EVP_PKEY *pk;
- int ret=0,i;
-
- if (x == NULL) return(0);
+{
+ EVP_PKEY *pk;
+ int ret = 0, i;
- if (pkey == NULL)
- pk=X509_get_pubkey(x);
- else
- pk=pkey;
+ if (x == NULL)
+ return (0);
- if (pk == NULL) return(0);
+ if (pkey == NULL)
+ pk = X509_get_pubkey(x);
+ else
+ pk = pkey;
- switch (pk->type)
- {
- case EVP_PKEY_RSA:
- ret=EVP_PK_RSA|EVP_PKT_SIGN;
-/* if (!sign only extension) */
- ret|=EVP_PKT_ENC;
- break;
- case EVP_PKEY_DSA:
- ret=EVP_PK_DSA|EVP_PKT_SIGN;
- break;
- case EVP_PKEY_EC:
- ret=EVP_PK_EC|EVP_PKT_SIGN|EVP_PKT_EXCH;
- break;
- case EVP_PKEY_DH:
- ret=EVP_PK_DH|EVP_PKT_EXCH;
- break;
- case NID_id_GostR3410_94:
- case NID_id_GostR3410_2001:
- ret=EVP_PKT_EXCH|EVP_PKT_SIGN;
- break;
- default:
- break;
- }
+ if (pk == NULL)
+ return (0);
- i=OBJ_obj2nid(x->sig_alg->algorithm);
- if (i && OBJ_find_sigid_algs(i, NULL, &i))
- {
+ switch (pk->type) {
+ case EVP_PKEY_RSA:
+ ret = EVP_PK_RSA | EVP_PKT_SIGN;
+/* if (!sign only extension) */
+ ret |= EVP_PKT_ENC;
+ break;
+ case EVP_PKEY_DSA:
+ ret = EVP_PK_DSA | EVP_PKT_SIGN;
+ break;
+ case EVP_PKEY_EC:
+ ret = EVP_PK_EC | EVP_PKT_SIGN | EVP_PKT_EXCH;
+ break;
+ case EVP_PKEY_DH:
+ ret = EVP_PK_DH | EVP_PKT_EXCH;
+ break;
+ case NID_id_GostR3410_94:
+ case NID_id_GostR3410_2001:
+ ret = EVP_PKT_EXCH | EVP_PKT_SIGN;
+ break;
+ default:
+ break;
+ }
- switch (i)
- {
- case NID_rsaEncryption:
- case NID_rsa:
- ret|=EVP_PKS_RSA;
- break;
- case NID_dsa:
- case NID_dsa_2:
- ret|=EVP_PKS_DSA;
- break;
- case NID_X9_62_id_ecPublicKey:
- ret|=EVP_PKS_EC;
- break;
- default:
- break;
- }
- }
+ i = OBJ_obj2nid(x->sig_alg->algorithm);
+ if (i && OBJ_find_sigid_algs(i, NULL, &i)) {
- if (EVP_PKEY_size(pk) <= 1024/8)/* /8 because it's 1024 bits we look
- for, not bytes */
- ret|=EVP_PKT_EXP;
- if(pkey==NULL) EVP_PKEY_free(pk);
- return(ret);
- }
+ switch (i) {
+ case NID_rsaEncryption:
+ case NID_rsa:
+ ret |= EVP_PKS_RSA;
+ break;
+ case NID_dsa:
+ case NID_dsa_2:
+ ret |= EVP_PKS_DSA;
+ break;
+ case NID_X9_62_id_ecPublicKey:
+ ret |= EVP_PKS_EC;
+ break;
+ default:
+ break;
+ }
+ }
+ if (EVP_PKEY_size(pk) <= 1024 / 8) /* /8 because it's 1024 bits we look
+ * for, not bytes */
+ ret |= EVP_PKT_EXP;
+ if (pkey == NULL)
+ EVP_PKEY_free(pk);
+ return (ret);
+}
diff --git a/src/crypto/x509/x_algor.c b/src/crypto/x509/x_algor.c
index ae694e3d..abacd061 100644
--- a/src/crypto/x509/x_algor.c
+++ b/src/crypto/x509/x_algor.c
@@ -1,5 +1,7 @@
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2000. */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2000.
+ */
/* ====================================================================
* Copyright (c) 2000 The OpenSSL Project. All rights reserved.
*
@@ -8,7 +10,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -61,12 +63,12 @@
ASN1_SEQUENCE(X509_ALGOR) = {
- ASN1_SIMPLE(X509_ALGOR, algorithm, ASN1_OBJECT),
- ASN1_OPT(X509_ALGOR, parameter, ASN1_ANY)
+ ASN1_SIMPLE(X509_ALGOR, algorithm, ASN1_OBJECT),
+ ASN1_OPT(X509_ALGOR, parameter, ASN1_ANY)
} ASN1_SEQUENCE_END(X509_ALGOR)
-ASN1_ITEM_TEMPLATE(X509_ALGORS) =
- ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, algorithms, X509_ALGOR)
+ASN1_ITEM_TEMPLATE(X509_ALGORS) =
+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, algorithms, X509_ALGOR)
ASN1_ITEM_TEMPLATE_END(X509_ALGORS)
IMPLEMENT_ASN1_FUNCTIONS(X509_ALGOR)
@@ -75,80 +77,75 @@ IMPLEMENT_ASN1_DUP_FUNCTION(X509_ALGOR)
IMPLEMENT_ASN1_SET_OF(X509_ALGOR)
-int X509_ALGOR_set0(X509_ALGOR *alg, const ASN1_OBJECT *aobj, int ptype, void *pval)
- {
- if (!alg)
- return 0;
- if (ptype != V_ASN1_UNDEF)
- {
- if (alg->parameter == NULL)
- alg->parameter = ASN1_TYPE_new();
- if (alg->parameter == NULL)
- return 0;
- }
- if (alg)
- {
- if (alg->algorithm)
- ASN1_OBJECT_free(alg->algorithm);
- alg->algorithm = (ASN1_OBJECT*) aobj;
- }
- if (ptype == 0)
- return 1;
- if (ptype == V_ASN1_UNDEF)
- {
- if (alg->parameter)
- {
- ASN1_TYPE_free(alg->parameter);
- alg->parameter = NULL;
- }
- }
- else
- ASN1_TYPE_set(alg->parameter, ptype, pval);
- return 1;
- }
+int X509_ALGOR_set0(X509_ALGOR *alg, const ASN1_OBJECT *aobj, int ptype,
+ void *pval)
+{
+ if (!alg)
+ return 0;
+ if (ptype != V_ASN1_UNDEF) {
+ if (alg->parameter == NULL)
+ alg->parameter = ASN1_TYPE_new();
+ if (alg->parameter == NULL)
+ return 0;
+ }
+ if (alg) {
+ if (alg->algorithm)
+ ASN1_OBJECT_free(alg->algorithm);
+ alg->algorithm = (ASN1_OBJECT *)aobj;
+ }
+ if (ptype == 0)
+ return 1;
+ if (ptype == V_ASN1_UNDEF) {
+ if (alg->parameter) {
+ ASN1_TYPE_free(alg->parameter);
+ alg->parameter = NULL;
+ }
+ } else
+ ASN1_TYPE_set(alg->parameter, ptype, pval);
+ return 1;
+}
void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval,
- X509_ALGOR *algor)
- {
- if (paobj)
- *paobj = algor->algorithm;
- if (pptype)
- {
- if (algor->parameter == NULL)
- {
- *pptype = V_ASN1_UNDEF;
- return;
- }
- else
- *pptype = algor->parameter->type;
- if (ppval)
- *ppval = algor->parameter->value.ptr;
- }
- }
+ X509_ALGOR *algor)
+{
+ if (paobj)
+ *paobj = algor->algorithm;
+ if (pptype) {
+ if (algor->parameter == NULL) {
+ *pptype = V_ASN1_UNDEF;
+ return;
+ } else
+ *pptype = algor->parameter->type;
+ if (ppval)
+ *ppval = algor->parameter->value.ptr;
+ }
+}
/* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */
void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md)
- {
- int param_type;
+{
+ int param_type;
- if (EVP_MD_flags(md) & EVP_MD_FLAG_DIGALGID_ABSENT)
- param_type = V_ASN1_UNDEF;
- else
- param_type = V_ASN1_NULL;
+ if (EVP_MD_flags(md) & EVP_MD_FLAG_DIGALGID_ABSENT)
+ param_type = V_ASN1_UNDEF;
+ else
+ param_type = V_ASN1_NULL;
- X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL);
+ X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL);
- }
+}
-/* X509_ALGOR_cmp returns 0 if |a| and |b| are equal and non-zero otherwise. */
+/*
+ * X509_ALGOR_cmp returns 0 if |a| and |b| are equal and non-zero otherwise.
+ */
int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b)
- {
- int rv;
- rv = OBJ_cmp(a->algorithm, b->algorithm);
- if (rv)
- return rv;
- if (!a->parameter && !b->parameter)
- return 0;
- return ASN1_TYPE_cmp(a->parameter, b->parameter);
- }
+{
+ int rv;
+ rv = OBJ_cmp(a->algorithm, b->algorithm);
+ if (rv)
+ return rv;
+ if (!a->parameter && !b->parameter)
+ return 0;
+ return ASN1_TYPE_cmp(a->parameter, b->parameter);
+}
diff --git a/src/crypto/x509/x_all.c b/src/crypto/x509/x_all.c
index 62b3f402..c430a7d3 100644
--- a/src/crypto/x509/x_all.c
+++ b/src/crypto/x509/x_all.c
@@ -63,435 +63,439 @@
#include <openssl/stack.h>
#include <openssl/x509.h>
-
int X509_verify(X509 *a, EVP_PKEY *r)
- {
- if (X509_ALGOR_cmp(a->sig_alg, a->cert_info->signature))
- return 0;
- return(ASN1_item_verify(ASN1_ITEM_rptr(X509_CINF),a->sig_alg,
- a->signature,a->cert_info,r));
- }
+{
+ if (X509_ALGOR_cmp(a->sig_alg, a->cert_info->signature))
+ return 0;
+ return (ASN1_item_verify(ASN1_ITEM_rptr(X509_CINF), a->sig_alg,
+ a->signature, a->cert_info, r));
+}
int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r)
- {
- return( ASN1_item_verify(ASN1_ITEM_rptr(X509_REQ_INFO),
- a->sig_alg,a->signature,a->req_info,r));
- }
+{
+ return (ASN1_item_verify(ASN1_ITEM_rptr(X509_REQ_INFO),
+ a->sig_alg, a->signature, a->req_info, r));
+}
int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md)
- {
- x->cert_info->enc.modified = 1;
- return(ASN1_item_sign(ASN1_ITEM_rptr(X509_CINF), x->cert_info->signature,
- x->sig_alg, x->signature, x->cert_info,pkey,md));
- }
+{
+ x->cert_info->enc.modified = 1;
+ return (ASN1_item_sign(ASN1_ITEM_rptr(X509_CINF), x->cert_info->signature,
+ x->sig_alg, x->signature, x->cert_info, pkey, md));
+}
int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx)
- {
- x->cert_info->enc.modified = 1;
- return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CINF),
- x->cert_info->signature,
- x->sig_alg, x->signature, x->cert_info, ctx);
- }
+{
+ x->cert_info->enc.modified = 1;
+ return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CINF),
+ x->cert_info->signature,
+ x->sig_alg, x->signature, x->cert_info, ctx);
+}
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,
- x->signature, x->req_info,pkey,md));
- }
+{
+ return (ASN1_item_sign(ASN1_ITEM_rptr(X509_REQ_INFO), x->sig_alg, NULL,
+ x->signature, x->req_info, pkey, md));
+}
int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx)
- {
- return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_REQ_INFO),
- x->sig_alg, NULL, x->signature, x->req_info, ctx);
- }
+{
+ return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_REQ_INFO),
+ x->sig_alg, NULL, x->signature, x->req_info,
+ ctx);
+}
int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md)
- {
- x->crl->enc.modified = 1;
- return(ASN1_item_sign(ASN1_ITEM_rptr(X509_CRL_INFO),x->crl->sig_alg,
- x->sig_alg, x->signature, x->crl,pkey,md));
- }
+{
+ x->crl->enc.modified = 1;
+ return (ASN1_item_sign(ASN1_ITEM_rptr(X509_CRL_INFO), x->crl->sig_alg,
+ x->sig_alg, x->signature, x->crl, pkey, md));
+}
int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx)
- {
- x->crl->enc.modified = 1;
- return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CRL_INFO),
- x->crl->sig_alg, x->sig_alg, x->signature, x->crl, ctx);
- }
+{
+ x->crl->enc.modified = 1;
+ return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CRL_INFO),
+ x->crl->sig_alg, x->sig_alg, x->signature,
+ x->crl, ctx);
+}
int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md)
- {
- return(ASN1_item_sign(ASN1_ITEM_rptr(NETSCAPE_SPKAC), x->sig_algor,NULL,
- x->signature, x->spkac,pkey,md));
- }
+{
+ return (ASN1_item_sign(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));
- }
+{
+ 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)
- {
- return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509), fp, x509);
- }
+{
+ return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509), fp, x509);
+}
int i2d_X509_fp(FILE *fp, X509 *x509)
- {
- return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509), fp, x509);
- }
+{
+ return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509), fp, x509);
+}
#endif
X509 *d2i_X509_bio(BIO *bp, X509 **x509)
- {
- return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509), bp, x509);
- }
+{
+ return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509), bp, x509);
+}
int i2d_X509_bio(BIO *bp, X509 *x509)
- {
- return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509), bp, x509);
- }
+{
+ return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509), bp, x509);
+}
#ifndef OPENSSL_NO_FP_API
X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl)
- {
- return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl);
- }
+{
+ return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl);
+}
int i2d_X509_CRL_fp(FILE *fp, X509_CRL *crl)
- {
- return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl);
- }
+{
+ return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl);
+}
#endif
X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl)
- {
- return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl);
- }
+{
+ return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl);
+}
int i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl)
- {
- return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl);
- }
+{
+ return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl);
+}
#ifndef OPENSSL_NO_FP_API
X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req)
- {
- return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_REQ), fp, req);
- }
+{
+ return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_REQ), fp, req);
+}
int i2d_X509_REQ_fp(FILE *fp, X509_REQ *req)
- {
- return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_REQ), fp, req);
- }
+{
+ return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_REQ), fp, req);
+}
#endif
X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **req)
- {
- return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_REQ), bp, req);
- }
+{
+ return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_REQ), bp, req);
+}
int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req)
- {
- return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_REQ), bp, req);
- }
-
+{
+ return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_REQ), bp, req);
+}
#ifndef OPENSSL_NO_FP_API
RSA *d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa)
- {
- return ASN1_d2i_fp_of(RSA, RSA_new, d2i_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_i2d_fp_of_const(RSA, i2d_RSAPrivateKey, fp, rsa);
- }
+{
+ return ASN1_i2d_fp_of_const(RSA, i2d_RSAPrivateKey, fp, rsa);
+}
RSA *d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa)
- {
- return ASN1_d2i_fp_of(RSA, RSA_new, d2i_RSAPublicKey, fp, rsa);
- }
+{
+ return ASN1_d2i_fp_of(RSA, RSA_new, d2i_RSAPublicKey, fp, rsa);
+}
RSA *d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa)
- {
- return ASN1_d2i_fp((void *(*)(void))
- RSA_new,(D2I_OF(void))d2i_RSA_PUBKEY, fp,
- (void **)rsa);
- }
+{
+ return ASN1_d2i_fp((void *(*)(void))
+ RSA_new, (D2I_OF(void)) d2i_RSA_PUBKEY, fp,
+ (void **)rsa);
+}
int i2d_RSAPublicKey_fp(FILE *fp, RSA *rsa)
- {
- return ASN1_i2d_fp_of_const(RSA, i2d_RSAPublicKey, fp, rsa);
- }
+{
+ return ASN1_i2d_fp_of_const(RSA, i2d_RSAPublicKey, fp, rsa);
+}
int i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa)
- {
- return ASN1_i2d_fp((I2D_OF_const(void))i2d_RSA_PUBKEY,fp,rsa);
- }
+{
+ return ASN1_i2d_fp((I2D_OF_const(void))i2d_RSA_PUBKEY, fp, rsa);
+}
#endif
RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa)
- {
- return ASN1_d2i_bio_of(RSA, RSA_new, d2i_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_i2d_bio_of_const(RSA, i2d_RSAPrivateKey, bp, rsa);
- }
+{
+ return ASN1_i2d_bio_of_const(RSA, i2d_RSAPrivateKey, bp, rsa);
+}
RSA *d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa)
- {
- return ASN1_d2i_bio_of(RSA, RSA_new, d2i_RSAPublicKey, bp, rsa);
- }
-
+{
+ return ASN1_d2i_bio_of(RSA, RSA_new, d2i_RSAPublicKey, bp, rsa);
+}
RSA *d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa)
- {
- return ASN1_d2i_bio_of(RSA,RSA_new,d2i_RSA_PUBKEY,bp,rsa);
- }
+{
+ return ASN1_d2i_bio_of(RSA, RSA_new, d2i_RSA_PUBKEY, bp, rsa);
+}
int i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa)
- {
- return ASN1_i2d_bio_of_const(RSA, i2d_RSAPublicKey, bp, rsa);
- }
+{
+ return ASN1_i2d_bio_of_const(RSA, i2d_RSAPublicKey, bp, rsa);
+}
int i2d_RSA_PUBKEY_bio(BIO *bp, RSA *rsa)
- {
- return ASN1_i2d_bio_of_const(RSA,i2d_RSA_PUBKEY,bp,rsa);
- }
+{
+ return ASN1_i2d_bio_of_const(RSA, i2d_RSA_PUBKEY, bp, rsa);
+}
#ifndef OPENSSL_NO_DSA
-#ifndef OPENSSL_NO_FP_API
+# ifndef OPENSSL_NO_FP_API
DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa)
- {
- return ASN1_d2i_fp_of(DSA,DSA_new,d2i_DSAPrivateKey,fp,dsa);
- }
+{
+ return ASN1_d2i_fp_of(DSA, DSA_new, d2i_DSAPrivateKey, fp, dsa);
+}
int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa)
- {
- return ASN1_i2d_fp_of_const(DSA,i2d_DSAPrivateKey,fp,dsa);
- }
+{
+ return ASN1_i2d_fp_of_const(DSA, i2d_DSAPrivateKey, fp, dsa);
+}
DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa)
- {
- return ASN1_d2i_fp_of(DSA,DSA_new,d2i_DSA_PUBKEY,fp,dsa);
- }
+{
+ return ASN1_d2i_fp_of(DSA, DSA_new, d2i_DSA_PUBKEY, fp, dsa);
+}
int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa)
- {
- return ASN1_i2d_fp_of_const(DSA,i2d_DSA_PUBKEY,fp,dsa);
- }
-#endif
+{
+ return ASN1_i2d_fp_of_const(DSA, i2d_DSA_PUBKEY, fp, dsa);
+}
+# endif
DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa)
- {
- return ASN1_d2i_bio_of(DSA,DSA_new,d2i_DSAPrivateKey,bp,dsa
-);
- }
+{
+ return ASN1_d2i_bio_of(DSA, DSA_new, d2i_DSAPrivateKey, bp, dsa);
+}
int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa)
- {
- return ASN1_i2d_bio_of_const(DSA,i2d_DSAPrivateKey,bp,dsa);
- }
+{
+ return ASN1_i2d_bio_of_const(DSA, i2d_DSAPrivateKey, bp, dsa);
+}
DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa)
- {
- return ASN1_d2i_bio_of(DSA,DSA_new,d2i_DSA_PUBKEY,bp,dsa);
- }
+{
+ return ASN1_d2i_bio_of(DSA, DSA_new, d2i_DSA_PUBKEY, bp, dsa);
+}
int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa)
- {
- return ASN1_i2d_bio_of_const(DSA,i2d_DSA_PUBKEY,bp,dsa);
- }
+{
+ return ASN1_i2d_bio_of_const(DSA, i2d_DSA_PUBKEY, bp, dsa);
+}
#endif
#ifndef OPENSSL_NO_FP_API
EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey)
- {
- return ASN1_d2i_fp_of(EC_KEY,EC_KEY_new,d2i_EC_PUBKEY,fp,eckey);
- }
-
+{
+ return ASN1_d2i_fp_of(EC_KEY, EC_KEY_new, d2i_EC_PUBKEY, fp, eckey);
+}
+
int i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey)
- {
- return ASN1_i2d_fp_of_const(EC_KEY,i2d_EC_PUBKEY,fp,eckey);
- }
+{
+ return ASN1_i2d_fp_of_const(EC_KEY, i2d_EC_PUBKEY, fp, eckey);
+}
EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey)
- {
- return ASN1_d2i_fp_of(EC_KEY,EC_KEY_new,d2i_ECPrivateKey,fp,eckey);
- }
-
+{
+ return ASN1_d2i_fp_of(EC_KEY, EC_KEY_new, d2i_ECPrivateKey, fp, eckey);
+}
+
int i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey)
- {
- return ASN1_i2d_fp_of_const(EC_KEY,i2d_ECPrivateKey,fp,eckey);
- }
+{
+ return ASN1_i2d_fp_of_const(EC_KEY, i2d_ECPrivateKey, fp, eckey);
+}
#endif
EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey)
- {
- return ASN1_d2i_bio_of(EC_KEY,EC_KEY_new,d2i_EC_PUBKEY,bp,eckey);
- }
-
+{
+ return ASN1_d2i_bio_of(EC_KEY, EC_KEY_new, d2i_EC_PUBKEY, bp, eckey);
+}
+
int i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *ecdsa)
- {
- return ASN1_i2d_bio_of_const(EC_KEY,i2d_EC_PUBKEY,bp,ecdsa);
- }
+{
+ return ASN1_i2d_bio_of_const(EC_KEY, i2d_EC_PUBKEY, bp, ecdsa);
+}
EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey)
- {
- return ASN1_d2i_bio_of(EC_KEY,EC_KEY_new,d2i_ECPrivateKey,bp,eckey);
- }
-
-int i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey)
- {
- return ASN1_i2d_bio_of_const(EC_KEY,i2d_ECPrivateKey,bp,eckey);
- }
+{
+ return ASN1_d2i_bio_of(EC_KEY, EC_KEY_new, d2i_ECPrivateKey, bp, eckey);
+}
+int i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey)
+{
+ return ASN1_i2d_bio_of_const(EC_KEY, i2d_ECPrivateKey, bp, eckey);
+}
-int X509_pubkey_digest(const X509 *data, const EVP_MD *type, unsigned char *md,
- unsigned int *len)
- {
- ASN1_BIT_STRING *key;
- key = X509_get0_pubkey_bitstr(data);
- if(!key) return 0;
- return EVP_Digest(key->data, key->length, md, len, type, NULL);
- }
+int X509_pubkey_digest(const X509 *data, const EVP_MD *type,
+ unsigned char *md, unsigned int *len)
+{
+ ASN1_BIT_STRING *key;
+ key = X509_get0_pubkey_bitstr(data);
+ if (!key)
+ return 0;
+ return EVP_Digest(key->data, key->length, md, len, type, NULL);
+}
int X509_digest(const X509 *data, const EVP_MD *type, unsigned char *md,
- unsigned int *len)
- {
- return(ASN1_item_digest(ASN1_ITEM_rptr(X509),type,(char *)data,md,len));
- }
-
-int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type, unsigned char *md,
- unsigned int *len)
- {
- return(ASN1_item_digest(ASN1_ITEM_rptr(X509_CRL),type,(char *)data,md,len));
- }
-
-int X509_REQ_digest(const X509_REQ *data, const EVP_MD *type, unsigned char *md,
- unsigned int *len)
- {
- return(ASN1_item_digest(ASN1_ITEM_rptr(X509_REQ),type,(char *)data,md,len));
- }
-
-int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type, unsigned char *md,
- unsigned int *len)
- {
- return(ASN1_item_digest(ASN1_ITEM_rptr(X509_NAME),type,(char *)data,md,len));
- }
+ unsigned int *len)
+{
+ return (ASN1_item_digest
+ (ASN1_ITEM_rptr(X509), type, (char *)data, md, len));
+}
+
+int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type,
+ unsigned char *md, unsigned int *len)
+{
+ return (ASN1_item_digest
+ (ASN1_ITEM_rptr(X509_CRL), type, (char *)data, md, len));
+}
+
+int X509_REQ_digest(const X509_REQ *data, const EVP_MD *type,
+ unsigned char *md, unsigned int *len)
+{
+ return (ASN1_item_digest
+ (ASN1_ITEM_rptr(X509_REQ), type, (char *)data, md, len));
+}
+
+int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type,
+ unsigned char *md, unsigned int *len)
+{
+ return (ASN1_item_digest
+ (ASN1_ITEM_rptr(X509_NAME), type, (char *)data, md, len));
+}
#ifndef OPENSSL_NO_FP_API
X509_SIG *d2i_PKCS8_fp(FILE *fp, X509_SIG **p8)
- {
- return ASN1_d2i_fp_of(X509_SIG,X509_SIG_new,d2i_X509_SIG,fp,p8);
- }
+{
+ return ASN1_d2i_fp_of(X509_SIG, X509_SIG_new, d2i_X509_SIG, fp, p8);
+}
int i2d_PKCS8_fp(FILE *fp, X509_SIG *p8)
- {
- return ASN1_i2d_fp_of(X509_SIG,i2d_X509_SIG,fp,p8);
- }
+{
+ return ASN1_i2d_fp_of(X509_SIG, i2d_X509_SIG, fp, p8);
+}
#endif
X509_SIG *d2i_PKCS8_bio(BIO *bp, X509_SIG **p8)
- {
- return ASN1_d2i_bio_of(X509_SIG,X509_SIG_new,d2i_X509_SIG,bp,p8);
- }
+{
+ return ASN1_d2i_bio_of(X509_SIG, X509_SIG_new, d2i_X509_SIG, bp, p8);
+}
int i2d_PKCS8_bio(BIO *bp, X509_SIG *p8)
- {
- return ASN1_i2d_bio_of(X509_SIG,i2d_X509_SIG,bp,p8);
- }
+{
+ return ASN1_i2d_bio_of(X509_SIG, i2d_X509_SIG, bp, p8);
+}
#ifndef OPENSSL_NO_FP_API
PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,
- PKCS8_PRIV_KEY_INFO **p8inf)
- {
- return ASN1_d2i_fp_of(PKCS8_PRIV_KEY_INFO,PKCS8_PRIV_KEY_INFO_new,
- d2i_PKCS8_PRIV_KEY_INFO,fp,p8inf);
- }
+ PKCS8_PRIV_KEY_INFO **p8inf)
+{
+ return ASN1_d2i_fp_of(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_new,
+ d2i_PKCS8_PRIV_KEY_INFO, fp, p8inf);
+}
int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO *p8inf)
- {
- return ASN1_i2d_fp_of(PKCS8_PRIV_KEY_INFO,i2d_PKCS8_PRIV_KEY_INFO,fp,
- p8inf);
- }
+{
+ return ASN1_i2d_fp_of(PKCS8_PRIV_KEY_INFO, i2d_PKCS8_PRIV_KEY_INFO, fp,
+ p8inf);
+}
int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key)
- {
- PKCS8_PRIV_KEY_INFO *p8inf;
- int ret;
- p8inf = EVP_PKEY2PKCS8(key);
- if(!p8inf) return 0;
- ret = i2d_PKCS8_PRIV_KEY_INFO_fp(fp, p8inf);
- PKCS8_PRIV_KEY_INFO_free(p8inf);
- return ret;
- }
+{
+ PKCS8_PRIV_KEY_INFO *p8inf;
+ int ret;
+ p8inf = EVP_PKEY2PKCS8(key);
+ if (!p8inf)
+ return 0;
+ ret = i2d_PKCS8_PRIV_KEY_INFO_fp(fp, p8inf);
+ PKCS8_PRIV_KEY_INFO_free(p8inf);
+ return ret;
+}
int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey)
- {
- return ASN1_i2d_fp_of_const(EVP_PKEY,i2d_PrivateKey,fp,pkey);
- }
+{
+ return ASN1_i2d_fp_of_const(EVP_PKEY, i2d_PrivateKey, fp, pkey);
+}
EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a)
{
- return ASN1_d2i_fp_of(EVP_PKEY,EVP_PKEY_new,d2i_AutoPrivateKey,fp,a);
+ return ASN1_d2i_fp_of(EVP_PKEY, EVP_PKEY_new, d2i_AutoPrivateKey, fp, a);
}
int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey)
- {
- return ASN1_i2d_fp_of_const(EVP_PKEY,i2d_PUBKEY,fp,pkey);
- }
+{
+ return ASN1_i2d_fp_of_const(EVP_PKEY, i2d_PUBKEY, fp, pkey);
+}
EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a)
{
- return ASN1_d2i_fp_of(EVP_PKEY,EVP_PKEY_new,d2i_PUBKEY,fp,a);
+ return ASN1_d2i_fp_of(EVP_PKEY, EVP_PKEY_new, d2i_PUBKEY, fp, a);
}
PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,
- PKCS8_PRIV_KEY_INFO **p8inf)
- {
- return ASN1_d2i_bio_of(PKCS8_PRIV_KEY_INFO,PKCS8_PRIV_KEY_INFO_new,
- d2i_PKCS8_PRIV_KEY_INFO,bp,p8inf);
- }
+ PKCS8_PRIV_KEY_INFO **p8inf)
+{
+ return ASN1_d2i_bio_of(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_new,
+ d2i_PKCS8_PRIV_KEY_INFO, bp, p8inf);
+}
int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, PKCS8_PRIV_KEY_INFO *p8inf)
- {
- return ASN1_i2d_bio_of(PKCS8_PRIV_KEY_INFO,i2d_PKCS8_PRIV_KEY_INFO,bp,
- p8inf);
- }
+{
+ return ASN1_i2d_bio_of(PKCS8_PRIV_KEY_INFO, i2d_PKCS8_PRIV_KEY_INFO, bp,
+ p8inf);
+}
int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key)
- {
- PKCS8_PRIV_KEY_INFO *p8inf;
- int ret;
- p8inf = EVP_PKEY2PKCS8(key);
- if(!p8inf) return 0;
- ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf);
- PKCS8_PRIV_KEY_INFO_free(p8inf);
- return ret;
- }
+{
+ PKCS8_PRIV_KEY_INFO *p8inf;
+ int ret;
+ p8inf = EVP_PKEY2PKCS8(key);
+ if (!p8inf)
+ return 0;
+ ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf);
+ PKCS8_PRIV_KEY_INFO_free(p8inf);
+ return ret;
+}
#endif
int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey)
- {
- return ASN1_i2d_bio_of_const(EVP_PKEY,i2d_PrivateKey,bp,pkey);
- }
+{
+ return ASN1_i2d_bio_of_const(EVP_PKEY, i2d_PrivateKey, bp, pkey);
+}
EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a)
- {
- return ASN1_d2i_bio_of(EVP_PKEY,EVP_PKEY_new,d2i_AutoPrivateKey,bp,a);
- }
+{
+ return ASN1_d2i_bio_of(EVP_PKEY, EVP_PKEY_new, d2i_AutoPrivateKey, bp, a);
+}
int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey)
- {
- return ASN1_i2d_bio_of_const(EVP_PKEY,i2d_PUBKEY,bp,pkey);
- }
+{
+ return ASN1_i2d_bio_of_const(EVP_PKEY, i2d_PUBKEY, bp, pkey);
+}
EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a)
- {
- return ASN1_d2i_bio_of(EVP_PKEY,EVP_PKEY_new,d2i_PUBKEY,bp,a);
- }
+{
+ return ASN1_d2i_bio_of(EVP_PKEY, EVP_PKEY_new, d2i_PUBKEY, bp, a);
+}
diff --git a/src/crypto/x509/x_attrib.c b/src/crypto/x509/x_attrib.c
index c460a702..de8c95cc 100644
--- a/src/crypto/x509/x_attrib.c
+++ b/src/crypto/x509/x_attrib.c
@@ -59,59 +59,53 @@
#include <openssl/x509.h>
#include <openssl/obj.h>
-
-/* X509_ATTRIBUTE: this has the following form:
- *
- * typedef struct x509_attributes_st
- * {
- * ASN1_OBJECT *object;
- * int single;
- * union {
- * char *ptr;
- * STACK_OF(ASN1_TYPE) *set;
- * ASN1_TYPE *single;
- * } value;
- * } X509_ATTRIBUTE;
- *
- * this needs some extra thought because the CHOICE type is
- * merged with the main structure and because the value can
- * be anything at all we *must* try the SET OF first because
- * the ASN1_ANY type will swallow anything including the whole
- * SET OF structure.
+/*
+ * X509_ATTRIBUTE: this has the following form: typedef struct
+ * x509_attributes_st { ASN1_OBJECT *object; int single; union { char *ptr;
+ * STACK_OF(ASN1_TYPE) *set; ASN1_TYPE *single; } value; } X509_ATTRIBUTE;
+ * this needs some extra thought because the CHOICE type is merged with the
+ * main structure and because the value can be anything at all we *must* try
+ * the SET OF first because the ASN1_ANY type will swallow anything including
+ * the whole SET OF structure.
*/
ASN1_CHOICE(X509_ATTRIBUTE_SET) = {
- ASN1_SET_OF(X509_ATTRIBUTE, value.set, ASN1_ANY),
- ASN1_SIMPLE(X509_ATTRIBUTE, value.single, ASN1_ANY)
+ ASN1_SET_OF(X509_ATTRIBUTE, value.set, ASN1_ANY),
+ ASN1_SIMPLE(X509_ATTRIBUTE, value.single, ASN1_ANY)
} ASN1_CHOICE_END_selector(X509_ATTRIBUTE, X509_ATTRIBUTE_SET, single)
ASN1_SEQUENCE(X509_ATTRIBUTE) = {
- ASN1_SIMPLE(X509_ATTRIBUTE, object, ASN1_OBJECT),
- /* CHOICE type merged with parent */
- ASN1_EX_COMBINE(0, 0, X509_ATTRIBUTE_SET)
+ ASN1_SIMPLE(X509_ATTRIBUTE, object, ASN1_OBJECT),
+ /* CHOICE type merged with parent */
+ ASN1_EX_COMBINE(0, 0, X509_ATTRIBUTE_SET)
} ASN1_SEQUENCE_END(X509_ATTRIBUTE)
IMPLEMENT_ASN1_FUNCTIONS(X509_ATTRIBUTE)
IMPLEMENT_ASN1_DUP_FUNCTION(X509_ATTRIBUTE)
X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value)
- {
- X509_ATTRIBUTE *ret=NULL;
- ASN1_TYPE *val=NULL;
+{
+ X509_ATTRIBUTE *ret = NULL;
+ ASN1_TYPE *val = NULL;
- if ((ret=X509_ATTRIBUTE_new()) == NULL)
- return(NULL);
- /* TODO(fork): const correctness. */
- ret->object=(ASN1_OBJECT*) OBJ_nid2obj(nid);
- ret->single=0;
- if ((ret->value.set=sk_ASN1_TYPE_new_null()) == NULL) goto err;
- if ((val=ASN1_TYPE_new()) == NULL) goto err;
- if (!sk_ASN1_TYPE_push(ret->value.set,val)) goto err;
+ if ((ret = X509_ATTRIBUTE_new()) == NULL)
+ return (NULL);
+ /* TODO(fork): const correctness. */
+ ret->object = (ASN1_OBJECT *)OBJ_nid2obj(nid);
+ ret->single = 0;
+ if ((ret->value.set = sk_ASN1_TYPE_new_null()) == NULL)
+ goto err;
+ if ((val = ASN1_TYPE_new()) == NULL)
+ goto err;
+ if (!sk_ASN1_TYPE_push(ret->value.set, val))
+ goto err;
- ASN1_TYPE_set(val,atrtype,value);
- return(ret);
-err:
- if (ret != NULL) X509_ATTRIBUTE_free(ret);
- if (val != NULL) ASN1_TYPE_free(val);
- return(NULL);
- }
+ ASN1_TYPE_set(val, atrtype, value);
+ return (ret);
+ err:
+ if (ret != NULL)
+ X509_ATTRIBUTE_free(ret);
+ if (val != NULL)
+ ASN1_TYPE_free(val);
+ return (NULL);
+}
diff --git a/src/crypto/x509/x_crl.c b/src/crypto/x509/x_crl.c
index d5168727..cd648901 100644
--- a/src/crypto/x509/x_crl.c
+++ b/src/crypto/x509/x_crl.c
@@ -67,494 +67,473 @@
#include "../internal.h"
-
-/* Method to handle CRL access.
- * In general a CRL could be very large (several Mb) and can consume large
- * amounts of resources if stored in memory by multiple processes.
- * This method allows general CRL operations to be redirected to more
- * efficient callbacks: for example a CRL entry database.
+/*
+ * Method to handle CRL access. In general a CRL could be very large (several
+ * Mb) and can consume large amounts of resources if stored in memory by
+ * multiple processes. This method allows general CRL operations to be
+ * redirected to more efficient callbacks: for example a CRL entry database.
*/
-#define X509_CRL_METHOD_DYNAMIC 1
+#define X509_CRL_METHOD_DYNAMIC 1
-struct x509_crl_method_st
- {
- int flags;
- int (*crl_init)(X509_CRL *crl);
- int (*crl_free)(X509_CRL *crl);
- int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret,
- ASN1_INTEGER *ser, X509_NAME *issuer);
- int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk);
- };
+struct x509_crl_method_st {
+ int flags;
+ int (*crl_init) (X509_CRL *crl);
+ int (*crl_free) (X509_CRL *crl);
+ int (*crl_lookup) (X509_CRL *crl, X509_REVOKED **ret,
+ ASN1_INTEGER *ser, X509_NAME *issuer);
+ int (*crl_verify) (X509_CRL *crl, EVP_PKEY *pk);
+};
-static int X509_REVOKED_cmp(const X509_REVOKED **a,
- const X509_REVOKED **b);
+static int X509_REVOKED_cmp(const X509_REVOKED **a, const X509_REVOKED **b);
static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp);
ASN1_SEQUENCE(X509_REVOKED) = {
- ASN1_SIMPLE(X509_REVOKED,serialNumber, ASN1_INTEGER),
- ASN1_SIMPLE(X509_REVOKED,revocationDate, ASN1_TIME),
- ASN1_SEQUENCE_OF_OPT(X509_REVOKED,extensions, X509_EXTENSION)
+ ASN1_SIMPLE(X509_REVOKED,serialNumber, ASN1_INTEGER),
+ ASN1_SIMPLE(X509_REVOKED,revocationDate, ASN1_TIME),
+ ASN1_SEQUENCE_OF_OPT(X509_REVOKED,extensions, X509_EXTENSION)
} ASN1_SEQUENCE_END(X509_REVOKED)
static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r);
static int def_crl_lookup(X509_CRL *crl,
- X509_REVOKED **ret, ASN1_INTEGER *serial, X509_NAME *issuer);
+ X509_REVOKED **ret, ASN1_INTEGER *serial,
+ X509_NAME *issuer);
-static const X509_CRL_METHOD int_crl_meth =
- {
- 0,
- 0,0,
- def_crl_lookup,
- def_crl_verify
- };
+static const X509_CRL_METHOD int_crl_meth = {
+ 0,
+ 0, 0,
+ def_crl_lookup,
+ def_crl_verify
+};
static const X509_CRL_METHOD *default_crl_method = &int_crl_meth;
-/* The X509_CRL_INFO structure needs a bit of customisation.
- * Since we cache the original encoding the signature wont be affected by
- * reordering of the revoked field.
+/*
+ * The X509_CRL_INFO structure needs a bit of customisation. Since we cache
+ * the original encoding the signature wont be affected by reordering of the
+ * revoked field.
*/
static int crl_inf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
- void *exarg)
+ void *exarg)
{
- X509_CRL_INFO *a = (X509_CRL_INFO *)*pval;
-
- if(!a || !a->revoked) return 1;
- switch(operation) {
- /* Just set cmp function here. We don't sort because that
- * would affect the output of X509_CRL_print().
- */
- case ASN1_OP_D2I_POST:
- (void)sk_X509_REVOKED_set_cmp_func(a->revoked,X509_REVOKED_cmp);
- break;
- }
- return 1;
+ X509_CRL_INFO *a = (X509_CRL_INFO *)*pval;
+
+ if (!a || !a->revoked)
+ return 1;
+ switch (operation) {
+ /*
+ * Just set cmp function here. We don't sort because that would
+ * affect the output of X509_CRL_print().
+ */
+ case ASN1_OP_D2I_POST:
+ (void)sk_X509_REVOKED_set_cmp_func(a->revoked, X509_REVOKED_cmp);
+ break;
+ }
+ return 1;
}
ASN1_SEQUENCE_enc(X509_CRL_INFO, enc, crl_inf_cb) = {
- ASN1_OPT(X509_CRL_INFO, version, ASN1_INTEGER),
- ASN1_SIMPLE(X509_CRL_INFO, sig_alg, X509_ALGOR),
- ASN1_SIMPLE(X509_CRL_INFO, issuer, X509_NAME),
- ASN1_SIMPLE(X509_CRL_INFO, lastUpdate, ASN1_TIME),
- ASN1_OPT(X509_CRL_INFO, nextUpdate, ASN1_TIME),
- ASN1_SEQUENCE_OF_OPT(X509_CRL_INFO, revoked, X509_REVOKED),
- ASN1_EXP_SEQUENCE_OF_OPT(X509_CRL_INFO, extensions, X509_EXTENSION, 0)
+ ASN1_OPT(X509_CRL_INFO, version, ASN1_INTEGER),
+ ASN1_SIMPLE(X509_CRL_INFO, sig_alg, X509_ALGOR),
+ ASN1_SIMPLE(X509_CRL_INFO, issuer, X509_NAME),
+ ASN1_SIMPLE(X509_CRL_INFO, lastUpdate, ASN1_TIME),
+ ASN1_OPT(X509_CRL_INFO, nextUpdate, ASN1_TIME),
+ ASN1_SEQUENCE_OF_OPT(X509_CRL_INFO, revoked, X509_REVOKED),
+ ASN1_EXP_SEQUENCE_OF_OPT(X509_CRL_INFO, extensions, X509_EXTENSION, 0)
} ASN1_SEQUENCE_END_enc(X509_CRL_INFO, X509_CRL_INFO)
-/* Set CRL entry issuer according to CRL certificate issuer extension.
- * Check for unhandled critical CRL entry extensions.
+/*
+ * Set CRL entry issuer according to CRL certificate issuer extension. Check
+ * for unhandled critical CRL entry extensions.
*/
static int crl_set_issuers(X509_CRL *crl)
- {
-
- size_t i, k;
- int j;
- GENERAL_NAMES *gens, *gtmp;
- STACK_OF(X509_REVOKED) *revoked;
-
- revoked = X509_CRL_get_REVOKED(crl);
-
- gens = NULL;
- for (i = 0; i < sk_X509_REVOKED_num(revoked); i++)
- {
- X509_REVOKED *rev = sk_X509_REVOKED_value(revoked, i);
- STACK_OF(X509_EXTENSION) *exts;
- ASN1_ENUMERATED *reason;
- X509_EXTENSION *ext;
- gtmp = X509_REVOKED_get_ext_d2i(rev,
- NID_certificate_issuer,
- &j, NULL);
- if (!gtmp && (j != -1))
- {
- crl->flags |= EXFLAG_INVALID;
- return 1;
- }
-
- if (gtmp)
- {
- gens = gtmp;
- if (!crl->issuers)
- {
- crl->issuers = sk_GENERAL_NAMES_new_null();
- if (!crl->issuers)
- return 0;
- }
- if (!sk_GENERAL_NAMES_push(crl->issuers, gtmp))
- return 0;
- }
- rev->issuer = gens;
-
- reason = X509_REVOKED_get_ext_d2i(rev, NID_crl_reason,
- &j, NULL);
- if (!reason && (j != -1))
- {
- crl->flags |= EXFLAG_INVALID;
- return 1;
- }
-
- if (reason)
- {
- rev->reason = ASN1_ENUMERATED_get(reason);
- ASN1_ENUMERATED_free(reason);
- }
- else
- rev->reason = CRL_REASON_NONE;
-
- /* Check for critical CRL entry extensions */
-
- exts = rev->extensions;
-
- for (k = 0; k < sk_X509_EXTENSION_num(exts); k++)
- {
- ext = sk_X509_EXTENSION_value(exts, k);
- if (ext->critical > 0)
- {
- if (OBJ_obj2nid(ext->object) ==
- NID_certificate_issuer)
- continue;
- crl->flags |= EXFLAG_CRITICAL;
- break;
- }
- }
-
-
- }
-
- return 1;
-
- }
-
-/* The X509_CRL structure needs a bit of customisation. Cache some extensions
+{
+
+ size_t i, k;
+ int j;
+ GENERAL_NAMES *gens, *gtmp;
+ STACK_OF(X509_REVOKED) *revoked;
+
+ revoked = X509_CRL_get_REVOKED(crl);
+
+ gens = NULL;
+ for (i = 0; i < sk_X509_REVOKED_num(revoked); i++) {
+ X509_REVOKED *rev = sk_X509_REVOKED_value(revoked, i);
+ STACK_OF(X509_EXTENSION) *exts;
+ ASN1_ENUMERATED *reason;
+ X509_EXTENSION *ext;
+ gtmp = X509_REVOKED_get_ext_d2i(rev,
+ NID_certificate_issuer, &j, NULL);
+ if (!gtmp && (j != -1)) {
+ crl->flags |= EXFLAG_INVALID;
+ return 1;
+ }
+
+ if (gtmp) {
+ gens = gtmp;
+ if (!crl->issuers) {
+ crl->issuers = sk_GENERAL_NAMES_new_null();
+ if (!crl->issuers)
+ return 0;
+ }
+ if (!sk_GENERAL_NAMES_push(crl->issuers, gtmp))
+ return 0;
+ }
+ rev->issuer = gens;
+
+ reason = X509_REVOKED_get_ext_d2i(rev, NID_crl_reason, &j, NULL);
+ if (!reason && (j != -1)) {
+ crl->flags |= EXFLAG_INVALID;
+ return 1;
+ }
+
+ if (reason) {
+ rev->reason = ASN1_ENUMERATED_get(reason);
+ ASN1_ENUMERATED_free(reason);
+ } else
+ rev->reason = CRL_REASON_NONE;
+
+ /* Check for critical CRL entry extensions */
+
+ exts = rev->extensions;
+
+ for (k = 0; k < sk_X509_EXTENSION_num(exts); k++) {
+ ext = sk_X509_EXTENSION_value(exts, k);
+ if (ext->critical > 0) {
+ if (OBJ_obj2nid(ext->object) == NID_certificate_issuer)
+ continue;
+ crl->flags |= EXFLAG_CRITICAL;
+ break;
+ }
+ }
+
+ }
+
+ return 1;
+
+}
+
+/*
+ * The X509_CRL structure needs a bit of customisation. Cache some extensions
* and hash of the whole CRL.
*/
static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
- void *exarg)
- {
- X509_CRL *crl = (X509_CRL *)*pval;
- STACK_OF(X509_EXTENSION) *exts;
- X509_EXTENSION *ext;
- size_t idx;
-
- switch(operation)
- {
- case ASN1_OP_NEW_POST:
- crl->idp = NULL;
- crl->akid = NULL;
- crl->flags = 0;
- crl->idp_flags = 0;
- crl->idp_reasons = CRLDP_ALL_REASONS;
- crl->meth = default_crl_method;
- crl->meth_data = NULL;
- crl->issuers = NULL;
- crl->crl_number = NULL;
- crl->base_crl_number = NULL;
- break;
-
- case ASN1_OP_D2I_POST:
- X509_CRL_digest(crl, EVP_sha1(), crl->sha1_hash, NULL);
- crl->idp = X509_CRL_get_ext_d2i(crl,
- NID_issuing_distribution_point, NULL, NULL);
- if (crl->idp)
- setup_idp(crl, crl->idp);
-
- crl->akid = X509_CRL_get_ext_d2i(crl,
- NID_authority_key_identifier, NULL, NULL);
-
- crl->crl_number = X509_CRL_get_ext_d2i(crl,
- NID_crl_number, NULL, NULL);
-
- crl->base_crl_number = X509_CRL_get_ext_d2i(crl,
- NID_delta_crl, NULL, NULL);
- /* Delta CRLs must have CRL number */
- if (crl->base_crl_number && !crl->crl_number)
- crl->flags |= EXFLAG_INVALID;
-
- /* See if we have any unhandled critical CRL extensions and
- * indicate this in a flag. We only currently handle IDP so
- * anything else critical sets the flag.
- *
- * This code accesses the X509_CRL structure directly:
- * applications shouldn't do this.
- */
-
- exts = crl->crl->extensions;
-
- for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++)
- {
- int nid;
- ext = sk_X509_EXTENSION_value(exts, idx);
- nid = OBJ_obj2nid(ext->object);
- if (nid == NID_freshest_crl)
- crl->flags |= EXFLAG_FRESHEST;
- if (ext->critical > 0)
- {
- /* We handle IDP and deltas */
- if ((nid == NID_issuing_distribution_point)
- || (nid == NID_authority_key_identifier)
- || (nid == NID_delta_crl))
- break;;
- crl->flags |= EXFLAG_CRITICAL;
- break;
- }
- }
-
-
- if (!crl_set_issuers(crl))
- return 0;
-
- if (crl->meth->crl_init)
- {
- if (crl->meth->crl_init(crl) == 0)
- return 0;
- }
- break;
-
- case ASN1_OP_FREE_POST:
- if (crl->meth->crl_free)
- {
- if (!crl->meth->crl_free(crl))
- return 0;
- }
- if (crl->akid)
- AUTHORITY_KEYID_free(crl->akid);
- if (crl->idp)
- ISSUING_DIST_POINT_free(crl->idp);
- ASN1_INTEGER_free(crl->crl_number);
- ASN1_INTEGER_free(crl->base_crl_number);
- sk_GENERAL_NAMES_pop_free(crl->issuers, GENERAL_NAMES_free);
- break;
- }
- return 1;
- }
+ void *exarg)
+{
+ X509_CRL *crl = (X509_CRL *)*pval;
+ STACK_OF(X509_EXTENSION) *exts;
+ X509_EXTENSION *ext;
+ size_t idx;
+
+ switch (operation) {
+ case ASN1_OP_NEW_POST:
+ crl->idp = NULL;
+ crl->akid = NULL;
+ crl->flags = 0;
+ crl->idp_flags = 0;
+ crl->idp_reasons = CRLDP_ALL_REASONS;
+ crl->meth = default_crl_method;
+ crl->meth_data = NULL;
+ crl->issuers = NULL;
+ crl->crl_number = NULL;
+ crl->base_crl_number = NULL;
+ break;
+
+ case ASN1_OP_D2I_POST:
+ X509_CRL_digest(crl, EVP_sha1(), crl->sha1_hash, NULL);
+ crl->idp = X509_CRL_get_ext_d2i(crl,
+ NID_issuing_distribution_point, NULL,
+ NULL);
+ if (crl->idp)
+ setup_idp(crl, crl->idp);
+
+ crl->akid = X509_CRL_get_ext_d2i(crl,
+ NID_authority_key_identifier, NULL,
+ NULL);
+
+ crl->crl_number = X509_CRL_get_ext_d2i(crl,
+ NID_crl_number, NULL, NULL);
+
+ crl->base_crl_number = X509_CRL_get_ext_d2i(crl,
+ NID_delta_crl, NULL,
+ NULL);
+ /* Delta CRLs must have CRL number */
+ if (crl->base_crl_number && !crl->crl_number)
+ crl->flags |= EXFLAG_INVALID;
+
+ /*
+ * See if we have any unhandled critical CRL extensions and indicate
+ * this in a flag. We only currently handle IDP so anything else
+ * critical sets the flag. This code accesses the X509_CRL structure
+ * directly: applications shouldn't do this.
+ */
+
+ exts = crl->crl->extensions;
+
+ for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++) {
+ int nid;
+ ext = sk_X509_EXTENSION_value(exts, idx);
+ nid = OBJ_obj2nid(ext->object);
+ if (nid == NID_freshest_crl)
+ crl->flags |= EXFLAG_FRESHEST;
+ if (ext->critical > 0) {
+ /* We handle IDP and deltas */
+ if ((nid == NID_issuing_distribution_point)
+ || (nid == NID_authority_key_identifier)
+ || (nid == NID_delta_crl))
+ break;;
+ crl->flags |= EXFLAG_CRITICAL;
+ break;
+ }
+ }
+
+ if (!crl_set_issuers(crl))
+ return 0;
+
+ if (crl->meth->crl_init) {
+ if (crl->meth->crl_init(crl) == 0)
+ return 0;
+ }
+ break;
+
+ case ASN1_OP_FREE_POST:
+ if (crl->meth->crl_free) {
+ if (!crl->meth->crl_free(crl))
+ return 0;
+ }
+ if (crl->akid)
+ AUTHORITY_KEYID_free(crl->akid);
+ if (crl->idp)
+ ISSUING_DIST_POINT_free(crl->idp);
+ ASN1_INTEGER_free(crl->crl_number);
+ ASN1_INTEGER_free(crl->base_crl_number);
+ sk_GENERAL_NAMES_pop_free(crl->issuers, GENERAL_NAMES_free);
+ break;
+ }
+ return 1;
+}
/* Convert IDP into a more convenient form */
static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp)
- {
- int idp_only = 0;
- /* Set various flags according to IDP */
- crl->idp_flags |= IDP_PRESENT;
- if (idp->onlyuser > 0)
- {
- idp_only++;
- crl->idp_flags |= IDP_ONLYUSER;
- }
- if (idp->onlyCA > 0)
- {
- idp_only++;
- crl->idp_flags |= IDP_ONLYCA;
- }
- if (idp->onlyattr > 0)
- {
- idp_only++;
- crl->idp_flags |= IDP_ONLYATTR;
- }
-
- if (idp_only > 1)
- crl->idp_flags |= IDP_INVALID;
-
- if (idp->indirectCRL > 0)
- crl->idp_flags |= IDP_INDIRECT;
-
- if (idp->onlysomereasons)
- {
- crl->idp_flags |= IDP_REASONS;
- if (idp->onlysomereasons->length > 0)
- crl->idp_reasons = idp->onlysomereasons->data[0];
- if (idp->onlysomereasons->length > 1)
- crl->idp_reasons |=
- (idp->onlysomereasons->data[1] << 8);
- crl->idp_reasons &= CRLDP_ALL_REASONS;
- }
-
- DIST_POINT_set_dpname(idp->distpoint, X509_CRL_get_issuer(crl));
- }
+{
+ int idp_only = 0;
+ /* Set various flags according to IDP */
+ crl->idp_flags |= IDP_PRESENT;
+ if (idp->onlyuser > 0) {
+ idp_only++;
+ crl->idp_flags |= IDP_ONLYUSER;
+ }
+ if (idp->onlyCA > 0) {
+ idp_only++;
+ crl->idp_flags |= IDP_ONLYCA;
+ }
+ if (idp->onlyattr > 0) {
+ idp_only++;
+ crl->idp_flags |= IDP_ONLYATTR;
+ }
+
+ if (idp_only > 1)
+ crl->idp_flags |= IDP_INVALID;
+
+ if (idp->indirectCRL > 0)
+ crl->idp_flags |= IDP_INDIRECT;
+
+ if (idp->onlysomereasons) {
+ crl->idp_flags |= IDP_REASONS;
+ if (idp->onlysomereasons->length > 0)
+ crl->idp_reasons = idp->onlysomereasons->data[0];
+ if (idp->onlysomereasons->length > 1)
+ crl->idp_reasons |= (idp->onlysomereasons->data[1] << 8);
+ crl->idp_reasons &= CRLDP_ALL_REASONS;
+ }
+
+ DIST_POINT_set_dpname(idp->distpoint, X509_CRL_get_issuer(crl));
+}
ASN1_SEQUENCE_ref(X509_CRL, crl_cb) = {
- ASN1_SIMPLE(X509_CRL, crl, X509_CRL_INFO),
- ASN1_SIMPLE(X509_CRL, sig_alg, X509_ALGOR),
- ASN1_SIMPLE(X509_CRL, signature, ASN1_BIT_STRING)
+ ASN1_SIMPLE(X509_CRL, crl, X509_CRL_INFO),
+ ASN1_SIMPLE(X509_CRL, sig_alg, X509_ALGOR),
+ ASN1_SIMPLE(X509_CRL, signature, ASN1_BIT_STRING)
} ASN1_SEQUENCE_END_ref(X509_CRL, X509_CRL)
IMPLEMENT_ASN1_FUNCTIONS(X509_REVOKED)
+
IMPLEMENT_ASN1_DUP_FUNCTION(X509_REVOKED)
+
IMPLEMENT_ASN1_FUNCTIONS(X509_CRL_INFO)
IMPLEMENT_ASN1_FUNCTIONS(X509_CRL)
IMPLEMENT_ASN1_DUP_FUNCTION(X509_CRL)
-static int X509_REVOKED_cmp(const X509_REVOKED **a,
- const X509_REVOKED **b)
- {
- return(ASN1_STRING_cmp(
- (ASN1_STRING *)(*a)->serialNumber,
- (ASN1_STRING *)(*b)->serialNumber));
- }
+static int X509_REVOKED_cmp(const X509_REVOKED **a, const X509_REVOKED **b)
+{
+ return (ASN1_STRING_cmp((ASN1_STRING *)(*a)->serialNumber,
+ (ASN1_STRING *)(*b)->serialNumber));
+}
int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev)
{
- X509_CRL_INFO *inf;
- inf = crl->crl;
- 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, ERR_R_MALLOC_FAILURE);
- return 0;
- }
- inf->enc.modified = 1;
- return 1;
+ X509_CRL_INFO *inf;
+ inf = crl->crl;
+ 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, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ inf->enc.modified = 1;
+ return 1;
}
int X509_CRL_verify(X509_CRL *crl, EVP_PKEY *r)
- {
- if (crl->meth->crl_verify)
- return crl->meth->crl_verify(crl, r);
- return 0;
- }
+{
+ if (crl->meth->crl_verify)
+ return crl->meth->crl_verify(crl, r);
+ return 0;
+}
int X509_CRL_get0_by_serial(X509_CRL *crl,
- X509_REVOKED **ret, ASN1_INTEGER *serial)
- {
- if (crl->meth->crl_lookup)
- return crl->meth->crl_lookup(crl, ret, serial, NULL);
- return 0;
- }
+ X509_REVOKED **ret, ASN1_INTEGER *serial)
+{
+ if (crl->meth->crl_lookup)
+ return crl->meth->crl_lookup(crl, ret, serial, NULL);
+ return 0;
+}
int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x)
- {
- if (crl->meth->crl_lookup)
- return crl->meth->crl_lookup(crl, ret,
- X509_get_serialNumber(x),
- X509_get_issuer_name(x));
- return 0;
- }
+{
+ if (crl->meth->crl_lookup)
+ return crl->meth->crl_lookup(crl, ret,
+ X509_get_serialNumber(x),
+ X509_get_issuer_name(x));
+ return 0;
+}
static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r)
- {
- return(ASN1_item_verify(ASN1_ITEM_rptr(X509_CRL_INFO),
- crl->sig_alg, crl->signature,crl->crl,r));
- }
+{
+ return (ASN1_item_verify(ASN1_ITEM_rptr(X509_CRL_INFO),
+ crl->sig_alg, crl->signature, crl->crl, r));
+}
static int crl_revoked_issuer_match(X509_CRL *crl, X509_NAME *nm,
- X509_REVOKED *rev)
- {
- size_t i;
-
- if (!rev->issuer)
- {
- if (!nm)
- return 1;
- if (!X509_NAME_cmp(nm, X509_CRL_get_issuer(crl)))
- return 1;
- return 0;
- }
-
- if (!nm)
- nm = X509_CRL_get_issuer(crl);
-
- for (i = 0; i < sk_GENERAL_NAME_num(rev->issuer); i++)
- {
- GENERAL_NAME *gen = sk_GENERAL_NAME_value(rev->issuer, i);
- if (gen->type != GEN_DIRNAME)
- continue;
- if (!X509_NAME_cmp(nm, gen->d.directoryName))
- return 1;
- }
- return 0;
-
- }
+ X509_REVOKED *rev)
+{
+ size_t i;
+
+ if (!rev->issuer) {
+ if (!nm)
+ return 1;
+ if (!X509_NAME_cmp(nm, X509_CRL_get_issuer(crl)))
+ return 1;
+ return 0;
+ }
+
+ if (!nm)
+ nm = X509_CRL_get_issuer(crl);
+
+ for (i = 0; i < sk_GENERAL_NAME_num(rev->issuer); i++) {
+ GENERAL_NAME *gen = sk_GENERAL_NAME_value(rev->issuer, i);
+ if (gen->type != GEN_DIRNAME)
+ continue;
+ if (!X509_NAME_cmp(nm, gen->d.directoryName))
+ return 1;
+ }
+ return 0;
+
+}
static struct CRYPTO_STATIC_MUTEX g_crl_sort_lock = CRYPTO_STATIC_MUTEX_INIT;
static int def_crl_lookup(X509_CRL *crl,
- X509_REVOKED **ret, ASN1_INTEGER *serial, X509_NAME *issuer)
- {
- X509_REVOKED rtmp, *rev;
- size_t idx;
- rtmp.serialNumber = serial;
- /* Sort revoked into serial number order if not already sorted.
- * Do this under a lock to avoid race condition.
- */
-
- CRYPTO_STATIC_MUTEX_lock_read(&g_crl_sort_lock);
- const int is_sorted = sk_X509_REVOKED_is_sorted(crl->crl->revoked);
- CRYPTO_STATIC_MUTEX_unlock(&g_crl_sort_lock);
-
- if (!is_sorted)
- {
- CRYPTO_STATIC_MUTEX_lock_write(&g_crl_sort_lock);
- if (!sk_X509_REVOKED_is_sorted(crl->crl->revoked))
- {
- sk_X509_REVOKED_sort(crl->crl->revoked);
- }
- CRYPTO_STATIC_MUTEX_unlock(&g_crl_sort_lock);
- }
-
- if (!sk_X509_REVOKED_find(crl->crl->revoked, &idx, &rtmp))
- return 0;
- /* Need to look for matching name */
- for(;idx < sk_X509_REVOKED_num(crl->crl->revoked); idx++)
- {
- rev = sk_X509_REVOKED_value(crl->crl->revoked, idx);
- if (ASN1_INTEGER_cmp(rev->serialNumber, serial))
- return 0;
- if (crl_revoked_issuer_match(crl, issuer, rev))
- {
- if (ret)
- *ret = rev;
- if (rev->reason == CRL_REASON_REMOVE_FROM_CRL)
- return 2;
- return 1;
- }
- }
- return 0;
- }
+ X509_REVOKED **ret, ASN1_INTEGER *serial,
+ X509_NAME *issuer)
+{
+ X509_REVOKED rtmp, *rev;
+ size_t idx;
+ rtmp.serialNumber = serial;
+ /*
+ * Sort revoked into serial number order if not already sorted. Do this
+ * under a lock to avoid race condition.
+ */
+
+ CRYPTO_STATIC_MUTEX_lock_read(&g_crl_sort_lock);
+ const int is_sorted = sk_X509_REVOKED_is_sorted(crl->crl->revoked);
+ CRYPTO_STATIC_MUTEX_unlock(&g_crl_sort_lock);
+
+ if (!is_sorted) {
+ CRYPTO_STATIC_MUTEX_lock_write(&g_crl_sort_lock);
+ if (!sk_X509_REVOKED_is_sorted(crl->crl->revoked)) {
+ sk_X509_REVOKED_sort(crl->crl->revoked);
+ }
+ CRYPTO_STATIC_MUTEX_unlock(&g_crl_sort_lock);
+ }
+
+ if (!sk_X509_REVOKED_find(crl->crl->revoked, &idx, &rtmp))
+ return 0;
+ /* Need to look for matching name */
+ for (; idx < sk_X509_REVOKED_num(crl->crl->revoked); idx++) {
+ rev = sk_X509_REVOKED_value(crl->crl->revoked, idx);
+ if (ASN1_INTEGER_cmp(rev->serialNumber, serial))
+ return 0;
+ if (crl_revoked_issuer_match(crl, issuer, rev)) {
+ if (ret)
+ *ret = rev;
+ if (rev->reason == CRL_REASON_REMOVE_FROM_CRL)
+ return 2;
+ return 1;
+ }
+ }
+ return 0;
+}
void X509_CRL_set_default_method(const X509_CRL_METHOD *meth)
- {
- if (meth == NULL)
- default_crl_method = &int_crl_meth;
- else
- default_crl_method = meth;
- }
-
-X509_CRL_METHOD *X509_CRL_METHOD_new(
- int (*crl_init)(X509_CRL *crl),
- int (*crl_free)(X509_CRL *crl),
- int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret,
- ASN1_INTEGER *ser, X509_NAME *issuer),
- int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk))
- {
- X509_CRL_METHOD *m;
- m = OPENSSL_malloc(sizeof(X509_CRL_METHOD));
- if (!m)
- return NULL;
- m->crl_init = crl_init;
- m->crl_free = crl_free;
- m->crl_lookup = crl_lookup;
- m->crl_verify = crl_verify;
- m->flags = X509_CRL_METHOD_DYNAMIC;
- return m;
- }
+{
+ if (meth == NULL)
+ default_crl_method = &int_crl_meth;
+ else
+ default_crl_method = meth;
+}
+
+X509_CRL_METHOD *X509_CRL_METHOD_new(int (*crl_init) (X509_CRL *crl),
+ int (*crl_free) (X509_CRL *crl),
+ int (*crl_lookup) (X509_CRL *crl,
+ X509_REVOKED **ret,
+ ASN1_INTEGER *ser,
+ X509_NAME *issuer),
+ int (*crl_verify) (X509_CRL *crl,
+ EVP_PKEY *pk))
+{
+ X509_CRL_METHOD *m;
+ m = OPENSSL_malloc(sizeof(X509_CRL_METHOD));
+ if (!m)
+ return NULL;
+ m->crl_init = crl_init;
+ m->crl_free = crl_free;
+ m->crl_lookup = crl_lookup;
+ m->crl_verify = crl_verify;
+ m->flags = X509_CRL_METHOD_DYNAMIC;
+ return m;
+}
void X509_CRL_METHOD_free(X509_CRL_METHOD *m)
- {
- if (!(m->flags & X509_CRL_METHOD_DYNAMIC))
- return;
- OPENSSL_free(m);
- }
+{
+ if (!(m->flags & X509_CRL_METHOD_DYNAMIC))
+ return;
+ OPENSSL_free(m);
+}
void X509_CRL_set_meth_data(X509_CRL *crl, void *dat)
- {
- crl->meth_data = dat;
- }
+{
+ crl->meth_data = dat;
+}
void *X509_CRL_get_meth_data(X509_CRL *crl)
- {
- return crl->meth_data;
- }
+{
+ return crl->meth_data;
+}
IMPLEMENT_ASN1_SET_OF(X509_REVOKED)
+
IMPLEMENT_ASN1_SET_OF(X509_CRL)
diff --git a/src/crypto/x509/x_exten.c b/src/crypto/x509/x_exten.c
index cf64c844..36403e48 100644
--- a/src/crypto/x509/x_exten.c
+++ b/src/crypto/x509/x_exten.c
@@ -61,13 +61,13 @@
ASN1_SEQUENCE(X509_EXTENSION) = {
- ASN1_SIMPLE(X509_EXTENSION, object, ASN1_OBJECT),
- ASN1_OPT(X509_EXTENSION, critical, ASN1_BOOLEAN),
- ASN1_SIMPLE(X509_EXTENSION, value, ASN1_OCTET_STRING)
+ ASN1_SIMPLE(X509_EXTENSION, object, ASN1_OBJECT),
+ ASN1_OPT(X509_EXTENSION, critical, ASN1_BOOLEAN),
+ ASN1_SIMPLE(X509_EXTENSION, value, ASN1_OCTET_STRING)
} ASN1_SEQUENCE_END(X509_EXTENSION)
-ASN1_ITEM_TEMPLATE(X509_EXTENSIONS) =
- ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Extension, X509_EXTENSION)
+ASN1_ITEM_TEMPLATE(X509_EXTENSIONS) =
+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Extension, X509_EXTENSION)
ASN1_ITEM_TEMPLATE_END(X509_EXTENSIONS)
IMPLEMENT_ASN1_FUNCTIONS(X509_EXTENSION)
diff --git a/src/crypto/x509/x_info.c b/src/crypto/x509/x_info.c
index be579d79..177cd0eb 100644
--- a/src/crypto/x509/x_info.c
+++ b/src/crypto/x509/x_info.c
@@ -61,35 +61,38 @@
#include <openssl/mem.h>
#include <openssl/thread.h>
-
X509_INFO *X509_INFO_new(void)
- {
- X509_INFO *ret=NULL;
+{
+ X509_INFO *ret = NULL;
+
+ ret = (X509_INFO *)OPENSSL_malloc(sizeof(X509_INFO));
+ if (ret == NULL) {
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+
+ ret->enc_cipher.cipher = NULL;
+ ret->enc_len = 0;
+ ret->enc_data = NULL;
- ret=(X509_INFO *)OPENSSL_malloc(sizeof(X509_INFO));
- if (ret == NULL)
- {
- OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
- return(NULL);
- }
-
- ret->enc_cipher.cipher=NULL;
- ret->enc_len=0;
- ret->enc_data=NULL;
-
- ret->x509=NULL;
- ret->crl=NULL;
- ret->x_pkey=NULL;
- return(ret);
- }
+ ret->x509 = NULL;
+ ret->crl = NULL;
+ ret->x_pkey = NULL;
+ return (ret);
+}
void X509_INFO_free(X509_INFO *x)
- {
- if (x == NULL) return;
+{
+ if (x == NULL)
+ return;
- if (x->x509 != NULL) X509_free(x->x509);
- if (x->crl != NULL) X509_CRL_free(x->crl);
- if (x->x_pkey != NULL) X509_PKEY_free(x->x_pkey);
- if (x->enc_data != NULL) OPENSSL_free(x->enc_data);
- OPENSSL_free(x);
- }
+ if (x->x509 != NULL)
+ X509_free(x->x509);
+ if (x->crl != NULL)
+ X509_CRL_free(x->crl);
+ if (x->x_pkey != NULL)
+ X509_PKEY_free(x->x_pkey);
+ if (x->enc_data != NULL)
+ OPENSSL_free(x->enc_data);
+ OPENSSL_free(x);
+}
diff --git a/src/crypto/x509/x_name.c b/src/crypto/x509/x_name.c
index a1dcd167..226e76dc 100644
--- a/src/crypto/x509/x_name.c
+++ b/src/crypto/x509/x_name.c
@@ -68,471 +68,470 @@
#include "../asn1/asn1_locl.h"
-
typedef STACK_OF(X509_NAME_ENTRY) STACK_OF_X509_NAME_ENTRY;
DECLARE_STACK_OF(STACK_OF_X509_NAME_ENTRY)
static int x509_name_ex_d2i(ASN1_VALUE **val,
- const unsigned char **in, long len,
- const ASN1_ITEM *it,
- int tag, int aclass, char opt, ASN1_TLC *ctx);
+ const unsigned char **in, long len,
+ const ASN1_ITEM *it,
+ int tag, int aclass, char opt, ASN1_TLC *ctx);
static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out,
- const ASN1_ITEM *it, int tag, int aclass);
+ const ASN1_ITEM *it, int tag, int aclass);
static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it);
static void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it);
static int x509_name_encode(X509_NAME *a);
static int x509_name_canon(X509_NAME *a);
static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in);
-static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname,
- unsigned char **in);
-
+static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) * intname,
+ unsigned char **in);
static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval,
- int indent,
- const char *fname,
- const ASN1_PCTX *pctx);
+ int indent,
+ const char *fname, const ASN1_PCTX *pctx);
ASN1_SEQUENCE(X509_NAME_ENTRY) = {
- ASN1_SIMPLE(X509_NAME_ENTRY, object, ASN1_OBJECT),
- ASN1_SIMPLE(X509_NAME_ENTRY, value, ASN1_PRINTABLE)
+ ASN1_SIMPLE(X509_NAME_ENTRY, object, ASN1_OBJECT),
+ ASN1_SIMPLE(X509_NAME_ENTRY, value, ASN1_PRINTABLE)
} ASN1_SEQUENCE_END(X509_NAME_ENTRY)
IMPLEMENT_ASN1_FUNCTIONS(X509_NAME_ENTRY)
IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME_ENTRY)
-/* For the "Name" type we need a SEQUENCE OF { SET OF X509_NAME_ENTRY }
- * so declare two template wrappers for this
+/*
+ * For the "Name" type we need a SEQUENCE OF { SET OF X509_NAME_ENTRY } so
+ * declare two template wrappers for this
*/
ASN1_ITEM_TEMPLATE(X509_NAME_ENTRIES) =
- ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, RDNS, X509_NAME_ENTRY)
+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, RDNS, X509_NAME_ENTRY)
ASN1_ITEM_TEMPLATE_END(X509_NAME_ENTRIES)
ASN1_ITEM_TEMPLATE(X509_NAME_INTERNAL) =
- ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Name, X509_NAME_ENTRIES)
+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Name, X509_NAME_ENTRIES)
ASN1_ITEM_TEMPLATE_END(X509_NAME_INTERNAL)
-/* Normally that's where it would end: we'd have two nested STACK structures
+/*
+ * Normally that's where it would end: we'd have two nested STACK structures
* representing the ASN1. Unfortunately X509_NAME uses a completely different
- * form and caches encodings so we have to process the internal form and convert
- * to the external form.
+ * form and caches encodings so we have to process the internal form and
+ * convert to the external form.
*/
static const ASN1_EXTERN_FUNCS x509_name_ff = {
- NULL,
- x509_name_ex_new,
- x509_name_ex_free,
- 0, /* Default clear behaviour is OK */
- x509_name_ex_d2i,
- x509_name_ex_i2d,
- x509_name_ex_print
+ NULL,
+ x509_name_ex_new,
+ x509_name_ex_free,
+ 0, /* Default clear behaviour is OK */
+ x509_name_ex_d2i,
+ x509_name_ex_i2d,
+ x509_name_ex_print
};
-IMPLEMENT_EXTERN_ASN1(X509_NAME, V_ASN1_SEQUENCE, x509_name_ff)
+IMPLEMENT_EXTERN_ASN1(X509_NAME, V_ASN1_SEQUENCE, x509_name_ff)
IMPLEMENT_ASN1_FUNCTIONS(X509_NAME)
+
IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME)
static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it)
{
- X509_NAME *ret = NULL;
- ret = OPENSSL_malloc(sizeof(X509_NAME));
- if(!ret) goto memerr;
- if ((ret->entries=sk_X509_NAME_ENTRY_new_null()) == NULL)
- goto memerr;
- if((ret->bytes = BUF_MEM_new()) == NULL) goto memerr;
- ret->canon_enc = NULL;
- ret->canon_enclen = 0;
- ret->modified=1;
- *val = (ASN1_VALUE *)ret;
- return 1;
+ X509_NAME *ret = NULL;
+ ret = OPENSSL_malloc(sizeof(X509_NAME));
+ if (!ret)
+ goto memerr;
+ if ((ret->entries = sk_X509_NAME_ENTRY_new_null()) == NULL)
+ goto memerr;
+ if ((ret->bytes = BUF_MEM_new()) == NULL)
+ goto memerr;
+ ret->canon_enc = NULL;
+ ret->canon_enclen = 0;
+ ret->modified = 1;
+ *val = (ASN1_VALUE *)ret;
+ return 1;
memerr:
- OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
- if (ret)
- {
- if (ret->entries)
- sk_X509_NAME_ENTRY_free(ret->entries);
- OPENSSL_free(ret);
- }
- return 0;
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+ if (ret) {
+ if (ret->entries)
+ sk_X509_NAME_ENTRY_free(ret->entries);
+ OPENSSL_free(ret);
+ }
+ return 0;
}
static void x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
- X509_NAME *a;
- if(!pval || !*pval)
- return;
- a = (X509_NAME *)*pval;
-
- BUF_MEM_free(a->bytes);
- sk_X509_NAME_ENTRY_pop_free(a->entries,X509_NAME_ENTRY_free);
- if (a->canon_enc)
- OPENSSL_free(a->canon_enc);
- OPENSSL_free(a);
- *pval = NULL;
+ X509_NAME *a;
+ if (!pval || !*pval)
+ return;
+ a = (X509_NAME *)*pval;
+
+ BUF_MEM_free(a->bytes);
+ sk_X509_NAME_ENTRY_pop_free(a->entries, X509_NAME_ENTRY_free);
+ if (a->canon_enc)
+ OPENSSL_free(a->canon_enc);
+ OPENSSL_free(a);
+ *pval = NULL;
}
static void local_sk_X509_NAME_ENTRY_free(STACK_OF(X509_NAME_ENTRY) *ne)
{
- sk_X509_NAME_ENTRY_free(ne);
+ sk_X509_NAME_ENTRY_free(ne);
}
static void local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne)
{
- sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free);
+ sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free);
}
static int x509_name_ex_d2i(ASN1_VALUE **val,
- const unsigned char **in, long len, const ASN1_ITEM *it,
- int tag, int aclass, char opt, ASN1_TLC *ctx)
+ const unsigned char **in, long len,
+ const ASN1_ITEM *it, int tag, int aclass,
+ char opt, ASN1_TLC *ctx)
{
- const unsigned char *p = *in, *q;
- union { STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
- ASN1_VALUE *a; } intname = {NULL};
- union { X509_NAME *x; ASN1_VALUE *a; } nm = {NULL};
- size_t i, j;
- int ret;
- STACK_OF(X509_NAME_ENTRY) *entries;
- X509_NAME_ENTRY *entry;
- q = p;
-
- /* Get internal representation of Name */
- ret = ASN1_item_ex_d2i(&intname.a,
- &p, len, ASN1_ITEM_rptr(X509_NAME_INTERNAL),
- tag, aclass, opt, ctx);
-
- if(ret <= 0) return ret;
-
- if(*val) x509_name_ex_free(val, NULL);
- /* We've decoded it: now cache encoding */
- if (!x509_name_ex_new(&nm.a, NULL) ||
- !BUF_MEM_grow(nm.x->bytes, p - q))
- {
- sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
- local_sk_X509_NAME_ENTRY_pop_free);
- goto err;
- }
- memcpy(nm.x->bytes->data, q, p - q);
-
- /* Convert internal representation to X509_NAME structure */
- for(i = 0; i < sk_STACK_OF_X509_NAME_ENTRY_num(intname.s); i++) {
- entries = sk_STACK_OF_X509_NAME_ENTRY_value(intname.s, i);
- for(j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) {
- entry = sk_X509_NAME_ENTRY_value(entries, j);
- entry->set = i;
- if(!sk_X509_NAME_ENTRY_push(nm.x->entries, entry))
- goto err;
- }
- sk_X509_NAME_ENTRY_free(entries);
- }
- sk_STACK_OF_X509_NAME_ENTRY_free(intname.s);
- ret = x509_name_canon(nm.x);
- if (!ret)
- goto err;
- nm.x->modified = 0;
- *val = nm.a;
- *in = p;
- return ret;
-err:
- if (nm.x != NULL)
- X509_NAME_free(nm.x);
- OPENSSL_PUT_ERROR(X509, ERR_R_ASN1_LIB);
- return 0;
+ const unsigned char *p = *in, *q;
+ union {
+ STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
+ ASN1_VALUE *a;
+ } intname = {
+ NULL
+ };
+ union {
+ X509_NAME *x;
+ ASN1_VALUE *a;
+ } nm = {
+ NULL
+ };
+ size_t i, j;
+ int ret;
+ STACK_OF(X509_NAME_ENTRY) *entries;
+ X509_NAME_ENTRY *entry;
+ q = p;
+
+ /* Get internal representation of Name */
+ ret = ASN1_item_ex_d2i(&intname.a,
+ &p, len, ASN1_ITEM_rptr(X509_NAME_INTERNAL),
+ tag, aclass, opt, ctx);
+
+ if (ret <= 0)
+ return ret;
+
+ if (*val)
+ x509_name_ex_free(val, NULL);
+ /* We've decoded it: now cache encoding */
+ if (!x509_name_ex_new(&nm.a, NULL) || !BUF_MEM_grow(nm.x->bytes, p - q)) {
+ sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
+ local_sk_X509_NAME_ENTRY_pop_free);
+ goto err;
+ }
+ memcpy(nm.x->bytes->data, q, p - q);
+
+ /* Convert internal representation to X509_NAME structure */
+ for (i = 0; i < sk_STACK_OF_X509_NAME_ENTRY_num(intname.s); i++) {
+ entries = sk_STACK_OF_X509_NAME_ENTRY_value(intname.s, i);
+ for (j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) {
+ entry = sk_X509_NAME_ENTRY_value(entries, j);
+ entry->set = i;
+ if (!sk_X509_NAME_ENTRY_push(nm.x->entries, entry))
+ goto err;
+ }
+ sk_X509_NAME_ENTRY_free(entries);
+ }
+ sk_STACK_OF_X509_NAME_ENTRY_free(intname.s);
+ ret = x509_name_canon(nm.x);
+ if (!ret)
+ goto err;
+ nm.x->modified = 0;
+ *val = nm.a;
+ *in = p;
+ return ret;
+ err:
+ if (nm.x != NULL)
+ X509_NAME_free(nm.x);
+ OPENSSL_PUT_ERROR(X509, ERR_R_ASN1_LIB);
+ return 0;
}
-static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass)
+static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out,
+ const ASN1_ITEM *it, int tag, int aclass)
{
- int ret;
- X509_NAME *a = (X509_NAME *)*val;
- if(a->modified) {
- ret = x509_name_encode(a);
- if(ret < 0)
- return ret;
- ret = x509_name_canon(a);
- if(ret < 0)
- return ret;
- }
- ret = a->bytes->length;
- if(out != NULL) {
- memcpy(*out,a->bytes->data,ret);
- *out+=ret;
- }
- return ret;
+ int ret;
+ X509_NAME *a = (X509_NAME *)*val;
+ if (a->modified) {
+ ret = x509_name_encode(a);
+ if (ret < 0)
+ return ret;
+ ret = x509_name_canon(a);
+ if (ret < 0)
+ return ret;
+ }
+ ret = a->bytes->length;
+ if (out != NULL) {
+ memcpy(*out, a->bytes->data, ret);
+ *out += ret;
+ }
+ return ret;
}
static int x509_name_encode(X509_NAME *a)
{
- union { STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
- ASN1_VALUE *a; } intname = {NULL};
- int len;
- unsigned char *p;
- STACK_OF(X509_NAME_ENTRY) *entries = NULL;
- X509_NAME_ENTRY *entry;
- int set = -1;
- size_t i;
- intname.s = sk_STACK_OF_X509_NAME_ENTRY_new_null();
- if(!intname.s) goto memerr;
- for(i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
- entry = sk_X509_NAME_ENTRY_value(a->entries, i);
- if(entry->set != set) {
- entries = sk_X509_NAME_ENTRY_new_null();
- if(!entries) goto memerr;
- if(!sk_STACK_OF_X509_NAME_ENTRY_push(intname.s,
- entries))
- goto memerr;
- set = entry->set;
- }
- if(!sk_X509_NAME_ENTRY_push(entries, entry)) goto memerr;
- }
- len = ASN1_item_ex_i2d(&intname.a, NULL,
- ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
- if (!BUF_MEM_grow(a->bytes,len)) goto memerr;
- p=(unsigned char *)a->bytes->data;
- ASN1_item_ex_i2d(&intname.a,
- &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
- sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
- local_sk_X509_NAME_ENTRY_free);
- a->modified = 0;
- return len;
-memerr:
- sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
- local_sk_X509_NAME_ENTRY_free);
- OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
- return -1;
+ union {
+ STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
+ ASN1_VALUE *a;
+ } intname = {
+ NULL
+ };
+ int len;
+ unsigned char *p;
+ STACK_OF(X509_NAME_ENTRY) *entries = NULL;
+ X509_NAME_ENTRY *entry;
+ int set = -1;
+ size_t i;
+ intname.s = sk_STACK_OF_X509_NAME_ENTRY_new_null();
+ if (!intname.s)
+ goto memerr;
+ for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
+ entry = sk_X509_NAME_ENTRY_value(a->entries, i);
+ if (entry->set != set) {
+ entries = sk_X509_NAME_ENTRY_new_null();
+ if (!entries)
+ goto memerr;
+ if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname.s, entries))
+ goto memerr;
+ set = entry->set;
+ }
+ if (!sk_X509_NAME_ENTRY_push(entries, entry))
+ goto memerr;
+ }
+ len = ASN1_item_ex_i2d(&intname.a, NULL,
+ ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
+ if (!BUF_MEM_grow(a->bytes, len))
+ goto memerr;
+ p = (unsigned char *)a->bytes->data;
+ ASN1_item_ex_i2d(&intname.a,
+ &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
+ sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
+ local_sk_X509_NAME_ENTRY_free);
+ a->modified = 0;
+ return len;
+ memerr:
+ sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
+ local_sk_X509_NAME_ENTRY_free);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+ return -1;
}
static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval,
- int indent,
- const char *fname,
- const ASN1_PCTX *pctx)
- {
- if (X509_NAME_print_ex(out, (X509_NAME *)*pval,
- indent, pctx->nm_flags) <= 0)
- return 0;
- return 2;
- }
-
-/* This function generates the canonical encoding of the Name structure.
- * In it all strings are converted to UTF8, leading, trailing and
- * multiple spaces collapsed, converted to lower case and the leading
- * SEQUENCE header removed.
- *
- * In future we could also normalize the UTF8 too.
- *
- * By doing this comparison of Name structures can be rapidly
- * perfomed by just using memcmp() of the canonical encoding.
- * By omitting the leading SEQUENCE name constraints of type
- * dirName can also be checked with a simple memcmp().
+ int indent,
+ const char *fname, const ASN1_PCTX *pctx)
+{
+ if (X509_NAME_print_ex(out, (X509_NAME *)*pval,
+ indent, pctx->nm_flags) <= 0)
+ return 0;
+ return 2;
+}
+
+/*
+ * This function generates the canonical encoding of the Name structure. In
+ * it all strings are converted to UTF8, leading, trailing and multiple
+ * spaces collapsed, converted to lower case and the leading SEQUENCE header
+ * removed. In future we could also normalize the UTF8 too. By doing this
+ * comparison of Name structures can be rapidly perfomed by just using
+ * memcmp() of the canonical encoding. By omitting the leading SEQUENCE name
+ * constraints of type dirName can also be checked with a simple memcmp().
*/
static int x509_name_canon(X509_NAME *a)
- {
- unsigned char *p;
- STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = NULL;
- STACK_OF(X509_NAME_ENTRY) *entries = NULL;
- X509_NAME_ENTRY *entry, *tmpentry = NULL;
- int set = -1, ret = 0;
- size_t i;
-
- if (a->canon_enc)
- {
- OPENSSL_free(a->canon_enc);
- a->canon_enc = NULL;
- }
- /* Special case: empty X509_NAME => null encoding */
- if (sk_X509_NAME_ENTRY_num(a->entries) == 0)
- {
- a->canon_enclen = 0;
- return 1;
- }
- intname = sk_STACK_OF_X509_NAME_ENTRY_new_null();
- if(!intname)
- goto err;
- for(i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++)
- {
- entry = sk_X509_NAME_ENTRY_value(a->entries, i);
- if(entry->set != set)
- {
- entries = sk_X509_NAME_ENTRY_new_null();
- if(!entries)
- goto err;
- if(!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries))
- {
- sk_X509_NAME_ENTRY_free(entries);
- goto err;
- }
- set = entry->set;
- }
- tmpentry = X509_NAME_ENTRY_new();
- if (tmpentry == NULL)
- goto err;
- tmpentry->object = OBJ_dup(entry->object);
- if (!asn1_string_canon(tmpentry->value, entry->value))
- goto err;
- if(!sk_X509_NAME_ENTRY_push(entries, tmpentry))
- goto err;
- tmpentry = NULL;
- }
-
- /* Finally generate encoding */
-
- a->canon_enclen = i2d_name_canon(intname, NULL);
-
- p = OPENSSL_malloc(a->canon_enclen);
-
- if (!p)
- goto err;
-
- a->canon_enc = p;
-
- i2d_name_canon(intname, &p);
-
- ret = 1;
-
- err:
-
- if (tmpentry)
- X509_NAME_ENTRY_free(tmpentry);
- if (intname)
- sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname,
- local_sk_X509_NAME_ENTRY_pop_free);
- return ret;
- }
+{
+ unsigned char *p;
+ STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = NULL;
+ STACK_OF(X509_NAME_ENTRY) *entries = NULL;
+ X509_NAME_ENTRY *entry, *tmpentry = NULL;
+ int set = -1, ret = 0;
+ size_t i;
+
+ if (a->canon_enc) {
+ OPENSSL_free(a->canon_enc);
+ a->canon_enc = NULL;
+ }
+ /* Special case: empty X509_NAME => null encoding */
+ if (sk_X509_NAME_ENTRY_num(a->entries) == 0) {
+ a->canon_enclen = 0;
+ return 1;
+ }
+ intname = sk_STACK_OF_X509_NAME_ENTRY_new_null();
+ if (!intname)
+ goto err;
+ for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
+ entry = sk_X509_NAME_ENTRY_value(a->entries, i);
+ if (entry->set != set) {
+ entries = sk_X509_NAME_ENTRY_new_null();
+ if (!entries)
+ goto err;
+ if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries)) {
+ sk_X509_NAME_ENTRY_free(entries);
+ goto err;
+ }
+ set = entry->set;
+ }
+ tmpentry = X509_NAME_ENTRY_new();
+ if (tmpentry == NULL)
+ goto err;
+ tmpentry->object = OBJ_dup(entry->object);
+ if (!asn1_string_canon(tmpentry->value, entry->value))
+ goto err;
+ if (!sk_X509_NAME_ENTRY_push(entries, tmpentry))
+ goto err;
+ tmpentry = NULL;
+ }
+
+ /* Finally generate encoding */
+
+ a->canon_enclen = i2d_name_canon(intname, NULL);
+
+ p = OPENSSL_malloc(a->canon_enclen);
+
+ if (!p)
+ goto err;
+
+ a->canon_enc = p;
+
+ i2d_name_canon(intname, &p);
+
+ ret = 1;
+
+ err:
+
+ if (tmpentry)
+ X509_NAME_ENTRY_free(tmpentry);
+ if (intname)
+ sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname,
+ local_sk_X509_NAME_ENTRY_pop_free);
+ return ret;
+}
/* Bitmap of all the types of string that will be canonicalized. */
-#define ASN1_MASK_CANON \
- (B_ASN1_UTF8STRING | B_ASN1_BMPSTRING | B_ASN1_UNIVERSALSTRING \
- | B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_IA5STRING \
- | B_ASN1_VISIBLESTRING)
-
+#define ASN1_MASK_CANON \
+ (B_ASN1_UTF8STRING | B_ASN1_BMPSTRING | B_ASN1_UNIVERSALSTRING \
+ | B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_IA5STRING \
+ | B_ASN1_VISIBLESTRING)
static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in)
- {
- unsigned char *to, *from;
- int len, i;
-
- /* If type not in bitmask just copy string across */
- if (!(ASN1_tag2bit(in->type) & ASN1_MASK_CANON))
- {
- if (!ASN1_STRING_copy(out, in))
- return 0;
- return 1;
- }
-
- out->type = V_ASN1_UTF8STRING;
- out->length = ASN1_STRING_to_UTF8(&out->data, in);
- if (out->length == -1)
- return 0;
-
- to = out->data;
- from = to;
-
- len = out->length;
-
- /* Convert string in place to canonical form.
- * Ultimately we may need to handle a wider range of characters
- * but for now ignore anything with MSB set and rely on the
- * isspace() and tolower() functions.
- */
-
- /* Ignore leading spaces */
- while((len > 0) && !(*from & 0x80) && isspace(*from))
- {
- from++;
- len--;
- }
-
- to = from + len - 1;
-
- /* Ignore trailing spaces */
- while ((len > 0) && !(*to & 0x80) && isspace(*to))
- {
- to--;
- len--;
- }
-
- to = out->data;
-
- i = 0;
- while(i < len)
- {
- /* If MSB set just copy across */
- if (*from & 0x80)
- {
- *to++ = *from++;
- i++;
- }
- /* Collapse multiple spaces */
- else if (isspace(*from))
- {
- /* Copy one space across */
- *to++ = ' ';
- /* Ignore subsequent spaces. Note: don't need to
- * check len here because we know the last
- * character is a non-space so we can't overflow.
- */
- do
- {
- from++;
- i++;
- }
- while(!(*from & 0x80) && isspace(*from));
- }
- else
- {
- *to++ = tolower(*from);
- from++;
- i++;
- }
- }
-
- out->length = to - out->data;
-
- return 1;
-
- }
-
-static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) *_intname,
- unsigned char **in)
- {
- int len, ltmp;
- size_t i;
- ASN1_VALUE *v;
- STACK_OF(ASN1_VALUE) *intname = (STACK_OF(ASN1_VALUE) *)_intname;
-
- len = 0;
- for (i = 0; i < sk_ASN1_VALUE_num(intname); i++)
- {
- v = sk_ASN1_VALUE_value(intname, i);
- ltmp = ASN1_item_ex_i2d(&v, in,
- ASN1_ITEM_rptr(X509_NAME_ENTRIES), -1, -1);
- if (ltmp < 0)
- return ltmp;
- len += ltmp;
- }
- return len;
- }
+{
+ unsigned char *to, *from;
+ int len, i;
+
+ /* If type not in bitmask just copy string across */
+ if (!(ASN1_tag2bit(in->type) & ASN1_MASK_CANON)) {
+ if (!ASN1_STRING_copy(out, in))
+ return 0;
+ return 1;
+ }
+
+ out->type = V_ASN1_UTF8STRING;
+ out->length = ASN1_STRING_to_UTF8(&out->data, in);
+ if (out->length == -1)
+ return 0;
+
+ to = out->data;
+ from = to;
+
+ len = out->length;
+
+ /*
+ * Convert string in place to canonical form. Ultimately we may need to
+ * handle a wider range of characters but for now ignore anything with
+ * MSB set and rely on the isspace() and tolower() functions.
+ */
+
+ /* Ignore leading spaces */
+ while ((len > 0) && !(*from & 0x80) && isspace(*from)) {
+ from++;
+ len--;
+ }
+
+ to = from + len - 1;
+
+ /* Ignore trailing spaces */
+ while ((len > 0) && !(*to & 0x80) && isspace(*to)) {
+ to--;
+ len--;
+ }
+
+ to = out->data;
+
+ i = 0;
+ while (i < len) {
+ /* If MSB set just copy across */
+ if (*from & 0x80) {
+ *to++ = *from++;
+ i++;
+ }
+ /* Collapse multiple spaces */
+ else if (isspace(*from)) {
+ /* Copy one space across */
+ *to++ = ' ';
+ /*
+ * Ignore subsequent spaces. Note: don't need to check len here
+ * because we know the last character is a non-space so we can't
+ * overflow.
+ */
+ do {
+ from++;
+ i++;
+ }
+ while (!(*from & 0x80) && isspace(*from));
+ } else {
+ *to++ = tolower(*from);
+ from++;
+ i++;
+ }
+ }
+
+ out->length = to - out->data;
+
+ return 1;
+
+}
+
+static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) * _intname,
+ unsigned char **in)
+{
+ int len, ltmp;
+ size_t i;
+ ASN1_VALUE *v;
+ STACK_OF(ASN1_VALUE) *intname = (STACK_OF(ASN1_VALUE) *)_intname;
+
+ len = 0;
+ for (i = 0; i < sk_ASN1_VALUE_num(intname); i++) {
+ v = sk_ASN1_VALUE_value(intname, i);
+ ltmp = ASN1_item_ex_i2d(&v, in,
+ ASN1_ITEM_rptr(X509_NAME_ENTRIES), -1, -1);
+ if (ltmp < 0)
+ return ltmp;
+ len += ltmp;
+ }
+ return len;
+}
int X509_NAME_set(X509_NAME **xn, X509_NAME *name)
- {
- X509_NAME *in;
-
- if (!xn || !name) return(0);
-
- if (*xn != name)
- {
- in=X509_NAME_dup(name);
- if (in != NULL)
- {
- X509_NAME_free(*xn);
- *xn=in;
- }
- }
- return(*xn != NULL);
- }
-
+{
+ X509_NAME *in;
+
+ if (!xn || !name)
+ return (0);
+
+ if (*xn != name) {
+ in = X509_NAME_dup(name);
+ if (in != NULL) {
+ X509_NAME_free(*xn);
+ *xn = in;
+ }
+ }
+ return (*xn != NULL);
+}
+
IMPLEMENT_ASN1_SET_OF(X509_NAME_ENTRY)
diff --git a/src/crypto/x509/x_pkey.c b/src/crypto/x509/x_pkey.c
index f5e98b82..fc445954 100644
--- a/src/crypto/x509/x_pkey.c
+++ b/src/crypto/x509/x_pkey.c
@@ -63,38 +63,41 @@
#include <openssl/mem.h>
#include <openssl/thread.h>
-
X509_PKEY *X509_PKEY_new(void)
- {
- X509_PKEY *ret = OPENSSL_malloc(sizeof(X509_PKEY));
- if (ret == NULL)
- {
- OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- memset(ret, 0, sizeof(X509_PKEY));
+{
+ X509_PKEY *ret = OPENSSL_malloc(sizeof(X509_PKEY));
+ if (ret == NULL) {
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ memset(ret, 0, sizeof(X509_PKEY));
- ret->enc_algor = X509_ALGOR_new();
- if (ret->enc_algor == NULL)
- goto err;
- ret->enc_pkey = M_ASN1_OCTET_STRING_new();
- if (ret->enc_pkey == NULL)
- goto err;
- return ret;
+ ret->enc_algor = X509_ALGOR_new();
+ if (ret->enc_algor == NULL)
+ goto err;
+ ret->enc_pkey = M_ASN1_OCTET_STRING_new();
+ if (ret->enc_pkey == NULL)
+ goto err;
+ return ret;
-err:
- if (ret != NULL)
- X509_PKEY_free(ret);
- return NULL;
- }
+ err:
+ if (ret != NULL)
+ X509_PKEY_free(ret);
+ return NULL;
+}
void X509_PKEY_free(X509_PKEY *x)
- {
- if (x == NULL) return;
+{
+ if (x == NULL)
+ return;
- if (x->enc_algor != NULL) X509_ALGOR_free(x->enc_algor);
- if (x->enc_pkey != NULL) M_ASN1_OCTET_STRING_free(x->enc_pkey);
- if (x->dec_pkey != NULL)EVP_PKEY_free(x->dec_pkey);
- if ((x->key_data != NULL) && (x->key_free)) OPENSSL_free(x->key_data);
- OPENSSL_free(x);
- }
+ if (x->enc_algor != NULL)
+ X509_ALGOR_free(x->enc_algor);
+ if (x->enc_pkey != NULL)
+ M_ASN1_OCTET_STRING_free(x->enc_pkey);
+ if (x->dec_pkey != NULL)
+ EVP_PKEY_free(x->dec_pkey);
+ if ((x->key_data != NULL) && (x->key_free))
+ OPENSSL_free(x->key_data);
+ OPENSSL_free(x);
+}
diff --git a/src/crypto/x509/x_pubkey.c b/src/crypto/x509/x_pubkey.c
index a16edcab..1549195e 100644
--- a/src/crypto/x509/x_pubkey.c
+++ b/src/crypto/x509/x_pubkey.c
@@ -54,78 +54,75 @@
* copied and put under another distribution licence
* [including the GNU Public Licence.] */
+#include <openssl/x509.h>
+
+#include <limits.h>
+
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
+#include <openssl/bytestring.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/mem.h>
#include <openssl/obj.h>
#include <openssl/thread.h>
-#include <openssl/x509.h>
-#include "../evp/internal.h"
#include "../internal.h"
-
/* Minor tweak to operation: free up EVP_PKEY */
static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
- void *exarg)
- {
- if (operation == ASN1_OP_FREE_POST)
- {
- X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval;
- EVP_PKEY_free(pubkey->pkey);
- }
- return 1;
- }
+ void *exarg)
+{
+ if (operation == ASN1_OP_FREE_POST) {
+ X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval;
+ EVP_PKEY_free(pubkey->pkey);
+ }
+ return 1;
+}
ASN1_SEQUENCE_cb(X509_PUBKEY, pubkey_cb) = {
- ASN1_SIMPLE(X509_PUBKEY, algor, X509_ALGOR),
- ASN1_SIMPLE(X509_PUBKEY, public_key, ASN1_BIT_STRING)
+ ASN1_SIMPLE(X509_PUBKEY, algor, X509_ALGOR),
+ ASN1_SIMPLE(X509_PUBKEY, public_key, ASN1_BIT_STRING)
} ASN1_SEQUENCE_END_cb(X509_PUBKEY, X509_PUBKEY)
IMPLEMENT_ASN1_FUNCTIONS(X509_PUBKEY)
int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
- {
- X509_PUBKEY *pk=NULL;
-
- if (x == NULL) return(0);
-
- if ((pk=X509_PUBKEY_new()) == NULL) goto error;
-
- if (pkey->ameth)
- {
- if (pkey->ameth->pub_encode)
- {
- if (!pkey->ameth->pub_encode(pk, pkey))
- {
- OPENSSL_PUT_ERROR(X509, X509_R_PUBLIC_KEY_ENCODE_ERROR);
- goto error;
- }
- }
- else
- {
- OPENSSL_PUT_ERROR(X509, X509_R_METHOD_NOT_SUPPORTED);
- goto error;
- }
- }
- else
- {
- OPENSSL_PUT_ERROR(X509, X509_R_UNSUPPORTED_ALGORITHM);
- goto error;
- }
-
- if (*x != NULL)
- X509_PUBKEY_free(*x);
-
- *x=pk;
-
- return 1;
-error:
- if (pk != NULL) X509_PUBKEY_free(pk);
- return 0;
- }
+{
+ X509_PUBKEY *pk = NULL;
+ uint8_t *spki = NULL;
+ size_t spki_len;
+
+ if (x == NULL)
+ return (0);
+
+ CBB cbb;
+ if (!CBB_init(&cbb, 0) ||
+ !EVP_marshal_public_key(&cbb, pkey) ||
+ !CBB_finish(&cbb, &spki, &spki_len) ||
+ spki_len > LONG_MAX) {
+ CBB_cleanup(&cbb);
+ OPENSSL_PUT_ERROR(X509, X509_R_PUBLIC_KEY_ENCODE_ERROR);
+ goto error;
+ }
+
+ const uint8_t *p = spki;
+ pk = d2i_X509_PUBKEY(NULL, &p, (long)spki_len);
+ if (pk == NULL || p != spki + spki_len) {
+ OPENSSL_PUT_ERROR(X509, X509_R_PUBLIC_KEY_DECODE_ERROR);
+ goto error;
+ }
+
+ OPENSSL_free(spki);
+ X509_PUBKEY_free(*x);
+ *x = pk;
+
+ return 1;
+ error:
+ X509_PUBKEY_free(pk);
+ OPENSSL_free(spki);
+ return 0;
+}
/* g_pubkey_lock is used to protect the initialisation of the |pkey| member of
* |X509_PUBKEY| objects. Really |X509_PUBKEY| should have a |CRYPTO_once_t|
@@ -134,251 +131,236 @@ error:
static struct CRYPTO_STATIC_MUTEX g_pubkey_lock = CRYPTO_STATIC_MUTEX_INIT;
EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
- {
- EVP_PKEY *ret=NULL;
-
- if (key == NULL) goto error;
-
- CRYPTO_STATIC_MUTEX_lock_read(&g_pubkey_lock);
- if (key->pkey != NULL)
- {
- CRYPTO_STATIC_MUTEX_unlock(&g_pubkey_lock);
- return EVP_PKEY_up_ref(key->pkey);
- }
- CRYPTO_STATIC_MUTEX_unlock(&g_pubkey_lock);
-
- if (key->public_key == NULL) goto error;
-
- if ((ret = EVP_PKEY_new()) == NULL)
- {
- 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_R_UNSUPPORTED_ALGORITHM);
- goto error;
- }
-
- if (ret->ameth->pub_decode)
- {
- if (!ret->ameth->pub_decode(ret, key))
- {
- OPENSSL_PUT_ERROR(X509, X509_R_PUBLIC_KEY_DECODE_ERROR);
- goto error;
- }
- }
- else
- {
- OPENSSL_PUT_ERROR(X509, X509_R_METHOD_NOT_SUPPORTED);
- goto error;
- }
-
- /* Check to see if another thread set key->pkey first */
- CRYPTO_STATIC_MUTEX_lock_write(&g_pubkey_lock);
- if (key->pkey)
- {
- CRYPTO_STATIC_MUTEX_unlock(&g_pubkey_lock);
- EVP_PKEY_free(ret);
- ret = key->pkey;
- }
- else
- {
- key->pkey = ret;
- CRYPTO_STATIC_MUTEX_unlock(&g_pubkey_lock);
- }
-
- return EVP_PKEY_up_ref(ret);
-
- error:
- if (ret != NULL)
- EVP_PKEY_free(ret);
- return(NULL);
- }
-
-/* Now two pseudo ASN1 routines that take an EVP_PKEY structure
- * and encode or decode as X509_PUBKEY
+{
+ EVP_PKEY *ret = NULL;
+ uint8_t *spki = NULL;
+
+ if (key == NULL)
+ goto error;
+
+ CRYPTO_STATIC_MUTEX_lock_read(&g_pubkey_lock);
+ if (key->pkey != NULL) {
+ CRYPTO_STATIC_MUTEX_unlock(&g_pubkey_lock);
+ return EVP_PKEY_up_ref(key->pkey);
+ }
+ CRYPTO_STATIC_MUTEX_unlock(&g_pubkey_lock);
+
+ /* Re-encode the |X509_PUBKEY| to DER and parse it. */
+ int spki_len = i2d_X509_PUBKEY(key, &spki);
+ if (spki_len < 0) {
+ goto error;
+ }
+ CBS cbs;
+ CBS_init(&cbs, spki, (size_t)spki_len);
+ ret = EVP_parse_public_key(&cbs);
+ if (ret == NULL || CBS_len(&cbs) != 0) {
+ OPENSSL_PUT_ERROR(X509, X509_R_PUBLIC_KEY_DECODE_ERROR);
+ goto error;
+ }
+
+ /* Check to see if another thread set key->pkey first */
+ CRYPTO_STATIC_MUTEX_lock_write(&g_pubkey_lock);
+ if (key->pkey) {
+ CRYPTO_STATIC_MUTEX_unlock(&g_pubkey_lock);
+ EVP_PKEY_free(ret);
+ ret = key->pkey;
+ } else {
+ key->pkey = ret;
+ CRYPTO_STATIC_MUTEX_unlock(&g_pubkey_lock);
+ }
+
+ OPENSSL_free(spki);
+ return EVP_PKEY_up_ref(ret);
+
+ error:
+ OPENSSL_free(spki);
+ EVP_PKEY_free(ret);
+ return NULL;
+}
+
+/*
+ * Now two pseudo ASN1 routines that take an EVP_PKEY structure and encode or
+ * decode as X509_PUBKEY
*/
-EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp,
- long length)
- {
- X509_PUBKEY *xpk;
- EVP_PKEY *pktmp;
- xpk = d2i_X509_PUBKEY(NULL, pp, length);
- if(!xpk) return NULL;
- pktmp = X509_PUBKEY_get(xpk);
- X509_PUBKEY_free(xpk);
- if(!pktmp) return NULL;
- if(a)
- {
- EVP_PKEY_free(*a);
- *a = pktmp;
- }
- return pktmp;
- }
+EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length)
+{
+ X509_PUBKEY *xpk;
+ EVP_PKEY *pktmp;
+ xpk = d2i_X509_PUBKEY(NULL, pp, length);
+ if (!xpk)
+ return NULL;
+ pktmp = X509_PUBKEY_get(xpk);
+ X509_PUBKEY_free(xpk);
+ if (!pktmp)
+ return NULL;
+ if (a) {
+ EVP_PKEY_free(*a);
+ *a = pktmp;
+ }
+ return pktmp;
+}
int i2d_PUBKEY(const EVP_PKEY *a, unsigned char **pp)
- {
- X509_PUBKEY *xpk=NULL;
- int ret;
- if(!a) return 0;
- if(!X509_PUBKEY_set(&xpk, (EVP_PKEY*) a)) return 0;
- ret = i2d_X509_PUBKEY(xpk, pp);
- X509_PUBKEY_free(xpk);
- return ret;
- }
-
-/* The following are equivalents but which return RSA and DSA
- * keys
+{
+ X509_PUBKEY *xpk = NULL;
+ int ret;
+ if (!a)
+ return 0;
+ if (!X509_PUBKEY_set(&xpk, (EVP_PKEY *)a))
+ return 0;
+ ret = i2d_X509_PUBKEY(xpk, pp);
+ X509_PUBKEY_free(xpk);
+ return ret;
+}
+
+/*
+ * The following are equivalents but which return RSA and DSA keys
*/
-RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp,
- long length)
- {
- EVP_PKEY *pkey;
- RSA *key;
- const unsigned char *q;
- q = *pp;
- pkey = d2i_PUBKEY(NULL, &q, length);
- if (!pkey) return NULL;
- key = EVP_PKEY_get1_RSA(pkey);
- EVP_PKEY_free(pkey);
- if (!key) return NULL;
- *pp = q;
- if (a)
- {
- RSA_free(*a);
- *a = key;
- }
- return key;
- }
+RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length)
+{
+ EVP_PKEY *pkey;
+ RSA *key;
+ const unsigned char *q;
+ q = *pp;
+ pkey = d2i_PUBKEY(NULL, &q, length);
+ if (!pkey)
+ return NULL;
+ key = EVP_PKEY_get1_RSA(pkey);
+ EVP_PKEY_free(pkey);
+ if (!key)
+ return NULL;
+ *pp = q;
+ if (a) {
+ RSA_free(*a);
+ *a = key;
+ }
+ return key;
+}
int i2d_RSA_PUBKEY(const RSA *a, unsigned char **pp)
- {
- EVP_PKEY *pktmp;
- int ret;
- if (!a) return 0;
- pktmp = EVP_PKEY_new();
- if (!pktmp)
- {
- OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
- return 0;
- }
- EVP_PKEY_set1_RSA(pktmp, (RSA*) a);
- ret = i2d_PUBKEY(pktmp, pp);
- EVP_PKEY_free(pktmp);
- return ret;
- }
+{
+ EVP_PKEY *pktmp;
+ int ret;
+ if (!a)
+ return 0;
+ pktmp = EVP_PKEY_new();
+ if (!pktmp) {
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ EVP_PKEY_set1_RSA(pktmp, (RSA *)a);
+ ret = i2d_PUBKEY(pktmp, pp);
+ EVP_PKEY_free(pktmp);
+ return ret;
+}
#ifndef OPENSSL_NO_DSA
-DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp,
- long length)
- {
- EVP_PKEY *pkey;
- DSA *key;
- const unsigned char *q;
- q = *pp;
- pkey = d2i_PUBKEY(NULL, &q, length);
- if (!pkey) return NULL;
- key = EVP_PKEY_get1_DSA(pkey);
- EVP_PKEY_free(pkey);
- if (!key) return NULL;
- *pp = q;
- if (a)
- {
- DSA_free(*a);
- *a = key;
- }
- return key;
- }
+DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length)
+{
+ EVP_PKEY *pkey;
+ DSA *key;
+ const unsigned char *q;
+ q = *pp;
+ pkey = d2i_PUBKEY(NULL, &q, length);
+ if (!pkey)
+ return NULL;
+ key = EVP_PKEY_get1_DSA(pkey);
+ EVP_PKEY_free(pkey);
+ if (!key)
+ return NULL;
+ *pp = q;
+ if (a) {
+ DSA_free(*a);
+ *a = key;
+ }
+ return key;
+}
int i2d_DSA_PUBKEY(const DSA *a, unsigned char **pp)
- {
- EVP_PKEY *pktmp;
- int ret;
- if(!a) return 0;
- pktmp = EVP_PKEY_new();
- if(!pktmp)
- {
- OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
- return 0;
- }
- EVP_PKEY_set1_DSA(pktmp, (DSA*) a);
- ret = i2d_PUBKEY(pktmp, pp);
- EVP_PKEY_free(pktmp);
- return ret;
- }
+{
+ EVP_PKEY *pktmp;
+ int ret;
+ if (!a)
+ return 0;
+ pktmp = EVP_PKEY_new();
+ if (!pktmp) {
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ EVP_PKEY_set1_DSA(pktmp, (DSA *)a);
+ ret = i2d_PUBKEY(pktmp, pp);
+ EVP_PKEY_free(pktmp);
+ return ret;
+}
#endif
EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length)
- {
- EVP_PKEY *pkey;
- EC_KEY *key;
- const unsigned char *q;
- q = *pp;
- pkey = d2i_PUBKEY(NULL, &q, length);
- if (!pkey) return(NULL);
- key = EVP_PKEY_get1_EC_KEY(pkey);
- EVP_PKEY_free(pkey);
- if (!key) return(NULL);
- *pp = q;
- if (a)
- {
- EC_KEY_free(*a);
- *a = key;
- }
- return(key);
- }
+{
+ EVP_PKEY *pkey;
+ EC_KEY *key;
+ const unsigned char *q;
+ q = *pp;
+ pkey = d2i_PUBKEY(NULL, &q, length);
+ if (!pkey)
+ return (NULL);
+ key = EVP_PKEY_get1_EC_KEY(pkey);
+ EVP_PKEY_free(pkey);
+ if (!key)
+ return (NULL);
+ *pp = q;
+ if (a) {
+ EC_KEY_free(*a);
+ *a = key;
+ }
+ return (key);
+}
int i2d_EC_PUBKEY(const EC_KEY *a, unsigned char **pp)
- {
- EVP_PKEY *pktmp;
- int ret;
- if (!a) return(0);
- if ((pktmp = EVP_PKEY_new()) == NULL)
- {
- OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
- return(0);
- }
- EVP_PKEY_set1_EC_KEY(pktmp, (EC_KEY*) a);
- ret = i2d_PUBKEY(pktmp, pp);
- EVP_PKEY_free(pktmp);
- return(ret);
- }
+{
+ EVP_PKEY *pktmp;
+ int ret;
+ if (!a)
+ return (0);
+ if ((pktmp = EVP_PKEY_new()) == NULL) {
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+ return (0);
+ }
+ EVP_PKEY_set1_EC_KEY(pktmp, (EC_KEY *)a);
+ ret = i2d_PUBKEY(pktmp, pp);
+ EVP_PKEY_free(pktmp);
+ return (ret);
+}
int X509_PUBKEY_set0_param(X509_PUBKEY *pub, const ASN1_OBJECT *aobj,
- int ptype, void *pval,
- unsigned char *penc, int penclen)
- {
- if (!X509_ALGOR_set0(pub->algor, aobj, ptype, pval))
- return 0;
- if (penc)
- {
- if (pub->public_key->data)
- OPENSSL_free(pub->public_key->data);
- pub->public_key->data = penc;
- pub->public_key->length = penclen;
- /* Set number of unused bits to zero */
- pub->public_key->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
- pub->public_key->flags|=ASN1_STRING_FLAG_BITS_LEFT;
- }
- return 1;
- }
+ int ptype, void *pval,
+ unsigned char *penc, int penclen)
+{
+ if (!X509_ALGOR_set0(pub->algor, aobj, ptype, pval))
+ return 0;
+ if (penc) {
+ if (pub->public_key->data)
+ OPENSSL_free(pub->public_key->data);
+ pub->public_key->data = penc;
+ pub->public_key->length = penclen;
+ /* Set number of unused bits to zero */
+ pub->public_key->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
+ pub->public_key->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+ }
+ return 1;
+}
int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg,
- const unsigned char **pk, int *ppklen,
- X509_ALGOR **pa,
- X509_PUBKEY *pub)
- {
- if (ppkalg)
- *ppkalg = pub->algor->algorithm;
- if (pk)
- {
- *pk = pub->public_key->data;
- *ppklen = pub->public_key->length;
- }
- if (pa)
- *pa = pub->algor;
- return 1;
- }
+ const unsigned char **pk, int *ppklen,
+ X509_ALGOR **pa, X509_PUBKEY *pub)
+{
+ if (ppkalg)
+ *ppkalg = pub->algor->algorithm;
+ if (pk) {
+ *pk = pub->public_key->data;
+ *ppklen = pub->public_key->length;
+ }
+ if (pa)
+ *pa = pub->algor;
+ return 1;
+}
diff --git a/src/crypto/x509/x_req.c b/src/crypto/x509/x_req.c
index 3d301297..5dfe19e5 100644
--- a/src/crypto/x509/x_req.c
+++ b/src/crypto/x509/x_req.c
@@ -60,53 +60,50 @@
#include <openssl/thread.h>
#include <openssl/x509.h>
-/* X509_REQ_INFO is handled in an unusual way to get round
- * invalid encodings. Some broken certificate requests don't
- * encode the attributes field if it is empty. This is in
- * violation of PKCS#10 but we need to tolerate it. We do
- * this by making the attributes field OPTIONAL then using
- * the callback to initialise it to an empty STACK.
- *
- * This means that the field will be correctly encoded unless
- * we NULL out the field.
- *
- * As a result we no longer need the req_kludge field because
- * the information is now contained in the attributes field:
- * 1. If it is NULL then it's the invalid omission.
- * 2. If it is empty it is the correct encoding.
- * 3. If it is not empty then some attributes are present.
- *
+/*
+ * X509_REQ_INFO is handled in an unusual way to get round invalid encodings.
+ * Some broken certificate requests don't encode the attributes field if it
+ * is empty. This is in violation of PKCS#10 but we need to tolerate it. We
+ * do this by making the attributes field OPTIONAL then using the callback to
+ * initialise it to an empty STACK. This means that the field will be
+ * correctly encoded unless we NULL out the field. As a result we no longer
+ * need the req_kludge field because the information is now contained in the
+ * attributes field: 1. If it is NULL then it's the invalid omission. 2. If
+ * it is empty it is the correct encoding. 3. If it is not empty then some
+ * attributes are present.
*/
static int rinf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
- void *exarg)
+ void *exarg)
{
- X509_REQ_INFO *rinf = (X509_REQ_INFO *)*pval;
+ X509_REQ_INFO *rinf = (X509_REQ_INFO *)*pval;
- if(operation == ASN1_OP_NEW_POST) {
- rinf->attributes = sk_X509_ATTRIBUTE_new_null();
- if(!rinf->attributes) return 0;
- }
- return 1;
+ if (operation == ASN1_OP_NEW_POST) {
+ rinf->attributes = sk_X509_ATTRIBUTE_new_null();
+ if (!rinf->attributes)
+ return 0;
+ }
+ return 1;
}
ASN1_SEQUENCE_enc(X509_REQ_INFO, enc, rinf_cb) = {
- ASN1_SIMPLE(X509_REQ_INFO, version, ASN1_INTEGER),
- ASN1_SIMPLE(X509_REQ_INFO, subject, X509_NAME),
- ASN1_SIMPLE(X509_REQ_INFO, pubkey, X509_PUBKEY),
- /* This isn't really OPTIONAL but it gets round invalid
- * encodings
- */
- ASN1_IMP_SET_OF_OPT(X509_REQ_INFO, attributes, X509_ATTRIBUTE, 0)
+ ASN1_SIMPLE(X509_REQ_INFO, version, ASN1_INTEGER),
+ ASN1_SIMPLE(X509_REQ_INFO, subject, X509_NAME),
+ ASN1_SIMPLE(X509_REQ_INFO, pubkey, X509_PUBKEY),
+ /* This isn't really OPTIONAL but it gets round invalid
+ * encodings
+ */
+ ASN1_IMP_SET_OF_OPT(X509_REQ_INFO, attributes, X509_ATTRIBUTE, 0)
} ASN1_SEQUENCE_END_enc(X509_REQ_INFO, X509_REQ_INFO)
IMPLEMENT_ASN1_FUNCTIONS(X509_REQ_INFO)
ASN1_SEQUENCE_ref(X509_REQ, 0) = {
- ASN1_SIMPLE(X509_REQ, req_info, X509_REQ_INFO),
- ASN1_SIMPLE(X509_REQ, sig_alg, X509_ALGOR),
- ASN1_SIMPLE(X509_REQ, signature, ASN1_BIT_STRING)
+ ASN1_SIMPLE(X509_REQ, req_info, X509_REQ_INFO),
+ ASN1_SIMPLE(X509_REQ, sig_alg, X509_ALGOR),
+ ASN1_SIMPLE(X509_REQ, signature, ASN1_BIT_STRING)
} ASN1_SEQUENCE_END_ref(X509_REQ, X509_REQ)
IMPLEMENT_ASN1_FUNCTIONS(X509_REQ)
+
IMPLEMENT_ASN1_DUP_FUNCTION(X509_REQ)
diff --git a/src/crypto/x509/x_sig.c b/src/crypto/x509/x_sig.c
index fabdb676..e18024a7 100644
--- a/src/crypto/x509/x_sig.c
+++ b/src/crypto/x509/x_sig.c
@@ -62,8 +62,8 @@
ASN1_SEQUENCE(X509_SIG) = {
- ASN1_SIMPLE(X509_SIG, algor, X509_ALGOR),
- ASN1_SIMPLE(X509_SIG, digest, ASN1_OCTET_STRING)
+ ASN1_SIMPLE(X509_SIG, algor, X509_ALGOR),
+ ASN1_SIMPLE(X509_SIG, digest, ASN1_OCTET_STRING)
} ASN1_SEQUENCE_END(X509_SIG)
IMPLEMENT_ASN1_FUNCTIONS(X509_SIG)
diff --git a/src/crypto/x509/x_spki.c b/src/crypto/x509/x_spki.c
index 35bf2465..86da6ddf 100644
--- a/src/crypto/x509/x_spki.c
+++ b/src/crypto/x509/x_spki.c
@@ -55,24 +55,26 @@
* copied and put under another distribution licence
* [including the GNU Public Licence.] */
- /* This module was send to me my Pat Richards <patr@x509.com> who
- * wrote it. It is under my Copyright with his permission. */
+ /*
+ * This module was send to me my Pat Richards <patr@x509.com> who wrote it.
+ * It is under my Copyright with his permission.
+ */
#include <openssl/x509.h>
#include <openssl/asn1t.h>
ASN1_SEQUENCE(NETSCAPE_SPKAC) = {
- ASN1_SIMPLE(NETSCAPE_SPKAC, pubkey, X509_PUBKEY),
- ASN1_SIMPLE(NETSCAPE_SPKAC, challenge, ASN1_IA5STRING)
+ ASN1_SIMPLE(NETSCAPE_SPKAC, pubkey, X509_PUBKEY),
+ ASN1_SIMPLE(NETSCAPE_SPKAC, challenge, ASN1_IA5STRING)
} ASN1_SEQUENCE_END(NETSCAPE_SPKAC)
IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_SPKAC)
ASN1_SEQUENCE(NETSCAPE_SPKI) = {
- ASN1_SIMPLE(NETSCAPE_SPKI, spkac, NETSCAPE_SPKAC),
- ASN1_SIMPLE(NETSCAPE_SPKI, sig_algor, X509_ALGOR),
- ASN1_SIMPLE(NETSCAPE_SPKI, signature, ASN1_BIT_STRING)
+ ASN1_SIMPLE(NETSCAPE_SPKI, spkac, NETSCAPE_SPKAC),
+ ASN1_SIMPLE(NETSCAPE_SPKI, sig_algor, X509_ALGOR),
+ ASN1_SIMPLE(NETSCAPE_SPKI, signature, ASN1_BIT_STRING)
} ASN1_SEQUENCE_END(NETSCAPE_SPKI)
IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_SPKI)
diff --git a/src/crypto/x509/x_val.c b/src/crypto/x509/x_val.c
index 26200ee4..ad4f7e14 100644
--- a/src/crypto/x509/x_val.c
+++ b/src/crypto/x509/x_val.c
@@ -62,8 +62,8 @@
ASN1_SEQUENCE(X509_VAL) = {
- ASN1_SIMPLE(X509_VAL, notBefore, ASN1_TIME),
- ASN1_SIMPLE(X509_VAL, notAfter, ASN1_TIME)
+ ASN1_SIMPLE(X509_VAL, notBefore, ASN1_TIME),
+ ASN1_SIMPLE(X509_VAL, notAfter, ASN1_TIME)
} ASN1_SEQUENCE_END(X509_VAL)
IMPLEMENT_ASN1_FUNCTIONS(X509_VAL)
diff --git a/src/crypto/x509/x_x509.c b/src/crypto/x509/x_x509.c
index 7bbe4f36..f12140fb 100644
--- a/src/crypto/x509/x_x509.c
+++ b/src/crypto/x509/x_x509.c
@@ -67,20 +67,19 @@
#include "../internal.h"
-
static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT;
ASN1_SEQUENCE_enc(X509_CINF, enc, 0) = {
- ASN1_EXP_OPT(X509_CINF, version, ASN1_INTEGER, 0),
- ASN1_SIMPLE(X509_CINF, serialNumber, ASN1_INTEGER),
- ASN1_SIMPLE(X509_CINF, signature, X509_ALGOR),
- ASN1_SIMPLE(X509_CINF, issuer, X509_NAME),
- ASN1_SIMPLE(X509_CINF, validity, X509_VAL),
- ASN1_SIMPLE(X509_CINF, subject, X509_NAME),
- ASN1_SIMPLE(X509_CINF, key, X509_PUBKEY),
- ASN1_IMP_OPT(X509_CINF, issuerUID, ASN1_BIT_STRING, 1),
- ASN1_IMP_OPT(X509_CINF, subjectUID, ASN1_BIT_STRING, 2),
- ASN1_EXP_SEQUENCE_OF_OPT(X509_CINF, extensions, X509_EXTENSION, 3)
+ ASN1_EXP_OPT(X509_CINF, version, ASN1_INTEGER, 0),
+ ASN1_SIMPLE(X509_CINF, serialNumber, ASN1_INTEGER),
+ ASN1_SIMPLE(X509_CINF, signature, X509_ALGOR),
+ ASN1_SIMPLE(X509_CINF, issuer, X509_NAME),
+ ASN1_SIMPLE(X509_CINF, validity, X509_VAL),
+ ASN1_SIMPLE(X509_CINF, subject, X509_NAME),
+ ASN1_SIMPLE(X509_CINF, key, X509_PUBKEY),
+ ASN1_IMP_OPT(X509_CINF, issuerUID, ASN1_BIT_STRING, 1),
+ ASN1_IMP_OPT(X509_CINF, subjectUID, ASN1_BIT_STRING, 2),
+ ASN1_EXP_SEQUENCE_OF_OPT(X509_CINF, extensions, X509_EXTENSION, 3)
} ASN1_SEQUENCE_END_enc(X509_CINF, X509_CINF)
IMPLEMENT_ASN1_FUNCTIONS(X509_CINF)
@@ -89,139 +88,149 @@ IMPLEMENT_ASN1_FUNCTIONS(X509_CINF)
extern void policy_cache_free(X509_POLICY_CACHE *cache);
static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
- void *exarg)
+ void *exarg)
{
- X509 *ret = (X509 *)*pval;
-
- switch(operation) {
-
- case ASN1_OP_NEW_POST:
- ret->valid=0;
- ret->name = NULL;
- ret->ex_flags = 0;
- ret->ex_pathlen = -1;
- ret->skid = NULL;
- ret->akid = NULL;
- ret->aux = NULL;
- ret->crldp = NULL;
- CRYPTO_new_ex_data(&ret->ex_data);
- break;
-
- case ASN1_OP_D2I_POST:
- if (ret->name != NULL) OPENSSL_free(ret->name);
- ret->name=X509_NAME_oneline(ret->cert_info->subject,NULL,0);
- break;
-
- case ASN1_OP_FREE_POST:
- CRYPTO_free_ex_data(&g_ex_data_class, ret, &ret->ex_data);
- X509_CERT_AUX_free(ret->aux);
- ASN1_OCTET_STRING_free(ret->skid);
- AUTHORITY_KEYID_free(ret->akid);
- CRL_DIST_POINTS_free(ret->crldp);
- policy_cache_free(ret->policy_cache);
- GENERAL_NAMES_free(ret->altname);
- NAME_CONSTRAINTS_free(ret->nc);
-
- if (ret->name != NULL) OPENSSL_free(ret->name);
- break;
-
- }
-
- return 1;
+ X509 *ret = (X509 *)*pval;
+
+ switch (operation) {
+
+ case ASN1_OP_NEW_POST:
+ ret->valid = 0;
+ ret->name = NULL;
+ ret->ex_flags = 0;
+ ret->ex_pathlen = -1;
+ ret->skid = NULL;
+ ret->akid = NULL;
+ ret->aux = NULL;
+ ret->crldp = NULL;
+ CRYPTO_new_ex_data(&ret->ex_data);
+ break;
+
+ case ASN1_OP_D2I_POST:
+ if (ret->name != NULL)
+ OPENSSL_free(ret->name);
+ ret->name = X509_NAME_oneline(ret->cert_info->subject, NULL, 0);
+ break;
+
+ case ASN1_OP_FREE_POST:
+ CRYPTO_free_ex_data(&g_ex_data_class, ret, &ret->ex_data);
+ X509_CERT_AUX_free(ret->aux);
+ ASN1_OCTET_STRING_free(ret->skid);
+ AUTHORITY_KEYID_free(ret->akid);
+ CRL_DIST_POINTS_free(ret->crldp);
+ policy_cache_free(ret->policy_cache);
+ GENERAL_NAMES_free(ret->altname);
+ NAME_CONSTRAINTS_free(ret->nc);
+
+ if (ret->name != NULL)
+ OPENSSL_free(ret->name);
+ break;
+
+ }
+
+ return 1;
}
ASN1_SEQUENCE_ref(X509, x509_cb) = {
- ASN1_SIMPLE(X509, cert_info, X509_CINF),
- ASN1_SIMPLE(X509, sig_alg, X509_ALGOR),
- ASN1_SIMPLE(X509, signature, ASN1_BIT_STRING)
+ ASN1_SIMPLE(X509, cert_info, X509_CINF),
+ ASN1_SIMPLE(X509, sig_alg, X509_ALGOR),
+ ASN1_SIMPLE(X509, signature, ASN1_BIT_STRING)
} ASN1_SEQUENCE_END_ref(X509, X509)
IMPLEMENT_ASN1_FUNCTIONS(X509)
+
IMPLEMENT_ASN1_DUP_FUNCTION(X509)
X509 *X509_up_ref(X509 *x)
- {
- CRYPTO_refcount_inc(&x->references);
- return x;
- }
-
-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,
- dup_func, free_func))
- {
- return -1;
- }
- return index;
- }
+{
+ CRYPTO_refcount_inc(&x->references);
+ return x;
+}
+
+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,
+ dup_func, free_func)) {
+ return -1;
+ }
+ return index;
+}
int X509_set_ex_data(X509 *r, int idx, void *arg)
- {
- return(CRYPTO_set_ex_data(&r->ex_data,idx,arg));
- }
+{
+ return (CRYPTO_set_ex_data(&r->ex_data, idx, arg));
+}
void *X509_get_ex_data(X509 *r, int idx)
- {
- return(CRYPTO_get_ex_data(&r->ex_data,idx));
- }
-
-/* X509_AUX ASN1 routines. X509_AUX is the name given to
- * a certificate with extra info tagged on the end. Since these
- * functions set how a certificate is trusted they should only
- * be used when the certificate comes from a reliable source
- * such as local storage.
- *
+{
+ return (CRYPTO_get_ex_data(&r->ex_data, idx));
+}
+
+/*
+ * X509_AUX ASN1 routines. X509_AUX is the name given to a certificate with
+ * extra info tagged on the end. Since these functions set how a certificate
+ * is trusted they should only be used when the certificate comes from a
+ * reliable source such as local storage.
*/
X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length)
{
- const unsigned char *q = *pp;
- X509 *ret;
- int freeret = 0;
-
- if (!a || *a == NULL)
- freeret = 1;
- ret = d2i_X509(a, &q, length);
- /* If certificate unreadable then forget it */
- if(!ret) return NULL;
- /* update length */
- 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)
- {
- X509_free(ret);
- if (a)
- *a = NULL;
- }
- return NULL;
+ const unsigned char *q = *pp;
+ X509 *ret;
+ int freeret = 0;
+
+ if (!a || *a == NULL)
+ freeret = 1;
+ ret = d2i_X509(a, &q, length);
+ /* If certificate unreadable then forget it */
+ if (!ret)
+ return NULL;
+ /* update length */
+ 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) {
+ X509_free(ret);
+ if (a)
+ *a = NULL;
+ }
+ return NULL;
}
int i2d_X509_AUX(X509 *a, unsigned char **pp)
{
- int length;
- length = i2d_X509(a, pp);
- if(a) length += i2d_X509_CERT_AUX(a->aux, pp);
- return length;
+ int length, tmplen;
+ length = i2d_X509(a, pp);
+ if (length < 0 || a == NULL) {
+ return length;
+ }
+
+ tmplen = i2d_X509_CERT_AUX(a->aux, pp);
+ if (tmplen < 0) {
+ return tmplen;
+ }
+ length += tmplen;
+
+ return length;
}
void X509_get0_signature(ASN1_BIT_STRING **psig, X509_ALGOR **palg,
- const X509 *x)
- {
- if (psig)
- *psig = x->signature;
- if (palg)
- *palg = x->sig_alg;
- }
+ const X509 *x)
+{
+ if (psig)
+ *psig = x->signature;
+ if (palg)
+ *palg = x->sig_alg;
+}
int X509_get_signature_nid(const X509 *x)
- {
- return OBJ_obj2nid(x->sig_alg->algorithm);
- }
+{
+ return OBJ_obj2nid(x->sig_alg->algorithm);
+}
diff --git a/src/crypto/x509/x_x509a.c b/src/crypto/x509/x_x509a.c
index fb7172b4..a63ee422 100644
--- a/src/crypto/x509/x_x509a.c
+++ b/src/crypto/x509/x_x509a.c
@@ -1,5 +1,7 @@
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999. */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
*
@@ -8,7 +10,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -59,139 +61,145 @@
#include <openssl/obj.h>
#include <openssl/x509.h>
-
-/* X509_CERT_AUX routines. These are used to encode additional
- * user modifiable data about a certificate. This data is
- * appended to the X509 encoding when the *_X509_AUX routines
- * are used. This means that the "traditional" X509 routines
- * will simply ignore the extra data. */
+/*
+ * X509_CERT_AUX routines. These are used to encode additional user
+ * modifiable data about a certificate. This data is appended to the X509
+ * encoding when the *_X509_AUX routines are used. This means that the
+ * "traditional" X509 routines will simply ignore the extra data.
+ */
static X509_CERT_AUX *aux_get(X509 *x);
ASN1_SEQUENCE(X509_CERT_AUX) = {
- ASN1_SEQUENCE_OF_OPT(X509_CERT_AUX, trust, ASN1_OBJECT),
- ASN1_IMP_SEQUENCE_OF_OPT(X509_CERT_AUX, reject, ASN1_OBJECT, 0),
- ASN1_OPT(X509_CERT_AUX, alias, ASN1_UTF8STRING),
- ASN1_OPT(X509_CERT_AUX, keyid, ASN1_OCTET_STRING),
- ASN1_IMP_SEQUENCE_OF_OPT(X509_CERT_AUX, other, X509_ALGOR, 1)
+ ASN1_SEQUENCE_OF_OPT(X509_CERT_AUX, trust, ASN1_OBJECT),
+ ASN1_IMP_SEQUENCE_OF_OPT(X509_CERT_AUX, reject, ASN1_OBJECT, 0),
+ ASN1_OPT(X509_CERT_AUX, alias, ASN1_UTF8STRING),
+ ASN1_OPT(X509_CERT_AUX, keyid, ASN1_OCTET_STRING),
+ ASN1_IMP_SEQUENCE_OF_OPT(X509_CERT_AUX, other, X509_ALGOR, 1)
} ASN1_SEQUENCE_END(X509_CERT_AUX)
IMPLEMENT_ASN1_FUNCTIONS(X509_CERT_AUX)
static X509_CERT_AUX *aux_get(X509 *x)
{
- if(!x) return NULL;
- if(!x->aux && !(x->aux = X509_CERT_AUX_new())) return NULL;
- return x->aux;
+ if (!x)
+ return NULL;
+ if (!x->aux && !(x->aux = X509_CERT_AUX_new()))
+ return NULL;
+ return x->aux;
}
int X509_alias_set1(X509 *x, unsigned char *name, int len)
{
- X509_CERT_AUX *aux;
- if (!name)
- {
- if (!x || !x->aux || !x->aux->alias)
- return 1;
- ASN1_UTF8STRING_free(x->aux->alias);
- x->aux->alias = NULL;
- return 1;
- }
- if(!(aux = aux_get(x))) return 0;
- if(!aux->alias && !(aux->alias = ASN1_UTF8STRING_new())) return 0;
- return ASN1_STRING_set(aux->alias, name, len);
+ X509_CERT_AUX *aux;
+ if (!name) {
+ if (!x || !x->aux || !x->aux->alias)
+ return 1;
+ ASN1_UTF8STRING_free(x->aux->alias);
+ x->aux->alias = NULL;
+ return 1;
+ }
+ if (!(aux = aux_get(x)))
+ return 0;
+ if (!aux->alias && !(aux->alias = ASN1_UTF8STRING_new()))
+ return 0;
+ return ASN1_STRING_set(aux->alias, name, len);
}
int X509_keyid_set1(X509 *x, unsigned char *id, int len)
{
- X509_CERT_AUX *aux;
- if (!id)
- {
- if (!x || !x->aux || !x->aux->keyid)
- return 1;
- ASN1_OCTET_STRING_free(x->aux->keyid);
- x->aux->keyid = NULL;
- return 1;
- }
- if(!(aux = aux_get(x))) return 0;
- if(!aux->keyid && !(aux->keyid = ASN1_OCTET_STRING_new())) return 0;
- return ASN1_STRING_set(aux->keyid, id, len);
+ X509_CERT_AUX *aux;
+ if (!id) {
+ if (!x || !x->aux || !x->aux->keyid)
+ return 1;
+ ASN1_OCTET_STRING_free(x->aux->keyid);
+ x->aux->keyid = NULL;
+ return 1;
+ }
+ if (!(aux = aux_get(x)))
+ return 0;
+ if (!aux->keyid && !(aux->keyid = ASN1_OCTET_STRING_new()))
+ return 0;
+ return ASN1_STRING_set(aux->keyid, id, len);
}
unsigned char *X509_alias_get0(X509 *x, int *len)
{
- if(!x->aux || !x->aux->alias) return NULL;
- if(len) *len = x->aux->alias->length;
- return x->aux->alias->data;
+ if (!x->aux || !x->aux->alias)
+ return NULL;
+ if (len)
+ *len = x->aux->alias->length;
+ return x->aux->alias->data;
}
unsigned char *X509_keyid_get0(X509 *x, int *len)
{
- if(!x->aux || !x->aux->keyid) return NULL;
- if(len) *len = x->aux->keyid->length;
- return x->aux->keyid->data;
+ if (!x->aux || !x->aux->keyid)
+ return NULL;
+ if (len)
+ *len = x->aux->keyid->length;
+ return x->aux->keyid->data;
}
int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj)
{
- 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;
+ 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)
{
- 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;
+ 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)
{
- if(x->aux && x->aux->trust) {
- sk_ASN1_OBJECT_pop_free(x->aux->trust, ASN1_OBJECT_free);
- x->aux->trust = NULL;
- }
+ if (x->aux && x->aux->trust) {
+ sk_ASN1_OBJECT_pop_free(x->aux->trust, ASN1_OBJECT_free);
+ x->aux->trust = NULL;
+ }
}
void X509_reject_clear(X509 *x)
{
- if(x->aux && x->aux->reject) {
- sk_ASN1_OBJECT_pop_free(x->aux->reject, ASN1_OBJECT_free);
- x->aux->reject = NULL;
- }
+ if (x->aux && x->aux->reject) {
+ sk_ASN1_OBJECT_pop_free(x->aux->reject, ASN1_OBJECT_free);
+ x->aux->reject = NULL;
+ }
}
ASN1_SEQUENCE(X509_CERT_PAIR) = {
- ASN1_EXP_OPT(X509_CERT_PAIR, forward, X509, 0),
- ASN1_EXP_OPT(X509_CERT_PAIR, reverse, X509, 1)
+ ASN1_EXP_OPT(X509_CERT_PAIR, forward, X509, 0),
+ ASN1_EXP_OPT(X509_CERT_PAIR, reverse, X509, 1)
} ASN1_SEQUENCE_END(X509_CERT_PAIR)
IMPLEMENT_ASN1_FUNCTIONS(X509_CERT_PAIR)
diff --git a/src/crypto/x509v3/ext_dat.h b/src/crypto/x509v3/ext_dat.h
index f1fb8ef3..9ece19c5 100644
--- a/src/crypto/x509v3/ext_dat.h
+++ b/src/crypto/x509v3/ext_dat.h
@@ -1,5 +1,6 @@
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
*/
/* ====================================================================
* Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved.
@@ -9,7 +10,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -56,74 +57,79 @@
/* This file contains a table of "standard" extensions */
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_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_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.
+/*
+ * This table will be searched using OBJ_bsearch so it *must* kept in order
+ * of the ext_nid values.
*/
/* TODO(fork): OCSP support */
#define OPENSSL_NO_OCSP
static const X509V3_EXT_METHOD *const standard_exts[] = {
-&v3_nscert,
-&v3_ns_ia5_list[0],
-&v3_ns_ia5_list[1],
-&v3_ns_ia5_list[2],
-&v3_ns_ia5_list[3],
-&v3_ns_ia5_list[4],
-&v3_ns_ia5_list[5],
-&v3_ns_ia5_list[6],
-&v3_skey_id,
-&v3_key_usage,
-&v3_pkey_usage_period,
-&v3_alt[0],
-&v3_alt[1],
-&v3_bcons,
-&v3_crl_num,
-&v3_cpols,
-&v3_akey_id,
-&v3_crld,
-&v3_ext_ku,
-&v3_delta_crl,
-&v3_crl_reason,
+ &v3_nscert,
+ &v3_ns_ia5_list[0],
+ &v3_ns_ia5_list[1],
+ &v3_ns_ia5_list[2],
+ &v3_ns_ia5_list[3],
+ &v3_ns_ia5_list[4],
+ &v3_ns_ia5_list[5],
+ &v3_ns_ia5_list[6],
+ &v3_skey_id,
+ &v3_key_usage,
+ &v3_pkey_usage_period,
+ &v3_alt[0],
+ &v3_alt[1],
+ &v3_bcons,
+ &v3_crl_num,
+ &v3_cpols,
+ &v3_akey_id,
+ &v3_crld,
+ &v3_ext_ku,
+ &v3_delta_crl,
+ &v3_crl_reason,
#ifndef OPENSSL_NO_OCSP
-&v3_crl_invdate,
+ &v3_crl_invdate,
#endif
-&v3_sxnet,
-&v3_info,
+ &v3_sxnet,
+ &v3_info,
#ifndef OPENSSL_NO_OCSP
-&v3_ocsp_nonce,
-&v3_ocsp_crlid,
-&v3_ocsp_accresp,
-&v3_ocsp_nocheck,
-&v3_ocsp_acutoff,
-&v3_ocsp_serviceloc,
+ &v3_ocsp_nonce,
+ &v3_ocsp_crlid,
+ &v3_ocsp_accresp,
+ &v3_ocsp_nocheck,
+ &v3_ocsp_acutoff,
+ &v3_ocsp_serviceloc,
#endif
-&v3_sinfo,
-&v3_policy_constraints,
+ &v3_sinfo,
+ &v3_policy_constraints,
#ifndef OPENSSL_NO_OCSP
-&v3_crl_hold,
+ &v3_crl_hold,
#endif
-&v3_pci,
-&v3_name_constraints,
-&v3_policy_mappings,
-&v3_inhibit_anyp,
-&v3_idp,
-&v3_alt[2],
-&v3_freshest_crl,
+ &v3_pci,
+ &v3_name_constraints,
+ &v3_policy_mappings,
+ &v3_inhibit_anyp,
+ &v3_idp,
+ &v3_alt[2],
+ &v3_freshest_crl,
};
/* Number of standard extensions */
#define STANDARD_EXTENSION_COUNT (sizeof(standard_exts)/sizeof(X509V3_EXT_METHOD *))
-
diff --git a/src/crypto/x509v3/pcy_cache.c b/src/crypto/x509v3/pcy_cache.c
index 08f20aa2..f1e512ea 100644
--- a/src/crypto/x509v3/pcy_cache.c
+++ b/src/crypto/x509v3/pcy_cache.c
@@ -1,5 +1,6 @@
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2004.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2004.
*/
/* ====================================================================
* Copyright (c) 2004 The OpenSSL Project. All rights reserved.
@@ -9,7 +10,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -62,238 +63,222 @@
#include "pcy_int.h"
#include "../internal.h"
-
static int policy_data_cmp(const X509_POLICY_DATA **a,
- const X509_POLICY_DATA **b);
+ const X509_POLICY_DATA **b);
static int policy_cache_set_int(long *out, ASN1_INTEGER *value);
-/* Set cache entry according to CertificatePolicies extension.
- * Note: this destroys the passed CERTIFICATEPOLICIES structure.
+/*
+ * Set cache entry according to CertificatePolicies extension. Note: this
+ * destroys the passed CERTIFICATEPOLICIES structure.
*/
static int policy_cache_create(X509 *x,
- CERTIFICATEPOLICIES *policies, int crit)
- {
- size_t i;
- int ret = 0;
- X509_POLICY_CACHE *cache = x->policy_cache;
- X509_POLICY_DATA *data = NULL;
- POLICYINFO *policy;
- if (sk_POLICYINFO_num(policies) == 0)
- goto bad_policy;
- cache->data = sk_X509_POLICY_DATA_new(policy_data_cmp);
- if (!cache->data)
- goto bad_policy;
- for (i = 0; i < sk_POLICYINFO_num(policies); i++)
- {
- policy = sk_POLICYINFO_value(policies, i);
- data = policy_data_new(policy, NULL, crit);
- if (!data)
- goto bad_policy;
- /* Duplicate policy OIDs are illegal: reject if matches
- * found.
- */
- if (OBJ_obj2nid(data->valid_policy) == NID_any_policy)
- {
- if (cache->anyPolicy)
- {
- ret = -1;
- goto bad_policy;
- }
- cache->anyPolicy = data;
- }
- else if (sk_X509_POLICY_DATA_find(cache->data, NULL, data))
- {
- ret = -1;
- goto bad_policy;
- }
- else if (!sk_X509_POLICY_DATA_push(cache->data, data))
- goto bad_policy;
- data = NULL;
- }
- ret = 1;
- bad_policy:
- if (ret == -1)
- x->ex_flags |= EXFLAG_INVALID_POLICY;
- if (data)
- policy_data_free(data);
- sk_POLICYINFO_pop_free(policies, POLICYINFO_free);
- if (ret <= 0)
- {
- sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free);
- cache->data = NULL;
- }
- return ret;
- }
-
-
+ CERTIFICATEPOLICIES *policies, int crit)
+{
+ size_t i;
+ int ret = 0;
+ X509_POLICY_CACHE *cache = x->policy_cache;
+ X509_POLICY_DATA *data = NULL;
+ POLICYINFO *policy;
+ if (sk_POLICYINFO_num(policies) == 0)
+ goto bad_policy;
+ cache->data = sk_X509_POLICY_DATA_new(policy_data_cmp);
+ if (!cache->data)
+ goto bad_policy;
+ for (i = 0; i < sk_POLICYINFO_num(policies); i++) {
+ policy = sk_POLICYINFO_value(policies, i);
+ data = policy_data_new(policy, NULL, crit);
+ if (!data)
+ goto bad_policy;
+ /*
+ * Duplicate policy OIDs are illegal: reject if matches found.
+ */
+ if (OBJ_obj2nid(data->valid_policy) == NID_any_policy) {
+ if (cache->anyPolicy) {
+ ret = -1;
+ goto bad_policy;
+ }
+ cache->anyPolicy = data;
+ } else if (sk_X509_POLICY_DATA_find(cache->data, NULL, data)) {
+ ret = -1;
+ goto bad_policy;
+ } else if (!sk_X509_POLICY_DATA_push(cache->data, data))
+ goto bad_policy;
+ data = NULL;
+ }
+ ret = 1;
+ bad_policy:
+ if (ret == -1)
+ x->ex_flags |= EXFLAG_INVALID_POLICY;
+ if (data)
+ policy_data_free(data);
+ sk_POLICYINFO_pop_free(policies, POLICYINFO_free);
+ if (ret <= 0) {
+ sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free);
+ cache->data = NULL;
+ }
+ return ret;
+}
+
static int policy_cache_new(X509 *x)
- {
- X509_POLICY_CACHE *cache;
- ASN1_INTEGER *ext_any = NULL;
- POLICY_CONSTRAINTS *ext_pcons = NULL;
- CERTIFICATEPOLICIES *ext_cpols = NULL;
- POLICY_MAPPINGS *ext_pmaps = NULL;
- int i;
- cache = OPENSSL_malloc(sizeof(X509_POLICY_CACHE));
- if (!cache)
- return 0;
- cache->anyPolicy = NULL;
- cache->data = NULL;
- cache->any_skip = -1;
- cache->explicit_skip = -1;
- cache->map_skip = -1;
-
- x->policy_cache = cache;
-
- /* Handle requireExplicitPolicy *first*. Need to process this
- * even if we don't have any policies.
- */
- ext_pcons = X509_get_ext_d2i(x, NID_policy_constraints, &i, NULL);
-
- if (!ext_pcons)
- {
- if (i != -1)
- goto bad_cache;
- }
- else
- {
- if (!ext_pcons->requireExplicitPolicy
- && !ext_pcons->inhibitPolicyMapping)
- goto bad_cache;
- if (!policy_cache_set_int(&cache->explicit_skip,
- ext_pcons->requireExplicitPolicy))
- goto bad_cache;
- if (!policy_cache_set_int(&cache->map_skip,
- ext_pcons->inhibitPolicyMapping))
- goto bad_cache;
- }
-
- /* Process CertificatePolicies */
-
- ext_cpols = X509_get_ext_d2i(x, NID_certificate_policies, &i, NULL);
- /* If no CertificatePolicies extension or problem decoding then
- * there is no point continuing because the valid policies will be
- * NULL.
- */
- if (!ext_cpols)
- {
- /* If not absent some problem with extension */
- if (i != -1)
- goto bad_cache;
- return 1;
- }
-
- i = policy_cache_create(x, ext_cpols, i);
-
- /* NB: ext_cpols freed by policy_cache_set_policies */
-
- if (i <= 0)
- return i;
-
- ext_pmaps = X509_get_ext_d2i(x, NID_policy_mappings, &i, NULL);
-
- if (!ext_pmaps)
- {
- /* If not absent some problem with extension */
- if (i != -1)
- goto bad_cache;
- }
- else
- {
- i = policy_cache_set_mapping(x, ext_pmaps);
- if (i <= 0)
- goto bad_cache;
- }
-
- ext_any = X509_get_ext_d2i(x, NID_inhibit_any_policy, &i, NULL);
-
- if (!ext_any)
- {
- if (i != -1)
- goto bad_cache;
- }
- else if (!policy_cache_set_int(&cache->any_skip, ext_any))
- goto bad_cache;
-
- if (0)
- {
- bad_cache:
- x->ex_flags |= EXFLAG_INVALID_POLICY;
- }
-
- if(ext_pcons)
- POLICY_CONSTRAINTS_free(ext_pcons);
-
- if (ext_any)
- ASN1_INTEGER_free(ext_any);
-
- return 1;
-
-
+{
+ X509_POLICY_CACHE *cache;
+ ASN1_INTEGER *ext_any = NULL;
+ POLICY_CONSTRAINTS *ext_pcons = NULL;
+ CERTIFICATEPOLICIES *ext_cpols = NULL;
+ POLICY_MAPPINGS *ext_pmaps = NULL;
+ int i;
+ cache = OPENSSL_malloc(sizeof(X509_POLICY_CACHE));
+ if (!cache)
+ return 0;
+ cache->anyPolicy = NULL;
+ cache->data = NULL;
+ cache->any_skip = -1;
+ cache->explicit_skip = -1;
+ cache->map_skip = -1;
+
+ x->policy_cache = cache;
+
+ /*
+ * Handle requireExplicitPolicy *first*. Need to process this even if we
+ * don't have any policies.
+ */
+ ext_pcons = X509_get_ext_d2i(x, NID_policy_constraints, &i, NULL);
+
+ if (!ext_pcons) {
+ if (i != -1)
+ goto bad_cache;
+ } else {
+ if (!ext_pcons->requireExplicitPolicy
+ && !ext_pcons->inhibitPolicyMapping)
+ goto bad_cache;
+ if (!policy_cache_set_int(&cache->explicit_skip,
+ ext_pcons->requireExplicitPolicy))
+ goto bad_cache;
+ if (!policy_cache_set_int(&cache->map_skip,
+ ext_pcons->inhibitPolicyMapping))
+ goto bad_cache;
+ }
+
+ /* Process CertificatePolicies */
+
+ ext_cpols = X509_get_ext_d2i(x, NID_certificate_policies, &i, NULL);
+ /*
+ * If no CertificatePolicies extension or problem decoding then there is
+ * no point continuing because the valid policies will be NULL.
+ */
+ if (!ext_cpols) {
+ /* If not absent some problem with extension */
+ if (i != -1)
+ goto bad_cache;
+ return 1;
+ }
+
+ i = policy_cache_create(x, ext_cpols, i);
+
+ /* NB: ext_cpols freed by policy_cache_set_policies */
+
+ if (i <= 0)
+ return i;
+
+ ext_pmaps = X509_get_ext_d2i(x, NID_policy_mappings, &i, NULL);
+
+ if (!ext_pmaps) {
+ /* If not absent some problem with extension */
+ if (i != -1)
+ goto bad_cache;
+ } else {
+ i = policy_cache_set_mapping(x, ext_pmaps);
+ if (i <= 0)
+ goto bad_cache;
+ }
+
+ ext_any = X509_get_ext_d2i(x, NID_inhibit_any_policy, &i, NULL);
+
+ if (!ext_any) {
+ if (i != -1)
+ goto bad_cache;
+ } else if (!policy_cache_set_int(&cache->any_skip, ext_any))
+ goto bad_cache;
+
+ if (0) {
+ bad_cache:
+ x->ex_flags |= EXFLAG_INVALID_POLICY;
+ }
+
+ if (ext_pcons)
+ POLICY_CONSTRAINTS_free(ext_pcons);
+
+ if (ext_any)
+ ASN1_INTEGER_free(ext_any);
+
+ return 1;
+
}
void policy_cache_free(X509_POLICY_CACHE *cache)
- {
- if (!cache)
- return;
- if (cache->anyPolicy)
- policy_data_free(cache->anyPolicy);
- if (cache->data)
- sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free);
- OPENSSL_free(cache);
- }
-
-/* g_x509_policy_cache_lock is used to protect against concurrent calls to
- * |policy_cache_new|. Ideally this would be done with a |CRYPTO_once_t|
- * in the |X509| structure, but |CRYPTO_once_t| isn't public. */
+{
+ if (!cache)
+ return;
+ if (cache->anyPolicy)
+ policy_data_free(cache->anyPolicy);
+ if (cache->data)
+ sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free);
+ OPENSSL_free(cache);
+}
+
+/*
+ * g_x509_policy_cache_lock is used to protect against concurrent calls to
+ * |policy_cache_new|. Ideally this would be done with a |CRYPTO_once_t| in
+ * the |X509| structure, but |CRYPTO_once_t| isn't public.
+ */
static struct CRYPTO_STATIC_MUTEX g_x509_policy_cache_lock =
CRYPTO_STATIC_MUTEX_INIT;
const X509_POLICY_CACHE *policy_cache_set(X509 *x)
- {
- X509_POLICY_CACHE *cache;
+{
+ X509_POLICY_CACHE *cache;
- CRYPTO_STATIC_MUTEX_lock_read(&g_x509_policy_cache_lock);
- cache = x->policy_cache;
- CRYPTO_STATIC_MUTEX_unlock(&g_x509_policy_cache_lock);
+ CRYPTO_STATIC_MUTEX_lock_read(&g_x509_policy_cache_lock);
+ cache = x->policy_cache;
+ CRYPTO_STATIC_MUTEX_unlock(&g_x509_policy_cache_lock);
- if (cache != NULL)
- return cache;
+ if (cache != NULL)
+ return cache;
- CRYPTO_STATIC_MUTEX_lock_write(&g_x509_policy_cache_lock);
- if (x->policy_cache == NULL)
- policy_cache_new(x);
- cache = x->policy_cache;
- CRYPTO_STATIC_MUTEX_unlock(&g_x509_policy_cache_lock);
+ CRYPTO_STATIC_MUTEX_lock_write(&g_x509_policy_cache_lock);
+ if (x->policy_cache == NULL)
+ policy_cache_new(x);
+ cache = x->policy_cache;
+ CRYPTO_STATIC_MUTEX_unlock(&g_x509_policy_cache_lock);
- return cache;
- }
+ return cache;
+}
X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache,
- const ASN1_OBJECT *id)
- {
- size_t idx;
- X509_POLICY_DATA tmp;
-
- tmp.valid_policy = (ASN1_OBJECT *)id;
- if (!sk_X509_POLICY_DATA_find(cache->data, &idx, &tmp))
- return NULL;
- return sk_X509_POLICY_DATA_value(cache->data, idx);
- }
+ const ASN1_OBJECT *id)
+{
+ size_t idx;
+ X509_POLICY_DATA tmp;
+
+ tmp.valid_policy = (ASN1_OBJECT *)id;
+ if (!sk_X509_POLICY_DATA_find(cache->data, &idx, &tmp))
+ return NULL;
+ return sk_X509_POLICY_DATA_value(cache->data, idx);
+}
static int policy_data_cmp(const X509_POLICY_DATA **a,
- const X509_POLICY_DATA **b)
- {
- return OBJ_cmp((*a)->valid_policy, (*b)->valid_policy);
- }
+ const X509_POLICY_DATA **b)
+{
+ return OBJ_cmp((*a)->valid_policy, (*b)->valid_policy);
+}
static int policy_cache_set_int(long *out, ASN1_INTEGER *value)
- {
- if (value == NULL)
- return 1;
- if (value->type == V_ASN1_NEG_INTEGER)
- return 0;
- *out = ASN1_INTEGER_get(value);
- return 1;
- }
+{
+ if (value == NULL)
+ return 1;
+ if (value->type == V_ASN1_NEG_INTEGER)
+ return 0;
+ *out = ASN1_INTEGER_get(value);
+ return 1;
+}
diff --git a/src/crypto/x509v3/pcy_data.c b/src/crypto/x509v3/pcy_data.c
index cd45dcaa..498de4dd 100644
--- a/src/crypto/x509v3/pcy_data.c
+++ b/src/crypto/x509v3/pcy_data.c
@@ -1,6 +1,7 @@
/* pcy_data.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2004.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2004.
*/
/* ====================================================================
* Copyright (c) 2004 The OpenSSL Project. All rights reserved.
@@ -10,7 +11,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -63,75 +64,67 @@
#include "pcy_int.h"
-
/* Policy Node routines */
void policy_data_free(X509_POLICY_DATA *data)
- {
- ASN1_OBJECT_free(data->valid_policy);
- /* Don't free qualifiers if shared */
- if (!(data->flags & POLICY_DATA_FLAG_SHARED_QUALIFIERS))
- sk_POLICYQUALINFO_pop_free(data->qualifier_set,
- POLICYQUALINFO_free);
- sk_ASN1_OBJECT_pop_free(data->expected_policy_set, ASN1_OBJECT_free);
- OPENSSL_free(data);
- }
+{
+ ASN1_OBJECT_free(data->valid_policy);
+ /* Don't free qualifiers if shared */
+ if (!(data->flags & POLICY_DATA_FLAG_SHARED_QUALIFIERS))
+ sk_POLICYQUALINFO_pop_free(data->qualifier_set, POLICYQUALINFO_free);
+ sk_ASN1_OBJECT_pop_free(data->expected_policy_set, ASN1_OBJECT_free);
+ OPENSSL_free(data);
+}
-/* Create a data based on an existing policy. If 'id' is NULL use the
- * oid in the policy, otherwise use 'id'. This behaviour covers the two
- * types of data in RFC3280: data with from a CertificatePolcies extension
- * and additional data with just the qualifiers of anyPolicy and ID from
- * another source.
+/*
+ * Create a data based on an existing policy. If 'id' is NULL use the oid in
+ * the policy, otherwise use 'id'. This behaviour covers the two types of
+ * data in RFC3280: data with from a CertificatePolcies extension and
+ * additional data with just the qualifiers of anyPolicy and ID from another
+ * source.
*/
X509_POLICY_DATA *policy_data_new(POLICYINFO *policy,
- const ASN1_OBJECT *cid, int crit)
- {
- X509_POLICY_DATA *ret;
- ASN1_OBJECT *id;
- if (!policy && !cid)
- return NULL;
- if (cid)
- {
- id = OBJ_dup(cid);
- if (!id)
- return NULL;
- }
- else
- id = NULL;
- ret = OPENSSL_malloc(sizeof(X509_POLICY_DATA));
- if (!ret)
- return NULL;
- ret->expected_policy_set = sk_ASN1_OBJECT_new_null();
- if (!ret->expected_policy_set)
- {
- OPENSSL_free(ret);
- if (id)
- ASN1_OBJECT_free(id);
- return NULL;
- }
-
- if (crit)
- ret->flags = POLICY_DATA_FLAG_CRITICAL;
- else
- ret->flags = 0;
+ const ASN1_OBJECT *cid, int crit)
+{
+ X509_POLICY_DATA *ret;
+ ASN1_OBJECT *id;
+ if (!policy && !cid)
+ return NULL;
+ if (cid) {
+ id = OBJ_dup(cid);
+ if (!id)
+ return NULL;
+ } else
+ id = NULL;
+ ret = OPENSSL_malloc(sizeof(X509_POLICY_DATA));
+ if (!ret)
+ return NULL;
+ ret->expected_policy_set = sk_ASN1_OBJECT_new_null();
+ if (!ret->expected_policy_set) {
+ OPENSSL_free(ret);
+ if (id)
+ ASN1_OBJECT_free(id);
+ return NULL;
+ }
- if (id)
- ret->valid_policy = id;
- else
- {
- ret->valid_policy = policy->policyid;
- policy->policyid = NULL;
- }
+ if (crit)
+ ret->flags = POLICY_DATA_FLAG_CRITICAL;
+ else
+ ret->flags = 0;
- if (policy)
- {
- ret->qualifier_set = policy->qualifiers;
- policy->qualifiers = NULL;
- }
- else
- ret->qualifier_set = NULL;
+ if (id)
+ ret->valid_policy = id;
+ else {
+ ret->valid_policy = policy->policyid;
+ policy->policyid = NULL;
+ }
- return ret;
- }
+ if (policy) {
+ ret->qualifier_set = policy->qualifiers;
+ policy->qualifiers = NULL;
+ } else
+ ret->qualifier_set = NULL;
+ return ret;
+}
diff --git a/src/crypto/x509v3/pcy_int.h b/src/crypto/x509v3/pcy_int.h
index ccff9284..b5075f9e 100644
--- a/src/crypto/x509v3/pcy_int.h
+++ b/src/crypto/x509v3/pcy_int.h
@@ -1,6 +1,7 @@
/* pcy_int.h */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2004.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2004.
*/
/* ====================================================================
* Copyright (c) 2004 The OpenSSL Project. All rights reserved.
@@ -10,7 +11,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -56,121 +57,126 @@
*
*/
-
typedef struct X509_POLICY_DATA_st X509_POLICY_DATA;
DECLARE_STACK_OF(X509_POLICY_DATA)
/* Internal structures */
-/* This structure and the field names correspond to the Policy 'node' of
- * RFC3280. NB this structure contains no pointers to parent or child
- * data: X509_POLICY_NODE contains that. This means that the main policy data
- * can be kept static and cached with the certificate.
+/*
+ * This structure and the field names correspond to the Policy 'node' of
+ * RFC3280. NB this structure contains no pointers to parent or child data:
+ * X509_POLICY_NODE contains that. This means that the main policy data can
+ * be kept static and cached with the certificate.
*/
-struct X509_POLICY_DATA_st
- {
- unsigned int flags;
- /* Policy OID and qualifiers for this data */
- ASN1_OBJECT *valid_policy;
- STACK_OF(POLICYQUALINFO) *qualifier_set;
- STACK_OF(ASN1_OBJECT) *expected_policy_set;
- };
+struct X509_POLICY_DATA_st {
+ unsigned int flags;
+ /* Policy OID and qualifiers for this data */
+ ASN1_OBJECT *valid_policy;
+ STACK_OF(POLICYQUALINFO) *qualifier_set;
+ STACK_OF(ASN1_OBJECT) *expected_policy_set;
+};
/* X509_POLICY_DATA flags values */
-/* This flag indicates the structure has been mapped using a policy mapping
- * extension. If policy mapping is not active its references get deleted.
+/*
+ * This flag indicates the structure has been mapped using a policy mapping
+ * extension. If policy mapping is not active its references get deleted.
*/
-#define POLICY_DATA_FLAG_MAPPED 0x1
+#define POLICY_DATA_FLAG_MAPPED 0x1
-/* This flag indicates the data doesn't correspond to a policy in Certificate
+/*
+ * This flag indicates the data doesn't correspond to a policy in Certificate
* Policies: it has been mapped to any policy.
*/
-#define POLICY_DATA_FLAG_MAPPED_ANY 0x2
+#define POLICY_DATA_FLAG_MAPPED_ANY 0x2
/* AND with flags to see if any mapping has occurred */
-#define POLICY_DATA_FLAG_MAP_MASK 0x3
+#define POLICY_DATA_FLAG_MAP_MASK 0x3
/* qualifiers are shared and shouldn't be freed */
-#define POLICY_DATA_FLAG_SHARED_QUALIFIERS 0x4
+#define POLICY_DATA_FLAG_SHARED_QUALIFIERS 0x4
/* Parent node is an extra node and should be freed */
-#define POLICY_DATA_FLAG_EXTRA_NODE 0x8
+#define POLICY_DATA_FLAG_EXTRA_NODE 0x8
/* Corresponding CertificatePolicies is critical */
-#define POLICY_DATA_FLAG_CRITICAL 0x10
+#define POLICY_DATA_FLAG_CRITICAL 0x10
/* This structure is cached with a certificate */
struct X509_POLICY_CACHE_st {
- /* anyPolicy data or NULL if no anyPolicy */
- X509_POLICY_DATA *anyPolicy;
- /* other policy data */
- STACK_OF(X509_POLICY_DATA) *data;
- /* If InhibitAnyPolicy present this is its value or -1 if absent. */
- long any_skip;
- /* If policyConstraints and requireExplicitPolicy present this is its
- * value or -1 if absent.
- */
- long explicit_skip;
- /* If policyConstraints and policyMapping present this is its
- * value or -1 if absent.
- */
- long map_skip;
- };
-
-/*#define POLICY_CACHE_FLAG_CRITICAL POLICY_DATA_FLAG_CRITICAL*/
+ /* anyPolicy data or NULL if no anyPolicy */
+ X509_POLICY_DATA *anyPolicy;
+ /* other policy data */
+ STACK_OF(X509_POLICY_DATA) *data;
+ /* If InhibitAnyPolicy present this is its value or -1 if absent. */
+ long any_skip;
+ /*
+ * If policyConstraints and requireExplicitPolicy present this is its
+ * value or -1 if absent.
+ */
+ long explicit_skip;
+ /*
+ * If policyConstraints and policyMapping present this is its value or -1
+ * if absent.
+ */
+ long map_skip;
+};
+
+/*
+ * #define POLICY_CACHE_FLAG_CRITICAL POLICY_DATA_FLAG_CRITICAL
+ */
/* This structure represents the relationship between nodes */
-struct X509_POLICY_NODE_st
- {
- /* node data this refers to */
- const X509_POLICY_DATA *data;
- /* Parent node */
- X509_POLICY_NODE *parent;
- /* Number of child nodes */
- int nchild;
- };
-
-struct X509_POLICY_LEVEL_st
- {
- /* Cert for this level */
- X509 *cert;
- /* nodes at this level */
- STACK_OF(X509_POLICY_NODE) *nodes;
- /* anyPolicy node */
- X509_POLICY_NODE *anyPolicy;
- /* Extra data */
- /*STACK_OF(X509_POLICY_DATA) *extra_data;*/
- unsigned int flags;
- };
-
-struct X509_POLICY_TREE_st
- {
- /* This is the tree 'level' data */
- X509_POLICY_LEVEL *levels;
- int nlevel;
- /* Extra policy data when additional nodes (not from the certificate)
- * are required.
- */
- STACK_OF(X509_POLICY_DATA) *extra_data;
- /* This is the authority constained policy set */
- STACK_OF(X509_POLICY_NODE) *auth_policies;
- STACK_OF(X509_POLICY_NODE) *user_policies;
- unsigned int flags;
- };
+struct X509_POLICY_NODE_st {
+ /* node data this refers to */
+ const X509_POLICY_DATA *data;
+ /* Parent node */
+ X509_POLICY_NODE *parent;
+ /* Number of child nodes */
+ int nchild;
+};
+
+struct X509_POLICY_LEVEL_st {
+ /* Cert for this level */
+ X509 *cert;
+ /* nodes at this level */
+ STACK_OF(X509_POLICY_NODE) *nodes;
+ /* anyPolicy node */
+ X509_POLICY_NODE *anyPolicy;
+ /* Extra data */
+ /*
+ * STACK_OF(X509_POLICY_DATA) *extra_data;
+ */
+ unsigned int flags;
+};
+
+struct X509_POLICY_TREE_st {
+ /* This is the tree 'level' data */
+ X509_POLICY_LEVEL *levels;
+ int nlevel;
+ /*
+ * Extra policy data when additional nodes (not from the certificate) are
+ * required.
+ */
+ STACK_OF(X509_POLICY_DATA) *extra_data;
+ /* This is the authority constained policy set */
+ STACK_OF(X509_POLICY_NODE) *auth_policies;
+ STACK_OF(X509_POLICY_NODE) *user_policies;
+ unsigned int flags;
+};
/* Set if anyPolicy present in user policies */
-#define POLICY_FLAG_ANY_POLICY 0x2
+#define POLICY_FLAG_ANY_POLICY 0x2
/* Useful macros */
@@ -180,14 +186,13 @@ struct X509_POLICY_TREE_st
/* Internal functions */
X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, const ASN1_OBJECT *id,
- int crit);
+ int crit);
void policy_data_free(X509_POLICY_DATA *data);
X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache,
- const ASN1_OBJECT *id);
+ const ASN1_OBJECT *id);
int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps);
-
STACK_OF(X509_POLICY_NODE) *policy_node_cmp_new(void);
void policy_cache_init(void);
@@ -195,18 +200,18 @@ void policy_cache_init(void);
void policy_cache_free(X509_POLICY_CACHE *cache);
X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level,
- const X509_POLICY_NODE *parent,
- const ASN1_OBJECT *id);
+ const X509_POLICY_NODE *parent,
+ const ASN1_OBJECT *id);
X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *sk,
- const ASN1_OBJECT *id);
+ const ASN1_OBJECT *id);
X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level,
- const X509_POLICY_DATA *data,
- X509_POLICY_NODE *parent,
- X509_POLICY_TREE *tree);
+ const X509_POLICY_DATA *data,
+ X509_POLICY_NODE *parent,
+ X509_POLICY_TREE *tree);
void policy_node_free(X509_POLICY_NODE *node);
int policy_node_match(const X509_POLICY_LEVEL *lvl,
- const X509_POLICY_NODE *node, const ASN1_OBJECT *oid);
+ const X509_POLICY_NODE *node, const ASN1_OBJECT *oid);
const X509_POLICY_CACHE *policy_cache_set(X509 *x);
diff --git a/src/crypto/x509v3/pcy_lib.c b/src/crypto/x509v3/pcy_lib.c
index 16be2f00..764f38f9 100644
--- a/src/crypto/x509v3/pcy_lib.c
+++ b/src/crypto/x509v3/pcy_lib.c
@@ -1,6 +1,7 @@
/* pcy_lib.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2004.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2004.
*/
/* ====================================================================
* Copyright (c) 2004 The OpenSSL Project. All rights reserved.
@@ -10,7 +11,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -54,112 +55,110 @@
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com). */
-
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include "pcy_int.h"
-
/* accessor functions */
/* X509_POLICY_TREE stuff */
int X509_policy_tree_level_count(const X509_POLICY_TREE *tree)
- {
- if (!tree)
- return 0;
- return tree->nlevel;
- }
-
-X509_POLICY_LEVEL *
- X509_policy_tree_get0_level(const X509_POLICY_TREE *tree, int i)
- {
- if (!tree || (i < 0) || (i >= tree->nlevel))
- return NULL;
- return tree->levels + i;
- }
-
-STACK_OF(X509_POLICY_NODE) *
- X509_policy_tree_get0_policies(const X509_POLICY_TREE *tree)
- {
- if (!tree)
- return NULL;
- return tree->auth_policies;
- }
-
-STACK_OF(X509_POLICY_NODE) *
- X509_policy_tree_get0_user_policies(const X509_POLICY_TREE *tree)
- {
- if (!tree)
- return NULL;
- if (tree->flags & POLICY_FLAG_ANY_POLICY)
- return tree->auth_policies;
- else
- return tree->user_policies;
- }
+{
+ if (!tree)
+ return 0;
+ return tree->nlevel;
+}
+
+X509_POLICY_LEVEL *X509_policy_tree_get0_level(const X509_POLICY_TREE *tree,
+ int i)
+{
+ if (!tree || (i < 0) || (i >= tree->nlevel))
+ return NULL;
+ return tree->levels + i;
+}
+
+STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_policies(const
+ X509_POLICY_TREE
+ *tree)
+{
+ if (!tree)
+ return NULL;
+ return tree->auth_policies;
+}
+
+STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_user_policies(const
+ X509_POLICY_TREE
+ *tree)
+{
+ if (!tree)
+ return NULL;
+ if (tree->flags & POLICY_FLAG_ANY_POLICY)
+ return tree->auth_policies;
+ else
+ return tree->user_policies;
+}
/* X509_POLICY_LEVEL stuff */
int X509_policy_level_node_count(X509_POLICY_LEVEL *level)
- {
- int n;
- if (!level)
- return 0;
- if (level->anyPolicy)
- n = 1;
- else
- n = 0;
- if (level->nodes)
- n += sk_X509_POLICY_NODE_num(level->nodes);
- return n;
- }
+{
+ int n;
+ if (!level)
+ return 0;
+ if (level->anyPolicy)
+ n = 1;
+ else
+ n = 0;
+ if (level->nodes)
+ n += sk_X509_POLICY_NODE_num(level->nodes);
+ return n;
+}
X509_POLICY_NODE *X509_policy_level_get0_node(X509_POLICY_LEVEL *level, int i)
- {
- if (!level)
- return NULL;
- if (level->anyPolicy)
- {
- if (i == 0)
- return level->anyPolicy;
- i--;
- }
- return sk_X509_POLICY_NODE_value(level->nodes, i);
- }
+{
+ if (!level)
+ return NULL;
+ if (level->anyPolicy) {
+ if (i == 0)
+ return level->anyPolicy;
+ i--;
+ }
+ return sk_X509_POLICY_NODE_value(level->nodes, i);
+}
/* X509_POLICY_NODE stuff */
const ASN1_OBJECT *X509_policy_node_get0_policy(const X509_POLICY_NODE *node)
- {
- if (!node)
- return NULL;
- return node->data->valid_policy;
- }
+{
+ if (!node)
+ return NULL;
+ return node->data->valid_policy;
+}
#if 0
int X509_policy_node_get_critical(const X509_POLICY_NODE *node)
- {
- if (node_critical(node))
- return 1;
- return 0;
- }
+{
+ if (node_critical(node))
+ return 1;
+ return 0;
+}
#endif
-STACK_OF(POLICYQUALINFO) *
- X509_policy_node_get0_qualifiers(const X509_POLICY_NODE *node)
- {
- if (!node)
- return NULL;
- return node->data->qualifier_set;
- }
-
-const X509_POLICY_NODE *
- X509_policy_node_get0_parent(const X509_POLICY_NODE *node)
- {
- if (!node)
- return NULL;
- return node->parent;
- }
-
-
+STACK_OF(POLICYQUALINFO) *X509_policy_node_get0_qualifiers(const
+ X509_POLICY_NODE
+ *node)
+{
+ if (!node)
+ return NULL;
+ return node->data->qualifier_set;
+}
+
+const X509_POLICY_NODE *X509_policy_node_get0_parent(const X509_POLICY_NODE
+ *node)
+{
+ if (!node)
+ return NULL;
+ return node->parent;
+}
diff --git a/src/crypto/x509v3/pcy_map.c b/src/crypto/x509v3/pcy_map.c
index 2b8307b1..7263c692 100644
--- a/src/crypto/x509v3/pcy_map.c
+++ b/src/crypto/x509v3/pcy_map.c
@@ -1,6 +1,7 @@
/* pcy_map.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2004.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2004.
*/
/* ====================================================================
* Copyright (c) 2004 The OpenSSL Project. All rights reserved.
@@ -10,7 +11,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -62,72 +63,68 @@
#include "pcy_int.h"
-
-/* Set policy mapping entries in cache.
- * Note: this modifies the passed POLICY_MAPPINGS structure
+/*
+ * Set policy mapping entries in cache. Note: this modifies the passed
+ * POLICY_MAPPINGS structure
*/
int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps)
- {
- POLICY_MAPPING *map;
- X509_POLICY_DATA *data;
- X509_POLICY_CACHE *cache = x->policy_cache;
- size_t i;
- int ret = 0;
- if (sk_POLICY_MAPPING_num(maps) == 0)
- {
- ret = -1;
- goto bad_mapping;
- }
- for (i = 0; i < sk_POLICY_MAPPING_num(maps); i++)
- {
- map = sk_POLICY_MAPPING_value(maps, i);
- /* Reject if map to or from anyPolicy */
- if ((OBJ_obj2nid(map->subjectDomainPolicy) == NID_any_policy)
- || (OBJ_obj2nid(map->issuerDomainPolicy) == NID_any_policy))
- {
- ret = -1;
- goto bad_mapping;
- }
+{
+ POLICY_MAPPING *map;
+ X509_POLICY_DATA *data;
+ X509_POLICY_CACHE *cache = x->policy_cache;
+ size_t i;
+ int ret = 0;
+ if (sk_POLICY_MAPPING_num(maps) == 0) {
+ ret = -1;
+ goto bad_mapping;
+ }
+ for (i = 0; i < sk_POLICY_MAPPING_num(maps); i++) {
+ map = sk_POLICY_MAPPING_value(maps, i);
+ /* Reject if map to or from anyPolicy */
+ if ((OBJ_obj2nid(map->subjectDomainPolicy) == NID_any_policy)
+ || (OBJ_obj2nid(map->issuerDomainPolicy) == NID_any_policy)) {
+ ret = -1;
+ goto bad_mapping;
+ }
- /* Attempt to find matching policy data */
- data = policy_cache_find_data(cache, map->issuerDomainPolicy);
- /* If we don't have anyPolicy can't map */
- if (!data && !cache->anyPolicy)
- continue;
+ /* Attempt to find matching policy data */
+ data = policy_cache_find_data(cache, map->issuerDomainPolicy);
+ /* If we don't have anyPolicy can't map */
+ if (!data && !cache->anyPolicy)
+ continue;
- /* Create a NODE from anyPolicy */
- if (!data)
- {
- data = policy_data_new(NULL, map->issuerDomainPolicy,
- cache->anyPolicy->flags
- & POLICY_DATA_FLAG_CRITICAL);
- if (!data)
- goto bad_mapping;
- data->qualifier_set = cache->anyPolicy->qualifier_set;
- /*map->issuerDomainPolicy = NULL;*/
- data->flags |= POLICY_DATA_FLAG_MAPPED_ANY;
- data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
- if (!sk_X509_POLICY_DATA_push(cache->data, data))
- {
- policy_data_free(data);
- goto bad_mapping;
- }
- }
- else
- data->flags |= POLICY_DATA_FLAG_MAPPED;
- if (!sk_ASN1_OBJECT_push(data->expected_policy_set,
- map->subjectDomainPolicy))
- goto bad_mapping;
- map->subjectDomainPolicy = NULL;
+ /* Create a NODE from anyPolicy */
+ if (!data) {
+ data = policy_data_new(NULL, map->issuerDomainPolicy,
+ cache->anyPolicy->flags
+ & POLICY_DATA_FLAG_CRITICAL);
+ if (!data)
+ goto bad_mapping;
+ data->qualifier_set = cache->anyPolicy->qualifier_set;
+ /*
+ * map->issuerDomainPolicy = NULL;
+ */
+ data->flags |= POLICY_DATA_FLAG_MAPPED_ANY;
+ data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
+ if (!sk_X509_POLICY_DATA_push(cache->data, data)) {
+ policy_data_free(data);
+ goto bad_mapping;
+ }
+ } else
+ data->flags |= POLICY_DATA_FLAG_MAPPED;
+ if (!sk_ASN1_OBJECT_push(data->expected_policy_set,
+ map->subjectDomainPolicy))
+ goto bad_mapping;
+ map->subjectDomainPolicy = NULL;
- }
+ }
- ret = 1;
- bad_mapping:
- if (ret == -1)
- x->ex_flags |= EXFLAG_INVALID_POLICY;
- sk_POLICY_MAPPING_pop_free(maps, POLICY_MAPPING_free);
- return ret;
+ ret = 1;
+ bad_mapping:
+ if (ret == -1)
+ x->ex_flags |= EXFLAG_INVALID_POLICY;
+ sk_POLICY_MAPPING_pop_free(maps, POLICY_MAPPING_free);
+ return ret;
- }
+}
diff --git a/src/crypto/x509v3/pcy_node.c b/src/crypto/x509v3/pcy_node.c
index 55cc2039..cf4e79d8 100644
--- a/src/crypto/x509v3/pcy_node.c
+++ b/src/crypto/x509v3/pcy_node.c
@@ -1,6 +1,7 @@
/* pcy_node.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2004.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2004.
*/
/* ====================================================================
* Copyright (c) 2004 The OpenSSL Project. All rights reserved.
@@ -10,7 +11,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -62,136 +63,126 @@
#include "pcy_int.h"
-
-static int node_cmp(const X509_POLICY_NODE **a,
- const X509_POLICY_NODE **b)
- {
- return OBJ_cmp((*a)->data->valid_policy, (*b)->data->valid_policy);
- }
+static int node_cmp(const X509_POLICY_NODE **a, const X509_POLICY_NODE **b)
+{
+ return OBJ_cmp((*a)->data->valid_policy, (*b)->data->valid_policy);
+}
STACK_OF(X509_POLICY_NODE) *policy_node_cmp_new(void)
- {
- return sk_X509_POLICY_NODE_new(node_cmp);
- }
+{
+ return sk_X509_POLICY_NODE_new(node_cmp);
+}
X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *nodes,
- const ASN1_OBJECT *id)
- {
- X509_POLICY_DATA n;
- X509_POLICY_NODE l;
- size_t idx;
+ const ASN1_OBJECT *id)
+{
+ X509_POLICY_DATA n;
+ X509_POLICY_NODE l;
+ size_t idx;
- n.valid_policy = (ASN1_OBJECT *)id;
- l.data = &n;
+ n.valid_policy = (ASN1_OBJECT *)id;
+ l.data = &n;
- if (!sk_X509_POLICY_NODE_find(nodes, &idx, &l))
- return NULL;
+ if (!sk_X509_POLICY_NODE_find(nodes, &idx, &l))
+ return NULL;
- return sk_X509_POLICY_NODE_value(nodes, idx);
+ return sk_X509_POLICY_NODE_value(nodes, idx);
- }
+}
X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level,
- const X509_POLICY_NODE *parent,
- const ASN1_OBJECT *id)
- {
- X509_POLICY_NODE *node;
- size_t i;
- for (i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++)
- {
- node = sk_X509_POLICY_NODE_value(level->nodes, i);
- if (node->parent == parent)
- {
- if (!OBJ_cmp(node->data->valid_policy, id))
- return node;
- }
- }
- return NULL;
- }
+ const X509_POLICY_NODE *parent,
+ const ASN1_OBJECT *id)
+{
+ X509_POLICY_NODE *node;
+ size_t i;
+ for (i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++) {
+ node = sk_X509_POLICY_NODE_value(level->nodes, i);
+ if (node->parent == parent) {
+ if (!OBJ_cmp(node->data->valid_policy, id))
+ return node;
+ }
+ }
+ return NULL;
+}
X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level,
- const X509_POLICY_DATA *data,
- X509_POLICY_NODE *parent,
- X509_POLICY_TREE *tree)
- {
- X509_POLICY_NODE *node;
- node = OPENSSL_malloc(sizeof(X509_POLICY_NODE));
- if (!node)
- return NULL;
- node->data = data;
- node->parent = parent;
- node->nchild = 0;
- if (level)
- {
- if (OBJ_obj2nid(data->valid_policy) == NID_any_policy)
- {
- if (level->anyPolicy)
- goto node_error;
- level->anyPolicy = node;
- }
- else
- {
-
- if (!level->nodes)
- level->nodes = policy_node_cmp_new();
- if (!level->nodes)
- goto node_error;
- if (!sk_X509_POLICY_NODE_push(level->nodes, node))
- goto node_error;
- }
- }
-
- if (tree)
- {
- if (!tree->extra_data)
- tree->extra_data = sk_X509_POLICY_DATA_new_null();
- if (!tree->extra_data)
- goto node_error;
- if (!sk_X509_POLICY_DATA_push(tree->extra_data, data))
- goto node_error;
- }
-
- if (parent)
- parent->nchild++;
-
- return node;
-
- node_error:
- policy_node_free(node);
- return 0;
-
- }
+ const X509_POLICY_DATA *data,
+ X509_POLICY_NODE *parent,
+ X509_POLICY_TREE *tree)
+{
+ X509_POLICY_NODE *node;
+ node = OPENSSL_malloc(sizeof(X509_POLICY_NODE));
+ if (!node)
+ return NULL;
+ node->data = data;
+ node->parent = parent;
+ node->nchild = 0;
+ if (level) {
+ if (OBJ_obj2nid(data->valid_policy) == NID_any_policy) {
+ if (level->anyPolicy)
+ goto node_error;
+ level->anyPolicy = node;
+ } else {
+
+ if (!level->nodes)
+ level->nodes = policy_node_cmp_new();
+ if (!level->nodes)
+ goto node_error;
+ if (!sk_X509_POLICY_NODE_push(level->nodes, node))
+ goto node_error;
+ }
+ }
+
+ if (tree) {
+ if (!tree->extra_data)
+ tree->extra_data = sk_X509_POLICY_DATA_new_null();
+ if (!tree->extra_data)
+ goto node_error;
+ if (!sk_X509_POLICY_DATA_push(tree->extra_data, data))
+ goto node_error;
+ }
+
+ if (parent)
+ parent->nchild++;
+
+ return node;
+
+ node_error:
+ policy_node_free(node);
+ return 0;
+
+}
void policy_node_free(X509_POLICY_NODE *node)
- {
- OPENSSL_free(node);
- }
+{
+ OPENSSL_free(node);
+}
-/* See if a policy node matches a policy OID. If mapping enabled look through
+/*
+ * See if a policy node matches a policy OID. If mapping enabled look through
* expected policy set otherwise just valid policy.
*/
int policy_node_match(const X509_POLICY_LEVEL *lvl,
- const X509_POLICY_NODE *node, const ASN1_OBJECT *oid)
- {
- size_t i;
- ASN1_OBJECT *policy_oid;
- const X509_POLICY_DATA *x = node->data;
-
- if ( (lvl->flags & X509_V_FLAG_INHIBIT_MAP)
- || !(x->flags & POLICY_DATA_FLAG_MAP_MASK))
- {
- if (!OBJ_cmp(x->valid_policy, oid))
- return 1;
- return 0;
- }
-
- for (i = 0; i < sk_ASN1_OBJECT_num(x->expected_policy_set); i++)
- {
- policy_oid = sk_ASN1_OBJECT_value(x->expected_policy_set, i);
- if (!OBJ_cmp(policy_oid, oid))
- return 1;
- }
- return 0;
-
- }
+ const X509_POLICY_NODE *node, const ASN1_OBJECT *oid)
+{
+ size_t i;
+ ASN1_OBJECT *policy_oid;
+ const X509_POLICY_DATA *x = node->data;
+
+ if ((lvl->flags & X509_V_FLAG_INHIBIT_MAP)
+ || !(x->flags & POLICY_DATA_FLAG_MAP_MASK)) {
+ if (!OBJ_cmp(x->valid_policy, oid))
+ return 1;
+ return 0;
+ }
+
+ for (i = 0; i < sk_ASN1_OBJECT_num(x->expected_policy_set); i++) {
+ policy_oid = sk_ASN1_OBJECT_value(x->expected_policy_set, i);
+ if (!OBJ_cmp(policy_oid, oid))
+ return 1;
+ }
+ return 0;
+
+}
diff --git a/src/crypto/x509v3/pcy_tree.c b/src/crypto/x509v3/pcy_tree.c
index 8e9ef25d..e7484e52 100644
--- a/src/crypto/x509v3/pcy_tree.c
+++ b/src/crypto/x509v3/pcy_tree.c
@@ -1,5 +1,6 @@
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2004.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2004.
*/
/* ====================================================================
* Copyright (c) 2004 The OpenSSL Project. All rights reserved.
@@ -9,7 +10,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -66,811 +67,762 @@
#include "pcy_int.h"
-
-/* Enable this to print out the complete policy tree at various point during
+/*
+ * Enable this to print out the complete policy tree at various point during
* evaluation.
*/
-/*#define OPENSSL_POLICY_DEBUG*/
+/*
+ * #define OPENSSL_POLICY_DEBUG
+ */
#ifdef OPENSSL_POLICY_DEBUG
static void expected_print(BIO *err, X509_POLICY_LEVEL *lev,
- X509_POLICY_NODE *node, int indent)
- {
- if ( (lev->flags & X509_V_FLAG_INHIBIT_MAP)
- || !(node->data->flags & POLICY_DATA_FLAG_MAP_MASK))
- BIO_puts(err, " Not Mapped\n");
- else
- {
- int i;
- STACK_OF(ASN1_OBJECT) *pset = node->data->expected_policy_set;
- ASN1_OBJECT *oid;
- BIO_puts(err, " Expected: ");
- for (i = 0; i < sk_ASN1_OBJECT_num(pset); i++)
- {
- oid = sk_ASN1_OBJECT_value(pset, i);
- if (i)
- BIO_puts(err, ", ");
- i2a_ASN1_OBJECT(err, oid);
- }
- BIO_puts(err, "\n");
- }
- }
+ X509_POLICY_NODE *node, int indent)
+{
+ if ((lev->flags & X509_V_FLAG_INHIBIT_MAP)
+ || !(node->data->flags & POLICY_DATA_FLAG_MAP_MASK))
+ BIO_puts(err, " Not Mapped\n");
+ else {
+ int i;
+ STACK_OF(ASN1_OBJECT) *pset = node->data->expected_policy_set;
+ ASN1_OBJECT *oid;
+ BIO_puts(err, " Expected: ");
+ for (i = 0; i < sk_ASN1_OBJECT_num(pset); i++) {
+ oid = sk_ASN1_OBJECT_value(pset, i);
+ if (i)
+ BIO_puts(err, ", ");
+ i2a_ASN1_OBJECT(err, oid);
+ }
+ BIO_puts(err, "\n");
+ }
+}
static void tree_print(char *str, X509_POLICY_TREE *tree,
- X509_POLICY_LEVEL *curr)
- {
- X509_POLICY_LEVEL *plev;
- X509_POLICY_NODE *node;
- int i;
- BIO *err;
- err = BIO_new_fp(stderr, BIO_NOCLOSE);
- if (!curr)
- curr = tree->levels + tree->nlevel;
- else
- curr++;
- BIO_printf(err, "Level print after %s\n", str);
- BIO_printf(err, "Printing Up to Level %ld\n", curr - tree->levels);
- for (plev = tree->levels; plev != curr; plev++)
- {
- BIO_printf(err, "Level %ld, flags = %x\n",
- plev - tree->levels, plev->flags);
- for (i = 0; i < sk_X509_POLICY_NODE_num(plev->nodes); i++)
- {
- node = sk_X509_POLICY_NODE_value(plev->nodes, i);
- X509_POLICY_NODE_print(err, node, 2);
- expected_print(err, plev, node, 2);
- BIO_printf(err, " Flags: %x\n", node->data->flags);
- }
- if (plev->anyPolicy)
- X509_POLICY_NODE_print(err, plev->anyPolicy, 2);
- }
-
- BIO_free(err);
-
- }
+ X509_POLICY_LEVEL *curr)
+{
+ X509_POLICY_LEVEL *plev;
+ X509_POLICY_NODE *node;
+ int i;
+ BIO *err;
+ err = BIO_new_fp(stderr, BIO_NOCLOSE);
+ if (!curr)
+ curr = tree->levels + tree->nlevel;
+ else
+ curr++;
+ BIO_printf(err, "Level print after %s\n", str);
+ BIO_printf(err, "Printing Up to Level %ld\n", curr - tree->levels);
+ for (plev = tree->levels; plev != curr; plev++) {
+ BIO_printf(err, "Level %ld, flags = %x\n",
+ plev - tree->levels, plev->flags);
+ for (i = 0; i < sk_X509_POLICY_NODE_num(plev->nodes); i++) {
+ node = sk_X509_POLICY_NODE_value(plev->nodes, i);
+ X509_POLICY_NODE_print(err, node, 2);
+ expected_print(err, plev, node, 2);
+ BIO_printf(err, " Flags: %x\n", node->data->flags);
+ }
+ if (plev->anyPolicy)
+ X509_POLICY_NODE_print(err, plev->anyPolicy, 2);
+ }
+
+ BIO_free(err);
+
+}
#else
-#define tree_print(a,b,c) /* */
+# define tree_print(a,b,c) /* */
#endif
-/* Initialize policy tree. Return values:
- * 0 Some internal error occured.
- * -1 Inconsistent or invalid extensions in certificates.
- * 1 Tree initialized OK.
- * 2 Policy tree is empty.
- * 5 Tree OK and requireExplicitPolicy true.
- * 6 Tree empty and requireExplicitPolicy true.
+/*
+ * Initialize policy tree. Return values: 0 Some internal error occured. -1
+ * Inconsistent or invalid extensions in certificates. 1 Tree initialized
+ * OK. 2 Policy tree is empty. 5 Tree OK and requireExplicitPolicy true. 6
+ * Tree empty and requireExplicitPolicy true.
*/
static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
- unsigned int flags)
- {
- X509_POLICY_TREE *tree;
- X509_POLICY_LEVEL *level;
- const X509_POLICY_CACHE *cache;
- X509_POLICY_DATA *data = NULL;
- X509 *x;
- int ret = 1;
- int i, n;
- int explicit_policy;
- int any_skip;
- int map_skip;
- *ptree = NULL;
- n = sk_X509_num(certs);
+ unsigned int flags)
+{
+ X509_POLICY_TREE *tree;
+ X509_POLICY_LEVEL *level;
+ const X509_POLICY_CACHE *cache;
+ X509_POLICY_DATA *data = NULL;
+ X509 *x;
+ int ret = 1;
+ int i, n;
+ int explicit_policy;
+ int any_skip;
+ int map_skip;
+ *ptree = NULL;
+ n = sk_X509_num(certs);
#if 0
- /* Disable policy mapping for now... */
- flags |= X509_V_FLAG_INHIBIT_MAP;
+ /* Disable policy mapping for now... */
+ flags |= X509_V_FLAG_INHIBIT_MAP;
#endif
- if (flags & X509_V_FLAG_EXPLICIT_POLICY)
- explicit_policy = 0;
- else
- explicit_policy = n + 1;
-
- if (flags & X509_V_FLAG_INHIBIT_ANY)
- any_skip = 0;
- else
- any_skip = n + 1;
-
- if (flags & X509_V_FLAG_INHIBIT_MAP)
- map_skip = 0;
- else
- map_skip = n + 1;
-
- /* Can't do anything with just a trust anchor */
- if (n == 1)
- return 1;
- /* First setup policy cache in all certificates apart from the
- * trust anchor. Note any bad cache results on the way. Also can
- * calculate explicit_policy value at this point.
- */
- for (i = n - 2; i >= 0; i--)
- {
- x = sk_X509_value(certs, i);
- X509_check_purpose(x, -1, -1);
- cache = policy_cache_set(x);
- /* If cache NULL something bad happened: return immediately */
- if (cache == NULL)
- return 0;
- /* If inconsistent extensions keep a note of it but continue */
- if (x->ex_flags & EXFLAG_INVALID_POLICY)
- ret = -1;
- /* Otherwise if we have no data (hence no CertificatePolicies)
- * and haven't already set an inconsistent code note it.
- */
- else if ((ret == 1) && !cache->data)
- ret = 2;
- if (explicit_policy > 0)
- {
- if (!(x->ex_flags & EXFLAG_SI))
- explicit_policy--;
- if ((cache->explicit_skip != -1)
- && (cache->explicit_skip < explicit_policy))
- explicit_policy = cache->explicit_skip;
- }
- }
-
- if (ret != 1)
- {
- if (ret == 2 && !explicit_policy)
- return 6;
- return ret;
- }
-
-
- /* If we get this far initialize the tree */
-
- tree = OPENSSL_malloc(sizeof(X509_POLICY_TREE));
-
- if (!tree)
- return 0;
-
- tree->flags = 0;
- tree->levels = OPENSSL_malloc(sizeof(X509_POLICY_LEVEL) * n);
- tree->nlevel = 0;
- tree->extra_data = NULL;
- tree->auth_policies = NULL;
- tree->user_policies = NULL;
-
- if (!tree->levels)
- {
- OPENSSL_free(tree);
- return 0;
- }
-
- memset(tree->levels, 0, n * sizeof(X509_POLICY_LEVEL));
-
- tree->nlevel = n;
-
- level = tree->levels;
-
- /* Root data: initialize to anyPolicy */
-
- data = policy_data_new(NULL, OBJ_nid2obj(NID_any_policy), 0);
-
- if (!data || !level_add_node(level, data, NULL, tree))
- goto bad_tree;
-
- for (i = n - 2; i >= 0; i--)
- {
- level++;
- x = sk_X509_value(certs, i);
- cache = policy_cache_set(x);
- level->cert = X509_up_ref(x);
-
- if (!cache->anyPolicy)
- level->flags |= X509_V_FLAG_INHIBIT_ANY;
-
- /* Determine inhibit any and inhibit map flags */
- if (any_skip == 0)
- {
- /* Any matching allowed if certificate is self
- * issued and not the last in the chain.
- */
- if (!(x->ex_flags & EXFLAG_SI) || (i == 0))
- level->flags |= X509_V_FLAG_INHIBIT_ANY;
- }
- else
- {
- if (!(x->ex_flags & EXFLAG_SI))
- any_skip--;
- if ((cache->any_skip >= 0)
- && (cache->any_skip < any_skip))
- any_skip = cache->any_skip;
- }
-
- if (map_skip == 0)
- level->flags |= X509_V_FLAG_INHIBIT_MAP;
- else
- {
- if (!(x->ex_flags & EXFLAG_SI))
- map_skip--;
- if ((cache->map_skip >= 0)
- && (cache->map_skip < map_skip))
- map_skip = cache->map_skip;
- }
-
- }
-
- *ptree = tree;
-
- if (explicit_policy)
- return 1;
- else
- return 5;
-
- bad_tree:
-
- X509_policy_tree_free(tree);
-
- return 0;
-
- }
+ if (flags & X509_V_FLAG_EXPLICIT_POLICY)
+ explicit_policy = 0;
+ else
+ explicit_policy = n + 1;
+
+ if (flags & X509_V_FLAG_INHIBIT_ANY)
+ any_skip = 0;
+ else
+ any_skip = n + 1;
+
+ if (flags & X509_V_FLAG_INHIBIT_MAP)
+ map_skip = 0;
+ else
+ map_skip = n + 1;
+
+ /* Can't do anything with just a trust anchor */
+ if (n == 1)
+ return 1;
+ /*
+ * First setup policy cache in all certificates apart from the trust
+ * anchor. Note any bad cache results on the way. Also can calculate
+ * explicit_policy value at this point.
+ */
+ for (i = n - 2; i >= 0; i--) {
+ x = sk_X509_value(certs, i);
+ X509_check_purpose(x, -1, -1);
+ cache = policy_cache_set(x);
+ /* If cache NULL something bad happened: return immediately */
+ if (cache == NULL)
+ return 0;
+ /*
+ * If inconsistent extensions keep a note of it but continue
+ */
+ if (x->ex_flags & EXFLAG_INVALID_POLICY)
+ ret = -1;
+ /*
+ * Otherwise if we have no data (hence no CertificatePolicies) and
+ * haven't already set an inconsistent code note it.
+ */
+ else if ((ret == 1) && !cache->data)
+ ret = 2;
+ if (explicit_policy > 0) {
+ if (!(x->ex_flags & EXFLAG_SI))
+ explicit_policy--;
+ if ((cache->explicit_skip != -1)
+ && (cache->explicit_skip < explicit_policy))
+ explicit_policy = cache->explicit_skip;
+ }
+ }
+
+ if (ret != 1) {
+ if (ret == 2 && !explicit_policy)
+ return 6;
+ return ret;
+ }
+
+ /* If we get this far initialize the tree */
+
+ tree = OPENSSL_malloc(sizeof(X509_POLICY_TREE));
+
+ if (!tree)
+ return 0;
+
+ tree->flags = 0;
+ tree->levels = OPENSSL_malloc(sizeof(X509_POLICY_LEVEL) * n);
+ tree->nlevel = 0;
+ tree->extra_data = NULL;
+ tree->auth_policies = NULL;
+ tree->user_policies = NULL;
+
+ if (!tree->levels) {
+ OPENSSL_free(tree);
+ return 0;
+ }
+
+ memset(tree->levels, 0, n * sizeof(X509_POLICY_LEVEL));
+
+ tree->nlevel = n;
+
+ level = tree->levels;
+
+ /* Root data: initialize to anyPolicy */
+
+ data = policy_data_new(NULL, OBJ_nid2obj(NID_any_policy), 0);
+
+ if (!data || !level_add_node(level, data, NULL, tree))
+ goto bad_tree;
+
+ for (i = n - 2; i >= 0; i--) {
+ level++;
+ x = sk_X509_value(certs, i);
+ cache = policy_cache_set(x);
+ level->cert = X509_up_ref(x);
+
+ if (!cache->anyPolicy)
+ level->flags |= X509_V_FLAG_INHIBIT_ANY;
+
+ /* Determine inhibit any and inhibit map flags */
+ if (any_skip == 0) {
+ /*
+ * Any matching allowed if certificate is self issued and not the
+ * last in the chain.
+ */
+ if (!(x->ex_flags & EXFLAG_SI) || (i == 0))
+ level->flags |= X509_V_FLAG_INHIBIT_ANY;
+ } else {
+ if (!(x->ex_flags & EXFLAG_SI))
+ any_skip--;
+ if ((cache->any_skip >= 0)
+ && (cache->any_skip < any_skip))
+ any_skip = cache->any_skip;
+ }
+
+ if (map_skip == 0)
+ level->flags |= X509_V_FLAG_INHIBIT_MAP;
+ else {
+ if (!(x->ex_flags & EXFLAG_SI))
+ map_skip--;
+ if ((cache->map_skip >= 0)
+ && (cache->map_skip < map_skip))
+ map_skip = cache->map_skip;
+ }
+
+ }
+
+ *ptree = tree;
+
+ if (explicit_policy)
+ return 1;
+ else
+ return 5;
+
+ bad_tree:
+
+ X509_policy_tree_free(tree);
+
+ return 0;
+
+}
static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr,
- const X509_POLICY_DATA *data)
- {
- X509_POLICY_LEVEL *last = curr - 1;
- X509_POLICY_NODE *node;
- int matched = 0;
- size_t i;
- /* Iterate through all in nodes linking matches */
- for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++)
- {
- node = sk_X509_POLICY_NODE_value(last->nodes, i);
- if (policy_node_match(last, node, data->valid_policy))
- {
- if (!level_add_node(curr, data, node, NULL))
- return 0;
- matched = 1;
- }
- }
- if (!matched && last->anyPolicy)
- {
- if (!level_add_node(curr, data, last->anyPolicy, NULL))
- return 0;
- }
- return 1;
- }
-
-/* This corresponds to RFC3280 6.1.3(d)(1):
- * link any data from CertificatePolicies onto matching parent
- * or anyPolicy if no match.
+ const X509_POLICY_DATA *data)
+{
+ X509_POLICY_LEVEL *last = curr - 1;
+ X509_POLICY_NODE *node;
+ int matched = 0;
+ size_t i;
+ /* Iterate through all in nodes linking matches */
+ for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) {
+ node = sk_X509_POLICY_NODE_value(last->nodes, i);
+ if (policy_node_match(last, node, data->valid_policy)) {
+ if (!level_add_node(curr, data, node, NULL))
+ return 0;
+ matched = 1;
+ }
+ }
+ if (!matched && last->anyPolicy) {
+ if (!level_add_node(curr, data, last->anyPolicy, NULL))
+ return 0;
+ }
+ return 1;
+}
+
+/*
+ * This corresponds to RFC3280 6.1.3(d)(1): link any data from
+ * CertificatePolicies onto matching parent or anyPolicy if no match.
*/
static int tree_link_nodes(X509_POLICY_LEVEL *curr,
- const X509_POLICY_CACHE *cache)
- {
- size_t i;
- X509_POLICY_DATA *data;
-
- for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++)
- {
- data = sk_X509_POLICY_DATA_value(cache->data, i);
- /* If a node is mapped any it doesn't have a corresponding
- * CertificatePolicies entry.
- * However such an identical node would be created
- * if anyPolicy matching is enabled because there would be
- * no match with the parent valid_policy_set. So we create
- * link because then it will have the mapping flags
- * right and we can prune it later.
- */
+ const X509_POLICY_CACHE *cache)
+{
+ size_t i;
+ X509_POLICY_DATA *data;
+
+ for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++) {
+ data = sk_X509_POLICY_DATA_value(cache->data, i);
+ /*
+ * If a node is mapped any it doesn't have a corresponding
+ * CertificatePolicies entry. However such an identical node would
+ * be created if anyPolicy matching is enabled because there would be
+ * no match with the parent valid_policy_set. So we create link
+ * because then it will have the mapping flags right and we can prune
+ * it later.
+ */
#if 0
- if ((data->flags & POLICY_DATA_FLAG_MAPPED_ANY)
- && !(curr->flags & X509_V_FLAG_INHIBIT_ANY))
- continue;
+ if ((data->flags & POLICY_DATA_FLAG_MAPPED_ANY)
+ && !(curr->flags & X509_V_FLAG_INHIBIT_ANY))
+ continue;
#endif
- /* Look for matching nodes in previous level */
- if (!tree_link_matching_nodes(curr, data))
- return 0;
- }
- return 1;
- }
-
-/* This corresponds to RFC3280 6.1.3(d)(2):
- * Create new data for any unmatched policies in the parent and link
- * to anyPolicy.
+ /* Look for matching nodes in previous level */
+ if (!tree_link_matching_nodes(curr, data))
+ return 0;
+ }
+ return 1;
+}
+
+/*
+ * This corresponds to RFC3280 6.1.3(d)(2): Create new data for any unmatched
+ * policies in the parent and link to anyPolicy.
*/
static int tree_add_unmatched(X509_POLICY_LEVEL *curr,
- const X509_POLICY_CACHE *cache,
- const ASN1_OBJECT *id,
- X509_POLICY_NODE *node,
- X509_POLICY_TREE *tree)
- {
- X509_POLICY_DATA *data;
- if (id == NULL)
- id = node->data->valid_policy;
- /* Create a new node with qualifiers from anyPolicy and
- * id from unmatched node.
- */
- data = policy_data_new(NULL, id, node_critical(node));
-
- if (data == NULL)
- return 0;
- /* Curr may not have anyPolicy */
- data->qualifier_set = cache->anyPolicy->qualifier_set;
- data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
- if (!level_add_node(curr, data, node, tree))
- {
- policy_data_free(data);
- return 0;
- }
-
- return 1;
- }
+ const X509_POLICY_CACHE *cache,
+ const ASN1_OBJECT *id,
+ X509_POLICY_NODE *node, X509_POLICY_TREE *tree)
+{
+ X509_POLICY_DATA *data;
+ if (id == NULL)
+ id = node->data->valid_policy;
+ /*
+ * Create a new node with qualifiers from anyPolicy and id from unmatched
+ * node.
+ */
+ data = policy_data_new(NULL, id, node_critical(node));
+
+ if (data == NULL)
+ return 0;
+ /* Curr may not have anyPolicy */
+ data->qualifier_set = cache->anyPolicy->qualifier_set;
+ data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
+ if (!level_add_node(curr, data, node, tree)) {
+ policy_data_free(data);
+ return 0;
+ }
+
+ return 1;
+}
static int tree_link_unmatched(X509_POLICY_LEVEL *curr,
- const X509_POLICY_CACHE *cache,
- X509_POLICY_NODE *node,
- X509_POLICY_TREE *tree)
- {
- const X509_POLICY_LEVEL *last = curr - 1;
- size_t i;
-
- if ( (last->flags & X509_V_FLAG_INHIBIT_MAP)
- || !(node->data->flags & POLICY_DATA_FLAG_MAPPED))
- {
- /* If no policy mapping: matched if one child present */
- if (node->nchild)
- return 1;
- if (!tree_add_unmatched(curr, cache, NULL, node, tree))
- return 0;
- /* Add it */
- }
- else
- {
- /* If mapping: matched if one child per expected policy set */
- STACK_OF(ASN1_OBJECT) *expset = node->data->expected_policy_set;
- 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++)
- {
- ASN1_OBJECT *oid = sk_ASN1_OBJECT_value(expset, i);
- if (level_find_node(curr, node, oid))
- continue;
- if (!tree_add_unmatched(curr, cache, oid, node, tree))
- return 0;
- }
-
- }
-
- return 1;
-
- }
+ const X509_POLICY_CACHE *cache,
+ X509_POLICY_NODE *node, X509_POLICY_TREE *tree)
+{
+ const X509_POLICY_LEVEL *last = curr - 1;
+ size_t i;
+
+ if ((last->flags & X509_V_FLAG_INHIBIT_MAP)
+ || !(node->data->flags & POLICY_DATA_FLAG_MAPPED)) {
+ /* If no policy mapping: matched if one child present */
+ if (node->nchild)
+ return 1;
+ if (!tree_add_unmatched(curr, cache, NULL, node, tree))
+ return 0;
+ /* Add it */
+ } else {
+ /* If mapping: matched if one child per expected policy set */
+ STACK_OF(ASN1_OBJECT) *expset = node->data->expected_policy_set;
+ 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++) {
+ ASN1_OBJECT *oid = sk_ASN1_OBJECT_value(expset, i);
+ if (level_find_node(curr, node, oid))
+ continue;
+ if (!tree_add_unmatched(curr, cache, oid, node, tree))
+ return 0;
+ }
+
+ }
+
+ return 1;
+
+}
static int tree_link_any(X509_POLICY_LEVEL *curr,
- const X509_POLICY_CACHE *cache,
- X509_POLICY_TREE *tree)
- {
- size_t i;
- /*X509_POLICY_DATA *data;*/
- X509_POLICY_NODE *node;
- X509_POLICY_LEVEL *last = curr - 1;
-
- for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++)
- {
- node = sk_X509_POLICY_NODE_value(last->nodes, i);
-
- if (!tree_link_unmatched(curr, cache, node, tree))
- return 0;
+ const X509_POLICY_CACHE *cache,
+ X509_POLICY_TREE *tree)
+{
+ size_t i;
+ /*
+ * X509_POLICY_DATA *data;
+ */
+ X509_POLICY_NODE *node;
+ X509_POLICY_LEVEL *last = curr - 1;
+
+ for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) {
+ node = sk_X509_POLICY_NODE_value(last->nodes, i);
+
+ if (!tree_link_unmatched(curr, cache, node, tree))
+ return 0;
#if 0
- /* Skip any node with any children: we only want unmathced
- * nodes.
- *
- * Note: need something better for policy mapping
- * because each node may have multiple children
- */
- if (node->nchild)
- continue;
-
- /* Create a new node with qualifiers from anyPolicy and
- * id from unmatched node.
- */
- data = policy_data_new(NULL, node->data->valid_policy,
- node_critical(node));
-
- if (data == NULL)
- return 0;
- /* Curr may not have anyPolicy */
- data->qualifier_set = cache->anyPolicy->qualifier_set;
- data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
- if (!level_add_node(curr, data, node, tree))
- {
- policy_data_free(data);
- return 0;
- }
-
+ /*
+ * Skip any node with any children: we only want unmathced nodes.
+ * Note: need something better for policy mapping because each node
+ * may have multiple children
+ */
+ if (node->nchild)
+ continue;
+
+ /*
+ * Create a new node with qualifiers from anyPolicy and id from
+ * unmatched node.
+ */
+ data = policy_data_new(NULL, node->data->valid_policy,
+ node_critical(node));
+
+ if (data == NULL)
+ return 0;
+ /* Curr may not have anyPolicy */
+ data->qualifier_set = cache->anyPolicy->qualifier_set;
+ data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
+ if (!level_add_node(curr, data, node, tree)) {
+ policy_data_free(data);
+ return 0;
+ }
#endif
- }
- /* Finally add link to anyPolicy */
- if (last->anyPolicy)
- {
- if (!level_add_node(curr, cache->anyPolicy,
- last->anyPolicy, NULL))
- return 0;
- }
- return 1;
- }
-
-/* Prune the tree: delete any child mapped child data on the current level
+ }
+ /* Finally add link to anyPolicy */
+ if (last->anyPolicy) {
+ if (!level_add_node(curr, cache->anyPolicy, last->anyPolicy, NULL))
+ return 0;
+ }
+ return 1;
+}
+
+/*
+ * Prune the tree: delete any child mapped child data on the current level
* then proceed up the tree deleting any data with no children. If we ever
* have no data on a level we can halt because the tree will be empty.
*/
static int tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr)
- {
- STACK_OF(X509_POLICY_NODE) *nodes;
- X509_POLICY_NODE *node;
- int i;
- nodes = curr->nodes;
- if (curr->flags & X509_V_FLAG_INHIBIT_MAP)
- {
- for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--)
- {
- node = sk_X509_POLICY_NODE_value(nodes, i);
- /* Delete any mapped data: see RFC3280 XXXX */
- if (node->data->flags & POLICY_DATA_FLAG_MAP_MASK)
- {
- node->parent->nchild--;
- OPENSSL_free(node);
- (void)sk_X509_POLICY_NODE_delete(nodes,i);
- }
- }
- }
-
- for(;;) {
- --curr;
- nodes = curr->nodes;
- for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--)
- {
- node = sk_X509_POLICY_NODE_value(nodes, i);
- if (node->nchild == 0)
- {
- node->parent->nchild--;
- OPENSSL_free(node);
- (void)sk_X509_POLICY_NODE_delete(nodes, i);
- }
- }
- if (curr->anyPolicy && !curr->anyPolicy->nchild)
- {
- if (curr->anyPolicy->parent)
- curr->anyPolicy->parent->nchild--;
- OPENSSL_free(curr->anyPolicy);
- curr->anyPolicy = NULL;
- }
- if (curr == tree->levels)
- {
- /* If we zapped anyPolicy at top then tree is empty */
- if (!curr->anyPolicy)
- return 2;
- return 1;
- }
- }
-
- }
+{
+ STACK_OF(X509_POLICY_NODE) *nodes;
+ X509_POLICY_NODE *node;
+ int i;
+ nodes = curr->nodes;
+ if (curr->flags & X509_V_FLAG_INHIBIT_MAP) {
+ for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) {
+ node = sk_X509_POLICY_NODE_value(nodes, i);
+ /* Delete any mapped data: see RFC3280 XXXX */
+ if (node->data->flags & POLICY_DATA_FLAG_MAP_MASK) {
+ node->parent->nchild--;
+ OPENSSL_free(node);
+ (void)sk_X509_POLICY_NODE_delete(nodes, i);
+ }
+ }
+ }
+
+ for (;;) {
+ --curr;
+ nodes = curr->nodes;
+ for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) {
+ node = sk_X509_POLICY_NODE_value(nodes, i);
+ if (node->nchild == 0) {
+ node->parent->nchild--;
+ OPENSSL_free(node);
+ (void)sk_X509_POLICY_NODE_delete(nodes, i);
+ }
+ }
+ if (curr->anyPolicy && !curr->anyPolicy->nchild) {
+ if (curr->anyPolicy->parent)
+ curr->anyPolicy->parent->nchild--;
+ OPENSSL_free(curr->anyPolicy);
+ curr->anyPolicy = NULL;
+ }
+ if (curr == tree->levels) {
+ /* If we zapped anyPolicy at top then tree is empty */
+ if (!curr->anyPolicy)
+ return 2;
+ return 1;
+ }
+ }
+
+}
static int tree_add_auth_node(STACK_OF(X509_POLICY_NODE) **pnodes,
- X509_POLICY_NODE *pcy)
- {
- if (!*pnodes)
- {
- *pnodes = policy_node_cmp_new();
- if (!*pnodes)
- return 0;
- }
- else if (sk_X509_POLICY_NODE_find(*pnodes, NULL, pcy))
- return 1;
-
- if (!sk_X509_POLICY_NODE_push(*pnodes, pcy))
- return 0;
-
- return 1;
-
- }
-
-/* Calculate the authority set based on policy tree.
- * The 'pnodes' parameter is used as a store for the set of policy nodes
- * used to calculate the user set. If the authority set is not anyPolicy
- * then pnodes will just point to the authority set. If however the authority
- * set is anyPolicy then the set of valid policies (other than anyPolicy)
- * is store in pnodes. The return value of '2' is used in this case to indicate
- * that pnodes should be freed.
+ X509_POLICY_NODE *pcy)
+{
+ if (!*pnodes) {
+ *pnodes = policy_node_cmp_new();
+ if (!*pnodes)
+ return 0;
+ } else if (sk_X509_POLICY_NODE_find(*pnodes, NULL, pcy))
+ return 1;
+
+ if (!sk_X509_POLICY_NODE_push(*pnodes, pcy))
+ return 0;
+
+ return 1;
+
+}
+
+/*
+ * Calculate the authority set based on policy tree. The 'pnodes' parameter
+ * is used as a store for the set of policy nodes used to calculate the user
+ * set. If the authority set is not anyPolicy then pnodes will just point to
+ * the authority set. If however the authority set is anyPolicy then the set
+ * of valid policies (other than anyPolicy) is store in pnodes. The return
+ * value of '2' is used in this case to indicate that pnodes should be freed.
*/
static int tree_calculate_authority_set(X509_POLICY_TREE *tree,
- STACK_OF(X509_POLICY_NODE) **pnodes)
- {
- X509_POLICY_LEVEL *curr;
- X509_POLICY_NODE *node, *anyptr;
- STACK_OF(X509_POLICY_NODE) **addnodes;
- int i;
- size_t j;
- curr = tree->levels + tree->nlevel - 1;
-
- /* If last level contains anyPolicy set is anyPolicy */
- if (curr->anyPolicy)
- {
- if (!tree_add_auth_node(&tree->auth_policies, curr->anyPolicy))
- return 0;
- addnodes = pnodes;
- }
- else
- /* Add policies to authority set */
- addnodes = &tree->auth_policies;
-
- curr = tree->levels;
- for (i = 1; i < tree->nlevel; i++)
- {
- /* If no anyPolicy node on this this level it can't
- * appear on lower levels so end search.
- */
- if (!(anyptr = curr->anyPolicy))
- break;
- curr++;
- for (j = 0; j < sk_X509_POLICY_NODE_num(curr->nodes); j++)
- {
- node = sk_X509_POLICY_NODE_value(curr->nodes, j);
- if ((node->parent == anyptr)
- && !tree_add_auth_node(addnodes, node))
- return 0;
- }
- }
-
- if (addnodes == pnodes)
- return 2;
-
- *pnodes = tree->auth_policies;
-
- return 1;
- }
+ STACK_OF(X509_POLICY_NODE) **pnodes)
+{
+ X509_POLICY_LEVEL *curr;
+ X509_POLICY_NODE *node, *anyptr;
+ STACK_OF(X509_POLICY_NODE) **addnodes;
+ int i;
+ size_t j;
+ curr = tree->levels + tree->nlevel - 1;
+
+ /* If last level contains anyPolicy set is anyPolicy */
+ if (curr->anyPolicy) {
+ if (!tree_add_auth_node(&tree->auth_policies, curr->anyPolicy))
+ return 0;
+ addnodes = pnodes;
+ } else
+ /* Add policies to authority set */
+ addnodes = &tree->auth_policies;
+
+ curr = tree->levels;
+ for (i = 1; i < tree->nlevel; i++) {
+ /*
+ * If no anyPolicy node on this this level it can't appear on lower
+ * levels so end search.
+ */
+ if (!(anyptr = curr->anyPolicy))
+ break;
+ curr++;
+ for (j = 0; j < sk_X509_POLICY_NODE_num(curr->nodes); j++) {
+ node = sk_X509_POLICY_NODE_value(curr->nodes, j);
+ if ((node->parent == anyptr)
+ && !tree_add_auth_node(addnodes, node))
+ return 0;
+ }
+ }
+
+ if (addnodes == pnodes)
+ return 2;
+
+ *pnodes = tree->auth_policies;
+
+ return 1;
+}
static int tree_calculate_user_set(X509_POLICY_TREE *tree,
- STACK_OF(ASN1_OBJECT) *policy_oids,
- STACK_OF(X509_POLICY_NODE) *auth_nodes)
- {
- size_t i;
- X509_POLICY_NODE *node;
- ASN1_OBJECT *oid;
-
- X509_POLICY_NODE *anyPolicy;
- X509_POLICY_DATA *extra;
-
- /* Check if anyPolicy present in authority constrained policy set:
- * this will happen if it is a leaf node.
- */
-
- if (sk_ASN1_OBJECT_num(policy_oids) <= 0)
- return 1;
-
- anyPolicy = tree->levels[tree->nlevel - 1].anyPolicy;
-
- for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++)
- {
- oid = sk_ASN1_OBJECT_value(policy_oids, i);
- if (OBJ_obj2nid(oid) == NID_any_policy)
- {
- tree->flags |= POLICY_FLAG_ANY_POLICY;
- return 1;
- }
- }
-
- for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++)
- {
- oid = sk_ASN1_OBJECT_value(policy_oids, i);
- node = tree_find_sk(auth_nodes, oid);
- if (!node)
- {
- if (!anyPolicy)
- continue;
- /* Create a new node with policy ID from user set
- * and qualifiers from anyPolicy.
- */
- extra = policy_data_new(NULL, oid,
- node_critical(anyPolicy));
- if (!extra)
- return 0;
- extra->qualifier_set = anyPolicy->data->qualifier_set;
- extra->flags = POLICY_DATA_FLAG_SHARED_QUALIFIERS
- | POLICY_DATA_FLAG_EXTRA_NODE;
- node = level_add_node(NULL, extra, anyPolicy->parent,
- tree);
- }
- if (!tree->user_policies)
- {
- tree->user_policies = sk_X509_POLICY_NODE_new_null();
- if (!tree->user_policies)
- return 1;
- }
- if (!sk_X509_POLICY_NODE_push(tree->user_policies, node))
- return 0;
- }
- return 1;
-
- }
+ STACK_OF(ASN1_OBJECT) *policy_oids,
+ STACK_OF(X509_POLICY_NODE) *auth_nodes)
+{
+ size_t i;
+ X509_POLICY_NODE *node;
+ ASN1_OBJECT *oid;
+
+ X509_POLICY_NODE *anyPolicy;
+ X509_POLICY_DATA *extra;
+
+ /*
+ * Check if anyPolicy present in authority constrained policy set: this
+ * will happen if it is a leaf node.
+ */
+
+ if (sk_ASN1_OBJECT_num(policy_oids) <= 0)
+ return 1;
+
+ anyPolicy = tree->levels[tree->nlevel - 1].anyPolicy;
+
+ for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) {
+ oid = sk_ASN1_OBJECT_value(policy_oids, i);
+ if (OBJ_obj2nid(oid) == NID_any_policy) {
+ tree->flags |= POLICY_FLAG_ANY_POLICY;
+ return 1;
+ }
+ }
+
+ for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) {
+ oid = sk_ASN1_OBJECT_value(policy_oids, i);
+ node = tree_find_sk(auth_nodes, oid);
+ if (!node) {
+ if (!anyPolicy)
+ continue;
+ /*
+ * Create a new node with policy ID from user set and qualifiers
+ * from anyPolicy.
+ */
+ extra = policy_data_new(NULL, oid, node_critical(anyPolicy));
+ if (!extra)
+ return 0;
+ extra->qualifier_set = anyPolicy->data->qualifier_set;
+ extra->flags = POLICY_DATA_FLAG_SHARED_QUALIFIERS
+ | POLICY_DATA_FLAG_EXTRA_NODE;
+ node = level_add_node(NULL, extra, anyPolicy->parent, tree);
+ }
+ if (!tree->user_policies) {
+ tree->user_policies = sk_X509_POLICY_NODE_new_null();
+ if (!tree->user_policies)
+ return 1;
+ }
+ if (!sk_X509_POLICY_NODE_push(tree->user_policies, node))
+ return 0;
+ }
+ return 1;
+
+}
static int tree_evaluate(X509_POLICY_TREE *tree)
- {
- int ret, i;
- X509_POLICY_LEVEL *curr = tree->levels + 1;
- const X509_POLICY_CACHE *cache;
-
- for(i = 1; i < tree->nlevel; i++, curr++)
- {
- cache = policy_cache_set(curr->cert);
- if (!tree_link_nodes(curr, cache))
- return 0;
-
- if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY)
- && !tree_link_any(curr, cache, tree))
- return 0;
- tree_print("before tree_prune()", tree, curr);
- ret = tree_prune(tree, curr);
- if (ret != 1)
- return ret;
- }
-
- return 1;
-
- }
+{
+ int ret, i;
+ X509_POLICY_LEVEL *curr = tree->levels + 1;
+ const X509_POLICY_CACHE *cache;
-static void exnode_free(X509_POLICY_NODE *node)
- {
- if (node->data && (node->data->flags & POLICY_DATA_FLAG_EXTRA_NODE))
- OPENSSL_free(node);
- }
+ for (i = 1; i < tree->nlevel; i++, curr++) {
+ cache = policy_cache_set(curr->cert);
+ if (!tree_link_nodes(curr, cache))
+ return 0;
+
+ if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY)
+ && !tree_link_any(curr, cache, tree))
+ return 0;
+ tree_print("before tree_prune()", tree, curr);
+ ret = tree_prune(tree, curr);
+ if (ret != 1)
+ return ret;
+ }
+
+ return 1;
+}
+
+static void exnode_free(X509_POLICY_NODE *node)
+{
+ if (node->data && (node->data->flags & POLICY_DATA_FLAG_EXTRA_NODE))
+ OPENSSL_free(node);
+}
void X509_policy_tree_free(X509_POLICY_TREE *tree)
- {
- X509_POLICY_LEVEL *curr;
- int i;
-
- if (!tree)
- return;
-
- sk_X509_POLICY_NODE_free(tree->auth_policies);
- sk_X509_POLICY_NODE_pop_free(tree->user_policies, exnode_free);
-
- for(i = 0, curr = tree->levels; i < tree->nlevel; i++, curr++)
- {
- if (curr->cert)
- X509_free(curr->cert);
- if (curr->nodes)
- sk_X509_POLICY_NODE_pop_free(curr->nodes,
- policy_node_free);
- if (curr->anyPolicy)
- policy_node_free(curr->anyPolicy);
- }
-
- if (tree->extra_data)
- sk_X509_POLICY_DATA_pop_free(tree->extra_data,
- policy_data_free);
-
- OPENSSL_free(tree->levels);
- OPENSSL_free(tree);
-
- }
-
-/* Application policy checking function.
- * Return codes:
- * 0 Internal Error.
- * 1 Successful.
- * -1 One or more certificates contain invalid or inconsistent extensions
- * -2 User constrained policy set empty and requireExplicit true.
+{
+ X509_POLICY_LEVEL *curr;
+ int i;
+
+ if (!tree)
+ return;
+
+ sk_X509_POLICY_NODE_free(tree->auth_policies);
+ sk_X509_POLICY_NODE_pop_free(tree->user_policies, exnode_free);
+
+ for (i = 0, curr = tree->levels; i < tree->nlevel; i++, curr++) {
+ if (curr->cert)
+ X509_free(curr->cert);
+ if (curr->nodes)
+ sk_X509_POLICY_NODE_pop_free(curr->nodes, policy_node_free);
+ if (curr->anyPolicy)
+ policy_node_free(curr->anyPolicy);
+ }
+
+ if (tree->extra_data)
+ sk_X509_POLICY_DATA_pop_free(tree->extra_data, policy_data_free);
+
+ OPENSSL_free(tree->levels);
+ OPENSSL_free(tree);
+
+}
+
+/*
+ * Application policy checking function. Return codes: 0 Internal Error. 1
+ * Successful. -1 One or more certificates contain invalid or inconsistent
+ * extensions -2 User constrained policy set empty and requireExplicit true.
*/
int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
- STACK_OF(X509) *certs,
- STACK_OF(ASN1_OBJECT) *policy_oids,
- unsigned int flags)
- {
- int ret;
- X509_POLICY_TREE *tree = NULL;
- STACK_OF(X509_POLICY_NODE) *nodes, *auth_nodes = NULL;
- *ptree = NULL;
+ STACK_OF(X509) *certs,
+ STACK_OF(ASN1_OBJECT) *policy_oids, unsigned int flags)
+{
+ int ret;
+ X509_POLICY_TREE *tree = NULL;
+ STACK_OF(X509_POLICY_NODE) *nodes, *auth_nodes = NULL;
+ *ptree = NULL;
- *pexplicit_policy = 0;
- ret = tree_init(&tree, certs, flags);
+ *pexplicit_policy = 0;
+ ret = tree_init(&tree, certs, flags);
- switch (ret)
- {
+ switch (ret) {
- /* Tree empty requireExplicit False: OK */
- case 2:
- return 1;
+ /* Tree empty requireExplicit False: OK */
+ case 2:
+ return 1;
- /* Some internal error */
- case -1:
- return -1;
+ /* Some internal error */
+ case -1:
+ return -1;
- /* Some internal error */
- case 0:
- return 0;
+ /* Some internal error */
+ case 0:
+ return 0;
- /* Tree empty requireExplicit True: Error */
+ /* Tree empty requireExplicit True: Error */
- case 6:
- *pexplicit_policy = 1;
- return -2;
+ case 6:
+ *pexplicit_policy = 1;
+ return -2;
- /* Tree OK requireExplicit True: OK and continue */
- case 5:
- *pexplicit_policy = 1;
- break;
+ /* Tree OK requireExplicit True: OK and continue */
+ case 5:
+ *pexplicit_policy = 1;
+ break;
- /* Tree OK: continue */
+ /* Tree OK: continue */
- case 1:
- if (!tree)
- /*
- * tree_init() returns success and a null tree
- * if it's just looking at a trust anchor.
- * I'm not sure that returning success here is
- * correct, but I'm sure that reporting this
- * as an internal error which our caller
- * interprets as a malloc failure is wrong.
- */
- return 1;
- break;
- }
+ case 1:
+ if (!tree)
+ /*
+ * tree_init() returns success and a null tree
+ * if it's just looking at a trust anchor.
+ * I'm not sure that returning success here is
+ * correct, but I'm sure that reporting this
+ * as an internal error which our caller
+ * interprets as a malloc failure is wrong.
+ */
+ return 1;
+ break;
+ }
- if (!tree) goto error;
- ret = tree_evaluate(tree);
+ if (!tree)
+ goto error;
+ ret = tree_evaluate(tree);
- tree_print("tree_evaluate()", tree, NULL);
+ tree_print("tree_evaluate()", tree, NULL);
- if (ret <= 0)
- goto error;
+ if (ret <= 0)
+ goto error;
- /* Return value 2 means tree empty */
- if (ret == 2)
- {
- X509_policy_tree_free(tree);
- if (*pexplicit_policy)
- return -2;
- else
- return 1;
- }
+ /* Return value 2 means tree empty */
+ if (ret == 2) {
+ X509_policy_tree_free(tree);
+ if (*pexplicit_policy)
+ return -2;
+ else
+ return 1;
+ }
- /* Tree is not empty: continue */
+ /* Tree is not empty: continue */
- ret = tree_calculate_authority_set(tree, &auth_nodes);
+ ret = tree_calculate_authority_set(tree, &auth_nodes);
- if (!ret)
- goto error;
+ if (!ret)
+ goto error;
- if (!tree_calculate_user_set(tree, policy_oids, auth_nodes))
- goto error;
-
- if (ret == 2)
- sk_X509_POLICY_NODE_free(auth_nodes);
+ if (!tree_calculate_user_set(tree, policy_oids, auth_nodes))
+ goto error;
- if (tree)
- *ptree = tree;
+ if (ret == 2)
+ sk_X509_POLICY_NODE_free(auth_nodes);
- if (*pexplicit_policy)
- {
- nodes = X509_policy_tree_get0_user_policies(tree);
- if (sk_X509_POLICY_NODE_num(nodes) <= 0)
- return -2;
- }
+ if (tree)
+ *ptree = tree;
- return 1;
+ if (*pexplicit_policy) {
+ nodes = X509_policy_tree_get0_user_policies(tree);
+ if (sk_X509_POLICY_NODE_num(nodes) <= 0)
+ return -2;
+ }
- error:
+ return 1;
- X509_policy_tree_free(tree);
+ error:
- return 0;
+ X509_policy_tree_free(tree);
- }
+ return 0;
+}
diff --git a/src/crypto/x509v3/tab_test.c b/src/crypto/x509v3/tab_test.c
index c0e0cb61..19005474 100644
--- a/src/crypto/x509v3/tab_test.c
+++ b/src/crypto/x509v3/tab_test.c
@@ -1,6 +1,7 @@
/* tabtest.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
*/
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
@@ -10,7 +11,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -56,49 +57,52 @@
*
*/
-/* Simple program to check the ext_dat.h is correct and print out
- * problems if it is not.
+/*
+ * Simple program to check the ext_dat.h is correct and print out problems if
+ * it is not.
*/
#include <stdio.h>
#include <openssl/base.h>
#include <openssl/crypto.h>
+#include <openssl/obj.h>
#include <openssl/x509v3.h>
#if !defined(BORINGSSL_SHARED_LIBRARY)
-#include "ext_dat.h"
+# include "ext_dat.h"
#endif
int main(void)
{
#if !defined(BORINGSSL_SHARED_LIBRARY)
- unsigned i;
- int prev = -1, bad = 0;
- const X509V3_EXT_METHOD *const *tmp;
- CRYPTO_library_init();
- i = sizeof(standard_exts) / sizeof(X509V3_EXT_METHOD *);
- if(i != STANDARD_EXTENSION_COUNT)
- fprintf(stderr, "Extension number invalid expecting %d\n", i);
- tmp = standard_exts;
- for(i = 0; i < STANDARD_EXTENSION_COUNT; i++, tmp++) {
- if((*tmp)->ext_nid < prev) bad = 1;
- prev = (*tmp)->ext_nid;
-
- }
- if(bad) {
- 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));
- return 1;
- } else {
- printf("PASS\n");
- return 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 *);
+ if (i != STANDARD_EXTENSION_COUNT)
+ fprintf(stderr, "Extension number invalid expecting %d\n", i);
+ tmp = standard_exts;
+ for (i = 0; i < STANDARD_EXTENSION_COUNT; i++, tmp++) {
+ if ((*tmp)->ext_nid < prev)
+ bad = 1;
+ prev = (*tmp)->ext_nid;
+
+ }
+ if (bad) {
+ 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));
+ return 1;
+ } else {
+ printf("PASS\n");
+ return 0;
+ }
#else
- /* TODO(davidben): Fix this test in the shared library build. */
- printf("PASS\n");
- return 0;
+ /* TODO(davidben): Fix this test in the shared library build. */
+ printf("PASS\n");
+ return 0;
#endif
}
diff --git a/src/crypto/x509v3/v3_akey.c b/src/crypto/x509v3/v3_akey.c
index 9578a570..4503e615 100644
--- a/src/crypto/x509v3/v3_akey.c
+++ b/src/crypto/x509v3/v3_akey.c
@@ -1,6 +1,7 @@
/* v3_akey.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
*/
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
@@ -10,7 +11,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -65,148 +66,139 @@
#include <openssl/obj.h>
#include <openssl/x509v3.h>
-
static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
- AUTHORITY_KEYID *akeyid, STACK_OF(CONF_VALUE) *extlist);
+ AUTHORITY_KEYID *akeyid,
+ STACK_OF(CONF_VALUE)
+ *extlist);
static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
- X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values);
-
-const X509V3_EXT_METHOD v3_akey_id =
- {
- NID_authority_key_identifier,
- X509V3_EXT_MULTILINE, ASN1_ITEM_ref(AUTHORITY_KEYID),
- 0,0,0,0,
- 0,0,
- (X509V3_EXT_I2V)i2v_AUTHORITY_KEYID,
- (X509V3_EXT_V2I)v2i_AUTHORITY_KEYID,
- 0,0,
- NULL
- };
+ X509V3_CTX *ctx,
+ STACK_OF(CONF_VALUE) *values);
+
+const X509V3_EXT_METHOD v3_akey_id = {
+ NID_authority_key_identifier,
+ X509V3_EXT_MULTILINE, ASN1_ITEM_ref(AUTHORITY_KEYID),
+ 0, 0, 0, 0,
+ 0, 0,
+ (X509V3_EXT_I2V) i2v_AUTHORITY_KEYID,
+ (X509V3_EXT_V2I)v2i_AUTHORITY_KEYID,
+ 0, 0,
+ NULL
+};
static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
- AUTHORITY_KEYID *akeyid, STACK_OF(CONF_VALUE) *extlist)
+ AUTHORITY_KEYID *akeyid,
+ STACK_OF(CONF_VALUE)
+ *extlist)
{
- char *tmp;
- if(akeyid->keyid) {
- tmp = hex_to_string(akeyid->keyid->data, akeyid->keyid->length);
- X509V3_add_value("keyid", tmp, &extlist);
- OPENSSL_free(tmp);
- }
- if(akeyid->issuer)
- extlist = i2v_GENERAL_NAMES(NULL, akeyid->issuer, extlist);
- if(akeyid->serial) {
- tmp = hex_to_string(akeyid->serial->data,
- akeyid->serial->length);
- X509V3_add_value("serial", tmp, &extlist);
- OPENSSL_free(tmp);
- }
- return extlist;
+ char *tmp;
+ if (akeyid->keyid) {
+ tmp = hex_to_string(akeyid->keyid->data, akeyid->keyid->length);
+ X509V3_add_value("keyid", tmp, &extlist);
+ OPENSSL_free(tmp);
+ }
+ if (akeyid->issuer)
+ extlist = i2v_GENERAL_NAMES(NULL, akeyid->issuer, extlist);
+ if (akeyid->serial) {
+ tmp = hex_to_string(akeyid->serial->data, akeyid->serial->length);
+ X509V3_add_value("serial", tmp, &extlist);
+ OPENSSL_free(tmp);
+ }
+ return extlist;
}
-/* Currently two options:
- * keyid: use the issuers subject keyid, the value 'always' means its is
- * an error if the issuer certificate doesn't have a key id.
- * issuer: use the issuers cert issuer and serial number. The default is
- * to only use this if keyid is not present. With the option 'always'
- * this is always included.
+/*
+ * Currently two options: keyid: use the issuers subject keyid, the value
+ * 'always' means its is an error if the issuer certificate doesn't have a
+ * key id. issuer: use the issuers cert issuer and serial number. The default
+ * is to only use this if keyid is not present. With the option 'always' this
+ * is always included.
*/
static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
- X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values)
- {
- char keyid=0, issuer=0;
- size_t i;
- int j;
- CONF_VALUE *cnf;
- ASN1_OCTET_STRING *ikeyid = NULL;
- X509_NAME *isname = NULL;
- GENERAL_NAMES * gens = NULL;
- GENERAL_NAME *gen = NULL;
- ASN1_INTEGER *serial = NULL;
- X509_EXTENSION *ext;
- X509 *cert;
- AUTHORITY_KEYID *akeyid;
-
- for(i = 0; i < sk_CONF_VALUE_num(values); i++)
- {
- cnf = sk_CONF_VALUE_value(values, i);
- if(!strcmp(cnf->name, "keyid"))
- {
- keyid = 1;
- if(cnf->value && !strcmp(cnf->value, "always"))
- keyid = 2;
- }
- else if(!strcmp(cnf->name, "issuer"))
- {
- issuer = 1;
- if(cnf->value && !strcmp(cnf->value, "always"))
- issuer = 2;
- }
- else
- {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_OPTION);
- ERR_add_error_data(2, "name=", cnf->name);
- return NULL;
- }
- }
-
- if(!ctx || !ctx->issuer_cert)
- {
- if(ctx && (ctx->flags==CTX_TEST))
- return AUTHORITY_KEYID_new();
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_ISSUER_CERTIFICATE);
- return NULL;
- }
-
- cert = ctx->issuer_cert;
-
- if(keyid)
- {
- j = X509_get_ext_by_NID(cert, NID_subject_key_identifier, -1);
- if((j >= 0) && (ext = X509_get_ext(cert, j)))
- ikeyid = X509V3_EXT_d2i(ext);
- if(keyid==2 && !ikeyid)
- {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNABLE_TO_GET_ISSUER_KEYID);
- return NULL;
- }
- }
-
- if((issuer && !ikeyid) || (issuer == 2))
- {
- isname = X509_NAME_dup(X509_get_issuer_name(cert));
- serial = M_ASN1_INTEGER_dup(X509_get_serialNumber(cert));
- if(!isname || !serial)
- {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS);
- goto err;
- }
- }
-
- if(!(akeyid = AUTHORITY_KEYID_new())) goto err;
-
- if(isname)
- {
- if(!(gens = sk_GENERAL_NAME_new_null())
- || !(gen = GENERAL_NAME_new())
- || !sk_GENERAL_NAME_push(gens, gen))
- {
- OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- gen->type = GEN_DIRNAME;
- gen->d.dirn = isname;
- }
-
- akeyid->issuer = gens;
- akeyid->serial = serial;
- akeyid->keyid = ikeyid;
-
- return akeyid;
+ X509V3_CTX *ctx,
+ STACK_OF(CONF_VALUE) *values)
+{
+ char keyid = 0, issuer = 0;
+ size_t i;
+ int j;
+ CONF_VALUE *cnf;
+ ASN1_OCTET_STRING *ikeyid = NULL;
+ X509_NAME *isname = NULL;
+ GENERAL_NAMES *gens = NULL;
+ GENERAL_NAME *gen = NULL;
+ ASN1_INTEGER *serial = NULL;
+ X509_EXTENSION *ext;
+ X509 *cert;
+ AUTHORITY_KEYID *akeyid;
+
+ for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
+ cnf = sk_CONF_VALUE_value(values, i);
+ if (!strcmp(cnf->name, "keyid")) {
+ keyid = 1;
+ if (cnf->value && !strcmp(cnf->value, "always"))
+ keyid = 2;
+ } else if (!strcmp(cnf->name, "issuer")) {
+ issuer = 1;
+ if (cnf->value && !strcmp(cnf->value, "always"))
+ issuer = 2;
+ } else {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_OPTION);
+ ERR_add_error_data(2, "name=", cnf->name);
+ return NULL;
+ }
+ }
+
+ if (!ctx || !ctx->issuer_cert) {
+ if (ctx && (ctx->flags == CTX_TEST))
+ return AUTHORITY_KEYID_new();
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_ISSUER_CERTIFICATE);
+ return NULL;
+ }
+
+ cert = ctx->issuer_cert;
+
+ if (keyid) {
+ j = X509_get_ext_by_NID(cert, NID_subject_key_identifier, -1);
+ if ((j >= 0) && (ext = X509_get_ext(cert, j)))
+ ikeyid = X509V3_EXT_d2i(ext);
+ if (keyid == 2 && !ikeyid) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNABLE_TO_GET_ISSUER_KEYID);
+ return NULL;
+ }
+ }
+
+ if ((issuer && !ikeyid) || (issuer == 2)) {
+ isname = X509_NAME_dup(X509_get_issuer_name(cert));
+ serial = M_ASN1_INTEGER_dup(X509_get_serialNumber(cert));
+ if (!isname || !serial) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS);
+ goto err;
+ }
+ }
+
+ if (!(akeyid = AUTHORITY_KEYID_new()))
+ goto err;
+
+ if (isname) {
+ if (!(gens = sk_GENERAL_NAME_new_null())
+ || !(gen = GENERAL_NAME_new())
+ || !sk_GENERAL_NAME_push(gens, gen)) {
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ gen->type = GEN_DIRNAME;
+ gen->d.dirn = isname;
+ }
+
+ akeyid->issuer = gens;
+ akeyid->serial = serial;
+ akeyid->keyid = ikeyid;
+
+ return akeyid;
err:
- X509_NAME_free(isname);
- M_ASN1_INTEGER_free(serial);
- M_ASN1_OCTET_STRING_free(ikeyid);
- return NULL;
- }
+ X509_NAME_free(isname);
+ M_ASN1_INTEGER_free(serial);
+ M_ASN1_OCTET_STRING_free(ikeyid);
+ return NULL;
+}
diff --git a/src/crypto/x509v3/v3_akeya.c b/src/crypto/x509v3/v3_akeya.c
index 8b72cca2..844dee52 100644
--- a/src/crypto/x509v3/v3_akeya.c
+++ b/src/crypto/x509v3/v3_akeya.c
@@ -1,6 +1,7 @@
/* v3_akey_asn1.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
*/
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
@@ -10,7 +11,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -63,9 +64,9 @@
ASN1_SEQUENCE(AUTHORITY_KEYID) = {
- ASN1_IMP_OPT(AUTHORITY_KEYID, keyid, ASN1_OCTET_STRING, 0),
- ASN1_IMP_SEQUENCE_OF_OPT(AUTHORITY_KEYID, issuer, GENERAL_NAME, 1),
- ASN1_IMP_OPT(AUTHORITY_KEYID, serial, ASN1_INTEGER, 2)
+ ASN1_IMP_OPT(AUTHORITY_KEYID, keyid, ASN1_OCTET_STRING, 0),
+ ASN1_IMP_SEQUENCE_OF_OPT(AUTHORITY_KEYID, issuer, GENERAL_NAME, 1),
+ ASN1_IMP_OPT(AUTHORITY_KEYID, serial, ASN1_INTEGER, 2)
} ASN1_SEQUENCE_END(AUTHORITY_KEYID)
IMPLEMENT_ASN1_FUNCTIONS(AUTHORITY_KEYID)
diff --git a/src/crypto/x509v3/v3_alt.c b/src/crypto/x509v3/v3_alt.c
index cfc13486..152bd79f 100644
--- a/src/crypto/x509v3/v3_alt.c
+++ b/src/crypto/x509v3/v3_alt.c
@@ -1,5 +1,6 @@
/* v3_alt.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project.
*/
/* ====================================================================
@@ -10,7 +11,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -63,560 +64,551 @@
#include <openssl/obj.h>
#include <openssl/x509v3.h>
-
-static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
-static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
+static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method,
+ X509V3_CTX *ctx,
+ STACK_OF(CONF_VALUE) *nval);
+static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method,
+ X509V3_CTX *ctx,
+ STACK_OF(CONF_VALUE) *nval);
static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p);
static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens);
static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx);
static int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx);
const X509V3_EXT_METHOD v3_alt[] = {
-{ NID_subject_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES),
-0,0,0,0,
-0,0,
-(X509V3_EXT_I2V)i2v_GENERAL_NAMES,
-(X509V3_EXT_V2I)v2i_subject_alt,
-NULL, NULL, NULL},
-
-{ NID_issuer_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES),
-0,0,0,0,
-0,0,
-(X509V3_EXT_I2V)i2v_GENERAL_NAMES,
-(X509V3_EXT_V2I)v2i_issuer_alt,
-NULL, NULL, NULL},
-
-{ NID_certificate_issuer, 0, ASN1_ITEM_ref(GENERAL_NAMES),
-0,0,0,0,
-0,0,
-(X509V3_EXT_I2V)i2v_GENERAL_NAMES,
-NULL, NULL, NULL, NULL},
+ {NID_subject_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES),
+ 0, 0, 0, 0,
+ 0, 0,
+ (X509V3_EXT_I2V) i2v_GENERAL_NAMES,
+ (X509V3_EXT_V2I)v2i_subject_alt,
+ NULL, NULL, NULL},
+
+ {NID_issuer_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES),
+ 0, 0, 0, 0,
+ 0, 0,
+ (X509V3_EXT_I2V) i2v_GENERAL_NAMES,
+ (X509V3_EXT_V2I)v2i_issuer_alt,
+ NULL, NULL, NULL},
+
+ {NID_certificate_issuer, 0, ASN1_ITEM_ref(GENERAL_NAMES),
+ 0, 0, 0, 0,
+ 0, 0,
+ (X509V3_EXT_I2V) i2v_GENERAL_NAMES,
+ NULL, NULL, NULL, NULL},
};
STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method,
- GENERAL_NAMES *gens, STACK_OF(CONF_VALUE) *ret)
+ GENERAL_NAMES *gens,
+ STACK_OF(CONF_VALUE) *ret)
{
- size_t i;
- GENERAL_NAME *gen;
- for(i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
- gen = sk_GENERAL_NAME_value(gens, i);
- ret = i2v_GENERAL_NAME(method, gen, ret);
- }
- if(!ret) return sk_CONF_VALUE_new_null();
- return ret;
+ size_t i;
+ GENERAL_NAME *gen;
+ for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
+ gen = sk_GENERAL_NAME_value(gens, i);
+ ret = i2v_GENERAL_NAME(method, gen, ret);
+ }
+ if (!ret)
+ return sk_CONF_VALUE_new_null();
+ return ret;
}
STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method,
- GENERAL_NAME *gen, STACK_OF(CONF_VALUE) *ret)
+ GENERAL_NAME *gen,
+ STACK_OF(CONF_VALUE) *ret)
{
- unsigned char *p;
- char oline[256], htmp[5];
- int i;
- switch (gen->type)
- {
- case GEN_OTHERNAME:
- X509V3_add_value("othername","<unsupported>", &ret);
- break;
-
- case GEN_X400:
- X509V3_add_value("X400Name","<unsupported>", &ret);
- break;
-
- case GEN_EDIPARTY:
- X509V3_add_value("EdiPartyName","<unsupported>", &ret);
- break;
-
- case GEN_EMAIL:
- X509V3_add_value_uchar("email",gen->d.ia5->data, &ret);
- break;
-
- case GEN_DNS:
- X509V3_add_value_uchar("DNS",gen->d.ia5->data, &ret);
- break;
-
- case GEN_URI:
- X509V3_add_value_uchar("URI",gen->d.ia5->data, &ret);
- break;
-
- case GEN_DIRNAME:
- X509_NAME_oneline(gen->d.dirn, oline, 256);
- X509V3_add_value("DirName",oline, &ret);
- break;
-
- case GEN_IPADD:
- p = gen->d.ip->data;
- if(gen->d.ip->length == 4)
- BIO_snprintf(oline, sizeof oline,
- "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
- else if(gen->d.ip->length == 16)
- {
- oline[0] = 0;
- for (i = 0; i < 8; i++)
- {
- BIO_snprintf(htmp, sizeof htmp,
- "%X", p[0] << 8 | p[1]);
- p += 2;
- strcat(oline, htmp);
- if (i != 7)
- strcat(oline, ":");
- }
- }
- else
- {
- X509V3_add_value("IP Address","<invalid>", &ret);
- break;
- }
- X509V3_add_value("IP Address",oline, &ret);
- break;
-
- case GEN_RID:
- i2t_ASN1_OBJECT(oline, 256, gen->d.rid);
- X509V3_add_value("Registered ID",oline, &ret);
- break;
- }
- return ret;
+ unsigned char *p;
+ char oline[256], htmp[5];
+ int i;
+ switch (gen->type) {
+ case GEN_OTHERNAME:
+ X509V3_add_value("othername", "<unsupported>", &ret);
+ break;
+
+ case GEN_X400:
+ X509V3_add_value("X400Name", "<unsupported>", &ret);
+ break;
+
+ case GEN_EDIPARTY:
+ X509V3_add_value("EdiPartyName", "<unsupported>", &ret);
+ break;
+
+ case GEN_EMAIL:
+ X509V3_add_value_uchar("email", gen->d.ia5->data, &ret);
+ break;
+
+ case GEN_DNS:
+ X509V3_add_value_uchar("DNS", gen->d.ia5->data, &ret);
+ break;
+
+ case GEN_URI:
+ X509V3_add_value_uchar("URI", gen->d.ia5->data, &ret);
+ break;
+
+ case GEN_DIRNAME:
+ X509_NAME_oneline(gen->d.dirn, oline, 256);
+ X509V3_add_value("DirName", oline, &ret);
+ break;
+
+ case GEN_IPADD:
+ p = gen->d.ip->data;
+ if (gen->d.ip->length == 4)
+ BIO_snprintf(oline, sizeof oline,
+ "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
+ else if (gen->d.ip->length == 16) {
+ oline[0] = 0;
+ for (i = 0; i < 8; i++) {
+ BIO_snprintf(htmp, sizeof htmp, "%X", p[0] << 8 | p[1]);
+ p += 2;
+ strcat(oline, htmp);
+ if (i != 7)
+ strcat(oline, ":");
+ }
+ } else {
+ X509V3_add_value("IP Address", "<invalid>", &ret);
+ break;
+ }
+ X509V3_add_value("IP Address", oline, &ret);
+ break;
+
+ case GEN_RID:
+ i2t_ASN1_OBJECT(oline, 256, gen->d.rid);
+ X509V3_add_value("Registered ID", oline, &ret);
+ break;
+ }
+ return ret;
}
int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen)
{
- unsigned char *p;
- int i;
- switch (gen->type)
- {
- case GEN_OTHERNAME:
- BIO_printf(out, "othername:<unsupported>");
- break;
-
- case GEN_X400:
- BIO_printf(out, "X400Name:<unsupported>");
- break;
-
- case GEN_EDIPARTY:
- /* Maybe fix this: it is supported now */
- BIO_printf(out, "EdiPartyName:<unsupported>");
- break;
-
- case GEN_EMAIL:
- BIO_printf(out, "email:%s",gen->d.ia5->data);
- break;
-
- case GEN_DNS:
- BIO_printf(out, "DNS:%s",gen->d.ia5->data);
- break;
-
- case GEN_URI:
- BIO_printf(out, "URI:%s",gen->d.ia5->data);
- break;
-
- case GEN_DIRNAME:
- BIO_printf(out, "DirName: ");
- X509_NAME_print_ex(out, gen->d.dirn, 0, XN_FLAG_ONELINE);
- break;
-
- case GEN_IPADD:
- p = gen->d.ip->data;
- if(gen->d.ip->length == 4)
- BIO_printf(out, "IP Address:%d.%d.%d.%d",
- p[0], p[1], p[2], p[3]);
- else if(gen->d.ip->length == 16)
- {
- BIO_printf(out, "IP Address");
- for (i = 0; i < 8; i++)
- {
- BIO_printf(out, ":%X", p[0] << 8 | p[1]);
- p += 2;
- }
- BIO_puts(out, "\n");
- }
- else
- {
- BIO_printf(out,"IP Address:<invalid>");
- break;
- }
- break;
-
- case GEN_RID:
- BIO_printf(out, "Registered ID");
- i2a_ASN1_OBJECT(out, gen->d.rid);
- break;
- }
- return 1;
+ unsigned char *p;
+ int i;
+ switch (gen->type) {
+ case GEN_OTHERNAME:
+ BIO_printf(out, "othername:<unsupported>");
+ break;
+
+ case GEN_X400:
+ BIO_printf(out, "X400Name:<unsupported>");
+ break;
+
+ case GEN_EDIPARTY:
+ /* Maybe fix this: it is supported now */
+ BIO_printf(out, "EdiPartyName:<unsupported>");
+ break;
+
+ case GEN_EMAIL:
+ BIO_printf(out, "email:%s", gen->d.ia5->data);
+ break;
+
+ case GEN_DNS:
+ BIO_printf(out, "DNS:%s", gen->d.ia5->data);
+ break;
+
+ case GEN_URI:
+ BIO_printf(out, "URI:%s", gen->d.ia5->data);
+ break;
+
+ case GEN_DIRNAME:
+ BIO_printf(out, "DirName: ");
+ X509_NAME_print_ex(out, gen->d.dirn, 0, XN_FLAG_ONELINE);
+ break;
+
+ case GEN_IPADD:
+ p = gen->d.ip->data;
+ if (gen->d.ip->length == 4)
+ BIO_printf(out, "IP Address:%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
+ else if (gen->d.ip->length == 16) {
+ BIO_printf(out, "IP Address");
+ for (i = 0; i < 8; i++) {
+ BIO_printf(out, ":%X", p[0] << 8 | p[1]);
+ p += 2;
+ }
+ BIO_puts(out, "\n");
+ } else {
+ BIO_printf(out, "IP Address:<invalid>");
+ break;
+ }
+ break;
+
+ case GEN_RID:
+ BIO_printf(out, "Registered ID");
+ i2a_ASN1_OBJECT(out, gen->d.rid);
+ break;
+ }
+ return 1;
}
static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method,
- X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
+ X509V3_CTX *ctx,
+ STACK_OF(CONF_VALUE) *nval)
{
- GENERAL_NAMES *gens = NULL;
- CONF_VALUE *cnf;
- size_t i;
- if(!(gens = sk_GENERAL_NAME_new_null())) {
- 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(!name_cmp(cnf->name, "issuer") && cnf->value &&
- !strcmp(cnf->value, "copy")) {
- if(!copy_issuer(ctx, gens)) goto err;
- } else {
- GENERAL_NAME *gen;
- if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
- goto err;
- sk_GENERAL_NAME_push(gens, gen);
- }
- }
- return gens;
- err:
- sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
- return NULL;
+ GENERAL_NAMES *gens = NULL;
+ CONF_VALUE *cnf;
+ size_t i;
+ if (!(gens = sk_GENERAL_NAME_new_null())) {
+ 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 (!name_cmp(cnf->name, "issuer") && cnf->value &&
+ !strcmp(cnf->value, "copy")) {
+ if (!copy_issuer(ctx, gens))
+ goto err;
+ } else {
+ GENERAL_NAME *gen;
+ if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
+ goto err;
+ sk_GENERAL_NAME_push(gens, gen);
+ }
+ }
+ return gens;
+ err:
+ sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
+ return NULL;
}
/* Append subject altname of issuer to issuer alt name of subject */
static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens)
{
- GENERAL_NAMES *ialt;
- GENERAL_NAME *gen;
- X509_EXTENSION *ext;
- int i;
- size_t j;
- if(ctx && (ctx->flags == CTX_TEST)) return 1;
- if(!ctx || !ctx->issuer_cert) {
- 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, 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, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- }
- sk_GENERAL_NAME_free(ialt);
-
- return 1;
-
- err:
- return 0;
-
+ GENERAL_NAMES *ialt;
+ GENERAL_NAME *gen;
+ X509_EXTENSION *ext;
+ int i;
+ size_t j;
+ if (ctx && (ctx->flags == CTX_TEST))
+ return 1;
+ if (!ctx || !ctx->issuer_cert) {
+ 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, 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, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+ sk_GENERAL_NAME_free(ialt);
+
+ return 1;
+
+ err:
+ return 0;
+
}
static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method,
- X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
+ X509V3_CTX *ctx,
+ STACK_OF(CONF_VALUE) *nval)
{
- GENERAL_NAMES *gens = NULL;
- CONF_VALUE *cnf;
- size_t i;
- if(!(gens = sk_GENERAL_NAME_new_null())) {
- 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(!name_cmp(cnf->name, "email") && cnf->value &&
- !strcmp(cnf->value, "copy")) {
- if(!copy_email(ctx, gens, 0)) goto err;
- } else if(!name_cmp(cnf->name, "email") && cnf->value &&
- !strcmp(cnf->value, "move")) {
- if(!copy_email(ctx, gens, 1)) goto err;
- } else {
- GENERAL_NAME *gen;
- if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
- goto err;
- sk_GENERAL_NAME_push(gens, gen);
- }
- }
- return gens;
- err:
- sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
- return NULL;
+ GENERAL_NAMES *gens = NULL;
+ CONF_VALUE *cnf;
+ size_t i;
+ if (!(gens = sk_GENERAL_NAME_new_null())) {
+ 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 (!name_cmp(cnf->name, "email") && cnf->value &&
+ !strcmp(cnf->value, "copy")) {
+ if (!copy_email(ctx, gens, 0))
+ goto err;
+ } else if (!name_cmp(cnf->name, "email") && cnf->value &&
+ !strcmp(cnf->value, "move")) {
+ if (!copy_email(ctx, gens, 1))
+ goto err;
+ } else {
+ GENERAL_NAME *gen;
+ if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
+ goto err;
+ sk_GENERAL_NAME_push(gens, gen);
+ }
+ }
+ return gens;
+ err:
+ sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
+ return NULL;
}
-/* Copy any email addresses in a certificate or request to
- * GENERAL_NAMES
+/*
+ * Copy any email addresses in a certificate or request to GENERAL_NAMES
*/
static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p)
{
- X509_NAME *nm;
- ASN1_IA5STRING *email = NULL;
- X509_NAME_ENTRY *ne;
- GENERAL_NAME *gen = NULL;
- int i;
- if(ctx != NULL && ctx->flags == CTX_TEST)
- return 1;
- if(!ctx || (!ctx->subject_cert && !ctx->subject_req)) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_SUBJECT_DETAILS);
- goto err;
- }
- /* Find the subject name */
- if(ctx->subject_cert) nm = X509_get_subject_name(ctx->subject_cert);
- else nm = X509_REQ_get_subject_name(ctx->subject_req);
-
- /* Now add any email address(es) to STACK */
- i = -1;
- while((i = X509_NAME_get_index_by_NID(nm,
- NID_pkcs9_emailAddress, i)) >= 0) {
- ne = X509_NAME_get_entry(nm, i);
- email = M_ASN1_IA5STRING_dup(X509_NAME_ENTRY_get_data(ne));
- if (move_p)
- {
- X509_NAME_delete_entry(nm, i);
- X509_NAME_ENTRY_free(ne);
- i--;
- }
- if(!email || !(gen = GENERAL_NAME_new())) {
- 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, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- gen = NULL;
- }
-
-
- return 1;
-
- err:
- GENERAL_NAME_free(gen);
- M_ASN1_IA5STRING_free(email);
- return 0;
-
+ X509_NAME *nm;
+ ASN1_IA5STRING *email = NULL;
+ X509_NAME_ENTRY *ne;
+ GENERAL_NAME *gen = NULL;
+ int i;
+ if (ctx != NULL && ctx->flags == CTX_TEST)
+ return 1;
+ if (!ctx || (!ctx->subject_cert && !ctx->subject_req)) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_SUBJECT_DETAILS);
+ goto err;
+ }
+ /* Find the subject name */
+ if (ctx->subject_cert)
+ nm = X509_get_subject_name(ctx->subject_cert);
+ else
+ nm = X509_REQ_get_subject_name(ctx->subject_req);
+
+ /* Now add any email address(es) to STACK */
+ i = -1;
+ while ((i = X509_NAME_get_index_by_NID(nm,
+ NID_pkcs9_emailAddress, i)) >= 0) {
+ ne = X509_NAME_get_entry(nm, i);
+ email = M_ASN1_IA5STRING_dup(X509_NAME_ENTRY_get_data(ne));
+ if (move_p) {
+ X509_NAME_delete_entry(nm, i);
+ X509_NAME_ENTRY_free(ne);
+ i--;
+ }
+ if (!email || !(gen = GENERAL_NAME_new())) {
+ 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, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ gen = NULL;
+ }
+
+ return 1;
+
+ err:
+ GENERAL_NAME_free(gen);
+ M_ASN1_IA5STRING_free(email);
+ return 0;
+
}
GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method,
- X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
+ X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
{
- GENERAL_NAME *gen;
- GENERAL_NAMES *gens = NULL;
- CONF_VALUE *cnf;
- size_t i;
- if(!(gens = sk_GENERAL_NAME_new_null())) {
- 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(!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) goto err;
- sk_GENERAL_NAME_push(gens, gen);
- }
- return gens;
- err:
- sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
- return NULL;
+ GENERAL_NAME *gen;
+ GENERAL_NAMES *gens = NULL;
+ CONF_VALUE *cnf;
+ size_t i;
+ if (!(gens = sk_GENERAL_NAME_new_null())) {
+ 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 (!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
+ goto err;
+ sk_GENERAL_NAME_push(gens, gen);
+ }
+ return gens;
+ err:
+ sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
+ return NULL;
}
-GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
- CONF_VALUE *cnf)
- {
- return v2i_GENERAL_NAME_ex(NULL, method, ctx, cnf, 0);
- }
+GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method,
+ X509V3_CTX *ctx, CONF_VALUE *cnf)
+{
+ return v2i_GENERAL_NAME_ex(NULL, method, ctx, cnf, 0);
+}
GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
- const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
- int gen_type, char *value, int is_nc)
- {
- char is_string = 0;
- GENERAL_NAME *gen = NULL;
-
- if(!value)
- {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_MISSING_VALUE);
- return NULL;
- }
-
- if (out)
- gen = out;
- else
- {
- gen = GENERAL_NAME_new();
- if(gen == NULL)
- {
- OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
- }
-
- switch (gen_type)
- {
- case GEN_URI:
- case GEN_EMAIL:
- case GEN_DNS:
- is_string = 1;
- break;
-
- case GEN_RID:
- {
- ASN1_OBJECT *obj;
- if(!(obj = OBJ_txt2obj(value,0)))
- {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_BAD_OBJECT);
- ERR_add_error_data(2, "value=", value);
- goto err;
- }
- gen->d.rid = obj;
- }
- break;
-
- case GEN_IPADD:
- if (is_nc)
- gen->d.ip = a2i_IPADDRESS_NC(value);
- else
- gen->d.ip = a2i_IPADDRESS(value);
- if(gen->d.ip == NULL)
- {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_BAD_IP_ADDRESS);
- ERR_add_error_data(2, "value=", value);
- goto err;
- }
- break;
-
- case GEN_DIRNAME:
- if (!do_dirname(gen, value, ctx))
- {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_DIRNAME_ERROR);
- goto err;
- }
- break;
-
- case GEN_OTHERNAME:
- if (!do_othername(gen, value, ctx))
- {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_OTHERNAME_ERROR);
- goto err;
- }
- break;
- default:
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNSUPPORTED_TYPE);
- goto err;
- }
-
- if(is_string)
- {
- if(!(gen->d.ia5 = M_ASN1_IA5STRING_new()) ||
- !ASN1_STRING_set(gen->d.ia5, (unsigned char*)value,
- strlen(value)))
- {
- OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- }
-
- gen->type = gen_type;
-
- return gen;
-
- err:
- if (!out)
- GENERAL_NAME_free(gen);
- return NULL;
- }
+ const X509V3_EXT_METHOD *method,
+ X509V3_CTX *ctx, int gen_type, char *value,
+ int is_nc)
+{
+ char is_string = 0;
+ GENERAL_NAME *gen = NULL;
+
+ if (!value) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_MISSING_VALUE);
+ return NULL;
+ }
+
+ if (out)
+ gen = out;
+ else {
+ gen = GENERAL_NAME_new();
+ if (gen == NULL) {
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ }
+
+ switch (gen_type) {
+ case GEN_URI:
+ case GEN_EMAIL:
+ case GEN_DNS:
+ is_string = 1;
+ break;
+
+ case GEN_RID:
+ {
+ ASN1_OBJECT *obj;
+ if (!(obj = OBJ_txt2obj(value, 0))) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_BAD_OBJECT);
+ ERR_add_error_data(2, "value=", value);
+ goto err;
+ }
+ gen->d.rid = obj;
+ }
+ break;
+
+ case GEN_IPADD:
+ if (is_nc)
+ gen->d.ip = a2i_IPADDRESS_NC(value);
+ else
+ gen->d.ip = a2i_IPADDRESS(value);
+ if (gen->d.ip == NULL) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_BAD_IP_ADDRESS);
+ ERR_add_error_data(2, "value=", value);
+ goto err;
+ }
+ break;
+
+ case GEN_DIRNAME:
+ if (!do_dirname(gen, value, ctx)) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_DIRNAME_ERROR);
+ goto err;
+ }
+ break;
+
+ case GEN_OTHERNAME:
+ if (!do_othername(gen, value, ctx)) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_OTHERNAME_ERROR);
+ goto err;
+ }
+ break;
+ default:
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNSUPPORTED_TYPE);
+ goto err;
+ }
+
+ if (is_string) {
+ if (!(gen->d.ia5 = M_ASN1_IA5STRING_new()) ||
+ !ASN1_STRING_set(gen->d.ia5, (unsigned char *)value,
+ strlen(value))) {
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+
+ gen->type = gen_type;
+
+ return gen;
+
+ err:
+ if (!out)
+ GENERAL_NAME_free(gen);
+ return NULL;
+}
GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out,
- const X509V3_EXT_METHOD *method,
- X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc)
- {
- int type;
-
- char *name, *value;
-
- name = cnf->name;
- value = cnf->value;
-
- if(!value)
- {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_MISSING_VALUE);
- return NULL;
- }
-
- if(!name_cmp(name, "email"))
- type = GEN_EMAIL;
- else if(!name_cmp(name, "URI"))
- type = GEN_URI;
- else if(!name_cmp(name, "DNS"))
- type = GEN_DNS;
- else if(!name_cmp(name, "RID"))
- type = GEN_RID;
- else if(!name_cmp(name, "IP"))
- type = GEN_IPADD;
- else if(!name_cmp(name, "dirName"))
- type = GEN_DIRNAME;
- else if(!name_cmp(name, "otherName"))
- type = GEN_OTHERNAME;
- else
- {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNSUPPORTED_OPTION);
- ERR_add_error_data(2, "name=", name);
- return NULL;
- }
-
- return a2i_GENERAL_NAME(out, method, ctx, type, value, is_nc);
-
- }
+ const X509V3_EXT_METHOD *method,
+ X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc)
+{
+ int type;
+
+ char *name, *value;
+
+ name = cnf->name;
+ value = cnf->value;
+
+ if (!value) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_MISSING_VALUE);
+ return NULL;
+ }
+
+ if (!name_cmp(name, "email"))
+ type = GEN_EMAIL;
+ else if (!name_cmp(name, "URI"))
+ type = GEN_URI;
+ else if (!name_cmp(name, "DNS"))
+ type = GEN_DNS;
+ else if (!name_cmp(name, "RID"))
+ type = GEN_RID;
+ else if (!name_cmp(name, "IP"))
+ type = GEN_IPADD;
+ else if (!name_cmp(name, "dirName"))
+ type = GEN_DIRNAME;
+ else if (!name_cmp(name, "otherName"))
+ type = GEN_OTHERNAME;
+ else {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNSUPPORTED_OPTION);
+ ERR_add_error_data(2, "name=", name);
+ return NULL;
+ }
+
+ return a2i_GENERAL_NAME(out, method, ctx, type, value, is_nc);
+
+}
static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx)
- {
- char *objtmp = NULL, *p;
- int objlen;
- if (!(p = strchr(value, ';')))
- return 0;
- if (!(gen->d.otherName = OTHERNAME_new()))
- return 0;
- /* Free this up because we will overwrite it.
- * no need to free type_id because it is static
- */
- ASN1_TYPE_free(gen->d.otherName->value);
- if (!(gen->d.otherName->value = ASN1_generate_v3(p + 1, ctx)))
- return 0;
- objlen = p - value;
- objtmp = OPENSSL_malloc(objlen + 1);
- if (objtmp == NULL)
- return 0;
- strncpy(objtmp, value, objlen);
- objtmp[objlen] = 0;
- gen->d.otherName->type_id = OBJ_txt2obj(objtmp, 0);
- OPENSSL_free(objtmp);
- if (!gen->d.otherName->type_id)
- return 0;
- return 1;
- }
+{
+ char *objtmp = NULL, *p;
+ int objlen;
+ if (!(p = strchr(value, ';')))
+ return 0;
+ if (!(gen->d.otherName = OTHERNAME_new()))
+ return 0;
+ /*
+ * Free this up because we will overwrite it. no need to free type_id
+ * because it is static
+ */
+ ASN1_TYPE_free(gen->d.otherName->value);
+ if (!(gen->d.otherName->value = ASN1_generate_v3(p + 1, ctx)))
+ return 0;
+ objlen = p - value;
+ objtmp = OPENSSL_malloc(objlen + 1);
+ if (objtmp == NULL)
+ return 0;
+ strncpy(objtmp, value, objlen);
+ objtmp[objlen] = 0;
+ gen->d.otherName->type_id = OBJ_txt2obj(objtmp, 0);
+ OPENSSL_free(objtmp);
+ if (!gen->d.otherName->type_id)
+ return 0;
+ return 1;
+}
static int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx)
- {
- 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 == NULL)
- {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_SECTION_NOT_FOUND);
- ERR_add_error_data(2, "section=", value);
- goto err;
- }
- /* FIXME: should allow other character types... */
- if (!X509V3_NAME_from_section(nm, sk, MBSTRING_ASC))
- goto err;
- gen->d.dirn = nm;
- ret = 1;
-
-err:
- if (!ret)
- X509_NAME_free(nm);
- X509V3_section_free(ctx, sk);
- return ret;
- }
+{
+ 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 == NULL) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_SECTION_NOT_FOUND);
+ ERR_add_error_data(2, "section=", value);
+ goto err;
+ }
+ /* FIXME: should allow other character types... */
+ if (!X509V3_NAME_from_section(nm, sk, MBSTRING_ASC))
+ goto err;
+ gen->d.dirn = nm;
+ ret = 1;
+
+ err:
+ if (!ret)
+ X509_NAME_free(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 73ef21ee..aefefdff 100644
--- a/src/crypto/x509v3/v3_bcons.c
+++ b/src/crypto/x509v3/v3_bcons.c
@@ -1,6 +1,7 @@
/* v3_bcons.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
*/
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
@@ -10,7 +11,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -54,7 +55,6 @@
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com). */
-
#include <stdio.h>
#include <string.h>
@@ -65,62 +65,69 @@
#include <openssl/obj.h>
#include <openssl/x509v3.h>
-
-static STACK_OF(CONF_VALUE) *i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, BASIC_CONSTRAINTS *bcons, STACK_OF(CONF_VALUE) *extlist);
-static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values);
+static STACK_OF(CONF_VALUE) *i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method,
+ BASIC_CONSTRAINTS *bcons,
+ STACK_OF(CONF_VALUE)
+ *extlist);
+static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method,
+ X509V3_CTX *ctx,
+ STACK_OF(CONF_VALUE) *values);
const X509V3_EXT_METHOD v3_bcons = {
-NID_basic_constraints, 0,
-ASN1_ITEM_ref(BASIC_CONSTRAINTS),
-0,0,0,0,
-0,0,
-(X509V3_EXT_I2V)i2v_BASIC_CONSTRAINTS,
-(X509V3_EXT_V2I)v2i_BASIC_CONSTRAINTS,
-NULL,NULL,
-NULL
+ NID_basic_constraints, 0,
+ ASN1_ITEM_ref(BASIC_CONSTRAINTS),
+ 0, 0, 0, 0,
+ 0, 0,
+ (X509V3_EXT_I2V) i2v_BASIC_CONSTRAINTS,
+ (X509V3_EXT_V2I)v2i_BASIC_CONSTRAINTS,
+ NULL, NULL,
+ NULL
};
ASN1_SEQUENCE(BASIC_CONSTRAINTS) = {
- ASN1_OPT(BASIC_CONSTRAINTS, ca, ASN1_FBOOLEAN),
- ASN1_OPT(BASIC_CONSTRAINTS, pathlen, ASN1_INTEGER)
+ ASN1_OPT(BASIC_CONSTRAINTS, ca, ASN1_FBOOLEAN),
+ ASN1_OPT(BASIC_CONSTRAINTS, pathlen, ASN1_INTEGER)
} ASN1_SEQUENCE_END(BASIC_CONSTRAINTS)
IMPLEMENT_ASN1_FUNCTIONS(BASIC_CONSTRAINTS)
-
static STACK_OF(CONF_VALUE) *i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method,
- BASIC_CONSTRAINTS *bcons, STACK_OF(CONF_VALUE) *extlist)
+ BASIC_CONSTRAINTS *bcons,
+ STACK_OF(CONF_VALUE)
+ *extlist)
{
- X509V3_add_value_bool("CA", bcons->ca, &extlist);
- X509V3_add_value_int("pathlen", bcons->pathlen, &extlist);
- return extlist;
+ X509V3_add_value_bool("CA", bcons->ca, &extlist);
+ X509V3_add_value_int("pathlen", bcons->pathlen, &extlist);
+ return extlist;
}
static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method,
- X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values)
+ X509V3_CTX *ctx,
+ STACK_OF(CONF_VALUE) *values)
{
- BASIC_CONSTRAINTS *bcons=NULL;
- CONF_VALUE *val;
- size_t i;
- if(!(bcons = BASIC_CONSTRAINTS_new())) {
- OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
- for(i = 0; i < sk_CONF_VALUE_num(values); i++) {
- val = sk_CONF_VALUE_value(values, i);
- if(!strcmp(val->name, "CA")) {
- if(!X509V3_get_value_bool(val, &bcons->ca)) goto err;
- } else if(!strcmp(val->name, "pathlen")) {
- if(!X509V3_get_value_int(val, &bcons->pathlen)) goto err;
- } else {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NAME);
- X509V3_conf_err(val);
- goto err;
- }
- }
- return bcons;
- err:
- BASIC_CONSTRAINTS_free(bcons);
- return NULL;
+ BASIC_CONSTRAINTS *bcons = NULL;
+ CONF_VALUE *val;
+ size_t i;
+ if (!(bcons = BASIC_CONSTRAINTS_new())) {
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
+ val = sk_CONF_VALUE_value(values, i);
+ if (!strcmp(val->name, "CA")) {
+ if (!X509V3_get_value_bool(val, &bcons->ca))
+ goto err;
+ } else if (!strcmp(val->name, "pathlen")) {
+ if (!X509V3_get_value_int(val, &bcons->pathlen))
+ goto err;
+ } else {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NAME);
+ X509V3_conf_err(val);
+ goto err;
+ }
+ }
+ return bcons;
+ err:
+ BASIC_CONSTRAINTS_free(bcons);
+ return NULL;
}
-
diff --git a/src/crypto/x509v3/v3_bitst.c b/src/crypto/x509v3/v3_bitst.c
index e1e20871..86a8c361 100644
--- a/src/crypto/x509v3/v3_bitst.c
+++ b/src/crypto/x509v3/v3_bitst.c
@@ -1,6 +1,7 @@
/* v3_bitst.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
*/
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
@@ -10,7 +11,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -62,80 +63,79 @@
#include <openssl/obj.h>
#include <openssl/x509v3.h>
-
static const BIT_STRING_BITNAME ns_cert_type_table[] = {
-{0, "SSL Client", "client"},
-{1, "SSL Server", "server"},
-{2, "S/MIME", "email"},
-{3, "Object Signing", "objsign"},
-{4, "Unused", "reserved"},
-{5, "SSL CA", "sslCA"},
-{6, "S/MIME CA", "emailCA"},
-{7, "Object Signing CA", "objCA"},
-{-1, NULL, NULL}
+ {0, "SSL Client", "client"},
+ {1, "SSL Server", "server"},
+ {2, "S/MIME", "email"},
+ {3, "Object Signing", "objsign"},
+ {4, "Unused", "reserved"},
+ {5, "SSL CA", "sslCA"},
+ {6, "S/MIME CA", "emailCA"},
+ {7, "Object Signing CA", "objCA"},
+ {-1, NULL, NULL}
};
static const BIT_STRING_BITNAME key_usage_type_table[] = {
-{0, "Digital Signature", "digitalSignature"},
-{1, "Non Repudiation", "nonRepudiation"},
-{2, "Key Encipherment", "keyEncipherment"},
-{3, "Data Encipherment", "dataEncipherment"},
-{4, "Key Agreement", "keyAgreement"},
-{5, "Certificate Sign", "keyCertSign"},
-{6, "CRL Sign", "cRLSign"},
-{7, "Encipher Only", "encipherOnly"},
-{8, "Decipher Only", "decipherOnly"},
-{-1, NULL, NULL}
+ {0, "Digital Signature", "digitalSignature"},
+ {1, "Non Repudiation", "nonRepudiation"},
+ {2, "Key Encipherment", "keyEncipherment"},
+ {3, "Data Encipherment", "dataEncipherment"},
+ {4, "Key Agreement", "keyAgreement"},
+ {5, "Certificate Sign", "keyCertSign"},
+ {6, "CRL Sign", "cRLSign"},
+ {7, "Encipher Only", "encipherOnly"},
+ {8, "Decipher Only", "decipherOnly"},
+ {-1, NULL, NULL}
};
-
-
-const X509V3_EXT_METHOD v3_nscert = EXT_BITSTRING(NID_netscape_cert_type, ns_cert_type_table);
-const X509V3_EXT_METHOD v3_key_usage = EXT_BITSTRING(NID_key_usage, key_usage_type_table);
+const X509V3_EXT_METHOD v3_nscert =
+EXT_BITSTRING(NID_netscape_cert_type, ns_cert_type_table);
+const X509V3_EXT_METHOD v3_key_usage =
+EXT_BITSTRING(NID_key_usage, key_usage_type_table);
STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
- ASN1_BIT_STRING *bits, STACK_OF(CONF_VALUE) *ret)
+ ASN1_BIT_STRING *bits,
+ STACK_OF(CONF_VALUE) *ret)
{
- const BIT_STRING_BITNAME *bnam;
- for(bnam =method->usr_data; bnam->lname; bnam++) {
- if(ASN1_BIT_STRING_get_bit(bits, bnam->bitnum))
- X509V3_add_value(bnam->lname, NULL, &ret);
- }
- return ret;
+ const BIT_STRING_BITNAME *bnam;
+ for (bnam = method->usr_data; bnam->lname; bnam++) {
+ if (ASN1_BIT_STRING_get_bit(bits, bnam->bitnum))
+ X509V3_add_value(bnam->lname, NULL, &ret);
+ }
+ return ret;
}
-
+
ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
- X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
+ X509V3_CTX *ctx,
+ STACK_OF(CONF_VALUE) *nval)
{
- CONF_VALUE *val;
- ASN1_BIT_STRING *bs;
- size_t i;
- const BIT_STRING_BITNAME *bnam;
- if(!(bs = M_ASN1_BIT_STRING_new())) {
- OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
- for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
- val = sk_CONF_VALUE_value(nval, i);
- for(bnam = method->usr_data; bnam->lname; bnam++) {
- 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, ERR_R_MALLOC_FAILURE);
- M_ASN1_BIT_STRING_free(bs);
- return NULL;
- }
- break;
- }
- }
- if(!bnam->lname) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT);
- X509V3_conf_err(val);
- M_ASN1_BIT_STRING_free(bs);
- return NULL;
- }
- }
- return bs;
+ CONF_VALUE *val;
+ ASN1_BIT_STRING *bs;
+ size_t i;
+ const BIT_STRING_BITNAME *bnam;
+ if (!(bs = M_ASN1_BIT_STRING_new())) {
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+ val = sk_CONF_VALUE_value(nval, i);
+ for (bnam = method->usr_data; bnam->lname; bnam++) {
+ 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, ERR_R_MALLOC_FAILURE);
+ M_ASN1_BIT_STRING_free(bs);
+ return NULL;
+ }
+ break;
+ }
+ }
+ if (!bnam->lname) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT);
+ X509V3_conf_err(val);
+ M_ASN1_BIT_STRING_free(bs);
+ return NULL;
+ }
+ }
+ return bs;
}
-
-
diff --git a/src/crypto/x509v3/v3_conf.c b/src/crypto/x509v3/v3_conf.c
index fe715665..66abca4e 100644
--- a/src/crypto/x509v3/v3_conf.c
+++ b/src/crypto/x509v3/v3_conf.c
@@ -1,6 +1,7 @@
/* v3_conf.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
*/
/* ====================================================================
* Copyright (c) 1999-2002 The OpenSSL Project. All rights reserved.
@@ -10,7 +11,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -69,391 +70,391 @@
#include "../internal.h"
-
static int v3_check_critical(char **value);
static int v3_check_generic(char **value);
-static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid, int crit, char *value);
-static X509_EXTENSION *v3_generic_extension(const char *ext, char *value, int crit, int type, X509V3_CTX *ctx);
-static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid,
- int crit, void *ext_struc);
-static unsigned char *generic_asn1(char *value, X509V3_CTX *ctx, long *ext_len);
+static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid,
+ int crit, char *value);
+static X509_EXTENSION *v3_generic_extension(const char *ext, char *value,
+ int crit, int type,
+ X509V3_CTX *ctx);
+static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method,
+ int ext_nid, int crit, void *ext_struc);
+static unsigned char *generic_asn1(char *value, X509V3_CTX *ctx,
+ long *ext_len);
/* CONF *conf: Config file */
/* char *name: Name */
/* char *value: Value */
X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, char *name,
- char *value)
- {
- int crit;
- int ext_type;
- X509_EXTENSION *ret;
- crit = v3_check_critical(&value);
- if ((ext_type = v3_check_generic(&value)))
- return v3_generic_extension(name, value, crit, ext_type, ctx);
- ret = do_ext_nconf(conf, ctx, OBJ_sn2nid(name), crit, value);
- if (!ret)
- {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_ERROR_IN_EXTENSION);
- ERR_add_error_data(4,"name=", name, ", value=", value);
- }
- return ret;
- }
+ char *value)
+{
+ int crit;
+ int ext_type;
+ X509_EXTENSION *ret;
+ crit = v3_check_critical(&value);
+ if ((ext_type = v3_check_generic(&value)))
+ return v3_generic_extension(name, value, crit, ext_type, ctx);
+ ret = do_ext_nconf(conf, ctx, OBJ_sn2nid(name), crit, value);
+ if (!ret) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_ERROR_IN_EXTENSION);
+ ERR_add_error_data(4, "name=", name, ", value=", value);
+ }
+ return ret;
+}
/* CONF *conf: Config file */
/* char *value: Value */
X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid,
- char *value)
- {
- int crit;
- int ext_type;
- crit = v3_check_critical(&value);
- if ((ext_type = v3_check_generic(&value)))
- return v3_generic_extension(OBJ_nid2sn(ext_nid),
- value, crit, ext_type, ctx);
- return do_ext_nconf(conf, ctx, ext_nid, crit, value);
- }
+ char *value)
+{
+ int crit;
+ int ext_type;
+ crit = v3_check_critical(&value);
+ if ((ext_type = v3_check_generic(&value)))
+ return v3_generic_extension(OBJ_nid2sn(ext_nid),
+ value, crit, ext_type, ctx);
+ return do_ext_nconf(conf, ctx, ext_nid, crit, value);
+}
/* CONF *conf: Config file */
/* char *value: Value */
static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid,
- int crit, char *value)
- {
- const X509V3_EXT_METHOD *method;
- X509_EXTENSION *ext;
- STACK_OF(CONF_VALUE) *nval;
- void *ext_struc;
- if (ext_nid == NID_undef)
- {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_EXTENSION_NAME);
- return NULL;
- }
- if (!(method = X509V3_EXT_get_nid(ext_nid)))
- {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_EXTENSION);
- return NULL;
- }
- /* Now get internal extension representation based on type */
- if (method->v2i)
- {
- if(*value == '@') nval = NCONF_get_section(conf, value + 1);
- else nval = X509V3_parse_list(value);
- if(sk_CONF_VALUE_num(nval) <= 0)
- {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_EXTENSION_STRING);
- ERR_add_error_data(4, "name=", OBJ_nid2sn(ext_nid), ",section=", value);
- return NULL;
- }
- ext_struc = method->v2i(method, ctx, nval);
- if(*value != '@') sk_CONF_VALUE_pop_free(nval,
- X509V3_conf_free);
- if(!ext_struc) return NULL;
- }
- else if(method->s2i)
- {
- if(!(ext_struc = method->s2i(method, ctx, value))) return NULL;
- }
- else if(method->r2i)
- {
- if(!ctx->db || !ctx->db_meth)
- {
- 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, X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED);
- ERR_add_error_data(2, "name=", OBJ_nid2sn(ext_nid));
- return NULL;
- }
-
- ext = do_ext_i2d(method, ext_nid, crit, ext_struc);
- if(method->it) ASN1_item_free(ext_struc, ASN1_ITEM_ptr(method->it));
- else method->ext_free(ext_struc);
- return ext;
-
- }
-
-static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid,
- int crit, void *ext_struc)
- {
- unsigned char *ext_der;
- int ext_len;
- ASN1_OCTET_STRING *ext_oct;
- X509_EXTENSION *ext;
- /* Convert internal representation to DER */
- if (method->it)
- {
- ext_der = NULL;
- ext_len = ASN1_item_i2d(ext_struc, &ext_der, ASN1_ITEM_ptr(method->it));
- if (ext_len < 0) goto merr;
- }
- else
- {
- unsigned char *p;
- ext_len = method->i2d(ext_struc, NULL);
- if(!(ext_der = OPENSSL_malloc(ext_len))) goto merr;
- p = ext_der;
- method->i2d(ext_struc, &p);
- }
- if (!(ext_oct = M_ASN1_OCTET_STRING_new())) goto merr;
- ext_oct->data = ext_der;
- ext_oct->length = ext_len;
-
- ext = X509_EXTENSION_create_by_NID(NULL, ext_nid, crit, ext_oct);
- if (!ext) goto merr;
- M_ASN1_OCTET_STRING_free(ext_oct);
-
- return ext;
-
- merr:
- OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
- return NULL;
-
- }
+ int crit, char *value)
+{
+ const X509V3_EXT_METHOD *method;
+ X509_EXTENSION *ext;
+ STACK_OF(CONF_VALUE) *nval;
+ void *ext_struc;
+ if (ext_nid == NID_undef) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_EXTENSION_NAME);
+ return NULL;
+ }
+ if (!(method = X509V3_EXT_get_nid(ext_nid))) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_EXTENSION);
+ return NULL;
+ }
+ /* Now get internal extension representation based on type */
+ if (method->v2i) {
+ if (*value == '@')
+ nval = NCONF_get_section(conf, value + 1);
+ else
+ nval = X509V3_parse_list(value);
+ if (sk_CONF_VALUE_num(nval) <= 0) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_EXTENSION_STRING);
+ ERR_add_error_data(4, "name=", OBJ_nid2sn(ext_nid), ",section=",
+ value);
+ return NULL;
+ }
+ ext_struc = method->v2i(method, ctx, nval);
+ if (*value != '@')
+ sk_CONF_VALUE_pop_free(nval, X509V3_conf_free);
+ if (!ext_struc)
+ return NULL;
+ } else if (method->s2i) {
+ if (!(ext_struc = method->s2i(method, ctx, value)))
+ return NULL;
+ } else if (method->r2i) {
+ if (!ctx->db || !ctx->db_meth) {
+ 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, X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED);
+ ERR_add_error_data(2, "name=", OBJ_nid2sn(ext_nid));
+ return NULL;
+ }
+
+ ext = do_ext_i2d(method, ext_nid, crit, ext_struc);
+ if (method->it)
+ ASN1_item_free(ext_struc, ASN1_ITEM_ptr(method->it));
+ else
+ method->ext_free(ext_struc);
+ return ext;
+
+}
+
+static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method,
+ int ext_nid, int crit, void *ext_struc)
+{
+ unsigned char *ext_der;
+ int ext_len;
+ ASN1_OCTET_STRING *ext_oct;
+ X509_EXTENSION *ext;
+ /* Convert internal representation to DER */
+ if (method->it) {
+ ext_der = NULL;
+ ext_len =
+ ASN1_item_i2d(ext_struc, &ext_der, ASN1_ITEM_ptr(method->it));
+ if (ext_len < 0)
+ goto merr;
+ } else {
+ unsigned char *p;
+ ext_len = method->i2d(ext_struc, NULL);
+ if (!(ext_der = OPENSSL_malloc(ext_len)))
+ goto merr;
+ p = ext_der;
+ method->i2d(ext_struc, &p);
+ }
+ if (!(ext_oct = M_ASN1_OCTET_STRING_new()))
+ goto merr;
+ ext_oct->data = ext_der;
+ ext_oct->length = ext_len;
+
+ ext = X509_EXTENSION_create_by_NID(NULL, ext_nid, crit, ext_oct);
+ if (!ext)
+ goto merr;
+ M_ASN1_OCTET_STRING_free(ext_oct);
+
+ return ext;
+
+ merr:
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+ return NULL;
+
+}
/* Given an internal structure, nid and critical flag create an extension */
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_R_UNKNOWN_EXTENSION);
- return NULL;
- }
- return do_ext_i2d(method, ext_nid, crit, ext_struc);
+{
+ const X509V3_EXT_METHOD *method;
+ if (!(method = X509V3_EXT_get_nid(ext_nid))) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_EXTENSION);
+ return NULL;
+ }
+ return do_ext_i2d(method, ext_nid, crit, ext_struc);
}
/* Check the extension string for critical flag */
static int v3_check_critical(char **value)
{
- char *p = *value;
- if ((strlen(p) < 9) || strncmp(p, "critical,", 9)) return 0;
- p+=9;
- while(isspace((unsigned char)*p)) p++;
- *value = p;
- return 1;
+ char *p = *value;
+ if ((strlen(p) < 9) || strncmp(p, "critical,", 9))
+ return 0;
+ p += 9;
+ while (isspace((unsigned char)*p))
+ p++;
+ *value = p;
+ return 1;
}
/* Check extension string for generic extension and return the type */
static int v3_check_generic(char **value)
{
- int gen_type = 0;
- char *p = *value;
- if ((strlen(p) >= 4) && !strncmp(p, "DER:", 4))
- {
- p+=4;
- gen_type = 1;
- }
- else if ((strlen(p) >= 5) && !strncmp(p, "ASN1:", 5))
- {
- p+=5;
- gen_type = 2;
- }
- else
- return 0;
-
- while (isspace((unsigned char)*p)) p++;
- *value = p;
- return gen_type;
+ int gen_type = 0;
+ char *p = *value;
+ if ((strlen(p) >= 4) && !strncmp(p, "DER:", 4)) {
+ p += 4;
+ gen_type = 1;
+ } else if ((strlen(p) >= 5) && !strncmp(p, "ASN1:", 5)) {
+ p += 5;
+ gen_type = 2;
+ } else
+ return 0;
+
+ while (isspace((unsigned char)*p))
+ p++;
+ *value = p;
+ return gen_type;
}
/* Create a generic extension: for now just handle DER type */
static X509_EXTENSION *v3_generic_extension(const char *ext, char *value,
- int crit, int gen_type,
- X509V3_CTX *ctx)
- OPENSSL_SUPPRESS_POTENTIALLY_UNINITIALIZED_WARNINGS
- {
- unsigned char *ext_der=NULL;
- long ext_len;
- ASN1_OBJECT *obj=NULL;
- ASN1_OCTET_STRING *oct=NULL;
- X509_EXTENSION *extension=NULL;
- if (!(obj = OBJ_txt2obj(ext, 0)))
- {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXTENSION_NAME_ERROR);
- ERR_add_error_data(2, "name=", ext);
- goto err;
- }
-
- if (gen_type == 1)
- ext_der = string_to_hex(value, &ext_len);
- else if (gen_type == 2)
- ext_der = generic_asn1(value, ctx, &ext_len);
-
- if (ext_der == NULL)
- {
- 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, ERR_R_MALLOC_FAILURE);
- goto err;
- }
-
- oct->data = ext_der;
- oct->length = ext_len;
- ext_der = NULL;
-
- extension = X509_EXTENSION_create_by_OBJ(NULL, obj, crit, oct);
-
- err:
- ASN1_OBJECT_free(obj);
- M_ASN1_OCTET_STRING_free(oct);
- if(ext_der) OPENSSL_free(ext_der);
- return extension;
-
- }
-
-static unsigned char *generic_asn1(char *value, X509V3_CTX *ctx, long *ext_len)
- {
- ASN1_TYPE *typ;
- unsigned char *ext_der = NULL;
- typ = ASN1_generate_v3(value, ctx);
- if (typ == NULL)
- return NULL;
- *ext_len = i2d_ASN1_TYPE(typ, &ext_der);
- ASN1_TYPE_free(typ);
- return ext_der;
- }
-
-/* This is the main function: add a bunch of extensions based on a config file
- * section to an extension STACK.
- */
+ int crit, int gen_type,
+ X509V3_CTX *ctx)
+{
+ unsigned char *ext_der = NULL;
+ long ext_len = 0;
+ ASN1_OBJECT *obj = NULL;
+ ASN1_OCTET_STRING *oct = NULL;
+ X509_EXTENSION *extension = NULL;
+ if (!(obj = OBJ_txt2obj(ext, 0))) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXTENSION_NAME_ERROR);
+ ERR_add_error_data(2, "name=", ext);
+ goto err;
+ }
+
+ if (gen_type == 1)
+ ext_der = string_to_hex(value, &ext_len);
+ else if (gen_type == 2)
+ ext_der = generic_asn1(value, ctx, &ext_len);
+
+ if (ext_der == NULL) {
+ 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, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ oct->data = ext_der;
+ oct->length = ext_len;
+ ext_der = NULL;
+
+ extension = X509_EXTENSION_create_by_OBJ(NULL, obj, crit, oct);
+
+ err:
+ ASN1_OBJECT_free(obj);
+ M_ASN1_OCTET_STRING_free(oct);
+ if (ext_der)
+ OPENSSL_free(ext_der);
+ return extension;
+}
+
+static unsigned char *generic_asn1(char *value, X509V3_CTX *ctx,
+ long *ext_len)
+{
+ ASN1_TYPE *typ;
+ unsigned char *ext_der = NULL;
+ typ = ASN1_generate_v3(value, ctx);
+ if (typ == NULL)
+ return NULL;
+ *ext_len = i2d_ASN1_TYPE(typ, &ext_der);
+ ASN1_TYPE_free(typ);
+ return ext_der;
+}
+
+/*
+ * This is the main function: add a bunch of extensions based on a config
+ * file section to an extension STACK.
+ */
int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, char *section,
- STACK_OF(X509_EXTENSION) **sk)
- {
- X509_EXTENSION *ext;
- STACK_OF(CONF_VALUE) *nval;
- CONF_VALUE *val;
- size_t i;
- if (!(nval = NCONF_get_section(conf, section))) return 0;
- for (i = 0; i < sk_CONF_VALUE_num(nval); i++)
- {
- val = sk_CONF_VALUE_value(nval, i);
- if (!(ext = X509V3_EXT_nconf(conf, ctx, val->name, val->value)))
- return 0;
- if (sk) X509v3_add_ext(sk, ext, -1);
- X509_EXTENSION_free(ext);
- }
- return 1;
- }
-
-/* Convenience functions to add extensions to a certificate, CRL and request */
+ STACK_OF(X509_EXTENSION) **sk)
+{
+ X509_EXTENSION *ext;
+ STACK_OF(CONF_VALUE) *nval;
+ CONF_VALUE *val;
+ size_t i;
+ if (!(nval = NCONF_get_section(conf, section)))
+ return 0;
+ for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+ val = sk_CONF_VALUE_value(nval, i);
+ if (!(ext = X509V3_EXT_nconf(conf, ctx, val->name, val->value)))
+ return 0;
+ if (sk)
+ X509v3_add_ext(sk, ext, -1);
+ X509_EXTENSION_free(ext);
+ }
+ return 1;
+}
+
+/*
+ * Convenience functions to add extensions to a certificate, CRL and request
+ */
int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
- X509 *cert)
- {
- STACK_OF(X509_EXTENSION) **sk = NULL;
- if (cert)
- sk = &cert->cert_info->extensions;
- return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
- }
+ X509 *cert)
+{
+ STACK_OF(X509_EXTENSION) **sk = NULL;
+ if (cert)
+ sk = &cert->cert_info->extensions;
+ return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
+}
/* Same as above but for a CRL */
int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
- X509_CRL *crl)
- {
- STACK_OF(X509_EXTENSION) **sk = NULL;
- if (crl)
- sk = &crl->crl->extensions;
- return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
- }
+ X509_CRL *crl)
+{
+ STACK_OF(X509_EXTENSION) **sk = NULL;
+ if (crl)
+ sk = &crl->crl->extensions;
+ return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
+}
/* Add extensions to certificate request */
int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
- X509_REQ *req)
- {
- STACK_OF(X509_EXTENSION) *extlist = NULL, **sk = NULL;
- int i;
- if (req)
- sk = &extlist;
- i = X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
- if (!i || !sk)
- return i;
- i = X509_REQ_add_extensions(req, extlist);
- sk_X509_EXTENSION_pop_free(extlist, X509_EXTENSION_free);
- return i;
- }
+ X509_REQ *req)
+{
+ STACK_OF(X509_EXTENSION) *extlist = NULL, **sk = NULL;
+ int i;
+ if (req)
+ sk = &extlist;
+ i = X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
+ if (!i || !sk)
+ return i;
+ i = X509_REQ_add_extensions(req, extlist);
+ sk_X509_EXTENSION_pop_free(extlist, X509_EXTENSION_free);
+ return i;
+}
/* Config database functions */
-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_R_OPERATION_NOT_DEFINED);
- return NULL;
- }
- if (ctx->db_meth->get_string)
- return ctx->db_meth->get_string(ctx->db, name, section);
- return NULL;
- }
-
-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_R_OPERATION_NOT_DEFINED);
- return NULL;
- }
- if (ctx->db_meth->get_section)
- return ctx->db_meth->get_section(ctx->db, section);
- return NULL;
- }
+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_R_OPERATION_NOT_DEFINED);
+ return NULL;
+ }
+ if (ctx->db_meth->get_string)
+ return ctx->db_meth->get_string(ctx->db, name, section);
+ return NULL;
+}
+
+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_R_OPERATION_NOT_DEFINED);
+ return NULL;
+ }
+ if (ctx->db_meth->get_section)
+ return ctx->db_meth->get_section(ctx->db, section);
+ return NULL;
+}
void X509V3_string_free(X509V3_CTX *ctx, char *str)
- {
- if (!str) return;
- if (ctx->db_meth->free_string)
- ctx->db_meth->free_string(ctx->db, str);
- }
+{
+ if (!str)
+ return;
+ if (ctx->db_meth->free_string)
+ ctx->db_meth->free_string(ctx->db, str);
+}
void X509V3_section_free(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section)
- {
- if (!section) return;
- if (ctx->db_meth->free_section)
- ctx->db_meth->free_section(ctx->db, section);
- }
+{
+ if (!section)
+ return;
+ if (ctx->db_meth->free_section)
+ ctx->db_meth->free_section(ctx->db, section);
+}
static char *nconf_get_string(void *db, char *section, char *value)
- {
- /* TODO(fork): this should return a const value. */
- return (char *) NCONF_get_string(db, section, value);
- }
+{
+ /* TODO(fork): this should return a const value. */
+ return (char *)NCONF_get_string(db, section, value);
+}
static STACK_OF(CONF_VALUE) *nconf_get_section(void *db, char *section)
- {
- return NCONF_get_section(db, section);
- }
+{
+ return NCONF_get_section(db, section);
+}
static const X509V3_CONF_METHOD nconf_method = {
-nconf_get_string,
-nconf_get_section,
-NULL,
-NULL
+ nconf_get_string,
+ nconf_get_section,
+ NULL,
+ NULL
};
void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf)
- {
- ctx->db_meth = &nconf_method;
- ctx->db = conf;
- }
+{
+ ctx->db_meth = &nconf_method;
+ ctx->db = conf;
+}
void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subj, X509_REQ *req,
- X509_CRL *crl, int flags)
- {
- ctx->issuer_cert = issuer;
- ctx->subject_cert = subj;
- ctx->crl = crl;
- ctx->subject_req = req;
- ctx->flags = flags;
- }
-
+ X509_CRL *crl, int flags)
+{
+ ctx->issuer_cert = issuer;
+ ctx->subject_cert = subj;
+ ctx->crl = crl;
+ ctx->subject_req = req;
+ ctx->flags = flags;
+}
diff --git a/src/crypto/x509v3/v3_cpols.c b/src/crypto/x509v3/v3_cpols.c
index 0b586762..d67dcb08 100644
--- a/src/crypto/x509v3/v3_cpols.c
+++ b/src/crypto/x509v3/v3_cpols.c
@@ -1,6 +1,7 @@
/* v3_cpols.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
*/
/* ====================================================================
* Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved.
@@ -10,7 +11,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -72,35 +73,38 @@
/* Certificate policies extension support: this one is a bit complex... */
-static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol, BIO *out, int indent);
-static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *value);
-static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals, int indent);
+static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol,
+ BIO *out, int indent);
+static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method,
+ X509V3_CTX *ctx, char *value);
+static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals,
+ int indent);
static void print_notice(BIO *out, USERNOTICE *notice, int indent);
static POLICYINFO *policy_section(X509V3_CTX *ctx,
- STACK_OF(CONF_VALUE) *polstrs, int ia5org);
+ STACK_OF(CONF_VALUE) *polstrs, int ia5org);
static POLICYQUALINFO *notice_section(X509V3_CTX *ctx,
- STACK_OF(CONF_VALUE) *unot, int ia5org);
+ STACK_OF(CONF_VALUE) *unot, int ia5org);
static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos);
const X509V3_EXT_METHOD v3_cpols = {
-NID_certificate_policies, 0,ASN1_ITEM_ref(CERTIFICATEPOLICIES),
-0,0,0,0,
-0,0,
-0,0,
-(X509V3_EXT_I2R)i2r_certpol,
-(X509V3_EXT_R2I)r2i_certpol,
-NULL
+ NID_certificate_policies, 0, ASN1_ITEM_ref(CERTIFICATEPOLICIES),
+ 0, 0, 0, 0,
+ 0, 0,
+ 0, 0,
+ (X509V3_EXT_I2R)i2r_certpol,
+ (X509V3_EXT_R2I)r2i_certpol,
+ NULL
};
-ASN1_ITEM_TEMPLATE(CERTIFICATEPOLICIES) =
- ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, CERTIFICATEPOLICIES, POLICYINFO)
+ASN1_ITEM_TEMPLATE(CERTIFICATEPOLICIES) =
+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, CERTIFICATEPOLICIES, POLICYINFO)
ASN1_ITEM_TEMPLATE_END(CERTIFICATEPOLICIES)
IMPLEMENT_ASN1_FUNCTIONS(CERTIFICATEPOLICIES)
ASN1_SEQUENCE(POLICYINFO) = {
- ASN1_SIMPLE(POLICYINFO, policyid, ASN1_OBJECT),
- ASN1_SEQUENCE_OF_OPT(POLICYINFO, qualifiers, POLICYQUALINFO)
+ ASN1_SIMPLE(POLICYINFO, policyid, ASN1_OBJECT),
+ ASN1_SEQUENCE_OF_OPT(POLICYINFO, qualifiers, POLICYQUALINFO)
} ASN1_SEQUENCE_END(POLICYINFO)
IMPLEMENT_ASN1_FUNCTIONS(POLICYINFO)
@@ -108,368 +112,385 @@ IMPLEMENT_ASN1_FUNCTIONS(POLICYINFO)
ASN1_ADB_TEMPLATE(policydefault) = ASN1_SIMPLE(POLICYQUALINFO, d.other, ASN1_ANY);
ASN1_ADB(POLICYQUALINFO) = {
- ADB_ENTRY(NID_id_qt_cps, ASN1_SIMPLE(POLICYQUALINFO, d.cpsuri, ASN1_IA5STRING)),
- ADB_ENTRY(NID_id_qt_unotice, ASN1_SIMPLE(POLICYQUALINFO, d.usernotice, USERNOTICE))
+ ADB_ENTRY(NID_id_qt_cps, ASN1_SIMPLE(POLICYQUALINFO, d.cpsuri, ASN1_IA5STRING)),
+ ADB_ENTRY(NID_id_qt_unotice, ASN1_SIMPLE(POLICYQUALINFO, d.usernotice, USERNOTICE))
} ASN1_ADB_END(POLICYQUALINFO, 0, pqualid, 0, &policydefault_tt, NULL);
ASN1_SEQUENCE(POLICYQUALINFO) = {
- ASN1_SIMPLE(POLICYQUALINFO, pqualid, ASN1_OBJECT),
- ASN1_ADB_OBJECT(POLICYQUALINFO)
+ ASN1_SIMPLE(POLICYQUALINFO, pqualid, ASN1_OBJECT),
+ ASN1_ADB_OBJECT(POLICYQUALINFO)
} ASN1_SEQUENCE_END(POLICYQUALINFO)
IMPLEMENT_ASN1_FUNCTIONS(POLICYQUALINFO)
ASN1_SEQUENCE(USERNOTICE) = {
- ASN1_OPT(USERNOTICE, noticeref, NOTICEREF),
- ASN1_OPT(USERNOTICE, exptext, DISPLAYTEXT)
+ ASN1_OPT(USERNOTICE, noticeref, NOTICEREF),
+ ASN1_OPT(USERNOTICE, exptext, DISPLAYTEXT)
} ASN1_SEQUENCE_END(USERNOTICE)
IMPLEMENT_ASN1_FUNCTIONS(USERNOTICE)
ASN1_SEQUENCE(NOTICEREF) = {
- ASN1_SIMPLE(NOTICEREF, organization, DISPLAYTEXT),
- ASN1_SEQUENCE_OF(NOTICEREF, noticenos, ASN1_INTEGER)
+ ASN1_SIMPLE(NOTICEREF, organization, DISPLAYTEXT),
+ ASN1_SEQUENCE_OF(NOTICEREF, noticenos, ASN1_INTEGER)
} ASN1_SEQUENCE_END(NOTICEREF)
IMPLEMENT_ASN1_FUNCTIONS(NOTICEREF)
static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method,
- X509V3_CTX *ctx, char *value)
+ X509V3_CTX *ctx, char *value)
{
- STACK_OF(POLICYINFO) *pols = NULL;
- char *pstr;
- POLICYINFO *pol;
- ASN1_OBJECT *pobj;
- STACK_OF(CONF_VALUE) *vals;
- CONF_VALUE *cnf;
- size_t i;
- int ia5org;
- pols = sk_POLICYINFO_new_null();
- if (pols == NULL) {
- OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
- vals = X509V3_parse_list(value);
- if (vals == NULL) {
- 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, X509V3_R_INVALID_POLICY_IDENTIFIER);
- X509V3_conf_err(cnf);
- goto err;
- }
- pstr = cnf->name;
- if(!strcmp(pstr,"ia5org")) {
- ia5org = 1;
- continue;
- } else if(*pstr == '@') {
- STACK_OF(CONF_VALUE) *polsect;
- polsect = X509V3_get_section(ctx, pstr + 1);
- if(!polsect) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SECTION);
-
- X509V3_conf_err(cnf);
- goto err;
- }
- pol = policy_section(ctx, polsect, ia5org);
- X509V3_section_free(ctx, polsect);
- if(!pol) goto err;
- } else {
- if(!(pobj = OBJ_txt2obj(cnf->name, 0))) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER);
- X509V3_conf_err(cnf);
- goto err;
- }
- pol = POLICYINFO_new();
- pol->policyid = pobj;
- }
- if (!sk_POLICYINFO_push(pols, pol)){
- POLICYINFO_free(pol);
- OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- }
- sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
- return pols;
- err:
- sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
- sk_POLICYINFO_pop_free(pols, POLICYINFO_free);
- return NULL;
+ STACK_OF(POLICYINFO) *pols = NULL;
+ char *pstr;
+ POLICYINFO *pol;
+ ASN1_OBJECT *pobj;
+ STACK_OF(CONF_VALUE) *vals;
+ CONF_VALUE *cnf;
+ size_t i;
+ int ia5org;
+ pols = sk_POLICYINFO_new_null();
+ if (pols == NULL) {
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ vals = X509V3_parse_list(value);
+ if (vals == NULL) {
+ 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, X509V3_R_INVALID_POLICY_IDENTIFIER);
+ X509V3_conf_err(cnf);
+ goto err;
+ }
+ pstr = cnf->name;
+ if (!strcmp(pstr, "ia5org")) {
+ ia5org = 1;
+ continue;
+ } else if (*pstr == '@') {
+ STACK_OF(CONF_VALUE) *polsect;
+ polsect = X509V3_get_section(ctx, pstr + 1);
+ if (!polsect) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SECTION);
+
+ X509V3_conf_err(cnf);
+ goto err;
+ }
+ pol = policy_section(ctx, polsect, ia5org);
+ X509V3_section_free(ctx, polsect);
+ if (!pol)
+ goto err;
+ } else {
+ if (!(pobj = OBJ_txt2obj(cnf->name, 0))) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER);
+ X509V3_conf_err(cnf);
+ goto err;
+ }
+ pol = POLICYINFO_new();
+ if (pol == NULL) {
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+ ASN1_OBJECT_free(pobj);
+ goto err;
+ }
+ pol->policyid = pobj;
+ }
+ if (!sk_POLICYINFO_push(pols, pol)) {
+ POLICYINFO_free(pol);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+ sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
+ return pols;
+ err:
+ sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
+ sk_POLICYINFO_pop_free(pols, POLICYINFO_free);
+ return NULL;
}
static POLICYINFO *policy_section(X509V3_CTX *ctx,
- STACK_OF(CONF_VALUE) *polstrs, int ia5org)
+ STACK_OF(CONF_VALUE) *polstrs, int ia5org)
{
- size_t i;
- CONF_VALUE *cnf;
- POLICYINFO *pol;
- POLICYQUALINFO *qual;
- if(!(pol = POLICYINFO_new())) goto merr;
- for(i = 0; i < sk_CONF_VALUE_num(polstrs); i++) {
- cnf = sk_CONF_VALUE_value(polstrs, i);
- if(!strcmp(cnf->name, "policyIdentifier")) {
- ASN1_OBJECT *pobj;
- if(!(pobj = OBJ_txt2obj(cnf->value, 0))) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER);
- X509V3_conf_err(cnf);
- goto err;
- }
- pol->policyid = pobj;
-
- } else if(!name_cmp(cnf->name, "CPS")) {
- if(!pol->qualifiers) pol->qualifiers =
- sk_POLICYQUALINFO_new_null();
- if(!(qual = POLICYQUALINFO_new())) goto merr;
- if(!sk_POLICYQUALINFO_push(pol->qualifiers, qual))
- goto merr;
- /* TODO(fork): const correctness */
- qual->pqualid = (ASN1_OBJECT*) OBJ_nid2obj(NID_id_qt_cps);
- if (qual->pqualid == NULL) {
- OPENSSL_PUT_ERROR(X509V3, ERR_R_INTERNAL_ERROR);
- goto err;
- }
- qual->d.cpsuri = M_ASN1_IA5STRING_new();
- if (qual->d.cpsuri == NULL) {
- goto err;
- }
- if(!ASN1_STRING_set(qual->d.cpsuri, cnf->value,
- strlen(cnf->value))) goto merr;
- } else if(!name_cmp(cnf->name, "userNotice")) {
- STACK_OF(CONF_VALUE) *unot;
- if(*cnf->value != '@') {
- 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, X509V3_R_INVALID_SECTION);
-
- X509V3_conf_err(cnf);
- goto err;
- }
- qual = notice_section(ctx, unot, ia5org);
- X509V3_section_free(ctx, unot);
- if(!qual) goto err;
- if(!pol->qualifiers) pol->qualifiers =
- sk_POLICYQUALINFO_new_null();
- if(!sk_POLICYQUALINFO_push(pol->qualifiers, qual))
- goto merr;
- } else {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OPTION);
-
- X509V3_conf_err(cnf);
- goto err;
- }
- }
- if(!pol->policyid) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_POLICY_IDENTIFIER);
- goto err;
- }
-
- return pol;
-
- merr:
- OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-
- err:
- POLICYINFO_free(pol);
- return NULL;
-
-
+ size_t i;
+ CONF_VALUE *cnf;
+ POLICYINFO *pol;
+ POLICYQUALINFO *qual;
+ if (!(pol = POLICYINFO_new()))
+ goto merr;
+ for (i = 0; i < sk_CONF_VALUE_num(polstrs); i++) {
+ cnf = sk_CONF_VALUE_value(polstrs, i);
+ if (!strcmp(cnf->name, "policyIdentifier")) {
+ ASN1_OBJECT *pobj;
+ if (!(pobj = OBJ_txt2obj(cnf->value, 0))) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER);
+ X509V3_conf_err(cnf);
+ goto err;
+ }
+ pol->policyid = pobj;
+
+ } else if (!name_cmp(cnf->name, "CPS")) {
+ if (!pol->qualifiers)
+ pol->qualifiers = sk_POLICYQUALINFO_new_null();
+ if (!(qual = POLICYQUALINFO_new()))
+ goto merr;
+ if (!sk_POLICYQUALINFO_push(pol->qualifiers, qual))
+ goto merr;
+ /* TODO(fork): const correctness */
+ qual->pqualid = (ASN1_OBJECT *)OBJ_nid2obj(NID_id_qt_cps);
+ if (qual->pqualid == NULL) {
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ qual->d.cpsuri = M_ASN1_IA5STRING_new();
+ if (qual->d.cpsuri == NULL) {
+ goto err;
+ }
+ if (!ASN1_STRING_set(qual->d.cpsuri, cnf->value,
+ strlen(cnf->value)))
+ goto merr;
+ } else if (!name_cmp(cnf->name, "userNotice")) {
+ STACK_OF(CONF_VALUE) *unot;
+ if (*cnf->value != '@') {
+ 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, X509V3_R_INVALID_SECTION);
+
+ X509V3_conf_err(cnf);
+ goto err;
+ }
+ qual = notice_section(ctx, unot, ia5org);
+ X509V3_section_free(ctx, unot);
+ if (!qual)
+ goto err;
+ if (!pol->qualifiers)
+ pol->qualifiers = sk_POLICYQUALINFO_new_null();
+ if (!sk_POLICYQUALINFO_push(pol->qualifiers, qual))
+ goto merr;
+ } else {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OPTION);
+
+ X509V3_conf_err(cnf);
+ goto err;
+ }
+ }
+ if (!pol->policyid) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_POLICY_IDENTIFIER);
+ goto err;
+ }
+
+ return pol;
+
+ merr:
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+
+ err:
+ POLICYINFO_free(pol);
+ return NULL;
+
}
static POLICYQUALINFO *notice_section(X509V3_CTX *ctx,
- STACK_OF(CONF_VALUE) *unot, int ia5org)
+ STACK_OF(CONF_VALUE) *unot, int ia5org)
{
- size_t i;
- int ret;
- CONF_VALUE *cnf;
- USERNOTICE *not;
- POLICYQUALINFO *qual;
- if(!(qual = POLICYQUALINFO_new())) goto merr;
- /* TODO(fork): const correctness */
- qual->pqualid = (ASN1_OBJECT *) OBJ_nid2obj(NID_id_qt_unotice);
- if (qual->pqualid == NULL)
- {
- OPENSSL_PUT_ERROR(X509V3, ERR_R_INTERNAL_ERROR);
- goto err;
- }
- if(!(not = USERNOTICE_new())) goto merr;
- qual->d.usernotice = not;
- for(i = 0; i < sk_CONF_VALUE_num(unot); i++) {
- cnf = sk_CONF_VALUE_value(unot, i);
- if(!strcmp(cnf->name, "explicitText")) {
- not->exptext = M_ASN1_VISIBLESTRING_new();
- if (not->exptext == NULL)
- goto merr;
- if(!ASN1_STRING_set(not->exptext, cnf->value,
- strlen(cnf->value))) goto merr;
- } else if(!strcmp(cnf->name, "organization")) {
- NOTICEREF *nref;
- if(!not->noticeref) {
- if(!(nref = NOTICEREF_new())) goto merr;
- not->noticeref = nref;
- } else nref = not->noticeref;
- if(ia5org) nref->organization->type = V_ASN1_IA5STRING;
- else nref->organization->type = V_ASN1_VISIBLESTRING;
- if(!ASN1_STRING_set(nref->organization, cnf->value,
- strlen(cnf->value))) goto merr;
- } else if(!strcmp(cnf->name, "noticeNumbers")) {
- NOTICEREF *nref;
- STACK_OF(CONF_VALUE) *nos;
- if(!not->noticeref) {
- if(!(nref = NOTICEREF_new())) goto merr;
- not->noticeref = nref;
- } else nref = not->noticeref;
- nos = X509V3_parse_list(cnf->value);
- if(!nos || !sk_CONF_VALUE_num(nos)) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NUMBERS);
- X509V3_conf_err(cnf);
- goto err;
- }
- ret = nref_nos(nref->noticenos, nos);
- sk_CONF_VALUE_pop_free(nos, X509V3_conf_free);
- if (!ret)
- goto err;
- } else {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OPTION);
- X509V3_conf_err(cnf);
- goto err;
- }
- }
-
- if(not->noticeref &&
- (!not->noticeref->noticenos || !not->noticeref->organization)) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_NEED_ORGANIZATION_AND_NUMBERS);
- goto err;
- }
-
- return qual;
-
- merr:
- OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-
- err:
- POLICYQUALINFO_free(qual);
- return NULL;
+ size_t i;
+ int ret;
+ CONF_VALUE *cnf;
+ USERNOTICE *not;
+ POLICYQUALINFO *qual;
+ if (!(qual = POLICYQUALINFO_new()))
+ goto merr;
+ /* TODO(fork): const correctness */
+ qual->pqualid = (ASN1_OBJECT *)OBJ_nid2obj(NID_id_qt_unotice);
+ if (qual->pqualid == NULL) {
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ if (!(not = USERNOTICE_new()))
+ goto merr;
+ qual->d.usernotice = not;
+ for (i = 0; i < sk_CONF_VALUE_num(unot); i++) {
+ cnf = sk_CONF_VALUE_value(unot, i);
+ if (!strcmp(cnf->name, "explicitText")) {
+ not->exptext = M_ASN1_VISIBLESTRING_new();
+ if (not->exptext == NULL)
+ goto merr;
+ if (!ASN1_STRING_set(not->exptext, cnf->value,
+ strlen(cnf->value)))
+ goto merr;
+ } else if (!strcmp(cnf->name, "organization")) {
+ NOTICEREF *nref;
+ if (!not->noticeref) {
+ if (!(nref = NOTICEREF_new()))
+ goto merr;
+ not->noticeref = nref;
+ } else
+ nref = not->noticeref;
+ if (ia5org)
+ nref->organization->type = V_ASN1_IA5STRING;
+ else
+ nref->organization->type = V_ASN1_VISIBLESTRING;
+ if (!ASN1_STRING_set(nref->organization, cnf->value,
+ strlen(cnf->value)))
+ goto merr;
+ } else if (!strcmp(cnf->name, "noticeNumbers")) {
+ NOTICEREF *nref;
+ STACK_OF(CONF_VALUE) *nos;
+ if (!not->noticeref) {
+ if (!(nref = NOTICEREF_new()))
+ goto merr;
+ not->noticeref = nref;
+ } else
+ nref = not->noticeref;
+ nos = X509V3_parse_list(cnf->value);
+ if (!nos || !sk_CONF_VALUE_num(nos)) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NUMBERS);
+ X509V3_conf_err(cnf);
+ goto err;
+ }
+ ret = nref_nos(nref->noticenos, nos);
+ sk_CONF_VALUE_pop_free(nos, X509V3_conf_free);
+ if (!ret)
+ goto err;
+ } else {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OPTION);
+ X509V3_conf_err(cnf);
+ goto err;
+ }
+ }
+
+ if (not->noticeref &&
+ (!not->noticeref->noticenos || !not->noticeref->organization)) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_NEED_ORGANIZATION_AND_NUMBERS);
+ goto err;
+ }
+
+ return qual;
+
+ merr:
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+
+ err:
+ POLICYQUALINFO_free(qual);
+ return NULL;
}
static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos)
{
- CONF_VALUE *cnf;
- ASN1_INTEGER *aint;
-
- size_t i;
-
- 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, X509V3_R_INVALID_NUMBER);
- goto err;
- }
- if(!sk_ASN1_INTEGER_push(nnums, aint)) goto merr;
- }
- return 1;
-
- merr:
- OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
-
- err:
- sk_ASN1_INTEGER_pop_free(nnums, ASN1_STRING_free);
- return 0;
+ CONF_VALUE *cnf;
+ ASN1_INTEGER *aint;
+
+ size_t i;
+
+ 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, X509V3_R_INVALID_NUMBER);
+ goto err;
+ }
+ if (!sk_ASN1_INTEGER_push(nnums, aint))
+ goto merr;
+ }
+ return 1;
+
+ merr:
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+
+ err:
+ sk_ASN1_INTEGER_pop_free(nnums, ASN1_STRING_free);
+ return 0;
}
-
static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol,
- BIO *out, int indent)
+ BIO *out, int indent)
{
- size_t i;
- POLICYINFO *pinfo;
- /* First print out the policy OIDs */
- for(i = 0; i < sk_POLICYINFO_num(pol); i++) {
- pinfo = sk_POLICYINFO_value(pol, i);
- BIO_printf(out, "%*sPolicy: ", indent, "");
- i2a_ASN1_OBJECT(out, pinfo->policyid);
- BIO_puts(out, "\n");
- if(pinfo->qualifiers)
- print_qualifiers(out, pinfo->qualifiers, indent + 2);
- }
- return 1;
+ size_t i;
+ POLICYINFO *pinfo;
+ /* First print out the policy OIDs */
+ for (i = 0; i < sk_POLICYINFO_num(pol); i++) {
+ pinfo = sk_POLICYINFO_value(pol, i);
+ BIO_printf(out, "%*sPolicy: ", indent, "");
+ i2a_ASN1_OBJECT(out, pinfo->policyid);
+ BIO_puts(out, "\n");
+ if (pinfo->qualifiers)
+ print_qualifiers(out, pinfo->qualifiers, indent + 2);
+ }
+ return 1;
}
static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals,
- int indent)
+ int indent)
{
- POLICYQUALINFO *qualinfo;
- size_t i;
- for(i = 0; i < sk_POLICYQUALINFO_num(quals); i++) {
- qualinfo = sk_POLICYQUALINFO_value(quals, i);
- switch(OBJ_obj2nid(qualinfo->pqualid))
- {
- case NID_id_qt_cps:
- BIO_printf(out, "%*sCPS: %s\n", indent, "",
- qualinfo->d.cpsuri->data);
- break;
-
- case NID_id_qt_unotice:
- BIO_printf(out, "%*sUser Notice:\n", indent, "");
- print_notice(out, qualinfo->d.usernotice, indent + 2);
- break;
-
- default:
- BIO_printf(out, "%*sUnknown Qualifier: ",
- indent + 2, "");
-
- i2a_ASN1_OBJECT(out, qualinfo->pqualid);
- BIO_puts(out, "\n");
- break;
- }
- }
+ POLICYQUALINFO *qualinfo;
+ size_t i;
+ for (i = 0; i < sk_POLICYQUALINFO_num(quals); i++) {
+ qualinfo = sk_POLICYQUALINFO_value(quals, i);
+ switch (OBJ_obj2nid(qualinfo->pqualid)) {
+ case NID_id_qt_cps:
+ BIO_printf(out, "%*sCPS: %s\n", indent, "",
+ qualinfo->d.cpsuri->data);
+ break;
+
+ case NID_id_qt_unotice:
+ BIO_printf(out, "%*sUser Notice:\n", indent, "");
+ print_notice(out, qualinfo->d.usernotice, indent + 2);
+ break;
+
+ default:
+ BIO_printf(out, "%*sUnknown Qualifier: ", indent + 2, "");
+
+ i2a_ASN1_OBJECT(out, qualinfo->pqualid);
+ BIO_puts(out, "\n");
+ break;
+ }
+ }
}
static void print_notice(BIO *out, USERNOTICE *notice, int indent)
{
- size_t i;
- if(notice->noticeref) {
- NOTICEREF *ref;
- ref = notice->noticeref;
- BIO_printf(out, "%*sOrganization: %s\n", indent, "",
- ref->organization->data);
- BIO_printf(out, "%*sNumber%s: ", indent, "",
- sk_ASN1_INTEGER_num(ref->noticenos) > 1 ? "s" : "");
- for(i = 0; i < sk_ASN1_INTEGER_num(ref->noticenos); i++) {
- ASN1_INTEGER *num;
- char *tmp;
- num = sk_ASN1_INTEGER_value(ref->noticenos, i);
- if(i) BIO_puts(out, ", ");
- tmp = i2s_ASN1_INTEGER(NULL, num);
- BIO_puts(out, tmp);
- OPENSSL_free(tmp);
- }
- BIO_puts(out, "\n");
- }
- if(notice->exptext)
- BIO_printf(out, "%*sExplicit Text: %s\n", indent, "",
- notice->exptext->data);
+ size_t i;
+ if (notice->noticeref) {
+ NOTICEREF *ref;
+ ref = notice->noticeref;
+ BIO_printf(out, "%*sOrganization: %s\n", indent, "",
+ ref->organization->data);
+ BIO_printf(out, "%*sNumber%s: ", indent, "",
+ sk_ASN1_INTEGER_num(ref->noticenos) > 1 ? "s" : "");
+ for (i = 0; i < sk_ASN1_INTEGER_num(ref->noticenos); i++) {
+ ASN1_INTEGER *num;
+ char *tmp;
+ num = sk_ASN1_INTEGER_value(ref->noticenos, i);
+ if (i)
+ BIO_puts(out, ", ");
+ tmp = i2s_ASN1_INTEGER(NULL, num);
+ BIO_puts(out, tmp);
+ OPENSSL_free(tmp);
+ }
+ BIO_puts(out, "\n");
+ }
+ if (notice->exptext)
+ BIO_printf(out, "%*sExplicit Text: %s\n", indent, "",
+ notice->exptext->data);
}
void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent)
- {
- const X509_POLICY_DATA *dat = node->data;
-
- BIO_printf(out, "%*sPolicy: ", indent, "");
-
- i2a_ASN1_OBJECT(out, dat->valid_policy);
- BIO_puts(out, "\n");
- BIO_printf(out, "%*s%s\n", indent + 2, "",
- node_data_critical(dat) ? "Critical" : "Non Critical");
- if (dat->qualifier_set)
- print_qualifiers(out, dat->qualifier_set, indent + 2);
- else
- BIO_printf(out, "%*sNo Qualifiers\n", indent + 2, "");
- }
+{
+ const X509_POLICY_DATA *dat = node->data;
+
+ BIO_printf(out, "%*sPolicy: ", indent, "");
+
+ i2a_ASN1_OBJECT(out, dat->valid_policy);
+ BIO_puts(out, "\n");
+ BIO_printf(out, "%*s%s\n", indent + 2, "",
+ node_data_critical(dat) ? "Critical" : "Non Critical");
+ if (dat->qualifier_set)
+ print_qualifiers(out, dat->qualifier_set, indent + 2);
+ else
+ BIO_printf(out, "%*sNo Qualifiers\n", indent + 2, "");
+}
diff --git a/src/crypto/x509v3/v3_crld.c b/src/crypto/x509v3/v3_crld.c
index 3984c316..c93c4495 100644
--- a/src/crypto/x509v3/v3_crld.c
+++ b/src/crypto/x509v3/v3_crld.c
@@ -1,6 +1,7 @@
/* v3_crld.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
*/
/* ====================================================================
* Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved.
@@ -10,7 +11,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -65,552 +66,496 @@
#include <openssl/obj.h>
#include <openssl/x509v3.h>
-
static void *v2i_crld(const X509V3_EXT_METHOD *method,
- X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
+ X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out,
- int indent);
-
-const X509V3_EXT_METHOD v3_crld =
- {
- NID_crl_distribution_points, 0, ASN1_ITEM_ref(CRL_DIST_POINTS),
- 0,0,0,0,
- 0,0,
- 0,
- v2i_crld,
- i2r_crldp,0,
- NULL
- };
-
-const X509V3_EXT_METHOD v3_freshest_crl =
- {
- NID_freshest_crl, 0, ASN1_ITEM_ref(CRL_DIST_POINTS),
- 0,0,0,0,
- 0,0,
- 0,
- v2i_crld,
- i2r_crldp,0,
- NULL
- };
-
-static STACK_OF(GENERAL_NAME) *gnames_from_sectname(X509V3_CTX *ctx, char *sect)
- {
- STACK_OF(CONF_VALUE) *gnsect;
- STACK_OF(GENERAL_NAME) *gens;
- if (*sect == '@')
- gnsect = X509V3_get_section(ctx, sect + 1);
- else
- gnsect = X509V3_parse_list(sect);
- if (!gnsect)
- {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_SECTION_NOT_FOUND);
- return NULL;
- }
- gens = v2i_GENERAL_NAMES(NULL, ctx, gnsect);
- if (*sect == '@')
- X509V3_section_free(ctx, gnsect);
- else
- sk_CONF_VALUE_pop_free(gnsect, X509V3_conf_free);
- return gens;
- }
+ int indent);
+
+const X509V3_EXT_METHOD v3_crld = {
+ NID_crl_distribution_points, 0, ASN1_ITEM_ref(CRL_DIST_POINTS),
+ 0, 0, 0, 0,
+ 0, 0,
+ 0,
+ v2i_crld,
+ i2r_crldp, 0,
+ NULL
+};
+
+const X509V3_EXT_METHOD v3_freshest_crl = {
+ NID_freshest_crl, 0, ASN1_ITEM_ref(CRL_DIST_POINTS),
+ 0, 0, 0, 0,
+ 0, 0,
+ 0,
+ v2i_crld,
+ i2r_crldp, 0,
+ NULL
+};
+
+static STACK_OF(GENERAL_NAME) *gnames_from_sectname(X509V3_CTX *ctx,
+ char *sect)
+{
+ STACK_OF(CONF_VALUE) *gnsect;
+ STACK_OF(GENERAL_NAME) *gens;
+ if (*sect == '@')
+ gnsect = X509V3_get_section(ctx, sect + 1);
+ else
+ gnsect = X509V3_parse_list(sect);
+ if (!gnsect) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_SECTION_NOT_FOUND);
+ return NULL;
+ }
+ gens = v2i_GENERAL_NAMES(NULL, ctx, gnsect);
+ if (*sect == '@')
+ X509V3_section_free(ctx, gnsect);
+ else
+ sk_CONF_VALUE_pop_free(gnsect, X509V3_conf_free);
+ return gens;
+}
static int set_dist_point_name(DIST_POINT_NAME **pdp, X509V3_CTX *ctx,
- CONF_VALUE *cnf)
- {
- STACK_OF(GENERAL_NAME) *fnm = NULL;
- STACK_OF(X509_NAME_ENTRY) *rnm = NULL;
- if (!strncmp(cnf->name, "fullname", 9))
- {
- fnm = gnames_from_sectname(ctx, cnf->value);
- if (!fnm)
- goto err;
- }
- else if (!strcmp(cnf->name, "relativename"))
- {
- int ret;
- STACK_OF(CONF_VALUE) *dnsect;
- X509_NAME *nm;
- nm = X509_NAME_new();
- if (!nm)
- return -1;
- dnsect = X509V3_get_section(ctx, cnf->value);
- if (!dnsect)
- {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_SECTION_NOT_FOUND);
- return -1;
- }
- ret = X509V3_NAME_from_section(nm, dnsect, MBSTRING_ASC);
- X509V3_section_free(ctx, dnsect);
- rnm = nm->entries;
- nm->entries = NULL;
- X509_NAME_free(nm);
- if (!ret || sk_X509_NAME_ENTRY_num(rnm) <= 0)
- goto err;
- /* Since its a name fragment can't have more than one
- * RDNSequence
- */
- if (sk_X509_NAME_ENTRY_value(rnm,
- sk_X509_NAME_ENTRY_num(rnm) - 1)->set)
- {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_MULTIPLE_RDNS);
- goto err;
- }
- }
- else
- return 0;
-
- if (*pdp)
- {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_DISTPOINT_ALREADY_SET);
- goto err;
- }
-
- *pdp = DIST_POINT_NAME_new();
- if (!*pdp)
- goto err;
- if (fnm)
- {
- (*pdp)->type = 0;
- (*pdp)->name.fullname = fnm;
- }
- else
- {
- (*pdp)->type = 1;
- (*pdp)->name.relativename = rnm;
- }
-
- return 1;
-
- err:
- if (fnm)
- sk_GENERAL_NAME_pop_free(fnm, GENERAL_NAME_free);
- if (rnm)
- sk_X509_NAME_ENTRY_pop_free(rnm, X509_NAME_ENTRY_free);
- return -1;
- }
+ CONF_VALUE *cnf)
+{
+ STACK_OF(GENERAL_NAME) *fnm = NULL;
+ STACK_OF(X509_NAME_ENTRY) *rnm = NULL;
+ if (!strncmp(cnf->name, "fullname", 9)) {
+ fnm = gnames_from_sectname(ctx, cnf->value);
+ if (!fnm)
+ goto err;
+ } else if (!strcmp(cnf->name, "relativename")) {
+ int ret;
+ STACK_OF(CONF_VALUE) *dnsect;
+ X509_NAME *nm;
+ nm = X509_NAME_new();
+ if (!nm)
+ return -1;
+ dnsect = X509V3_get_section(ctx, cnf->value);
+ if (!dnsect) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_SECTION_NOT_FOUND);
+ return -1;
+ }
+ ret = X509V3_NAME_from_section(nm, dnsect, MBSTRING_ASC);
+ X509V3_section_free(ctx, dnsect);
+ rnm = nm->entries;
+ nm->entries = NULL;
+ X509_NAME_free(nm);
+ if (!ret || sk_X509_NAME_ENTRY_num(rnm) <= 0)
+ goto err;
+ /*
+ * Since its a name fragment can't have more than one RDNSequence
+ */
+ if (sk_X509_NAME_ENTRY_value(rnm,
+ sk_X509_NAME_ENTRY_num(rnm) - 1)->set) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_MULTIPLE_RDNS);
+ goto err;
+ }
+ } else
+ return 0;
+
+ if (*pdp) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_DISTPOINT_ALREADY_SET);
+ goto err;
+ }
+
+ *pdp = DIST_POINT_NAME_new();
+ if (!*pdp)
+ goto err;
+ if (fnm) {
+ (*pdp)->type = 0;
+ (*pdp)->name.fullname = fnm;
+ } else {
+ (*pdp)->type = 1;
+ (*pdp)->name.relativename = rnm;
+ }
+
+ return 1;
+
+ err:
+ if (fnm)
+ sk_GENERAL_NAME_pop_free(fnm, GENERAL_NAME_free);
+ if (rnm)
+ sk_X509_NAME_ENTRY_pop_free(rnm, X509_NAME_ENTRY_free);
+ return -1;
+}
static const BIT_STRING_BITNAME reason_flags[] = {
-{0, "Unused", "unused"},
-{1, "Key Compromise", "keyCompromise"},
-{2, "CA Compromise", "CACompromise"},
-{3, "Affiliation Changed", "affiliationChanged"},
-{4, "Superseded", "superseded"},
-{5, "Cessation Of Operation", "cessationOfOperation"},
-{6, "Certificate Hold", "certificateHold"},
-{7, "Privilege Withdrawn", "privilegeWithdrawn"},
-{8, "AA Compromise", "AACompromise"},
-{-1, NULL, NULL}
+ {0, "Unused", "unused"},
+ {1, "Key Compromise", "keyCompromise"},
+ {2, "CA Compromise", "CACompromise"},
+ {3, "Affiliation Changed", "affiliationChanged"},
+ {4, "Superseded", "superseded"},
+ {5, "Cessation Of Operation", "cessationOfOperation"},
+ {6, "Certificate Hold", "certificateHold"},
+ {7, "Privilege Withdrawn", "privilegeWithdrawn"},
+ {8, "AA Compromise", "AACompromise"},
+ {-1, NULL, NULL}
};
static int set_reasons(ASN1_BIT_STRING **preas, char *value)
- {
- STACK_OF(CONF_VALUE) *rsk = NULL;
- const BIT_STRING_BITNAME *pbn;
- const char *bnam;
- size_t i;
- int ret = 0;
- rsk = X509V3_parse_list(value);
- if (!rsk)
- return 0;
- if (*preas)
- return 0;
- for (i = 0; i < sk_CONF_VALUE_num(rsk); i++)
- {
- bnam = sk_CONF_VALUE_value(rsk, i)->name;
- if (!*preas)
- {
- *preas = ASN1_BIT_STRING_new();
- if (!*preas)
- goto err;
- }
- for (pbn = reason_flags; pbn->lname; pbn++)
- {
- if (!strcmp(pbn->sname, bnam))
- {
- if (!ASN1_BIT_STRING_set_bit(*preas,
- pbn->bitnum, 1))
- goto err;
- break;
- }
- }
- if (!pbn->lname)
- goto err;
- }
- ret = 1;
-
- err:
- sk_CONF_VALUE_pop_free(rsk, X509V3_conf_free);
- return ret;
- }
+{
+ STACK_OF(CONF_VALUE) *rsk = NULL;
+ const BIT_STRING_BITNAME *pbn;
+ const char *bnam;
+ size_t i;
+ int ret = 0;
+ rsk = X509V3_parse_list(value);
+ if (!rsk)
+ return 0;
+ if (*preas)
+ return 0;
+ for (i = 0; i < sk_CONF_VALUE_num(rsk); i++) {
+ bnam = sk_CONF_VALUE_value(rsk, i)->name;
+ if (!*preas) {
+ *preas = ASN1_BIT_STRING_new();
+ if (!*preas)
+ goto err;
+ }
+ for (pbn = reason_flags; pbn->lname; pbn++) {
+ if (!strcmp(pbn->sname, bnam)) {
+ if (!ASN1_BIT_STRING_set_bit(*preas, pbn->bitnum, 1))
+ goto err;
+ break;
+ }
+ }
+ if (!pbn->lname)
+ goto err;
+ }
+ ret = 1;
+
+ err:
+ sk_CONF_VALUE_pop_free(rsk, X509V3_conf_free);
+ return ret;
+}
static int print_reasons(BIO *out, const char *rname,
- ASN1_BIT_STRING *rflags, int indent)
- {
- int first = 1;
- const BIT_STRING_BITNAME *pbn;
- BIO_printf(out, "%*s%s:\n%*s", indent, "", rname, indent + 2, "");
- for (pbn = reason_flags; pbn->lname; pbn++)
- {
- if (ASN1_BIT_STRING_get_bit(rflags, pbn->bitnum))
- {
- if (first)
- first = 0;
- else
- BIO_puts(out, ", ");
- BIO_puts(out, pbn->lname);
- }
- }
- if (first)
- BIO_puts(out, "<EMPTY>\n");
- else
- BIO_puts(out, "\n");
- return 1;
- }
+ ASN1_BIT_STRING *rflags, int indent)
+{
+ int first = 1;
+ const BIT_STRING_BITNAME *pbn;
+ BIO_printf(out, "%*s%s:\n%*s", indent, "", rname, indent + 2, "");
+ for (pbn = reason_flags; pbn->lname; pbn++) {
+ if (ASN1_BIT_STRING_get_bit(rflags, pbn->bitnum)) {
+ if (first)
+ first = 0;
+ else
+ BIO_puts(out, ", ");
+ BIO_puts(out, pbn->lname);
+ }
+ }
+ if (first)
+ BIO_puts(out, "<EMPTY>\n");
+ else
+ BIO_puts(out, "\n");
+ return 1;
+}
static DIST_POINT *crldp_from_section(X509V3_CTX *ctx,
- STACK_OF(CONF_VALUE) *nval)
- {
- size_t i;
- CONF_VALUE *cnf;
- DIST_POINT *point = NULL;
- point = DIST_POINT_new();
- if (!point)
- goto err;
- for(i = 0; i < sk_CONF_VALUE_num(nval); i++)
- {
- int ret;
- cnf = sk_CONF_VALUE_value(nval, i);
- ret = set_dist_point_name(&point->distpoint, ctx, cnf);
- if (ret > 0)
- continue;
- if (ret < 0)
- goto err;
- if (!strcmp(cnf->name, "reasons"))
- {
- if (!set_reasons(&point->reasons, cnf->value))
- goto err;
- }
- else if (!strcmp(cnf->name, "CRLissuer"))
- {
- point->CRLissuer =
- gnames_from_sectname(ctx, cnf->value);
- if (!point->CRLissuer)
- goto err;
- }
- }
-
- return point;
-
-
- err:
- if (point)
- DIST_POINT_free(point);
- return NULL;
- }
+ STACK_OF(CONF_VALUE) *nval)
+{
+ size_t i;
+ CONF_VALUE *cnf;
+ DIST_POINT *point = NULL;
+ point = DIST_POINT_new();
+ if (!point)
+ goto err;
+ for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+ int ret;
+ cnf = sk_CONF_VALUE_value(nval, i);
+ ret = set_dist_point_name(&point->distpoint, ctx, cnf);
+ if (ret > 0)
+ continue;
+ if (ret < 0)
+ goto err;
+ if (!strcmp(cnf->name, "reasons")) {
+ if (!set_reasons(&point->reasons, cnf->value))
+ goto err;
+ } else if (!strcmp(cnf->name, "CRLissuer")) {
+ point->CRLissuer = gnames_from_sectname(ctx, cnf->value);
+ if (!point->CRLissuer)
+ goto err;
+ }
+ }
+
+ return point;
+
+ err:
+ if (point)
+ DIST_POINT_free(point);
+ return NULL;
+}
static void *v2i_crld(const X509V3_EXT_METHOD *method,
- X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
- {
- STACK_OF(DIST_POINT) *crld = NULL;
- GENERAL_NAMES *gens = NULL;
- GENERAL_NAME *gen = NULL;
- CONF_VALUE *cnf;
- size_t i;
- if(!(crld = sk_DIST_POINT_new_null())) goto merr;
- for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
- DIST_POINT *point;
- cnf = sk_CONF_VALUE_value(nval, i);
- if (!cnf->value)
- {
- STACK_OF(CONF_VALUE) *dpsect;
- dpsect = X509V3_get_section(ctx, cnf->name);
- if (!dpsect)
- goto err;
- point = crldp_from_section(ctx, dpsect);
- X509V3_section_free(ctx, dpsect);
- if (!point)
- goto err;
- if(!sk_DIST_POINT_push(crld, point))
- {
- DIST_POINT_free(point);
- goto merr;
- }
- }
- else
- {
- if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
- goto err;
- if(!(gens = GENERAL_NAMES_new()))
- goto merr;
- if(!sk_GENERAL_NAME_push(gens, gen))
- goto merr;
- gen = NULL;
- if(!(point = DIST_POINT_new()))
- goto merr;
- if(!sk_DIST_POINT_push(crld, point))
- {
- DIST_POINT_free(point);
- goto merr;
- }
- if(!(point->distpoint = DIST_POINT_NAME_new()))
- goto merr;
- point->distpoint->name.fullname = gens;
- point->distpoint->type = 0;
- gens = NULL;
- }
- }
- return crld;
-
- merr:
- OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
- err:
- GENERAL_NAME_free(gen);
- GENERAL_NAMES_free(gens);
- sk_DIST_POINT_pop_free(crld, DIST_POINT_free);
- return NULL;
+ X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
+{
+ STACK_OF(DIST_POINT) *crld = NULL;
+ GENERAL_NAMES *gens = NULL;
+ GENERAL_NAME *gen = NULL;
+ CONF_VALUE *cnf;
+ size_t i;
+ if (!(crld = sk_DIST_POINT_new_null()))
+ goto merr;
+ for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+ DIST_POINT *point;
+ cnf = sk_CONF_VALUE_value(nval, i);
+ if (!cnf->value) {
+ STACK_OF(CONF_VALUE) *dpsect;
+ dpsect = X509V3_get_section(ctx, cnf->name);
+ if (!dpsect)
+ goto err;
+ point = crldp_from_section(ctx, dpsect);
+ X509V3_section_free(ctx, dpsect);
+ if (!point)
+ goto err;
+ if (!sk_DIST_POINT_push(crld, point)) {
+ DIST_POINT_free(point);
+ goto merr;
+ }
+ } else {
+ if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
+ goto err;
+ if (!(gens = GENERAL_NAMES_new()))
+ goto merr;
+ if (!sk_GENERAL_NAME_push(gens, gen))
+ goto merr;
+ gen = NULL;
+ if (!(point = DIST_POINT_new()))
+ goto merr;
+ if (!sk_DIST_POINT_push(crld, point)) {
+ DIST_POINT_free(point);
+ goto merr;
+ }
+ if (!(point->distpoint = DIST_POINT_NAME_new()))
+ goto merr;
+ point->distpoint->name.fullname = gens;
+ point->distpoint->type = 0;
+ gens = NULL;
+ }
+ }
+ return crld;
+
+ merr:
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+ err:
+ GENERAL_NAME_free(gen);
+ GENERAL_NAMES_free(gens);
+ sk_DIST_POINT_pop_free(crld, DIST_POINT_free);
+ return NULL;
}
IMPLEMENT_ASN1_SET_OF(DIST_POINT)
static int dpn_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
- void *exarg)
- {
- DIST_POINT_NAME *dpn = (DIST_POINT_NAME *)*pval;
-
- switch(operation)
- {
- case ASN1_OP_NEW_POST:
- dpn->dpname = NULL;
- break;
-
- case ASN1_OP_FREE_POST:
- if (dpn->dpname)
- X509_NAME_free(dpn->dpname);
- break;
- }
- return 1;
- }
+ void *exarg)
+{
+ DIST_POINT_NAME *dpn = (DIST_POINT_NAME *)*pval;
+
+ switch (operation) {
+ case ASN1_OP_NEW_POST:
+ dpn->dpname = NULL;
+ break;
+
+ case ASN1_OP_FREE_POST:
+ if (dpn->dpname)
+ X509_NAME_free(dpn->dpname);
+ break;
+ }
+ return 1;
+}
ASN1_CHOICE_cb(DIST_POINT_NAME, dpn_cb) = {
- ASN1_IMP_SEQUENCE_OF(DIST_POINT_NAME, name.fullname, GENERAL_NAME, 0),
- ASN1_IMP_SET_OF(DIST_POINT_NAME, name.relativename, X509_NAME_ENTRY, 1)
+ ASN1_IMP_SEQUENCE_OF(DIST_POINT_NAME, name.fullname, GENERAL_NAME, 0),
+ ASN1_IMP_SET_OF(DIST_POINT_NAME, name.relativename, X509_NAME_ENTRY, 1)
} ASN1_CHOICE_END_cb(DIST_POINT_NAME, DIST_POINT_NAME, type)
IMPLEMENT_ASN1_FUNCTIONS(DIST_POINT_NAME)
ASN1_SEQUENCE(DIST_POINT) = {
- ASN1_EXP_OPT(DIST_POINT, distpoint, DIST_POINT_NAME, 0),
- ASN1_IMP_OPT(DIST_POINT, reasons, ASN1_BIT_STRING, 1),
- ASN1_IMP_SEQUENCE_OF_OPT(DIST_POINT, CRLissuer, GENERAL_NAME, 2)
+ ASN1_EXP_OPT(DIST_POINT, distpoint, DIST_POINT_NAME, 0),
+ ASN1_IMP_OPT(DIST_POINT, reasons, ASN1_BIT_STRING, 1),
+ ASN1_IMP_SEQUENCE_OF_OPT(DIST_POINT, CRLissuer, GENERAL_NAME, 2)
} ASN1_SEQUENCE_END(DIST_POINT)
IMPLEMENT_ASN1_FUNCTIONS(DIST_POINT)
-ASN1_ITEM_TEMPLATE(CRL_DIST_POINTS) =
- ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, CRLDistributionPoints, DIST_POINT)
+ASN1_ITEM_TEMPLATE(CRL_DIST_POINTS) =
+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, CRLDistributionPoints, DIST_POINT)
ASN1_ITEM_TEMPLATE_END(CRL_DIST_POINTS)
IMPLEMENT_ASN1_FUNCTIONS(CRL_DIST_POINTS)
ASN1_SEQUENCE(ISSUING_DIST_POINT) = {
- ASN1_EXP_OPT(ISSUING_DIST_POINT, distpoint, DIST_POINT_NAME, 0),
- ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyuser, ASN1_FBOOLEAN, 1),
- ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyCA, ASN1_FBOOLEAN, 2),
- ASN1_IMP_OPT(ISSUING_DIST_POINT, onlysomereasons, ASN1_BIT_STRING, 3),
- ASN1_IMP_OPT(ISSUING_DIST_POINT, indirectCRL, ASN1_FBOOLEAN, 4),
- ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyattr, ASN1_FBOOLEAN, 5)
+ ASN1_EXP_OPT(ISSUING_DIST_POINT, distpoint, DIST_POINT_NAME, 0),
+ ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyuser, ASN1_FBOOLEAN, 1),
+ ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyCA, ASN1_FBOOLEAN, 2),
+ ASN1_IMP_OPT(ISSUING_DIST_POINT, onlysomereasons, ASN1_BIT_STRING, 3),
+ ASN1_IMP_OPT(ISSUING_DIST_POINT, indirectCRL, ASN1_FBOOLEAN, 4),
+ ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyattr, ASN1_FBOOLEAN, 5)
} ASN1_SEQUENCE_END(ISSUING_DIST_POINT)
IMPLEMENT_ASN1_FUNCTIONS(ISSUING_DIST_POINT)
static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out,
- int indent);
+ int indent);
static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
- STACK_OF(CONF_VALUE) *nval);
-
-const X509V3_EXT_METHOD v3_idp =
- {
- NID_issuing_distribution_point, X509V3_EXT_MULTILINE,
- ASN1_ITEM_ref(ISSUING_DIST_POINT),
- 0,0,0,0,
- 0,0,
- 0,
- v2i_idp,
- i2r_idp,0,
- NULL
- };
+ STACK_OF(CONF_VALUE) *nval);
+
+const X509V3_EXT_METHOD v3_idp = {
+ NID_issuing_distribution_point, X509V3_EXT_MULTILINE,
+ ASN1_ITEM_ref(ISSUING_DIST_POINT),
+ 0, 0, 0, 0,
+ 0, 0,
+ 0,
+ v2i_idp,
+ i2r_idp, 0,
+ NULL
+};
static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
- STACK_OF(CONF_VALUE) *nval)
- {
- ISSUING_DIST_POINT *idp = NULL;
- CONF_VALUE *cnf;
- char *name, *val;
- size_t i;
- int ret;
- idp = ISSUING_DIST_POINT_new();
- if (!idp)
- goto merr;
- for(i = 0; i < sk_CONF_VALUE_num(nval); i++)
- {
- cnf = sk_CONF_VALUE_value(nval, i);
- name = cnf->name;
- val = cnf->value;
- ret = set_dist_point_name(&idp->distpoint, ctx, cnf);
- if (ret > 0)
- continue;
- if (ret < 0)
- goto err;
- if (!strcmp(name, "onlyuser"))
- {
- if (!X509V3_get_value_bool(cnf, &idp->onlyuser))
- goto err;
- }
- else if (!strcmp(name, "onlyCA"))
- {
- if (!X509V3_get_value_bool(cnf, &idp->onlyCA))
- goto err;
- }
- else if (!strcmp(name, "onlyAA"))
- {
- if (!X509V3_get_value_bool(cnf, &idp->onlyattr))
- goto err;
- }
- else if (!strcmp(name, "indirectCRL"))
- {
- if (!X509V3_get_value_bool(cnf, &idp->indirectCRL))
- goto err;
- }
- else if (!strcmp(name, "onlysomereasons"))
- {
- if (!set_reasons(&idp->onlysomereasons, val))
- goto err;
- }
- else
- {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NAME);
- X509V3_conf_err(cnf);
- goto err;
- }
- }
- return idp;
-
- merr:
- OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
- err:
- ISSUING_DIST_POINT_free(idp);
- return NULL;
- }
+ STACK_OF(CONF_VALUE) *nval)
+{
+ ISSUING_DIST_POINT *idp = NULL;
+ CONF_VALUE *cnf;
+ char *name, *val;
+ size_t i;
+ int ret;
+ idp = ISSUING_DIST_POINT_new();
+ if (!idp)
+ goto merr;
+ for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+ cnf = sk_CONF_VALUE_value(nval, i);
+ name = cnf->name;
+ val = cnf->value;
+ ret = set_dist_point_name(&idp->distpoint, ctx, cnf);
+ if (ret > 0)
+ continue;
+ if (ret < 0)
+ goto err;
+ if (!strcmp(name, "onlyuser")) {
+ if (!X509V3_get_value_bool(cnf, &idp->onlyuser))
+ goto err;
+ } else if (!strcmp(name, "onlyCA")) {
+ if (!X509V3_get_value_bool(cnf, &idp->onlyCA))
+ goto err;
+ } else if (!strcmp(name, "onlyAA")) {
+ if (!X509V3_get_value_bool(cnf, &idp->onlyattr))
+ goto err;
+ } else if (!strcmp(name, "indirectCRL")) {
+ if (!X509V3_get_value_bool(cnf, &idp->indirectCRL))
+ goto err;
+ } else if (!strcmp(name, "onlysomereasons")) {
+ if (!set_reasons(&idp->onlysomereasons, val))
+ goto err;
+ } else {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NAME);
+ X509V3_conf_err(cnf);
+ goto err;
+ }
+ }
+ return idp;
+
+ merr:
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+ err:
+ ISSUING_DIST_POINT_free(idp);
+ return NULL;
+}
static int print_gens(BIO *out, STACK_OF(GENERAL_NAME) *gens, int indent)
- {
- size_t i;
- for (i = 0; i < sk_GENERAL_NAME_num(gens); i++)
- {
- BIO_printf(out, "%*s", indent + 2, "");
- GENERAL_NAME_print(out, sk_GENERAL_NAME_value(gens, i));
- BIO_puts(out, "\n");
- }
- return 1;
- }
+{
+ size_t i;
+ for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
+ BIO_printf(out, "%*s", indent + 2, "");
+ GENERAL_NAME_print(out, sk_GENERAL_NAME_value(gens, i));
+ BIO_puts(out, "\n");
+ }
+ return 1;
+}
static int print_distpoint(BIO *out, DIST_POINT_NAME *dpn, int indent)
- {
- if (dpn->type == 0)
- {
- BIO_printf(out, "%*sFull Name:\n", indent, "");
- print_gens(out, dpn->name.fullname, indent);
- }
- else
- {
- X509_NAME ntmp;
- ntmp.entries = dpn->name.relativename;
- BIO_printf(out, "%*sRelative Name:\n%*s",
- indent, "", indent + 2, "");
- X509_NAME_print_ex(out, &ntmp, 0, XN_FLAG_ONELINE);
- BIO_puts(out, "\n");
- }
- return 1;
- }
+{
+ if (dpn->type == 0) {
+ BIO_printf(out, "%*sFull Name:\n", indent, "");
+ print_gens(out, dpn->name.fullname, indent);
+ } else {
+ X509_NAME ntmp;
+ ntmp.entries = dpn->name.relativename;
+ BIO_printf(out, "%*sRelative Name:\n%*s", indent, "", indent + 2, "");
+ X509_NAME_print_ex(out, &ntmp, 0, XN_FLAG_ONELINE);
+ BIO_puts(out, "\n");
+ }
+ return 1;
+}
static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out,
- int indent)
- {
- ISSUING_DIST_POINT *idp = pidp;
- if (idp->distpoint)
- print_distpoint(out, idp->distpoint, indent);
- if (idp->onlyuser > 0)
- BIO_printf(out, "%*sOnly User Certificates\n", indent, "");
- if (idp->onlyCA > 0)
- BIO_printf(out, "%*sOnly CA Certificates\n", indent, "");
- if (idp->indirectCRL > 0)
- BIO_printf(out, "%*sIndirect CRL\n", indent, "");
- if (idp->onlysomereasons)
- print_reasons(out, "Only Some Reasons",
- idp->onlysomereasons, indent);
- if (idp->onlyattr > 0)
- BIO_printf(out, "%*sOnly Attribute Certificates\n", indent, "");
- if (!idp->distpoint && (idp->onlyuser <= 0) && (idp->onlyCA <= 0)
- && (idp->indirectCRL <= 0) && !idp->onlysomereasons
- && (idp->onlyattr <= 0))
- BIO_printf(out, "%*s<EMPTY>\n", indent, "");
-
- return 1;
- }
+ int indent)
+{
+ ISSUING_DIST_POINT *idp = pidp;
+ if (idp->distpoint)
+ print_distpoint(out, idp->distpoint, indent);
+ if (idp->onlyuser > 0)
+ BIO_printf(out, "%*sOnly User Certificates\n", indent, "");
+ if (idp->onlyCA > 0)
+ BIO_printf(out, "%*sOnly CA Certificates\n", indent, "");
+ if (idp->indirectCRL > 0)
+ BIO_printf(out, "%*sIndirect CRL\n", indent, "");
+ if (idp->onlysomereasons)
+ print_reasons(out, "Only Some Reasons", idp->onlysomereasons, indent);
+ if (idp->onlyattr > 0)
+ BIO_printf(out, "%*sOnly Attribute Certificates\n", indent, "");
+ if (!idp->distpoint && (idp->onlyuser <= 0) && (idp->onlyCA <= 0)
+ && (idp->indirectCRL <= 0) && !idp->onlysomereasons
+ && (idp->onlyattr <= 0))
+ BIO_printf(out, "%*s<EMPTY>\n", indent, "");
+
+ return 1;
+}
static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out,
- int indent)
- {
- STACK_OF(DIST_POINT) *crld = pcrldp;
- DIST_POINT *point;
- size_t i;
- for(i = 0; i < sk_DIST_POINT_num(crld); i++)
- {
- BIO_puts(out, "\n");
- point = sk_DIST_POINT_value(crld, i);
- if(point->distpoint)
- print_distpoint(out, point->distpoint, indent);
- if(point->reasons)
- print_reasons(out, "Reasons", point->reasons,
- indent);
- if(point->CRLissuer)
- {
- BIO_printf(out, "%*sCRL Issuer:\n", indent, "");
- print_gens(out, point->CRLissuer, indent);
- }
- }
- return 1;
- }
+ int indent)
+{
+ STACK_OF(DIST_POINT) *crld = pcrldp;
+ DIST_POINT *point;
+ size_t i;
+ for (i = 0; i < sk_DIST_POINT_num(crld); i++) {
+ BIO_puts(out, "\n");
+ point = sk_DIST_POINT_value(crld, i);
+ if (point->distpoint)
+ print_distpoint(out, point->distpoint, indent);
+ if (point->reasons)
+ print_reasons(out, "Reasons", point->reasons, indent);
+ if (point->CRLissuer) {
+ BIO_printf(out, "%*sCRL Issuer:\n", indent, "");
+ print_gens(out, point->CRLissuer, indent);
+ }
+ }
+ return 1;
+}
int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname)
- {
- size_t i;
- STACK_OF(X509_NAME_ENTRY) *frag;
- X509_NAME_ENTRY *ne;
- if (!dpn || (dpn->type != 1))
- return 1;
- frag = dpn->name.relativename;
- dpn->dpname = X509_NAME_dup(iname);
- if (!dpn->dpname)
- return 0;
- for (i = 0; i < sk_X509_NAME_ENTRY_num(frag); i++)
- {
- ne = sk_X509_NAME_ENTRY_value(frag, i);
- if (!X509_NAME_add_entry(dpn->dpname, ne, -1, i ? 0 : 1))
- {
- X509_NAME_free(dpn->dpname);
- dpn->dpname = NULL;
- return 0;
- }
- }
- /* generate cached encoding of name */
- if (i2d_X509_NAME(dpn->dpname, NULL) < 0)
- {
- X509_NAME_free(dpn->dpname);
- dpn->dpname = NULL;
- return 0;
- }
- return 1;
- }
+{
+ size_t i;
+ STACK_OF(X509_NAME_ENTRY) *frag;
+ X509_NAME_ENTRY *ne;
+ if (!dpn || (dpn->type != 1))
+ return 1;
+ frag = dpn->name.relativename;
+ dpn->dpname = X509_NAME_dup(iname);
+ if (!dpn->dpname)
+ return 0;
+ for (i = 0; i < sk_X509_NAME_ENTRY_num(frag); i++) {
+ ne = sk_X509_NAME_ENTRY_value(frag, i);
+ if (!X509_NAME_add_entry(dpn->dpname, ne, -1, i ? 0 : 1)) {
+ X509_NAME_free(dpn->dpname);
+ dpn->dpname = NULL;
+ return 0;
+ }
+ }
+ /* generate cached encoding of name */
+ if (i2d_X509_NAME(dpn->dpname, NULL) < 0) {
+ X509_NAME_free(dpn->dpname);
+ dpn->dpname = NULL;
+ return 0;
+ }
+ return 1;
+}
diff --git a/src/crypto/x509v3/v3_enum.c b/src/crypto/x509v3/v3_enum.c
index 0fe6bb63..6bfb232c 100644
--- a/src/crypto/x509v3/v3_enum.c
+++ b/src/crypto/x509v3/v3_enum.c
@@ -1,6 +1,7 @@
/* v3_enum.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
*/
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
@@ -10,7 +11,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -60,39 +61,40 @@
#include <openssl/obj.h>
#include <openssl/x509v3.h>
-
static const ENUMERATED_NAMES crl_reasons[] = {
-{CRL_REASON_UNSPECIFIED, "Unspecified", "unspecified"},
-{CRL_REASON_KEY_COMPROMISE, "Key Compromise", "keyCompromise"},
-{CRL_REASON_CA_COMPROMISE, "CA Compromise", "CACompromise"},
-{CRL_REASON_AFFILIATION_CHANGED, "Affiliation Changed", "affiliationChanged"},
-{CRL_REASON_SUPERSEDED, "Superseded", "superseded"},
-{CRL_REASON_CESSATION_OF_OPERATION,
- "Cessation Of Operation", "cessationOfOperation"},
-{CRL_REASON_CERTIFICATE_HOLD, "Certificate Hold", "certificateHold"},
-{CRL_REASON_REMOVE_FROM_CRL, "Remove From CRL", "removeFromCRL"},
-{CRL_REASON_PRIVILEGE_WITHDRAWN, "Privilege Withdrawn", "privilegeWithdrawn"},
-{CRL_REASON_AA_COMPROMISE, "AA Compromise", "AACompromise"},
-{-1, NULL, NULL}
+ {CRL_REASON_UNSPECIFIED, "Unspecified", "unspecified"},
+ {CRL_REASON_KEY_COMPROMISE, "Key Compromise", "keyCompromise"},
+ {CRL_REASON_CA_COMPROMISE, "CA Compromise", "CACompromise"},
+ {CRL_REASON_AFFILIATION_CHANGED, "Affiliation Changed",
+ "affiliationChanged"},
+ {CRL_REASON_SUPERSEDED, "Superseded", "superseded"},
+ {CRL_REASON_CESSATION_OF_OPERATION,
+ "Cessation Of Operation", "cessationOfOperation"},
+ {CRL_REASON_CERTIFICATE_HOLD, "Certificate Hold", "certificateHold"},
+ {CRL_REASON_REMOVE_FROM_CRL, "Remove From CRL", "removeFromCRL"},
+ {CRL_REASON_PRIVILEGE_WITHDRAWN, "Privilege Withdrawn",
+ "privilegeWithdrawn"},
+ {CRL_REASON_AA_COMPROMISE, "AA Compromise", "AACompromise"},
+ {-1, NULL, NULL}
};
-const X509V3_EXT_METHOD v3_crl_reason = {
-NID_crl_reason, 0, ASN1_ITEM_ref(ASN1_ENUMERATED),
-0,0,0,0,
-(X509V3_EXT_I2S)i2s_ASN1_ENUMERATED_TABLE,
-0,
-0,0,0,0,
-(void *)crl_reasons};
-
+const X509V3_EXT_METHOD v3_crl_reason = {
+ NID_crl_reason, 0, ASN1_ITEM_ref(ASN1_ENUMERATED),
+ 0, 0, 0, 0,
+ (X509V3_EXT_I2S)i2s_ASN1_ENUMERATED_TABLE,
+ 0,
+ 0, 0, 0, 0,
+ (void *)crl_reasons
+};
-char *i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *method,
- ASN1_ENUMERATED *e)
+char *i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *method, ASN1_ENUMERATED *e)
{
- const ENUMERATED_NAMES *enam;
- long strval;
- strval = ASN1_ENUMERATED_get(e);
- for(enam = method->usr_data; enam->lname; enam++) {
- if(strval == enam->bitnum) return BUF_strdup(enam->lname);
- }
- return i2s_ASN1_ENUMERATED(method, e);
+ const ENUMERATED_NAMES *enam;
+ long strval;
+ strval = ASN1_ENUMERATED_get(e);
+ for (enam = method->usr_data; enam->lname; enam++) {
+ if (strval == enam->bitnum)
+ return BUF_strdup(enam->lname);
+ }
+ return i2s_ASN1_ENUMERATED(method, e);
}
diff --git a/src/crypto/x509v3/v3_extku.c b/src/crypto/x509v3/v3_extku.c
index d64eb9cc..952e032c 100644
--- a/src/crypto/x509v3/v3_extku.c
+++ b/src/crypto/x509v3/v3_extku.c
@@ -1,6 +1,7 @@
/* v3_extku.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
*/
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
@@ -10,7 +11,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -54,7 +55,6 @@
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com). */
-
#include <stdio.h>
#include <openssl/asn1t.h>
@@ -63,83 +63,86 @@
#include <openssl/obj.h>
#include <openssl/x509v3.h>
-
static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method,
- X509V3_CTX *ctx,
- STACK_OF(CONF_VALUE) *nval);
-static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method,
- void *eku, STACK_OF(CONF_VALUE) *extlist);
+ X509V3_CTX *ctx,
+ STACK_OF(CONF_VALUE) *nval);
+static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD
+ *method, void *eku, STACK_OF(CONF_VALUE)
+ *extlist);
const X509V3_EXT_METHOD v3_ext_ku = {
- NID_ext_key_usage, 0,
- ASN1_ITEM_ref(EXTENDED_KEY_USAGE),
- 0,0,0,0,
- 0,0,
- i2v_EXTENDED_KEY_USAGE,
- v2i_EXTENDED_KEY_USAGE,
- 0,0,
- NULL
+ NID_ext_key_usage, 0,
+ ASN1_ITEM_ref(EXTENDED_KEY_USAGE),
+ 0, 0, 0, 0,
+ 0, 0,
+ i2v_EXTENDED_KEY_USAGE,
+ v2i_EXTENDED_KEY_USAGE,
+ 0, 0,
+ NULL
};
/* NB OCSP acceptable responses also is a SEQUENCE OF OBJECT */
const X509V3_EXT_METHOD v3_ocsp_accresp = {
- NID_id_pkix_OCSP_acceptableResponses, 0,
- ASN1_ITEM_ref(EXTENDED_KEY_USAGE),
- 0,0,0,0,
- 0,0,
- i2v_EXTENDED_KEY_USAGE,
- v2i_EXTENDED_KEY_USAGE,
- 0,0,
- NULL
+ NID_id_pkix_OCSP_acceptableResponses, 0,
+ ASN1_ITEM_ref(EXTENDED_KEY_USAGE),
+ 0, 0, 0, 0,
+ 0, 0,
+ i2v_EXTENDED_KEY_USAGE,
+ v2i_EXTENDED_KEY_USAGE,
+ 0, 0,
+ NULL
};
-ASN1_ITEM_TEMPLATE(EXTENDED_KEY_USAGE) =
- ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, EXTENDED_KEY_USAGE, ASN1_OBJECT)
+ASN1_ITEM_TEMPLATE(EXTENDED_KEY_USAGE) =
+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, EXTENDED_KEY_USAGE, ASN1_OBJECT)
ASN1_ITEM_TEMPLATE_END(EXTENDED_KEY_USAGE)
IMPLEMENT_ASN1_FUNCTIONS(EXTENDED_KEY_USAGE)
-static STACK_OF(CONF_VALUE) *
- i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method, void *a,
- STACK_OF(CONF_VALUE) *ext_list)
+static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD
+ *method, void *a, STACK_OF(CONF_VALUE)
+ *ext_list)
{
- EXTENDED_KEY_USAGE *eku = a;
- size_t i;
- ASN1_OBJECT *obj;
- char obj_tmp[80];
- for(i = 0; i < sk_ASN1_OBJECT_num(eku); i++) {
- obj = sk_ASN1_OBJECT_value(eku, i);
- i2t_ASN1_OBJECT(obj_tmp, 80, obj);
- X509V3_add_value(NULL, obj_tmp, &ext_list);
- }
- return ext_list;
+ EXTENDED_KEY_USAGE *eku = a;
+ size_t i;
+ ASN1_OBJECT *obj;
+ char obj_tmp[80];
+ for (i = 0; i < sk_ASN1_OBJECT_num(eku); i++) {
+ obj = sk_ASN1_OBJECT_value(eku, i);
+ i2t_ASN1_OBJECT(obj_tmp, 80, obj);
+ X509V3_add_value(NULL, obj_tmp, &ext_list);
+ }
+ return ext_list;
}
static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method,
- X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
+ X509V3_CTX *ctx,
+ STACK_OF(CONF_VALUE) *nval)
{
- EXTENDED_KEY_USAGE *extku;
- char *extval;
- ASN1_OBJECT *objtmp;
- CONF_VALUE *val;
- size_t i;
+ EXTENDED_KEY_USAGE *extku;
+ char *extval;
+ ASN1_OBJECT *objtmp;
+ CONF_VALUE *val;
+ size_t i;
- if(!(extku = sk_ASN1_OBJECT_new_null())) {
- OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
+ if (!(extku = sk_ASN1_OBJECT_new_null())) {
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
- for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
- val = sk_CONF_VALUE_value(nval, i);
- if(val->value) extval = val->value;
- else extval = val->name;
- if(!(objtmp = OBJ_txt2obj(extval, 0))) {
- sk_ASN1_OBJECT_pop_free(extku, ASN1_OBJECT_free);
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER);
- X509V3_conf_err(val);
- return NULL;
- }
- sk_ASN1_OBJECT_push(extku, objtmp);
- }
- return extku;
+ for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+ val = sk_CONF_VALUE_value(nval, i);
+ if (val->value)
+ extval = val->value;
+ else
+ extval = val->name;
+ if (!(objtmp = OBJ_txt2obj(extval, 0))) {
+ sk_ASN1_OBJECT_pop_free(extku, ASN1_OBJECT_free);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER);
+ X509V3_conf_err(val);
+ return NULL;
+ }
+ sk_ASN1_OBJECT_push(extku, objtmp);
+ }
+ return extku;
}
diff --git a/src/crypto/x509v3/v3_genn.c b/src/crypto/x509v3/v3_genn.c
index 8b0a68d4..2331cd49 100644
--- a/src/crypto/x509v3/v3_genn.c
+++ b/src/crypto/x509v3/v3_genn.c
@@ -1,6 +1,7 @@
/* v3_genn.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
*/
/* ====================================================================
* Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved.
@@ -10,7 +11,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -54,7 +55,6 @@
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com). */
-
#include <stdio.h>
#include <openssl/asn1t.h>
@@ -64,189 +64,187 @@
ASN1_SEQUENCE(OTHERNAME) = {
- ASN1_SIMPLE(OTHERNAME, type_id, ASN1_OBJECT),
- /* Maybe have a true ANY DEFINED BY later */
- ASN1_EXP(OTHERNAME, value, ASN1_ANY, 0)
+ ASN1_SIMPLE(OTHERNAME, type_id, ASN1_OBJECT),
+ /* Maybe have a true ANY DEFINED BY later */
+ ASN1_EXP(OTHERNAME, value, ASN1_ANY, 0)
} ASN1_SEQUENCE_END(OTHERNAME)
IMPLEMENT_ASN1_FUNCTIONS(OTHERNAME)
ASN1_SEQUENCE(EDIPARTYNAME) = {
- ASN1_IMP_OPT(EDIPARTYNAME, nameAssigner, DIRECTORYSTRING, 0),
- ASN1_IMP_OPT(EDIPARTYNAME, partyName, DIRECTORYSTRING, 1)
+ ASN1_IMP_OPT(EDIPARTYNAME, nameAssigner, DIRECTORYSTRING, 0),
+ ASN1_IMP_OPT(EDIPARTYNAME, partyName, DIRECTORYSTRING, 1)
} ASN1_SEQUENCE_END(EDIPARTYNAME)
IMPLEMENT_ASN1_FUNCTIONS(EDIPARTYNAME)
ASN1_CHOICE(GENERAL_NAME) = {
- ASN1_IMP(GENERAL_NAME, d.otherName, OTHERNAME, GEN_OTHERNAME),
- ASN1_IMP(GENERAL_NAME, d.rfc822Name, ASN1_IA5STRING, GEN_EMAIL),
- ASN1_IMP(GENERAL_NAME, d.dNSName, ASN1_IA5STRING, GEN_DNS),
- /* Don't decode this */
- ASN1_IMP(GENERAL_NAME, d.x400Address, ASN1_SEQUENCE, GEN_X400),
- /* X509_NAME is a CHOICE type so use EXPLICIT */
- ASN1_EXP(GENERAL_NAME, d.directoryName, X509_NAME, GEN_DIRNAME),
- ASN1_IMP(GENERAL_NAME, d.ediPartyName, EDIPARTYNAME, GEN_EDIPARTY),
- ASN1_IMP(GENERAL_NAME, d.uniformResourceIdentifier, ASN1_IA5STRING, GEN_URI),
- ASN1_IMP(GENERAL_NAME, d.iPAddress, ASN1_OCTET_STRING, GEN_IPADD),
- ASN1_IMP(GENERAL_NAME, d.registeredID, ASN1_OBJECT, GEN_RID)
+ ASN1_IMP(GENERAL_NAME, d.otherName, OTHERNAME, GEN_OTHERNAME),
+ ASN1_IMP(GENERAL_NAME, d.rfc822Name, ASN1_IA5STRING, GEN_EMAIL),
+ ASN1_IMP(GENERAL_NAME, d.dNSName, ASN1_IA5STRING, GEN_DNS),
+ /* Don't decode this */
+ ASN1_IMP(GENERAL_NAME, d.x400Address, ASN1_SEQUENCE, GEN_X400),
+ /* X509_NAME is a CHOICE type so use EXPLICIT */
+ ASN1_EXP(GENERAL_NAME, d.directoryName, X509_NAME, GEN_DIRNAME),
+ ASN1_IMP(GENERAL_NAME, d.ediPartyName, EDIPARTYNAME, GEN_EDIPARTY),
+ ASN1_IMP(GENERAL_NAME, d.uniformResourceIdentifier, ASN1_IA5STRING, GEN_URI),
+ ASN1_IMP(GENERAL_NAME, d.iPAddress, ASN1_OCTET_STRING, GEN_IPADD),
+ ASN1_IMP(GENERAL_NAME, d.registeredID, ASN1_OBJECT, GEN_RID)
} ASN1_CHOICE_END(GENERAL_NAME)
IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAME)
-ASN1_ITEM_TEMPLATE(GENERAL_NAMES) =
- ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, GeneralNames, GENERAL_NAME)
+ASN1_ITEM_TEMPLATE(GENERAL_NAMES) =
+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, GeneralNames, GENERAL_NAME)
ASN1_ITEM_TEMPLATE_END(GENERAL_NAMES)
IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAMES)
GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a)
- {
- return (GENERAL_NAME *) ASN1_dup((i2d_of_void *) i2d_GENERAL_NAME,
- (d2i_of_void *) d2i_GENERAL_NAME,
- (char *) a);
- }
+{
+ return (GENERAL_NAME *)ASN1_dup((i2d_of_void *)i2d_GENERAL_NAME,
+ (d2i_of_void *)d2i_GENERAL_NAME,
+ (char *)a);
+}
/* Returns 0 if they are equal, != 0 otherwise. */
int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b)
- {
- int result = -1;
-
- if (!a || !b || a->type != b->type) return -1;
- switch(a->type)
- {
- case GEN_X400:
- case GEN_EDIPARTY:
- result = ASN1_TYPE_cmp(a->d.other, b->d.other);
- break;
-
- case GEN_OTHERNAME:
- result = OTHERNAME_cmp(a->d.otherName, b->d.otherName);
- break;
-
- case GEN_EMAIL:
- case GEN_DNS:
- case GEN_URI:
- result = ASN1_STRING_cmp(a->d.ia5, b->d.ia5);
- break;
-
- case GEN_DIRNAME:
- result = X509_NAME_cmp(a->d.dirn, b->d.dirn);
- break;
-
- case GEN_IPADD:
- result = ASN1_OCTET_STRING_cmp(a->d.ip, b->d.ip);
- break;
-
- case GEN_RID:
- result = OBJ_cmp(a->d.rid, b->d.rid);
- break;
- }
- return result;
- }
+{
+ int result = -1;
+
+ if (!a || !b || a->type != b->type)
+ return -1;
+ switch (a->type) {
+ case GEN_X400:
+ case GEN_EDIPARTY:
+ result = ASN1_TYPE_cmp(a->d.other, b->d.other);
+ break;
+
+ case GEN_OTHERNAME:
+ result = OTHERNAME_cmp(a->d.otherName, b->d.otherName);
+ break;
+
+ case GEN_EMAIL:
+ case GEN_DNS:
+ case GEN_URI:
+ result = ASN1_STRING_cmp(a->d.ia5, b->d.ia5);
+ break;
+
+ case GEN_DIRNAME:
+ result = X509_NAME_cmp(a->d.dirn, b->d.dirn);
+ break;
+
+ case GEN_IPADD:
+ result = ASN1_OCTET_STRING_cmp(a->d.ip, b->d.ip);
+ break;
+
+ case GEN_RID:
+ result = OBJ_cmp(a->d.rid, b->d.rid);
+ break;
+ }
+ return result;
+}
/* Returns 0 if they are equal, != 0 otherwise. */
int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b)
- {
- int result = -1;
-
- if (!a || !b) return -1;
- /* Check their type first. */
- if ((result = OBJ_cmp(a->type_id, b->type_id)) != 0)
- return result;
- /* Check the value. */
- result = ASN1_TYPE_cmp(a->value, b->value);
- return result;
- }
+{
+ int result = -1;
+
+ if (!a || !b)
+ return -1;
+ /* Check their type first. */
+ if ((result = OBJ_cmp(a->type_id, b->type_id)) != 0)
+ return result;
+ /* Check the value. */
+ result = ASN1_TYPE_cmp(a->value, b->value);
+ return result;
+}
void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value)
- {
- switch(type)
- {
- case GEN_X400:
- case GEN_EDIPARTY:
- a->d.other = value;
- break;
-
- case GEN_OTHERNAME:
- a->d.otherName = value;
- break;
-
- case GEN_EMAIL:
- case GEN_DNS:
- case GEN_URI:
- a->d.ia5 = value;
- break;
-
- case GEN_DIRNAME:
- a->d.dirn = value;
- break;
-
- case GEN_IPADD:
- a->d.ip = value;
- break;
-
- case GEN_RID:
- a->d.rid = value;
- break;
- }
- a->type = type;
- }
+{
+ switch (type) {
+ case GEN_X400:
+ case GEN_EDIPARTY:
+ a->d.other = value;
+ break;
+
+ case GEN_OTHERNAME:
+ a->d.otherName = value;
+ break;
+
+ case GEN_EMAIL:
+ case GEN_DNS:
+ case GEN_URI:
+ a->d.ia5 = value;
+ break;
+
+ case GEN_DIRNAME:
+ a->d.dirn = value;
+ break;
+
+ case GEN_IPADD:
+ a->d.ip = value;
+ break;
+
+ case GEN_RID:
+ a->d.rid = value;
+ break;
+ }
+ a->type = type;
+}
void *GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype)
- {
- if (ptype)
- *ptype = a->type;
- switch(a->type)
- {
- case GEN_X400:
- case GEN_EDIPARTY:
- return a->d.other;
-
- case GEN_OTHERNAME:
- return a->d.otherName;
-
- case GEN_EMAIL:
- case GEN_DNS:
- case GEN_URI:
- return a->d.ia5;
-
- case GEN_DIRNAME:
- return a->d.dirn;
-
- case GEN_IPADD:
- return a->d.ip;
-
- case GEN_RID:
- return a->d.rid;
-
- default:
- return NULL;
- }
- }
+{
+ if (ptype)
+ *ptype = a->type;
+ switch (a->type) {
+ case GEN_X400:
+ case GEN_EDIPARTY:
+ return a->d.other;
-int GENERAL_NAME_set0_othername(GENERAL_NAME *gen,
- ASN1_OBJECT *oid, ASN1_TYPE *value)
- {
- OTHERNAME *oth;
- oth = OTHERNAME_new();
- if (!oth)
- return 0;
- oth->type_id = oid;
- oth->value = value;
- GENERAL_NAME_set0_value(gen, GEN_OTHERNAME, oth);
- return 1;
- }
-
-int GENERAL_NAME_get0_otherName(GENERAL_NAME *gen,
- ASN1_OBJECT **poid, ASN1_TYPE **pvalue)
- {
- if (gen->type != GEN_OTHERNAME)
- return 0;
- if (poid)
- *poid = gen->d.otherName->type_id;
- if (pvalue)
- *pvalue = gen->d.otherName->value;
- return 1;
- }
+ case GEN_OTHERNAME:
+ return a->d.otherName;
+
+ case GEN_EMAIL:
+ case GEN_DNS:
+ case GEN_URI:
+ return a->d.ia5;
+
+ case GEN_DIRNAME:
+ return a->d.dirn;
+ case GEN_IPADD:
+ return a->d.ip;
+
+ case GEN_RID:
+ return a->d.rid;
+
+ default:
+ return NULL;
+ }
+}
+
+int GENERAL_NAME_set0_othername(GENERAL_NAME *gen,
+ ASN1_OBJECT *oid, ASN1_TYPE *value)
+{
+ OTHERNAME *oth;
+ oth = OTHERNAME_new();
+ if (!oth)
+ return 0;
+ oth->type_id = oid;
+ oth->value = value;
+ GENERAL_NAME_set0_value(gen, GEN_OTHERNAME, oth);
+ return 1;
+}
+
+int GENERAL_NAME_get0_otherName(GENERAL_NAME *gen,
+ ASN1_OBJECT **poid, ASN1_TYPE **pvalue)
+{
+ if (gen->type != GEN_OTHERNAME)
+ return 0;
+ if (poid)
+ *poid = gen->d.otherName->type_id;
+ if (pvalue)
+ *pvalue = gen->d.otherName->value;
+ return 1;
+}
diff --git a/src/crypto/x509v3/v3_ia5.c b/src/crypto/x509v3/v3_ia5.c
index 5a272335..6fc6b59b 100644
--- a/src/crypto/x509v3/v3_ia5.c
+++ b/src/crypto/x509v3/v3_ia5.c
@@ -1,6 +1,7 @@
/* v3_ia5.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
*/
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
@@ -10,7 +11,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -66,52 +67,53 @@
#include <openssl/obj.h>
#include <openssl/x509v3.h>
-
-static char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method, ASN1_IA5STRING *ia5);
-static ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str);
-const X509V3_EXT_METHOD v3_ns_ia5_list[] = {
-EXT_IA5STRING(NID_netscape_base_url),
-EXT_IA5STRING(NID_netscape_revocation_url),
-EXT_IA5STRING(NID_netscape_ca_revocation_url),
-EXT_IA5STRING(NID_netscape_renewal_url),
-EXT_IA5STRING(NID_netscape_ca_policy_url),
-EXT_IA5STRING(NID_netscape_ssl_server_name),
-EXT_IA5STRING(NID_netscape_comment),
-EXT_END
+static char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method,
+ ASN1_IA5STRING *ia5);
+static ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method,
+ X509V3_CTX *ctx, char *str);
+const X509V3_EXT_METHOD v3_ns_ia5_list[] = {
+ EXT_IA5STRING(NID_netscape_base_url),
+ EXT_IA5STRING(NID_netscape_revocation_url),
+ EXT_IA5STRING(NID_netscape_ca_revocation_url),
+ EXT_IA5STRING(NID_netscape_renewal_url),
+ EXT_IA5STRING(NID_netscape_ca_policy_url),
+ EXT_IA5STRING(NID_netscape_ssl_server_name),
+ EXT_IA5STRING(NID_netscape_comment),
+ EXT_END
};
-
static char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method,
- ASN1_IA5STRING *ia5)
+ ASN1_IA5STRING *ia5)
{
- char *tmp;
- if(!ia5 || !ia5->length) return NULL;
- if(!(tmp = OPENSSL_malloc(ia5->length + 1))) {
- OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
- memcpy(tmp, ia5->data, ia5->length);
- tmp[ia5->length] = 0;
- return tmp;
+ char *tmp;
+ if (!ia5 || !ia5->length)
+ return NULL;
+ if (!(tmp = OPENSSL_malloc(ia5->length + 1))) {
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ memcpy(tmp, ia5->data, ia5->length);
+ tmp[ia5->length] = 0;
+ return tmp;
}
static ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method,
- X509V3_CTX *ctx, char *str)
+ X509V3_CTX *ctx, char *str)
{
- ASN1_IA5STRING *ia5;
- if(!str) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_ARGUMENT);
- return NULL;
- }
- if(!(ia5 = M_ASN1_IA5STRING_new())) goto err;
- if(!ASN1_STRING_set((ASN1_STRING *)ia5, (unsigned char*)str,
- strlen(str))) {
- M_ASN1_IA5STRING_free(ia5);
- goto err;
- }
- return ia5;
- err:
- OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
- return NULL;
+ ASN1_IA5STRING *ia5;
+ if (!str) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_ARGUMENT);
+ return NULL;
+ }
+ if (!(ia5 = M_ASN1_IA5STRING_new()))
+ goto err;
+ if (!ASN1_STRING_set((ASN1_STRING *)ia5, (unsigned char *)str,
+ strlen(str))) {
+ M_ASN1_IA5STRING_free(ia5);
+ goto err;
+ }
+ return ia5;
+ err:
+ 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 475c56f7..482208d7 100644
--- a/src/crypto/x509v3/v3_info.c
+++ b/src/crypto/x509v3/v3_info.c
@@ -1,6 +1,7 @@
/* v3_info.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
*/
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
@@ -10,7 +11,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -68,133 +69,144 @@
#include <openssl/obj.h>
#include <openssl/x509v3.h>
+static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD
+ *method, AUTHORITY_INFO_ACCESS
+ *ainfo, STACK_OF(CONF_VALUE)
+ *ret);
+static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD
+ *method,
+ X509V3_CTX *ctx,
+ STACK_OF(CONF_VALUE)
+ *nval);
-static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD *method,
- AUTHORITY_INFO_ACCESS *ainfo,
- STACK_OF(CONF_VALUE) *ret);
-static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD *method,
- X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
+const X509V3_EXT_METHOD v3_info = { NID_info_access, X509V3_EXT_MULTILINE,
+ ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS),
+ 0, 0, 0, 0,
+ 0, 0,
+ (X509V3_EXT_I2V) i2v_AUTHORITY_INFO_ACCESS,
+ (X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS,
+ 0, 0,
+ NULL
+};
-const X509V3_EXT_METHOD v3_info =
-{ NID_info_access, X509V3_EXT_MULTILINE, ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS),
-0,0,0,0,
-0,0,
-(X509V3_EXT_I2V)i2v_AUTHORITY_INFO_ACCESS,
-(X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS,
-0,0,
-NULL};
-
-const X509V3_EXT_METHOD v3_sinfo =
-{ NID_sinfo_access, X509V3_EXT_MULTILINE, ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS),
-0,0,0,0,
-0,0,
-(X509V3_EXT_I2V)i2v_AUTHORITY_INFO_ACCESS,
-(X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS,
-0,0,
-NULL};
+const X509V3_EXT_METHOD v3_sinfo = { NID_sinfo_access, X509V3_EXT_MULTILINE,
+ ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS),
+ 0, 0, 0, 0,
+ 0, 0,
+ (X509V3_EXT_I2V) i2v_AUTHORITY_INFO_ACCESS,
+ (X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS,
+ 0, 0,
+ NULL
+};
ASN1_SEQUENCE(ACCESS_DESCRIPTION) = {
- ASN1_SIMPLE(ACCESS_DESCRIPTION, method, ASN1_OBJECT),
- ASN1_SIMPLE(ACCESS_DESCRIPTION, location, GENERAL_NAME)
+ ASN1_SIMPLE(ACCESS_DESCRIPTION, method, ASN1_OBJECT),
+ ASN1_SIMPLE(ACCESS_DESCRIPTION, location, GENERAL_NAME)
} ASN1_SEQUENCE_END(ACCESS_DESCRIPTION)
IMPLEMENT_ASN1_FUNCTIONS(ACCESS_DESCRIPTION)
-ASN1_ITEM_TEMPLATE(AUTHORITY_INFO_ACCESS) =
- ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, GeneralNames, ACCESS_DESCRIPTION)
+ASN1_ITEM_TEMPLATE(AUTHORITY_INFO_ACCESS) =
+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, GeneralNames, ACCESS_DESCRIPTION)
ASN1_ITEM_TEMPLATE_END(AUTHORITY_INFO_ACCESS)
IMPLEMENT_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS)
-static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD *method,
- AUTHORITY_INFO_ACCESS *ainfo,
- STACK_OF(CONF_VALUE) *ret)
+static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD
+ *method, AUTHORITY_INFO_ACCESS
+ *ainfo, STACK_OF(CONF_VALUE)
+ *ret)
{
- ACCESS_DESCRIPTION *desc;
- size_t i;
- int nlen;
- char objtmp[80], *ntmp;
- CONF_VALUE *vtmp;
- for(i = 0; i < sk_ACCESS_DESCRIPTION_num(ainfo); i++) {
- desc = sk_ACCESS_DESCRIPTION_value(ainfo, i);
- ret = i2v_GENERAL_NAME(method, desc->location, ret);
- if(!ret) break;
- vtmp = sk_CONF_VALUE_value(ret, i);
- i2t_ASN1_OBJECT(objtmp, sizeof objtmp, desc->method);
- nlen = strlen(objtmp) + strlen(vtmp->name) + 5;
- ntmp = OPENSSL_malloc(nlen);
- if(!ntmp) {
- OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
- BUF_strlcpy(ntmp, objtmp, nlen);
- BUF_strlcat(ntmp, " - ", nlen);
- BUF_strlcat(ntmp, vtmp->name, nlen);
- OPENSSL_free(vtmp->name);
- vtmp->name = ntmp;
-
- }
- if(!ret) return sk_CONF_VALUE_new_null();
- return ret;
+ ACCESS_DESCRIPTION *desc;
+ size_t i;
+ int nlen;
+ char objtmp[80], *ntmp;
+ CONF_VALUE *vtmp;
+ for (i = 0; i < sk_ACCESS_DESCRIPTION_num(ainfo); i++) {
+ desc = sk_ACCESS_DESCRIPTION_value(ainfo, i);
+ ret = i2v_GENERAL_NAME(method, desc->location, ret);
+ if (!ret)
+ break;
+ vtmp = sk_CONF_VALUE_value(ret, i);
+ i2t_ASN1_OBJECT(objtmp, sizeof objtmp, desc->method);
+ nlen = strlen(objtmp) + strlen(vtmp->name) + 5;
+ ntmp = OPENSSL_malloc(nlen);
+ if (!ntmp) {
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ BUF_strlcpy(ntmp, objtmp, nlen);
+ BUF_strlcat(ntmp, " - ", nlen);
+ BUF_strlcat(ntmp, vtmp->name, nlen);
+ OPENSSL_free(vtmp->name);
+ vtmp->name = ntmp;
+
+ }
+ if (!ret)
+ return sk_CONF_VALUE_new_null();
+ return ret;
}
-static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD *method,
- X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
+static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD
+ *method,
+ X509V3_CTX *ctx,
+ STACK_OF(CONF_VALUE)
+ *nval)
{
- AUTHORITY_INFO_ACCESS *ainfo = NULL;
- CONF_VALUE *cnf, ctmp;
- ACCESS_DESCRIPTION *acc;
- size_t i;
- int objlen;
- char *objtmp, *ptmp;
- if(!(ainfo = sk_ACCESS_DESCRIPTION_new_null())) {
- 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, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- ptmp = strchr(cnf->name, ';');
- if(!ptmp) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SYNTAX);
- goto err;
- }
- objlen = ptmp - cnf->name;
- ctmp.name = ptmp + 1;
- ctmp.value = cnf->value;
- if(!v2i_GENERAL_NAME_ex(acc->location, method, ctx, &ctmp, 0))
- goto err;
- if(!(objtmp = OPENSSL_malloc(objlen + 1))) {
- 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, X509V3_R_BAD_OBJECT);
- ERR_add_error_data(2, "value=", objtmp);
- OPENSSL_free(objtmp);
- goto err;
- }
- OPENSSL_free(objtmp);
+ AUTHORITY_INFO_ACCESS *ainfo = NULL;
+ CONF_VALUE *cnf, ctmp;
+ ACCESS_DESCRIPTION *acc;
+ size_t i;
+ int objlen;
+ char *objtmp, *ptmp;
+ if (!(ainfo = sk_ACCESS_DESCRIPTION_new_null())) {
+ 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, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ ptmp = strchr(cnf->name, ';');
+ if (!ptmp) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SYNTAX);
+ goto err;
+ }
+ objlen = ptmp - cnf->name;
+ ctmp.name = ptmp + 1;
+ ctmp.value = cnf->value;
+ if (!v2i_GENERAL_NAME_ex(acc->location, method, ctx, &ctmp, 0))
+ goto err;
+ if (!(objtmp = OPENSSL_malloc(objlen + 1))) {
+ 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, X509V3_R_BAD_OBJECT);
+ ERR_add_error_data(2, "value=", objtmp);
+ OPENSSL_free(objtmp);
+ goto err;
+ }
+ OPENSSL_free(objtmp);
- }
- return ainfo;
- err:
- sk_ACCESS_DESCRIPTION_pop_free(ainfo, ACCESS_DESCRIPTION_free);
- return NULL;
+ }
+ return ainfo;
+ err:
+ sk_ACCESS_DESCRIPTION_pop_free(ainfo, ACCESS_DESCRIPTION_free);
+ return NULL;
}
-int i2a_ACCESS_DESCRIPTION(BIO *bp, ACCESS_DESCRIPTION* a)
- {
- i2a_ASN1_OBJECT(bp, a->method);
+int i2a_ACCESS_DESCRIPTION(BIO *bp, ACCESS_DESCRIPTION *a)
+{
+ i2a_ASN1_OBJECT(bp, a->method);
#ifdef UNDEF
- i2a_GENERAL_NAME(bp, a->location);
+ i2a_GENERAL_NAME(bp, a->location);
#endif
- return 2;
- }
+ return 2;
+}
diff --git a/src/crypto/x509v3/v3_int.c b/src/crypto/x509v3/v3_int.c
index 8ca23bd7..7bde446c 100644
--- a/src/crypto/x509v3/v3_int.c
+++ b/src/crypto/x509v3/v3_int.c
@@ -1,6 +1,7 @@
/* v3_int.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
*/
/* ====================================================================
* Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved.
@@ -10,7 +11,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -59,29 +60,32 @@
#include <openssl/obj.h>
#include <openssl/x509v3.h>
+const X509V3_EXT_METHOD v3_crl_num = {
+ NID_crl_number, 0, ASN1_ITEM_ref(ASN1_INTEGER),
+ 0, 0, 0, 0,
+ (X509V3_EXT_I2S)i2s_ASN1_INTEGER,
+ 0,
+ 0, 0, 0, 0, NULL
+};
-const X509V3_EXT_METHOD v3_crl_num = {
- NID_crl_number, 0, ASN1_ITEM_ref(ASN1_INTEGER),
- 0,0,0,0,
- (X509V3_EXT_I2S)i2s_ASN1_INTEGER,
- 0,
- 0,0,0,0, NULL};
+const X509V3_EXT_METHOD v3_delta_crl = {
+ NID_delta_crl, 0, ASN1_ITEM_ref(ASN1_INTEGER),
+ 0, 0, 0, 0,
+ (X509V3_EXT_I2S)i2s_ASN1_INTEGER,
+ 0,
+ 0, 0, 0, 0, NULL
+};
-const X509V3_EXT_METHOD v3_delta_crl = {
- NID_delta_crl, 0, ASN1_ITEM_ref(ASN1_INTEGER),
- 0,0,0,0,
- (X509V3_EXT_I2S)i2s_ASN1_INTEGER,
- 0,
- 0,0,0,0, NULL};
+static void *s2i_asn1_int(X509V3_EXT_METHOD *meth, X509V3_CTX *ctx,
+ char *value)
+{
+ return s2i_ASN1_INTEGER(meth, value);
+}
-static void * s2i_asn1_int(X509V3_EXT_METHOD *meth, X509V3_CTX *ctx, char *value)
- {
- return s2i_ASN1_INTEGER(meth, value);
- }
-
-const X509V3_EXT_METHOD v3_inhibit_anyp = {
- NID_inhibit_any_policy, 0, ASN1_ITEM_ref(ASN1_INTEGER),
- 0,0,0,0,
- (X509V3_EXT_I2S)i2s_ASN1_INTEGER,
- (X509V3_EXT_S2I)s2i_asn1_int,
- 0,0,0,0, NULL};
+const X509V3_EXT_METHOD v3_inhibit_anyp = {
+ NID_inhibit_any_policy, 0, ASN1_ITEM_ref(ASN1_INTEGER),
+ 0, 0, 0, 0,
+ (X509V3_EXT_I2S)i2s_ASN1_INTEGER,
+ (X509V3_EXT_S2I)s2i_asn1_int,
+ 0, 0, 0, 0, NULL
+};
diff --git a/src/crypto/x509v3/v3_lib.c b/src/crypto/x509v3/v3_lib.c
index f8e5531d..c4718e33 100644
--- a/src/crypto/x509v3/v3_lib.c
+++ b/src/crypto/x509v3/v3_lib.c
@@ -1,6 +1,7 @@
/* v3_lib.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
*/
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
@@ -10,7 +11,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -70,266 +71,292 @@ static STACK_OF(X509V3_EXT_METHOD) *ext_list = NULL;
static void ext_list_free(X509V3_EXT_METHOD *ext);
-static int ext_stack_cmp(const X509V3_EXT_METHOD **a, const X509V3_EXT_METHOD **b)
+static int ext_stack_cmp(const X509V3_EXT_METHOD **a,
+ const X509V3_EXT_METHOD **b)
{
- return ((*a)->ext_nid - (*b)->ext_nid);
+ return ((*a)->ext_nid - (*b)->ext_nid);
}
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, ERR_R_MALLOC_FAILURE);
- ext_list_free(ext);
- return 0;
- }
- if(!sk_X509V3_EXT_METHOD_push(ext_list, ext)) {
- OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
- ext_list_free(ext);
- return 0;
- }
- return 1;
+ if (!ext_list && !(ext_list = sk_X509V3_EXT_METHOD_new(ext_stack_cmp))) {
+ 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, ERR_R_MALLOC_FAILURE);
+ ext_list_free(ext);
+ return 0;
+ }
+ return 1;
}
-static int ext_cmp(const void *void_a,
- const void *void_b)
+static int ext_cmp(const void *void_a, const void *void_b)
{
- const X509V3_EXT_METHOD **a = (const X509V3_EXT_METHOD**) void_a;
- const X509V3_EXT_METHOD **b = (const X509V3_EXT_METHOD**) void_b;
- return ext_stack_cmp(a, b);
+ const X509V3_EXT_METHOD **a = (const X509V3_EXT_METHOD **)void_a;
+ const X509V3_EXT_METHOD **b = (const X509V3_EXT_METHOD **)void_b;
+ return ext_stack_cmp(a, b);
}
const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid)
{
- X509V3_EXT_METHOD tmp;
- const X509V3_EXT_METHOD *t = &tmp, * const *ret;
- size_t idx;
-
- if(nid < 0) return NULL;
- tmp.ext_nid = nid;
- ret = bsearch(&t, standard_exts, STANDARD_EXTENSION_COUNT, sizeof(X509V3_EXT_METHOD*), ext_cmp);
- if(ret) return *ret;
- if(!ext_list) return NULL;
-
- if (!sk_X509V3_EXT_METHOD_find(ext_list, &idx, &tmp))
- return NULL;
- return sk_X509V3_EXT_METHOD_value(ext_list, idx);
+ X509V3_EXT_METHOD tmp;
+ const X509V3_EXT_METHOD *t = &tmp, *const *ret;
+ size_t idx;
+
+ if (nid < 0)
+ return NULL;
+ tmp.ext_nid = nid;
+ ret =
+ bsearch(&t, standard_exts, STANDARD_EXTENSION_COUNT,
+ sizeof(X509V3_EXT_METHOD *), ext_cmp);
+ if (ret)
+ return *ret;
+ if (!ext_list)
+ return NULL;
+
+ if (!sk_X509V3_EXT_METHOD_find(ext_list, &idx, &tmp))
+ return NULL;
+ return sk_X509V3_EXT_METHOD_value(ext_list, idx);
}
const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext)
{
- int nid;
- if((nid = OBJ_obj2nid(ext->object)) == NID_undef) return NULL;
- return X509V3_EXT_get_nid(nid);
+ int nid;
+ if ((nid = OBJ_obj2nid(ext->object)) == NID_undef)
+ return NULL;
+ return X509V3_EXT_get_nid(nid);
}
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_R_CANNOT_FIND_FREE_FUNCTION);
- return 0;
- }
-
- if (ext_method->it != NULL)
- ASN1_item_free(ext_data, ASN1_ITEM_ptr(ext_method->it));
- else if (ext_method->ext_free != NULL)
- ext_method->ext_free(ext_data);
- else
- {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_CANNOT_FIND_FREE_FUNCTION);
- return 0;
- }
-
- return 1;
+ const X509V3_EXT_METHOD *ext_method = X509V3_EXT_get_nid(nid);
+ if (ext_method == NULL) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_CANNOT_FIND_FREE_FUNCTION);
+ return 0;
+ }
+
+ if (ext_method->it != NULL)
+ ASN1_item_free(ext_data, ASN1_ITEM_ptr(ext_method->it));
+ else if (ext_method->ext_free != NULL)
+ ext_method->ext_free(ext_data);
+ else {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_CANNOT_FIND_FREE_FUNCTION);
+ return 0;
+ }
+
+ return 1;
}
int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist)
{
- for(;extlist->ext_nid!=-1;extlist++)
- if(!X509V3_EXT_add(extlist)) return 0;
- return 1;
+ for (; extlist->ext_nid != -1; extlist++)
+ if (!X509V3_EXT_add(extlist))
+ return 0;
+ return 1;
}
int X509V3_EXT_add_alias(int nid_to, int nid_from)
{
- const X509V3_EXT_METHOD *ext;
- X509V3_EXT_METHOD *tmpext;
-
- if(!(ext = X509V3_EXT_get_nid(nid_from))) {
- 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, ERR_R_MALLOC_FAILURE);
- return 0;
- }
- *tmpext = *ext;
- tmpext->ext_nid = nid_to;
- tmpext->ext_flags |= X509V3_EXT_DYNAMIC;
- return X509V3_EXT_add(tmpext);
+ const X509V3_EXT_METHOD *ext;
+ X509V3_EXT_METHOD *tmpext;
+
+ if (!(ext = X509V3_EXT_get_nid(nid_from))) {
+ 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, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ *tmpext = *ext;
+ tmpext->ext_nid = nid_to;
+ tmpext->ext_flags |= X509V3_EXT_DYNAMIC;
+ return X509V3_EXT_add(tmpext);
}
void X509V3_EXT_cleanup(void)
{
- sk_X509V3_EXT_METHOD_pop_free(ext_list, ext_list_free);
- ext_list = NULL;
+ sk_X509V3_EXT_METHOD_pop_free(ext_list, ext_list_free);
+ ext_list = NULL;
}
static void ext_list_free(X509V3_EXT_METHOD *ext)
{
- if(ext->ext_flags & X509V3_EXT_DYNAMIC) OPENSSL_free(ext);
+ if (ext->ext_flags & X509V3_EXT_DYNAMIC)
+ OPENSSL_free(ext);
}
-/* Legacy function: we don't need to add standard extensions
- * any more because they are now kept in ext_dat.h.
+/*
+ * Legacy function: we don't need to add standard extensions any more because
+ * they are now kept in ext_dat.h.
*/
int X509V3_add_standard_extensions(void)
{
- return 1;
+ return 1;
}
/* Return an extension internal structure */
void *X509V3_EXT_d2i(X509_EXTENSION *ext)
{
- const X509V3_EXT_METHOD *method;
- const unsigned char *p;
-
- if(!(method = X509V3_EXT_get(ext))) return NULL;
- p = ext->value->data;
- if(method->it) return ASN1_item_d2i(NULL, &p, ext->value->length, ASN1_ITEM_ptr(method->it));
- return method->d2i(NULL, &p, ext->value->length);
+ const X509V3_EXT_METHOD *method;
+ const unsigned char *p;
+
+ if (!(method = X509V3_EXT_get(ext)))
+ return NULL;
+ p = ext->value->data;
+ if (method->it)
+ return ASN1_item_d2i(NULL, &p, ext->value->length,
+ ASN1_ITEM_ptr(method->it));
+ return method->d2i(NULL, &p, ext->value->length);
}
-/* Get critical flag and decoded version of extension from a NID.
- * The "idx" variable returns the last found extension and can
- * be used to retrieve multiple extensions of the same NID.
- * However multiple extensions with the same NID is usually
- * due to a badly encoded certificate so if idx is NULL we
- * choke if multiple extensions exist.
- * The "crit" variable is set to the critical value.
- * The return value is the decoded extension or NULL on
- * error. The actual error can have several different causes,
- * the value of *crit reflects the cause:
- * >= 0, extension found but not decoded (reflects critical value).
- * -1 extension not found.
- * -2 extension occurs more than once.
+/*
+ * Get critical flag and decoded version of extension from a NID. The "idx"
+ * variable returns the last found extension and can be used to retrieve
+ * multiple extensions of the same NID. However multiple extensions with the
+ * same NID is usually due to a badly encoded certificate so if idx is NULL
+ * we choke if multiple extensions exist. The "crit" variable is set to the
+ * critical value. The return value is the decoded extension or NULL on
+ * error. The actual error can have several different causes, the value of
+ * *crit reflects the cause: >= 0, extension found but not decoded (reflects
+ * critical value). -1 extension not found. -2 extension occurs more than
+ * once.
*/
-void *X509V3_get_d2i(STACK_OF(X509_EXTENSION) *x, int nid, int *crit, int *idx)
+void *X509V3_get_d2i(STACK_OF(X509_EXTENSION) *x, int nid, int *crit,
+ int *idx)
{
- int lastpos;
- size_t i;
- X509_EXTENSION *ex, *found_ex = NULL;
- if(!x) {
- if(idx) *idx = -1;
- if(crit) *crit = -1;
- return NULL;
- }
- if(idx) lastpos = *idx + 1;
- else lastpos = 0;
- if(lastpos < 0) lastpos = 0;
- for(i = lastpos; i < sk_X509_EXTENSION_num(x); i++)
- {
- ex = sk_X509_EXTENSION_value(x, i);
- if(OBJ_obj2nid(ex->object) == nid) {
- if(idx) {
- *idx = i;
- found_ex = ex;
- break;
- } else if(found_ex) {
- /* Found more than one */
- if(crit) *crit = -2;
- return NULL;
- }
- found_ex = ex;
- }
- }
- if(found_ex) {
- /* Found it */
- if(crit) *crit = X509_EXTENSION_get_critical(found_ex);
- return X509V3_EXT_d2i(found_ex);
- }
-
- /* Extension not found */
- if(idx) *idx = -1;
- if(crit) *crit = -1;
- return NULL;
+ int lastpos;
+ size_t i;
+ X509_EXTENSION *ex, *found_ex = NULL;
+ if (!x) {
+ if (idx)
+ *idx = -1;
+ if (crit)
+ *crit = -1;
+ return NULL;
+ }
+ if (idx)
+ lastpos = *idx + 1;
+ else
+ lastpos = 0;
+ if (lastpos < 0)
+ lastpos = 0;
+ for (i = lastpos; i < sk_X509_EXTENSION_num(x); i++) {
+ ex = sk_X509_EXTENSION_value(x, i);
+ if (OBJ_obj2nid(ex->object) == nid) {
+ if (idx) {
+ *idx = i;
+ found_ex = ex;
+ break;
+ } else if (found_ex) {
+ /* Found more than one */
+ if (crit)
+ *crit = -2;
+ return NULL;
+ }
+ found_ex = ex;
+ }
+ }
+ if (found_ex) {
+ /* Found it */
+ if (crit)
+ *crit = X509_EXTENSION_get_critical(found_ex);
+ return X509V3_EXT_d2i(found_ex);
+ }
+
+ /* Extension not found */
+ if (idx)
+ *idx = -1;
+ if (crit)
+ *crit = -1;
+ return NULL;
}
-/* This function is a general extension append, replace and delete utility.
+/*
+ * This function is a general extension append, replace and delete utility.
* The precise operation is governed by the 'flags' value. The 'crit' and
* 'value' arguments (if relevant) are the extensions internal structure.
*/
int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value,
- int crit, unsigned long flags)
+ int crit, unsigned long flags)
{
- int extidx = -1;
- int errcode;
- X509_EXTENSION *ext, *extmp;
- unsigned long ext_op = flags & X509V3_ADD_OP_MASK;
-
- /* If appending we don't care if it exists, otherwise
- * look for existing extension.
- */
- if(ext_op != X509V3_ADD_APPEND)
- extidx = X509v3_get_ext_by_NID(*x, nid, -1);
-
- /* See if extension exists */
- if(extidx >= 0) {
- /* If keep existing, nothing to do */
- if(ext_op == X509V3_ADD_KEEP_EXISTING)
- return 1;
- /* If default then its an error */
- if(ext_op == X509V3_ADD_DEFAULT) {
- errcode = X509V3_R_EXTENSION_EXISTS;
- goto err;
- }
- /* If delete, just delete it */
- if(ext_op == X509V3_ADD_DELETE) {
- if(!sk_X509_EXTENSION_delete(*x, extidx)) return -1;
- return 1;
- }
- } else {
- /* If replace existing or delete, error since
- * extension must exist
- */
- if((ext_op == X509V3_ADD_REPLACE_EXISTING) ||
- (ext_op == X509V3_ADD_DELETE)) {
- errcode = X509V3_R_EXTENSION_NOT_FOUND;
- goto err;
- }
- }
-
- /* If we get this far then we have to create an extension:
- * could have some flags for alternative encoding schemes...
- */
-
- ext = X509V3_EXT_i2d(nid, crit, value);
-
- if(!ext) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_ERROR_CREATING_EXTENSION);
- return 0;
- }
-
- /* If extension exists replace it.. */
- if(extidx >= 0) {
- extmp = sk_X509_EXTENSION_value(*x, extidx);
- X509_EXTENSION_free(extmp);
- if(!sk_X509_EXTENSION_set(*x, extidx, ext)) return -1;
- return 1;
- }
-
- if(!*x && !(*x = sk_X509_EXTENSION_new_null())) return -1;
- if(!sk_X509_EXTENSION_push(*x, ext)) return -1;
-
- return 1;
-
- err:
- if(!(flags & X509V3_ADD_SILENT))
- OPENSSL_PUT_ERROR(X509V3, errcode);
- return 0;
+ int extidx = -1;
+ int errcode;
+ X509_EXTENSION *ext, *extmp;
+ unsigned long ext_op = flags & X509V3_ADD_OP_MASK;
+
+ /*
+ * If appending we don't care if it exists, otherwise look for existing
+ * extension.
+ */
+ if (ext_op != X509V3_ADD_APPEND)
+ extidx = X509v3_get_ext_by_NID(*x, nid, -1);
+
+ /* See if extension exists */
+ if (extidx >= 0) {
+ /* If keep existing, nothing to do */
+ if (ext_op == X509V3_ADD_KEEP_EXISTING)
+ return 1;
+ /* If default then its an error */
+ if (ext_op == X509V3_ADD_DEFAULT) {
+ errcode = X509V3_R_EXTENSION_EXISTS;
+ goto err;
+ }
+ /* If delete, just delete it */
+ if (ext_op == X509V3_ADD_DELETE) {
+ if (!sk_X509_EXTENSION_delete(*x, extidx))
+ return -1;
+ return 1;
+ }
+ } else {
+ /*
+ * If replace existing or delete, error since extension must exist
+ */
+ if ((ext_op == X509V3_ADD_REPLACE_EXISTING) ||
+ (ext_op == X509V3_ADD_DELETE)) {
+ errcode = X509V3_R_EXTENSION_NOT_FOUND;
+ goto err;
+ }
+ }
+
+ /*
+ * If we get this far then we have to create an extension: could have
+ * some flags for alternative encoding schemes...
+ */
+
+ ext = X509V3_EXT_i2d(nid, crit, value);
+
+ if (!ext) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_ERROR_CREATING_EXTENSION);
+ return 0;
+ }
+
+ /* If extension exists replace it.. */
+ if (extidx >= 0) {
+ extmp = sk_X509_EXTENSION_value(*x, extidx);
+ X509_EXTENSION_free(extmp);
+ if (!sk_X509_EXTENSION_set(*x, extidx, ext))
+ return -1;
+ return 1;
+ }
+
+ if (!*x && !(*x = sk_X509_EXTENSION_new_null()))
+ return -1;
+ if (!sk_X509_EXTENSION_push(*x, ext))
+ return -1;
+
+ return 1;
+
+ err:
+ if (!(flags & X509V3_ADD_SILENT))
+ OPENSSL_PUT_ERROR(X509V3, errcode);
+ return 0;
}
diff --git a/src/crypto/x509v3/v3_ncons.c b/src/crypto/x509v3/v3_ncons.c
index 19f5e949..368ad272 100644
--- a/src/crypto/x509v3/v3_ncons.c
+++ b/src/crypto/x509v3/v3_ncons.c
@@ -1,5 +1,6 @@
/* v3_ncons.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project.
*/
/* ====================================================================
@@ -10,7 +11,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -54,7 +55,6 @@
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com). */
-
#include <stdio.h>
#include <string.h>
@@ -65,14 +65,14 @@
#include <openssl/obj.h>
#include <openssl/x509v3.h>
-
static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method,
- X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
-static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method,
- void *a, BIO *bp, int ind);
+ X509V3_CTX *ctx,
+ STACK_OF(CONF_VALUE) *nval);
+static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a,
+ BIO *bp, int ind);
static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method,
- STACK_OF(GENERAL_SUBTREE) *trees,
- BIO *bp, int ind, const char *name);
+ STACK_OF(GENERAL_SUBTREE) *trees, BIO *bp,
+ int ind, const char *name);
static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip);
static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc);
@@ -83,428 +83,400 @@ static int nc_email(ASN1_IA5STRING *sub, ASN1_IA5STRING *eml);
static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base);
const X509V3_EXT_METHOD v3_name_constraints = {
- NID_name_constraints, 0,
- ASN1_ITEM_ref(NAME_CONSTRAINTS),
- 0,0,0,0,
- 0,0,
- 0, v2i_NAME_CONSTRAINTS,
- i2r_NAME_CONSTRAINTS,0,
- NULL
+ NID_name_constraints, 0,
+ ASN1_ITEM_ref(NAME_CONSTRAINTS),
+ 0, 0, 0, 0,
+ 0, 0,
+ 0, v2i_NAME_CONSTRAINTS,
+ i2r_NAME_CONSTRAINTS, 0,
+ NULL
};
ASN1_SEQUENCE(GENERAL_SUBTREE) = {
- ASN1_SIMPLE(GENERAL_SUBTREE, base, GENERAL_NAME),
- ASN1_IMP_OPT(GENERAL_SUBTREE, minimum, ASN1_INTEGER, 0),
- ASN1_IMP_OPT(GENERAL_SUBTREE, maximum, ASN1_INTEGER, 1)
+ ASN1_SIMPLE(GENERAL_SUBTREE, base, GENERAL_NAME),
+ ASN1_IMP_OPT(GENERAL_SUBTREE, minimum, ASN1_INTEGER, 0),
+ ASN1_IMP_OPT(GENERAL_SUBTREE, maximum, ASN1_INTEGER, 1)
} ASN1_SEQUENCE_END(GENERAL_SUBTREE)
ASN1_SEQUENCE(NAME_CONSTRAINTS) = {
- ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, permittedSubtrees,
- GENERAL_SUBTREE, 0),
- ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, excludedSubtrees,
- GENERAL_SUBTREE, 1),
+ ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, permittedSubtrees,
+ GENERAL_SUBTREE, 0),
+ ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, excludedSubtrees,
+ GENERAL_SUBTREE, 1),
} ASN1_SEQUENCE_END(NAME_CONSTRAINTS)
-
+
IMPLEMENT_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE)
IMPLEMENT_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS)
static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method,
- X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
- {
- size_t i;
- CONF_VALUE tval, *val;
- STACK_OF(GENERAL_SUBTREE) **ptree = NULL;
- NAME_CONSTRAINTS *ncons = NULL;
- GENERAL_SUBTREE *sub = NULL;
- ncons = NAME_CONSTRAINTS_new();
- if (!ncons)
- goto memerr;
- for(i = 0; i < sk_CONF_VALUE_num(nval); i++)
- {
- val = sk_CONF_VALUE_value(nval, i);
- if (!strncmp(val->name, "permitted", 9) && val->name[9])
- {
- ptree = &ncons->permittedSubtrees;
- tval.name = val->name + 10;
- }
- else if (!strncmp(val->name, "excluded", 8) && val->name[8])
- {
- ptree = &ncons->excludedSubtrees;
- tval.name = val->name + 9;
- }
- else
- {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SYNTAX);
- goto err;
- }
- tval.value = val->value;
- sub = GENERAL_SUBTREE_new();
- if (!v2i_GENERAL_NAME_ex(sub->base, method, ctx, &tval, 1))
- goto err;
- if (!*ptree)
- *ptree = sk_GENERAL_SUBTREE_new_null();
- if (!*ptree || !sk_GENERAL_SUBTREE_push(*ptree, sub))
- goto memerr;
- sub = NULL;
- }
-
- return ncons;
-
- memerr:
- OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
- err:
- if (ncons)
- NAME_CONSTRAINTS_free(ncons);
- if (sub)
- GENERAL_SUBTREE_free(sub);
-
- return NULL;
- }
-
-
-
+ X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
+{
+ size_t i;
+ CONF_VALUE tval, *val;
+ STACK_OF(GENERAL_SUBTREE) **ptree = NULL;
+ NAME_CONSTRAINTS *ncons = NULL;
+ GENERAL_SUBTREE *sub = NULL;
+ ncons = NAME_CONSTRAINTS_new();
+ if (!ncons)
+ goto memerr;
+ for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+ val = sk_CONF_VALUE_value(nval, i);
+ if (!strncmp(val->name, "permitted", 9) && val->name[9]) {
+ ptree = &ncons->permittedSubtrees;
+ tval.name = val->name + 10;
+ } else if (!strncmp(val->name, "excluded", 8) && val->name[8]) {
+ ptree = &ncons->excludedSubtrees;
+ tval.name = val->name + 9;
+ } else {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SYNTAX);
+ goto err;
+ }
+ tval.value = val->value;
+ sub = GENERAL_SUBTREE_new();
+ if (!v2i_GENERAL_NAME_ex(sub->base, method, ctx, &tval, 1))
+ goto err;
+ if (!*ptree)
+ *ptree = sk_GENERAL_SUBTREE_new_null();
+ if (!*ptree || !sk_GENERAL_SUBTREE_push(*ptree, sub))
+ goto memerr;
+ sub = NULL;
+ }
+
+ return ncons;
+
+ memerr:
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+ err:
+ if (ncons)
+ NAME_CONSTRAINTS_free(ncons);
+ if (sub)
+ GENERAL_SUBTREE_free(sub);
+
+ return NULL;
+}
static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a,
- BIO *bp, int ind)
- {
- NAME_CONSTRAINTS *ncons = a;
- do_i2r_name_constraints(method, ncons->permittedSubtrees,
- bp, ind, "Permitted");
- do_i2r_name_constraints(method, ncons->excludedSubtrees,
- bp, ind, "Excluded");
- return 1;
- }
+ BIO *bp, int ind)
+{
+ NAME_CONSTRAINTS *ncons = a;
+ do_i2r_name_constraints(method, ncons->permittedSubtrees,
+ bp, ind, "Permitted");
+ do_i2r_name_constraints(method, ncons->excludedSubtrees,
+ bp, ind, "Excluded");
+ return 1;
+}
static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method,
- STACK_OF(GENERAL_SUBTREE) *trees,
- BIO *bp, int ind, const char *name)
- {
- GENERAL_SUBTREE *tree;
- size_t i;
- if (sk_GENERAL_SUBTREE_num(trees) > 0)
- BIO_printf(bp, "%*s%s:\n", ind, "", name);
- for(i = 0; i < sk_GENERAL_SUBTREE_num(trees); i++)
- {
- tree = sk_GENERAL_SUBTREE_value(trees, i);
- BIO_printf(bp, "%*s", ind + 2, "");
- if (tree->base->type == GEN_IPADD)
- print_nc_ipadd(bp, tree->base->d.ip);
- else
- GENERAL_NAME_print(bp, tree->base);
- BIO_puts(bp, "\n");
- }
- return 1;
- }
+ STACK_OF(GENERAL_SUBTREE) *trees,
+ BIO *bp, int ind, const char *name)
+{
+ GENERAL_SUBTREE *tree;
+ size_t i;
+ if (sk_GENERAL_SUBTREE_num(trees) > 0)
+ BIO_printf(bp, "%*s%s:\n", ind, "", name);
+ for (i = 0; i < sk_GENERAL_SUBTREE_num(trees); i++) {
+ tree = sk_GENERAL_SUBTREE_value(trees, i);
+ BIO_printf(bp, "%*s", ind + 2, "");
+ if (tree->base->type == GEN_IPADD)
+ print_nc_ipadd(bp, tree->base->d.ip);
+ else
+ GENERAL_NAME_print(bp, tree->base);
+ BIO_puts(bp, "\n");
+ }
+ return 1;
+}
static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip)
- {
- int i, len;
- unsigned char *p;
- p = ip->data;
- len = ip->length;
- BIO_puts(bp, "IP:");
- if(len == 8)
- {
- BIO_printf(bp, "%d.%d.%d.%d/%d.%d.%d.%d",
- p[0], p[1], p[2], p[3],
- p[4], p[5], p[6], p[7]);
- }
- else if(len == 32)
- {
- for (i = 0; i < 16; i++)
- {
- BIO_printf(bp, "%X", p[0] << 8 | p[1]);
- p += 2;
- if (i == 7)
- BIO_puts(bp, "/");
- else if (i != 15)
- BIO_puts(bp, ":");
- }
- }
- else
- BIO_printf(bp, "IP Address:<invalid>");
- return 1;
- }
-
-/* Check a certificate conforms to a specified set of constraints.
- * Return values:
- * X509_V_OK: All constraints obeyed.
- * X509_V_ERR_PERMITTED_VIOLATION: Permitted subtree violation.
- * X509_V_ERR_EXCLUDED_VIOLATION: Excluded subtree violation.
- * X509_V_ERR_SUBTREE_MINMAX: Min or max values present and matching type.
- * X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: Unsupported constraint type.
- * X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: bad unsupported constraint syntax.
- * X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: bad or unsupported syntax of name
-
+{
+ int i, len;
+ unsigned char *p;
+ p = ip->data;
+ len = ip->length;
+ BIO_puts(bp, "IP:");
+ if (len == 8) {
+ BIO_printf(bp, "%d.%d.%d.%d/%d.%d.%d.%d",
+ p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
+ } else if (len == 32) {
+ for (i = 0; i < 16; i++) {
+ BIO_printf(bp, "%X", p[0] << 8 | p[1]);
+ p += 2;
+ if (i == 7)
+ BIO_puts(bp, "/");
+ else if (i != 15)
+ BIO_puts(bp, ":");
+ }
+ } else
+ BIO_printf(bp, "IP Address:<invalid>");
+ return 1;
+}
+
+/*
+ * Check a certificate conforms to a specified set of constraints. Return
+ * values: X509_V_OK: All constraints obeyed.
+ * X509_V_ERR_PERMITTED_VIOLATION: Permitted subtree violation.
+ * X509_V_ERR_EXCLUDED_VIOLATION: Excluded subtree violation.
+ * X509_V_ERR_SUBTREE_MINMAX: Min or max values present and matching type.
+ * X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: Unsupported constraint type.
+ * X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: bad unsupported constraint
+ * syntax. X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: bad or unsupported syntax of
+ * name
+ *
*/
int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc)
- {
- int r, i;
- size_t j;
- X509_NAME *nm;
+{
+ int r, i;
+ size_t j;
+ X509_NAME *nm;
- nm = X509_get_subject_name(x);
+ nm = X509_get_subject_name(x);
- if (X509_NAME_entry_count(nm) > 0)
- {
- GENERAL_NAME gntmp;
- gntmp.type = GEN_DIRNAME;
- gntmp.d.directoryName = nm;
+ if (X509_NAME_entry_count(nm) > 0) {
+ GENERAL_NAME gntmp;
+ gntmp.type = GEN_DIRNAME;
+ gntmp.d.directoryName = nm;
- r = nc_match(&gntmp, nc);
+ r = nc_match(&gntmp, nc);
- if (r != X509_V_OK)
- return r;
+ if (r != X509_V_OK)
+ return r;
- gntmp.type = GEN_EMAIL;
+ gntmp.type = GEN_EMAIL;
+ /* Process any email address attributes in subject name */
- /* Process any email address attributes in subject name */
+ for (i = -1;;) {
+ X509_NAME_ENTRY *ne;
+ i = X509_NAME_get_index_by_NID(nm, NID_pkcs9_emailAddress, i);
+ if (i == -1)
+ break;
+ ne = X509_NAME_get_entry(nm, i);
+ gntmp.d.rfc822Name = X509_NAME_ENTRY_get_data(ne);
+ if (gntmp.d.rfc822Name->type != V_ASN1_IA5STRING)
+ return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
- for (i = -1;;)
- {
- X509_NAME_ENTRY *ne;
- i = X509_NAME_get_index_by_NID(nm,
- NID_pkcs9_emailAddress,
- i);
- if (i == -1)
- break;
- ne = X509_NAME_get_entry(nm, i);
- gntmp.d.rfc822Name = X509_NAME_ENTRY_get_data(ne);
- if (gntmp.d.rfc822Name->type != V_ASN1_IA5STRING)
- return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
+ r = nc_match(&gntmp, nc);
- r = nc_match(&gntmp, nc);
+ if (r != X509_V_OK)
+ return r;
+ }
- if (r != X509_V_OK)
- return r;
- }
-
- }
+ }
- for (j = 0; j < sk_GENERAL_NAME_num(x->altname); j++)
- {
- GENERAL_NAME *gen = sk_GENERAL_NAME_value(x->altname, j);
- r = nc_match(gen, nc);
- if (r != X509_V_OK)
- return r;
- }
+ for (j = 0; j < sk_GENERAL_NAME_num(x->altname); j++) {
+ GENERAL_NAME *gen = sk_GENERAL_NAME_value(x->altname, j);
+ r = nc_match(gen, nc);
+ if (r != X509_V_OK)
+ return r;
+ }
- return X509_V_OK;
+ return X509_V_OK;
- }
+}
static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc)
- {
- GENERAL_SUBTREE *sub;
- int r, match = 0;
- size_t i;
-
- /* Permitted subtrees: if any subtrees exist of matching the type
- * at least one subtree must match.
- */
-
- for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees); i++)
- {
- sub = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i);
- if (gen->type != sub->base->type)
- continue;
- if (sub->minimum || sub->maximum)
- return X509_V_ERR_SUBTREE_MINMAX;
- /* If we already have a match don't bother trying any more */
- if (match == 2)
- continue;
- if (match == 0)
- match = 1;
- r = nc_match_single(gen, sub->base);
- if (r == X509_V_OK)
- match = 2;
- else if (r != X509_V_ERR_PERMITTED_VIOLATION)
- return r;
- }
-
- if (match == 1)
- return X509_V_ERR_PERMITTED_VIOLATION;
-
- /* Excluded subtrees: must not match any of these */
-
- for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); i++)
- {
- sub = sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i);
- if (gen->type != sub->base->type)
- continue;
- if (sub->minimum || sub->maximum)
- return X509_V_ERR_SUBTREE_MINMAX;
-
- r = nc_match_single(gen, sub->base);
- if (r == X509_V_OK)
- return X509_V_ERR_EXCLUDED_VIOLATION;
- else if (r != X509_V_ERR_PERMITTED_VIOLATION)
- return r;
-
- }
-
- return X509_V_OK;
-
- }
+{
+ GENERAL_SUBTREE *sub;
+ int r, match = 0;
+ size_t i;
+
+ /*
+ * Permitted subtrees: if any subtrees exist of matching the type at
+ * least one subtree must match.
+ */
+
+ for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees); i++) {
+ sub = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i);
+ if (gen->type != sub->base->type)
+ continue;
+ if (sub->minimum || sub->maximum)
+ return X509_V_ERR_SUBTREE_MINMAX;
+ /* If we already have a match don't bother trying any more */
+ if (match == 2)
+ continue;
+ if (match == 0)
+ match = 1;
+ r = nc_match_single(gen, sub->base);
+ if (r == X509_V_OK)
+ match = 2;
+ else if (r != X509_V_ERR_PERMITTED_VIOLATION)
+ return r;
+ }
+
+ if (match == 1)
+ return X509_V_ERR_PERMITTED_VIOLATION;
+
+ /* Excluded subtrees: must not match any of these */
+
+ for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); i++) {
+ sub = sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i);
+ if (gen->type != sub->base->type)
+ continue;
+ if (sub->minimum || sub->maximum)
+ return X509_V_ERR_SUBTREE_MINMAX;
+
+ r = nc_match_single(gen, sub->base);
+ if (r == X509_V_OK)
+ return X509_V_ERR_EXCLUDED_VIOLATION;
+ else if (r != X509_V_ERR_PERMITTED_VIOLATION)
+ return r;
+
+ }
+
+ return X509_V_OK;
+
+}
static int nc_match_single(GENERAL_NAME *gen, GENERAL_NAME *base)
- {
- switch(base->type)
- {
- case GEN_DIRNAME:
- return nc_dn(gen->d.directoryName, base->d.directoryName);
+{
+ switch (base->type) {
+ case GEN_DIRNAME:
+ return nc_dn(gen->d.directoryName, base->d.directoryName);
- case GEN_DNS:
- return nc_dns(gen->d.dNSName, base->d.dNSName);
+ case GEN_DNS:
+ return nc_dns(gen->d.dNSName, base->d.dNSName);
- case GEN_EMAIL:
- return nc_email(gen->d.rfc822Name, base->d.rfc822Name);
+ case GEN_EMAIL:
+ return nc_email(gen->d.rfc822Name, base->d.rfc822Name);
- case GEN_URI:
- return nc_uri(gen->d.uniformResourceIdentifier,
- base->d.uniformResourceIdentifier);
+ case GEN_URI:
+ return nc_uri(gen->d.uniformResourceIdentifier,
+ base->d.uniformResourceIdentifier);
- default:
- return X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE;
- }
+ default:
+ return X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE;
+ }
- }
+}
-/* directoryName name constraint matching.
- * The canonical encoding of X509_NAME makes this comparison easy. It is
- * matched if the subtree is a subset of the name.
+/*
+ * directoryName name constraint matching. The canonical encoding of
+ * X509_NAME makes this comparison easy. It is matched if the subtree is a
+ * subset of the name.
*/
static int nc_dn(X509_NAME *nm, X509_NAME *base)
- {
- /* Ensure canonical encodings are up to date. */
- if (nm->modified && i2d_X509_NAME(nm, NULL) < 0)
- return X509_V_ERR_OUT_OF_MEM;
- if (base->modified && i2d_X509_NAME(base, NULL) < 0)
- return X509_V_ERR_OUT_OF_MEM;
- if (base->canon_enclen > nm->canon_enclen)
- return X509_V_ERR_PERMITTED_VIOLATION;
- if (memcmp(base->canon_enc, nm->canon_enc, base->canon_enclen))
- return X509_V_ERR_PERMITTED_VIOLATION;
- return X509_V_OK;
- }
+{
+ /* Ensure canonical encodings are up to date. */
+ if (nm->modified && i2d_X509_NAME(nm, NULL) < 0)
+ return X509_V_ERR_OUT_OF_MEM;
+ if (base->modified && i2d_X509_NAME(base, NULL) < 0)
+ return X509_V_ERR_OUT_OF_MEM;
+ if (base->canon_enclen > nm->canon_enclen)
+ return X509_V_ERR_PERMITTED_VIOLATION;
+ if (memcmp(base->canon_enc, nm->canon_enc, base->canon_enclen))
+ return X509_V_ERR_PERMITTED_VIOLATION;
+ return X509_V_OK;
+}
static int nc_dns(ASN1_IA5STRING *dns, ASN1_IA5STRING *base)
- {
- char *baseptr = (char *)base->data;
- char *dnsptr = (char *)dns->data;
- /* Empty matches everything */
- if (!*baseptr)
- return X509_V_OK;
- /* Otherwise can add zero or more components on the left so
- * compare RHS and if dns is longer and expect '.' as preceding
- * character.
- */
- if (dns->length > base->length)
- {
- dnsptr += dns->length - base->length;
- if (*baseptr != '.' && dnsptr[-1] != '.')
- return X509_V_ERR_PERMITTED_VIOLATION;
- }
-
- if (OPENSSL_strcasecmp(baseptr, dnsptr))
- return X509_V_ERR_PERMITTED_VIOLATION;
-
- return X509_V_OK;
-
- }
+{
+ char *baseptr = (char *)base->data;
+ char *dnsptr = (char *)dns->data;
+ /* Empty matches everything */
+ if (!*baseptr)
+ return X509_V_OK;
+ /*
+ * Otherwise can add zero or more components on the left so compare RHS
+ * and if dns is longer and expect '.' as preceding character.
+ */
+ if (dns->length > base->length) {
+ dnsptr += dns->length - base->length;
+ if (*baseptr != '.' && dnsptr[-1] != '.')
+ return X509_V_ERR_PERMITTED_VIOLATION;
+ }
+
+ if (OPENSSL_strcasecmp(baseptr, dnsptr))
+ return X509_V_ERR_PERMITTED_VIOLATION;
+
+ return X509_V_OK;
+
+}
static int nc_email(ASN1_IA5STRING *eml, ASN1_IA5STRING *base)
- {
- const char *baseptr = (char *)base->data;
- const char *emlptr = (char *)eml->data;
-
- const char *baseat = strchr(baseptr, '@');
- const char *emlat = strchr(emlptr, '@');
- if (!emlat)
- return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
- /* Special case: inital '.' is RHS match */
- if (!baseat && (*baseptr == '.'))
- {
- if (eml->length > base->length)
- {
- emlptr += eml->length - base->length;
- if (!OPENSSL_strcasecmp(baseptr, emlptr))
- return X509_V_OK;
- }
- return X509_V_ERR_PERMITTED_VIOLATION;
- }
-
- /* If we have anything before '@' match local part */
-
- if (baseat)
- {
- if (baseat != baseptr)
- {
- if ((baseat - baseptr) != (emlat - emlptr))
- return X509_V_ERR_PERMITTED_VIOLATION;
- /* Case sensitive match of local part */
- if (strncmp(baseptr, emlptr, emlat - emlptr))
- return X509_V_ERR_PERMITTED_VIOLATION;
- }
- /* Position base after '@' */
- baseptr = baseat + 1;
- }
- emlptr = emlat + 1;
- /* Just have hostname left to match: case insensitive */
- if (OPENSSL_strcasecmp(baseptr, emlptr))
- return X509_V_ERR_PERMITTED_VIOLATION;
-
- return X509_V_OK;
-
- }
+{
+ const char *baseptr = (char *)base->data;
+ const char *emlptr = (char *)eml->data;
+
+ const char *baseat = strchr(baseptr, '@');
+ const char *emlat = strchr(emlptr, '@');
+ if (!emlat)
+ return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
+ /* Special case: inital '.' is RHS match */
+ if (!baseat && (*baseptr == '.')) {
+ if (eml->length > base->length) {
+ emlptr += eml->length - base->length;
+ if (!OPENSSL_strcasecmp(baseptr, emlptr))
+ return X509_V_OK;
+ }
+ return X509_V_ERR_PERMITTED_VIOLATION;
+ }
+
+ /* If we have anything before '@' match local part */
+
+ if (baseat) {
+ if (baseat != baseptr) {
+ if ((baseat - baseptr) != (emlat - emlptr))
+ return X509_V_ERR_PERMITTED_VIOLATION;
+ /* Case sensitive match of local part */
+ if (strncmp(baseptr, emlptr, emlat - emlptr))
+ return X509_V_ERR_PERMITTED_VIOLATION;
+ }
+ /* Position base after '@' */
+ baseptr = baseat + 1;
+ }
+ emlptr = emlat + 1;
+ /* Just have hostname left to match: case insensitive */
+ if (OPENSSL_strcasecmp(baseptr, emlptr))
+ return X509_V_ERR_PERMITTED_VIOLATION;
+
+ return X509_V_OK;
+
+}
static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base)
- {
- const char *baseptr = (char *)base->data;
- const char *hostptr = (char *)uri->data;
- const char *p = strchr(hostptr, ':');
- int hostlen;
- /* Check for foo:// and skip past it */
- if (!p || (p[1] != '/') || (p[2] != '/'))
- return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
- hostptr = p + 3;
-
- /* Determine length of hostname part of URI */
-
- /* Look for a port indicator as end of hostname first */
-
- p = strchr(hostptr, ':');
- /* Otherwise look for trailing slash */
- if (!p)
- p = strchr(hostptr, '/');
-
- if (!p)
- hostlen = strlen(hostptr);
- else
- hostlen = p - hostptr;
-
- if (hostlen == 0)
- return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
-
- /* Special case: inital '.' is RHS match */
- if (*baseptr == '.')
- {
- if (hostlen > base->length)
- {
- p = hostptr + hostlen - base->length;
- if (!OPENSSL_strncasecmp(p, baseptr, base->length))
- return X509_V_OK;
- }
- return X509_V_ERR_PERMITTED_VIOLATION;
- }
-
- if ((base->length != (int)hostlen) || OPENSSL_strncasecmp(hostptr, baseptr, hostlen))
- return X509_V_ERR_PERMITTED_VIOLATION;
-
- return X509_V_OK;
-
- }
+{
+ const char *baseptr = (char *)base->data;
+ const char *hostptr = (char *)uri->data;
+ const char *p = strchr(hostptr, ':');
+ int hostlen;
+ /* Check for foo:// and skip past it */
+ if (!p || (p[1] != '/') || (p[2] != '/'))
+ return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
+ hostptr = p + 3;
+
+ /* Determine length of hostname part of URI */
+
+ /* Look for a port indicator as end of hostname first */
+
+ p = strchr(hostptr, ':');
+ /* Otherwise look for trailing slash */
+ if (!p)
+ p = strchr(hostptr, '/');
+
+ if (!p)
+ hostlen = strlen(hostptr);
+ else
+ hostlen = p - hostptr;
+
+ if (hostlen == 0)
+ return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
+
+ /* Special case: inital '.' is RHS match */
+ if (*baseptr == '.') {
+ if (hostlen > base->length) {
+ p = hostptr + hostlen - base->length;
+ if (!OPENSSL_strncasecmp(p, baseptr, base->length))
+ return X509_V_OK;
+ }
+ return X509_V_ERR_PERMITTED_VIOLATION;
+ }
+
+ if ((base->length != (int)hostlen)
+ || OPENSSL_strncasecmp(hostptr, baseptr, hostlen))
+ return X509_V_ERR_PERMITTED_VIOLATION;
+
+ return X509_V_OK;
+
+}
diff --git a/src/crypto/x509v3/v3_pci.c b/src/crypto/x509v3/v3_pci.c
index f19a37a8..220f65e1 100644
--- a/src/crypto/x509v3/v3_pci.c
+++ b/src/crypto/x509v3/v3_pci.c
@@ -1,6 +1,7 @@
/* v3_pci.c -*- mode:C; c-file-style: "eay" -*- */
-/* Contributed to the OpenSSL Project 2004
- * by Richard Levitte (richard@levitte.org)
+/*
+ * Contributed to the OpenSSL Project 2004 by Richard Levitte
+ * (richard@levitte.org)
*/
/* Copyright (c) 2004 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
@@ -43,293 +44,274 @@
#include <openssl/obj.h>
#include <openssl/x509v3.h>
-
static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *ext,
- BIO *out, int indent);
+ BIO *out, int indent);
static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method,
- X509V3_CTX *ctx, char *str);
+ X509V3_CTX *ctx, char *str);
const X509V3_EXT_METHOD v3_pci =
- { NID_proxyCertInfo, 0, ASN1_ITEM_ref(PROXY_CERT_INFO_EXTENSION),
- 0,0,0,0,
- 0,0,
- NULL, NULL,
- (X509V3_EXT_I2R)i2r_pci,
- (X509V3_EXT_R2I)r2i_pci,
- NULL,
- };
+ { NID_proxyCertInfo, 0, ASN1_ITEM_ref(PROXY_CERT_INFO_EXTENSION),
+ 0, 0, 0, 0,
+ 0, 0,
+ NULL, NULL,
+ (X509V3_EXT_I2R)i2r_pci,
+ (X509V3_EXT_R2I)r2i_pci,
+ NULL,
+};
static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *pci,
- BIO *out, int indent)
- {
- BIO_printf(out, "%*sPath Length Constraint: ", indent, "");
- if (pci->pcPathLengthConstraint)
- i2a_ASN1_INTEGER(out, pci->pcPathLengthConstraint);
- else
- BIO_printf(out, "infinite");
- BIO_puts(out, "\n");
- BIO_printf(out, "%*sPolicy Language: ", indent, "");
- i2a_ASN1_OBJECT(out, pci->proxyPolicy->policyLanguage);
- BIO_puts(out, "\n");
- if (pci->proxyPolicy->policy && pci->proxyPolicy->policy->data)
- BIO_printf(out, "%*sPolicy Text: %s\n", indent, "",
- pci->proxyPolicy->policy->data);
- return 1;
- }
+ BIO *out, int indent)
+{
+ BIO_printf(out, "%*sPath Length Constraint: ", indent, "");
+ if (pci->pcPathLengthConstraint)
+ i2a_ASN1_INTEGER(out, pci->pcPathLengthConstraint);
+ else
+ BIO_printf(out, "infinite");
+ BIO_puts(out, "\n");
+ BIO_printf(out, "%*sPolicy Language: ", indent, "");
+ i2a_ASN1_OBJECT(out, pci->proxyPolicy->policyLanguage);
+ BIO_puts(out, "\n");
+ if (pci->proxyPolicy->policy && pci->proxyPolicy->policy->data)
+ BIO_printf(out, "%*sPolicy Text: %s\n", indent, "",
+ pci->proxyPolicy->policy->data);
+ return 1;
+}
static int process_pci_value(CONF_VALUE *val,
- ASN1_OBJECT **language, ASN1_INTEGER **pathlen,
- ASN1_OCTET_STRING **policy)
- {
- int free_policy = 0;
+ ASN1_OBJECT **language, ASN1_INTEGER **pathlen,
+ ASN1_OCTET_STRING **policy)
+{
+ int free_policy = 0;
- if (strcmp(val->name, "language") == 0)
- {
- if (*language)
- {
- 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, X509V3_R_INVALID_OBJECT_IDENTIFIER);
- X509V3_conf_err(val);
- return 0;
- }
- }
- else if (strcmp(val->name, "pathlen") == 0)
- {
- if (*pathlen)
- {
- 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, X509V3_R_POLICY_PATH_LENGTH);
- X509V3_conf_err(val);
- return 0;
- }
- }
- else if (strcmp(val->name, "policy") == 0)
- {
- unsigned char *tmp_data = NULL;
- long val_len;
- if (!*policy)
- {
- *policy = ASN1_OCTET_STRING_new();
- if (!*policy)
- {
- OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
- X509V3_conf_err(val);
- return 0;
- }
- free_policy = 1;
- }
- if (strncmp(val->value, "hex:", 4) == 0)
- {
- unsigned char *tmp_data2 =
- string_to_hex(val->value + 4, &val_len);
+ if (strcmp(val->name, "language") == 0) {
+ if (*language) {
+ 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, X509V3_R_INVALID_OBJECT_IDENTIFIER);
+ X509V3_conf_err(val);
+ return 0;
+ }
+ } else if (strcmp(val->name, "pathlen") == 0) {
+ if (*pathlen) {
+ 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, X509V3_R_POLICY_PATH_LENGTH);
+ X509V3_conf_err(val);
+ return 0;
+ }
+ } else if (strcmp(val->name, "policy") == 0) {
+ unsigned char *tmp_data = NULL;
+ long val_len;
+ if (!*policy) {
+ *policy = ASN1_OCTET_STRING_new();
+ if (!*policy) {
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+ X509V3_conf_err(val);
+ return 0;
+ }
+ free_policy = 1;
+ }
+ if (strncmp(val->value, "hex:", 4) == 0) {
+ unsigned char *tmp_data2 =
+ string_to_hex(val->value + 4, &val_len);
- if (!tmp_data2)
- {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_ILLEGAL_HEX_DIGIT);
- X509V3_conf_err(val);
- goto err;
- }
+ if (!tmp_data2) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_ILLEGAL_HEX_DIGIT);
+ X509V3_conf_err(val);
+ goto err;
+ }
- tmp_data = OPENSSL_realloc((*policy)->data,
- (*policy)->length + val_len + 1);
- if (tmp_data)
- {
- (*policy)->data = tmp_data;
- memcpy(&(*policy)->data[(*policy)->length],
- tmp_data2, val_len);
- (*policy)->length += val_len;
- (*policy)->data[(*policy)->length] = '\0';
- }
- else
- {
- OPENSSL_free(tmp_data2);
- /* realloc failure implies the original data space is b0rked too! */
- (*policy)->data = NULL;
- (*policy)->length = 0;
- OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
- X509V3_conf_err(val);
- goto err;
- }
- OPENSSL_free(tmp_data2);
- }
- else if (strncmp(val->value, "file:", 5) == 0)
- {
- unsigned char buf[2048];
- int n;
- BIO *b = BIO_new_file(val->value + 5, "r");
- if (!b)
- {
- OPENSSL_PUT_ERROR(X509V3, ERR_R_BIO_LIB);
- X509V3_conf_err(val);
- goto err;
- }
- while((n = BIO_read(b, buf, sizeof(buf))) > 0
- || (n == 0 && BIO_should_retry(b)))
- {
- if (!n) continue;
+ tmp_data = OPENSSL_realloc((*policy)->data,
+ (*policy)->length + val_len + 1);
+ if (tmp_data) {
+ (*policy)->data = tmp_data;
+ memcpy(&(*policy)->data[(*policy)->length],
+ tmp_data2, val_len);
+ (*policy)->length += val_len;
+ (*policy)->data[(*policy)->length] = '\0';
+ } else {
+ OPENSSL_free(tmp_data2);
+ /*
+ * realloc failure implies the original data space is b0rked
+ * too!
+ */
+ (*policy)->data = NULL;
+ (*policy)->length = 0;
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+ X509V3_conf_err(val);
+ goto err;
+ }
+ OPENSSL_free(tmp_data2);
+ } else if (strncmp(val->value, "file:", 5) == 0) {
+ unsigned char buf[2048];
+ int n;
+ BIO *b = BIO_new_file(val->value + 5, "r");
+ if (!b) {
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_BIO_LIB);
+ X509V3_conf_err(val);
+ goto err;
+ }
+ while ((n = BIO_read(b, buf, sizeof(buf))) > 0
+ || (n == 0 && BIO_should_retry(b))) {
+ if (!n)
+ continue;
- tmp_data = OPENSSL_realloc((*policy)->data,
- (*policy)->length + n + 1);
+ tmp_data = OPENSSL_realloc((*policy)->data,
+ (*policy)->length + n + 1);
- if (!tmp_data)
- break;
+ if (!tmp_data)
+ break;
- (*policy)->data = tmp_data;
- memcpy(&(*policy)->data[(*policy)->length],
- buf, n);
- (*policy)->length += n;
- (*policy)->data[(*policy)->length] = '\0';
- }
- BIO_free_all(b);
+ (*policy)->data = tmp_data;
+ memcpy(&(*policy)->data[(*policy)->length], buf, n);
+ (*policy)->length += n;
+ (*policy)->data[(*policy)->length] = '\0';
+ }
+ BIO_free_all(b);
- if (n < 0)
- {
- OPENSSL_PUT_ERROR(X509V3, ERR_R_BIO_LIB);
- X509V3_conf_err(val);
- goto err;
- }
- }
- else if (strncmp(val->value, "text:", 5) == 0)
- {
- val_len = strlen(val->value + 5);
- tmp_data = OPENSSL_realloc((*policy)->data,
- (*policy)->length + val_len + 1);
- if (tmp_data)
- {
- (*policy)->data = tmp_data;
- memcpy(&(*policy)->data[(*policy)->length],
- val->value + 5, val_len);
- (*policy)->length += val_len;
- (*policy)->data[(*policy)->length] = '\0';
- }
- else
- {
- /* realloc failure implies the original data space is b0rked too! */
- (*policy)->data = NULL;
- (*policy)->length = 0;
- OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
- X509V3_conf_err(val);
- goto err;
- }
- }
- else
- {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_INCORRECT_POLICY_SYNTAX_TAG);
- X509V3_conf_err(val);
- goto err;
- }
- if (!tmp_data)
- {
- OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
- X509V3_conf_err(val);
- goto err;
- }
- }
- return 1;
-err:
- if (free_policy)
- {
- ASN1_OCTET_STRING_free(*policy);
- *policy = NULL;
- }
- return 0;
- }
+ if (n < 0) {
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_BIO_LIB);
+ X509V3_conf_err(val);
+ goto err;
+ }
+ } else if (strncmp(val->value, "text:", 5) == 0) {
+ val_len = strlen(val->value + 5);
+ tmp_data = OPENSSL_realloc((*policy)->data,
+ (*policy)->length + val_len + 1);
+ if (tmp_data) {
+ (*policy)->data = tmp_data;
+ memcpy(&(*policy)->data[(*policy)->length],
+ val->value + 5, val_len);
+ (*policy)->length += val_len;
+ (*policy)->data[(*policy)->length] = '\0';
+ } else {
+ /*
+ * realloc failure implies the original data space is b0rked
+ * too!
+ */
+ (*policy)->data = NULL;
+ (*policy)->length = 0;
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+ X509V3_conf_err(val);
+ goto err;
+ }
+ } else {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INCORRECT_POLICY_SYNTAX_TAG);
+ X509V3_conf_err(val);
+ goto err;
+ }
+ if (!tmp_data) {
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+ X509V3_conf_err(val);
+ goto err;
+ }
+ }
+ return 1;
+ err:
+ if (free_policy) {
+ ASN1_OCTET_STRING_free(*policy);
+ *policy = NULL;
+ }
+ return 0;
+}
static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method,
- X509V3_CTX *ctx, char *value)
- {
- PROXY_CERT_INFO_EXTENSION *pci = NULL;
- STACK_OF(CONF_VALUE) *vals;
- ASN1_OBJECT *language = NULL;
- ASN1_INTEGER *pathlen = NULL;
- ASN1_OCTET_STRING *policy = NULL;
- size_t i, j;
- int nid;
+ X509V3_CTX *ctx, char *value)
+{
+ PROXY_CERT_INFO_EXTENSION *pci = NULL;
+ STACK_OF(CONF_VALUE) *vals;
+ ASN1_OBJECT *language = NULL;
+ ASN1_INTEGER *pathlen = NULL;
+ ASN1_OCTET_STRING *policy = NULL;
+ size_t i, j;
+ int nid;
- vals = X509V3_parse_list(value);
- for (i = 0; i < sk_CONF_VALUE_num(vals); i++)
- {
- CONF_VALUE *cnf = sk_CONF_VALUE_value(vals, i);
- if (!cnf->name || (*cnf->name != '@' && !cnf->value))
- {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_PROXY_POLICY_SETTING);
- X509V3_conf_err(cnf);
- goto err;
- }
- if (*cnf->name == '@')
- {
- STACK_OF(CONF_VALUE) *sect;
- int success_p = 1;
+ vals = X509V3_parse_list(value);
+ for (i = 0; i < sk_CONF_VALUE_num(vals); i++) {
+ CONF_VALUE *cnf = sk_CONF_VALUE_value(vals, i);
+ if (!cnf->name || (*cnf->name != '@' && !cnf->value)) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_PROXY_POLICY_SETTING);
+ X509V3_conf_err(cnf);
+ goto err;
+ }
+ if (*cnf->name == '@') {
+ STACK_OF(CONF_VALUE) *sect;
+ int success_p = 1;
- sect = X509V3_get_section(ctx, cnf->name + 1);
- if (!sect)
- {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SECTION);
- X509V3_conf_err(cnf);
- goto err;
- }
- for (j = 0; success_p && j < sk_CONF_VALUE_num(sect); j++)
- {
- success_p =
- process_pci_value(sk_CONF_VALUE_value(sect, j),
- &language, &pathlen, &policy);
- }
- X509V3_section_free(ctx, sect);
- if (!success_p)
- goto err;
- }
- else
- {
- if (!process_pci_value(cnf,
- &language, &pathlen, &policy))
- {
- X509V3_conf_err(cnf);
- goto err;
- }
- }
- }
+ sect = X509V3_get_section(ctx, cnf->name + 1);
+ if (!sect) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SECTION);
+ X509V3_conf_err(cnf);
+ goto err;
+ }
+ for (j = 0; success_p && j < sk_CONF_VALUE_num(sect); j++) {
+ success_p =
+ process_pci_value(sk_CONF_VALUE_value(sect, j),
+ &language, &pathlen, &policy);
+ }
+ X509V3_section_free(ctx, sect);
+ if (!success_p)
+ goto err;
+ } else {
+ if (!process_pci_value(cnf, &language, &pathlen, &policy)) {
+ X509V3_conf_err(cnf);
+ goto err;
+ }
+ }
+ }
- /* Language is mandatory */
- if (!language)
- {
- 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,
- X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY);
- goto err;
- }
+ /* Language is mandatory */
+ if (!language) {
+ 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,
+ X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY);
+ goto err;
+ }
- pci = PROXY_CERT_INFO_EXTENSION_new();
- if (!pci)
- {
- OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
- goto err;
- }
+ pci = PROXY_CERT_INFO_EXTENSION_new();
+ if (!pci) {
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
- pci->proxyPolicy->policyLanguage = language; language = NULL;
- pci->proxyPolicy->policy = policy; policy = NULL;
- pci->pcPathLengthConstraint = pathlen; pathlen = NULL;
- goto end;
-err:
- if (language) { ASN1_OBJECT_free(language); language = NULL; }
- if (pathlen) { ASN1_INTEGER_free(pathlen); pathlen = NULL; }
- if (policy) { ASN1_OCTET_STRING_free(policy); policy = NULL; }
- if (pci) { PROXY_CERT_INFO_EXTENSION_free(pci); pci = NULL; }
-end:
- sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
- return pci;
- }
+ pci->proxyPolicy->policyLanguage = language;
+ language = NULL;
+ pci->proxyPolicy->policy = policy;
+ policy = NULL;
+ pci->pcPathLengthConstraint = pathlen;
+ pathlen = NULL;
+ goto end;
+ err:
+ if (language) {
+ ASN1_OBJECT_free(language);
+ language = NULL;
+ }
+ if (pathlen) {
+ ASN1_INTEGER_free(pathlen);
+ pathlen = NULL;
+ }
+ if (policy) {
+ ASN1_OCTET_STRING_free(policy);
+ policy = NULL;
+ }
+ if (pci) {
+ PROXY_CERT_INFO_EXTENSION_free(pci);
+ pci = NULL;
+ }
+ end:
+ sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
+ return pci;
+}
diff --git a/src/crypto/x509v3/v3_pcia.c b/src/crypto/x509v3/v3_pcia.c
index e3e3192f..3f285f30 100644
--- a/src/crypto/x509v3/v3_pcia.c
+++ b/src/crypto/x509v3/v3_pcia.c
@@ -1,6 +1,7 @@
/* v3_pcia.c -*- mode:C; c-file-style: "eay" -*- */
-/* Contributed to the OpenSSL Project 2004
- * by Richard Levitte (richard@levitte.org)
+/*
+ * Contributed to the OpenSSL Project 2004 by Richard Levitte
+ * (richard@levitte.org)
*/
/* Copyright (c) 2004 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
@@ -40,17 +41,17 @@
ASN1_SEQUENCE(PROXY_POLICY) =
- {
- ASN1_SIMPLE(PROXY_POLICY,policyLanguage,ASN1_OBJECT),
- ASN1_OPT(PROXY_POLICY,policy,ASN1_OCTET_STRING)
+ {
+ ASN1_SIMPLE(PROXY_POLICY,policyLanguage,ASN1_OBJECT),
+ ASN1_OPT(PROXY_POLICY,policy,ASN1_OCTET_STRING)
} ASN1_SEQUENCE_END(PROXY_POLICY)
IMPLEMENT_ASN1_FUNCTIONS(PROXY_POLICY)
ASN1_SEQUENCE(PROXY_CERT_INFO_EXTENSION) =
- {
- ASN1_OPT(PROXY_CERT_INFO_EXTENSION,pcPathLengthConstraint,ASN1_INTEGER),
- ASN1_SIMPLE(PROXY_CERT_INFO_EXTENSION,proxyPolicy,PROXY_POLICY)
+ {
+ ASN1_OPT(PROXY_CERT_INFO_EXTENSION,pcPathLengthConstraint,ASN1_INTEGER),
+ ASN1_SIMPLE(PROXY_CERT_INFO_EXTENSION,proxyPolicy,PROXY_POLICY)
} ASN1_SEQUENCE_END(PROXY_CERT_INFO_EXTENSION)
IMPLEMENT_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION)
diff --git a/src/crypto/x509v3/v3_pcons.c b/src/crypto/x509v3/v3_pcons.c
index b7522904..1a463143 100644
--- a/src/crypto/x509v3/v3_pcons.c
+++ b/src/crypto/x509v3/v3_pcons.c
@@ -1,5 +1,6 @@
/* v3_pcons.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project.
*/
/* ====================================================================
@@ -10,7 +11,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -54,7 +55,6 @@
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com). */
-
#include <stdio.h>
#include <string.h>
@@ -65,78 +65,75 @@
#include <openssl/obj.h>
#include <openssl/x509v3.h>
-
-static STACK_OF(CONF_VALUE) *
-i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *bcons,
- STACK_OF(CONF_VALUE) *extlist);
+static STACK_OF(CONF_VALUE) *i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD
+ *method, void *bcons, STACK_OF(CONF_VALUE)
+ *extlist);
static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method,
- X509V3_CTX *ctx,
- STACK_OF(CONF_VALUE) *values);
+ X509V3_CTX *ctx,
+ STACK_OF(CONF_VALUE) *values);
const X509V3_EXT_METHOD v3_policy_constraints = {
-NID_policy_constraints, 0,
-ASN1_ITEM_ref(POLICY_CONSTRAINTS),
-0,0,0,0,
-0,0,
-i2v_POLICY_CONSTRAINTS,
-v2i_POLICY_CONSTRAINTS,
-NULL,NULL,
-NULL
+ NID_policy_constraints, 0,
+ ASN1_ITEM_ref(POLICY_CONSTRAINTS),
+ 0, 0, 0, 0,
+ 0, 0,
+ i2v_POLICY_CONSTRAINTS,
+ v2i_POLICY_CONSTRAINTS,
+ NULL, NULL,
+ NULL
};
ASN1_SEQUENCE(POLICY_CONSTRAINTS) = {
- ASN1_IMP_OPT(POLICY_CONSTRAINTS, requireExplicitPolicy, ASN1_INTEGER,0),
- ASN1_IMP_OPT(POLICY_CONSTRAINTS, inhibitPolicyMapping, ASN1_INTEGER,1)
+ ASN1_IMP_OPT(POLICY_CONSTRAINTS, requireExplicitPolicy, ASN1_INTEGER,0),
+ ASN1_IMP_OPT(POLICY_CONSTRAINTS, inhibitPolicyMapping, ASN1_INTEGER,1)
} ASN1_SEQUENCE_END(POLICY_CONSTRAINTS)
IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS)
-
-static STACK_OF(CONF_VALUE) *
-i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a,
- STACK_OF(CONF_VALUE) *extlist)
+static STACK_OF(CONF_VALUE) *i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD
+ *method, void *a, STACK_OF(CONF_VALUE)
+ *extlist)
{
- POLICY_CONSTRAINTS *pcons = a;
- X509V3_add_value_int("Require Explicit Policy",
- pcons->requireExplicitPolicy, &extlist);
- X509V3_add_value_int("Inhibit Policy Mapping",
- pcons->inhibitPolicyMapping, &extlist);
- return extlist;
+ POLICY_CONSTRAINTS *pcons = a;
+ X509V3_add_value_int("Require Explicit Policy",
+ pcons->requireExplicitPolicy, &extlist);
+ X509V3_add_value_int("Inhibit Policy Mapping",
+ pcons->inhibitPolicyMapping, &extlist);
+ return extlist;
}
static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method,
- X509V3_CTX *ctx,
- STACK_OF(CONF_VALUE) *values)
+ X509V3_CTX *ctx,
+ STACK_OF(CONF_VALUE) *values)
{
- POLICY_CONSTRAINTS *pcons=NULL;
- CONF_VALUE *val;
- size_t i;
- if(!(pcons = POLICY_CONSTRAINTS_new())) {
- OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
- for(i = 0; i < sk_CONF_VALUE_num(values); i++) {
- val = sk_CONF_VALUE_value(values, i);
- if(!strcmp(val->name, "requireExplicitPolicy")) {
- if(!X509V3_get_value_int(val,
- &pcons->requireExplicitPolicy)) goto err;
- } else if(!strcmp(val->name, "inhibitPolicyMapping")) {
- if(!X509V3_get_value_int(val,
- &pcons->inhibitPolicyMapping)) goto err;
- } else {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NAME);
- X509V3_conf_err(val);
- goto err;
- }
- }
- if (!pcons->inhibitPolicyMapping && !pcons->requireExplicitPolicy) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_ILLEGAL_EMPTY_EXTENSION);
- goto err;
- }
+ POLICY_CONSTRAINTS *pcons = NULL;
+ CONF_VALUE *val;
+ size_t i;
+ if (!(pcons = POLICY_CONSTRAINTS_new())) {
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
+ val = sk_CONF_VALUE_value(values, i);
+ if (!strcmp(val->name, "requireExplicitPolicy")) {
+ if (!X509V3_get_value_int(val, &pcons->requireExplicitPolicy))
+ goto err;
+ } else if (!strcmp(val->name, "inhibitPolicyMapping")) {
+ if (!X509V3_get_value_int(val, &pcons->inhibitPolicyMapping))
+ goto err;
+ } else {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NAME);
+ X509V3_conf_err(val);
+ goto err;
+ }
+ }
+ if (!pcons->inhibitPolicyMapping && !pcons->requireExplicitPolicy) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_ILLEGAL_EMPTY_EXTENSION);
+ goto err;
+ }
- return pcons;
- err:
- POLICY_CONSTRAINTS_free(pcons);
- return NULL;
+ return pcons;
+ err:
+ POLICY_CONSTRAINTS_free(pcons);
+ return NULL;
}
-
diff --git a/src/crypto/x509v3/v3_pku.c b/src/crypto/x509v3/v3_pku.c
index 445eda67..e4868b47 100644
--- a/src/crypto/x509v3/v3_pku.c
+++ b/src/crypto/x509v3/v3_pku.c
@@ -1,6 +1,7 @@
/* v3_pku.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
*/
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
@@ -10,7 +11,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -62,48 +63,48 @@
#include <openssl/obj.h>
#include <openssl/x509v3.h>
-
-static int i2r_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method, PKEY_USAGE_PERIOD *usage, BIO *out, int indent);
+static int i2r_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method,
+ PKEY_USAGE_PERIOD *usage, BIO *out,
+ int indent);
/*
-static PKEY_USAGE_PERIOD *v2i_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values);
-*/
+ * static PKEY_USAGE_PERIOD *v2i_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method,
+ * X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values);
+ */
const X509V3_EXT_METHOD v3_pkey_usage_period = {
-NID_private_key_usage_period, 0, ASN1_ITEM_ref(PKEY_USAGE_PERIOD),
-0,0,0,0,
-0,0,0,0,
-(X509V3_EXT_I2R)i2r_PKEY_USAGE_PERIOD, NULL,
-NULL
+ NID_private_key_usage_period, 0, ASN1_ITEM_ref(PKEY_USAGE_PERIOD),
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ (X509V3_EXT_I2R)i2r_PKEY_USAGE_PERIOD, NULL,
+ NULL
};
ASN1_SEQUENCE(PKEY_USAGE_PERIOD) = {
- ASN1_IMP_OPT(PKEY_USAGE_PERIOD, notBefore, ASN1_GENERALIZEDTIME, 0),
- ASN1_IMP_OPT(PKEY_USAGE_PERIOD, notAfter, ASN1_GENERALIZEDTIME, 1)
+ ASN1_IMP_OPT(PKEY_USAGE_PERIOD, notBefore, ASN1_GENERALIZEDTIME, 0),
+ ASN1_IMP_OPT(PKEY_USAGE_PERIOD, notAfter, ASN1_GENERALIZEDTIME, 1)
} ASN1_SEQUENCE_END(PKEY_USAGE_PERIOD)
IMPLEMENT_ASN1_FUNCTIONS(PKEY_USAGE_PERIOD)
static int i2r_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method,
- PKEY_USAGE_PERIOD *usage, BIO *out, int indent)
+ PKEY_USAGE_PERIOD *usage, BIO *out,
+ int indent)
{
- BIO_printf(out, "%*s", indent, "");
- if(usage->notBefore) {
- BIO_write(out, "Not Before: ", 12);
- ASN1_GENERALIZEDTIME_print(out, usage->notBefore);
- if(usage->notAfter) BIO_write(out, ", ", 2);
- }
- if(usage->notAfter) {
- BIO_write(out, "Not After: ", 11);
- ASN1_GENERALIZEDTIME_print(out, usage->notAfter);
- }
- return 1;
+ BIO_printf(out, "%*s", indent, "");
+ if (usage->notBefore) {
+ BIO_write(out, "Not Before: ", 12);
+ ASN1_GENERALIZEDTIME_print(out, usage->notBefore);
+ if (usage->notAfter)
+ BIO_write(out, ", ", 2);
+ }
+ if (usage->notAfter) {
+ BIO_write(out, "Not After: ", 11);
+ ASN1_GENERALIZEDTIME_print(out, usage->notAfter);
+ }
+ return 1;
}
/*
-static PKEY_USAGE_PERIOD *v2i_PKEY_USAGE_PERIOD(method, ctx, values)
-X509V3_EXT_METHOD *method;
-X509V3_CTX *ctx;
-STACK_OF(CONF_VALUE) *values;
-{
-return NULL;
-}
-*/
+ * static PKEY_USAGE_PERIOD *v2i_PKEY_USAGE_PERIOD(method, ctx, values)
+ * X509V3_EXT_METHOD *method; X509V3_CTX *ctx; STACK_OF(CONF_VALUE) *values;
+ * { return NULL; }
+ */
diff --git a/src/crypto/x509v3/v3_pmaps.c b/src/crypto/x509v3/v3_pmaps.c
index 5b909773..caacdb27 100644
--- a/src/crypto/x509v3/v3_pmaps.c
+++ b/src/crypto/x509v3/v3_pmaps.c
@@ -1,5 +1,6 @@
/* v3_pmaps.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project.
*/
/* ====================================================================
@@ -10,7 +11,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -54,7 +55,6 @@
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com). */
-
#include <stdio.h>
#include <openssl/asn1t.h>
@@ -63,94 +63,92 @@
#include <openssl/obj.h>
#include <openssl/x509v3.h>
-
static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method,
- X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
-static STACK_OF(CONF_VALUE) *
-i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, void *pmps,
- STACK_OF(CONF_VALUE) *extlist);
+ X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
+static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD
+ *method, void *pmps, STACK_OF(CONF_VALUE)
+ *extlist);
const X509V3_EXT_METHOD v3_policy_mappings = {
- NID_policy_mappings, 0,
- ASN1_ITEM_ref(POLICY_MAPPINGS),
- 0,0,0,0,
- 0,0,
- i2v_POLICY_MAPPINGS,
- v2i_POLICY_MAPPINGS,
- 0,0,
- NULL
+ NID_policy_mappings, 0,
+ ASN1_ITEM_ref(POLICY_MAPPINGS),
+ 0, 0, 0, 0,
+ 0, 0,
+ i2v_POLICY_MAPPINGS,
+ v2i_POLICY_MAPPINGS,
+ 0, 0,
+ NULL
};
ASN1_SEQUENCE(POLICY_MAPPING) = {
- ASN1_SIMPLE(POLICY_MAPPING, issuerDomainPolicy, ASN1_OBJECT),
- ASN1_SIMPLE(POLICY_MAPPING, subjectDomainPolicy, ASN1_OBJECT)
+ ASN1_SIMPLE(POLICY_MAPPING, issuerDomainPolicy, ASN1_OBJECT),
+ ASN1_SIMPLE(POLICY_MAPPING, subjectDomainPolicy, ASN1_OBJECT)
} ASN1_SEQUENCE_END(POLICY_MAPPING)
-ASN1_ITEM_TEMPLATE(POLICY_MAPPINGS) =
- ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, POLICY_MAPPINGS,
- POLICY_MAPPING)
+ASN1_ITEM_TEMPLATE(POLICY_MAPPINGS) =
+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, POLICY_MAPPINGS,
+ POLICY_MAPPING)
ASN1_ITEM_TEMPLATE_END(POLICY_MAPPINGS)
IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING)
-
-static STACK_OF(CONF_VALUE) *
-i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, void *a,
- STACK_OF(CONF_VALUE) *ext_list)
+static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD
+ *method, void *a, STACK_OF(CONF_VALUE)
+ *ext_list)
{
- POLICY_MAPPINGS *pmaps = a;
- POLICY_MAPPING *pmap;
- size_t i;
- char obj_tmp1[80];
- char obj_tmp2[80];
- for(i = 0; i < sk_POLICY_MAPPING_num(pmaps); i++) {
- pmap = sk_POLICY_MAPPING_value(pmaps, i);
- i2t_ASN1_OBJECT(obj_tmp1, 80, pmap->issuerDomainPolicy);
- i2t_ASN1_OBJECT(obj_tmp2, 80, pmap->subjectDomainPolicy);
- X509V3_add_value(obj_tmp1, obj_tmp2, &ext_list);
- }
- return ext_list;
+ POLICY_MAPPINGS *pmaps = a;
+ POLICY_MAPPING *pmap;
+ size_t i;
+ char obj_tmp1[80];
+ char obj_tmp2[80];
+ for (i = 0; i < sk_POLICY_MAPPING_num(pmaps); i++) {
+ pmap = sk_POLICY_MAPPING_value(pmaps, i);
+ i2t_ASN1_OBJECT(obj_tmp1, 80, pmap->issuerDomainPolicy);
+ i2t_ASN1_OBJECT(obj_tmp2, 80, pmap->subjectDomainPolicy);
+ X509V3_add_value(obj_tmp1, obj_tmp2, &ext_list);
+ }
+ return ext_list;
}
static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method,
- X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
+ X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
{
- POLICY_MAPPINGS *pmaps;
- POLICY_MAPPING *pmap;
- ASN1_OBJECT *obj1, *obj2;
- CONF_VALUE *val;
- size_t i;
+ POLICY_MAPPINGS *pmaps;
+ POLICY_MAPPING *pmap;
+ ASN1_OBJECT *obj1, *obj2;
+ CONF_VALUE *val;
+ size_t i;
- if(!(pmaps = sk_POLICY_MAPPING_new_null())) {
- OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
+ if (!(pmaps = sk_POLICY_MAPPING_new_null())) {
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
- for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
- 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, X509V3_R_INVALID_OBJECT_IDENTIFIER);
- X509V3_conf_err(val);
- return NULL;
- }
- obj1 = OBJ_txt2obj(val->name, 0);
- obj2 = OBJ_txt2obj(val->value, 0);
- if(!obj1 || !obj2) {
- sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free);
- 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, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
- pmap->issuerDomainPolicy = obj1;
- pmap->subjectDomainPolicy = obj2;
- sk_POLICY_MAPPING_push(pmaps, pmap);
- }
- return pmaps;
+ for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+ 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, X509V3_R_INVALID_OBJECT_IDENTIFIER);
+ X509V3_conf_err(val);
+ return NULL;
+ }
+ obj1 = OBJ_txt2obj(val->name, 0);
+ obj2 = OBJ_txt2obj(val->value, 0);
+ if (!obj1 || !obj2) {
+ sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free);
+ 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, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ pmap->issuerDomainPolicy = obj1;
+ pmap->subjectDomainPolicy = obj2;
+ sk_POLICY_MAPPING_push(pmaps, pmap);
+ }
+ return pmaps;
}
diff --git a/src/crypto/x509v3/v3_prn.c b/src/crypto/x509v3/v3_prn.c
index 87aef4d4..5015efcc 100644
--- a/src/crypto/x509v3/v3_prn.c
+++ b/src/crypto/x509v3/v3_prn.c
@@ -1,6 +1,7 @@
/* v3_prn.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
*/
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
@@ -10,7 +11,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -63,145 +64,169 @@
#include <openssl/mem.h>
#include <openssl/x509v3.h>
-
/* Extension printing routines */
-static int unknown_ext_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, int indent, int supported);
+static int unknown_ext_print(BIO *out, X509_EXTENSION *ext,
+ unsigned long flag, int indent, int supported);
/* Print out a name+value stack */
-void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent, int ml)
+void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent,
+ int ml)
{
- size_t i;
- CONF_VALUE *nval;
- if(!val) return;
- if(!ml || !sk_CONF_VALUE_num(val)) {
- BIO_printf(out, "%*s", indent, "");
- if(!sk_CONF_VALUE_num(val)) BIO_puts(out, "<EMPTY>\n");
- }
- for(i = 0; i < sk_CONF_VALUE_num(val); i++) {
- if(ml) BIO_printf(out, "%*s", indent, "");
- else if(i > 0) BIO_printf(out, ", ");
- nval = sk_CONF_VALUE_value(val, i);
- if(!nval->name) BIO_puts(out, nval->value);
- else if(!nval->value) BIO_puts(out, nval->name);
- else BIO_printf(out, "%s:%s", nval->name, nval->value);
- if(ml) BIO_puts(out, "\n");
- }
+ size_t i;
+ CONF_VALUE *nval;
+ if (!val)
+ return;
+ if (!ml || !sk_CONF_VALUE_num(val)) {
+ BIO_printf(out, "%*s", indent, "");
+ if (!sk_CONF_VALUE_num(val))
+ BIO_puts(out, "<EMPTY>\n");
+ }
+ for (i = 0; i < sk_CONF_VALUE_num(val); i++) {
+ if (ml)
+ BIO_printf(out, "%*s", indent, "");
+ else if (i > 0)
+ BIO_printf(out, ", ");
+ nval = sk_CONF_VALUE_value(val, i);
+ if (!nval->name)
+ BIO_puts(out, nval->value);
+ else if (!nval->value)
+ BIO_puts(out, nval->name);
+ else
+ BIO_printf(out, "%s:%s", nval->name, nval->value);
+ if (ml)
+ BIO_puts(out, "\n");
+ }
}
/* Main routine: print out a general extension */
-int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, int indent)
+int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag,
+ int indent)
{
- void *ext_str = NULL;
- char *value = NULL;
- const unsigned char *p;
- const X509V3_EXT_METHOD *method;
- STACK_OF(CONF_VALUE) *nval = NULL;
- int ok = 1;
-
- if(!(method = X509V3_EXT_get(ext)))
- return unknown_ext_print(out, ext, flag, indent, 0);
- p = ext->value->data;
- if(method->it) ext_str = ASN1_item_d2i(NULL, &p, ext->value->length, ASN1_ITEM_ptr(method->it));
- else ext_str = method->d2i(NULL, &p, ext->value->length);
-
- if(!ext_str) return unknown_ext_print(out, ext, flag, indent, 1);
-
- if(method->i2s) {
- if(!(value = method->i2s(method, ext_str))) {
- ok = 0;
- goto err;
- }
- BIO_printf(out, "%*s%s", indent, "", value);
- } else if(method->i2v) {
- if(!(nval = method->i2v(method, ext_str, NULL))) {
- ok = 0;
- goto err;
- }
- X509V3_EXT_val_prn(out, nval, indent,
- method->ext_flags & X509V3_EXT_MULTILINE);
- } else if(method->i2r) {
- if(!method->i2r(method, ext_str, out, indent)) ok = 0;
- } else ok = 0;
-
- err:
- sk_CONF_VALUE_pop_free(nval, X509V3_conf_free);
- if(value) OPENSSL_free(value);
- if(method->it) ASN1_item_free(ext_str, ASN1_ITEM_ptr(method->it));
- else method->ext_free(ext_str);
- return ok;
+ void *ext_str = NULL;
+ char *value = NULL;
+ const unsigned char *p;
+ const X509V3_EXT_METHOD *method;
+ STACK_OF(CONF_VALUE) *nval = NULL;
+ int ok = 1;
+
+ if (!(method = X509V3_EXT_get(ext)))
+ return unknown_ext_print(out, ext, flag, indent, 0);
+ p = ext->value->data;
+ if (method->it)
+ ext_str =
+ ASN1_item_d2i(NULL, &p, ext->value->length,
+ ASN1_ITEM_ptr(method->it));
+ else
+ ext_str = method->d2i(NULL, &p, ext->value->length);
+
+ if (!ext_str)
+ return unknown_ext_print(out, ext, flag, indent, 1);
+
+ if (method->i2s) {
+ if (!(value = method->i2s(method, ext_str))) {
+ ok = 0;
+ goto err;
+ }
+ BIO_printf(out, "%*s%s", indent, "", value);
+ } else if (method->i2v) {
+ if (!(nval = method->i2v(method, ext_str, NULL))) {
+ ok = 0;
+ goto err;
+ }
+ X509V3_EXT_val_prn(out, nval, indent,
+ method->ext_flags & X509V3_EXT_MULTILINE);
+ } else if (method->i2r) {
+ if (!method->i2r(method, ext_str, out, indent))
+ ok = 0;
+ } else
+ ok = 0;
+
+ err:
+ sk_CONF_VALUE_pop_free(nval, X509V3_conf_free);
+ if (value)
+ OPENSSL_free(value);
+ if (method->it)
+ ASN1_item_free(ext_str, ASN1_ITEM_ptr(method->it));
+ else
+ method->ext_free(ext_str);
+ return ok;
}
-int X509V3_extensions_print(BIO *bp, const char *title, STACK_OF(X509_EXTENSION) *exts, unsigned long flag, int indent)
+int X509V3_extensions_print(BIO *bp, const char *title,
+ STACK_OF(X509_EXTENSION) *exts,
+ unsigned long flag, int indent)
{
- size_t i;
- int j;
-
- if(sk_X509_EXTENSION_num(exts) <= 0) return 1;
-
- if(title)
- {
- BIO_printf(bp,"%*s%s:\n",indent, "", title);
- indent += 4;
- }
-
- for (i=0; i<sk_X509_EXTENSION_num(exts); i++)
- {
- ASN1_OBJECT *obj;
- X509_EXTENSION *ex;
- ex=sk_X509_EXTENSION_value(exts, i);
- if (indent && BIO_printf(bp,"%*s",indent, "") <= 0) return 0;
- obj=X509_EXTENSION_get_object(ex);
- i2a_ASN1_OBJECT(bp,obj);
- j=X509_EXTENSION_get_critical(ex);
- if (BIO_printf(bp,": %s\n",j?"critical":"") <= 0)
- return 0;
- if(!X509V3_EXT_print(bp, ex, flag, indent + 4))
- {
- BIO_printf(bp, "%*s", indent + 4, "");
- M_ASN1_OCTET_STRING_print(bp,ex->value);
- }
- if (BIO_write(bp,"\n",1) <= 0) return 0;
- }
- return 1;
+ size_t i;
+ int j;
+
+ if (sk_X509_EXTENSION_num(exts) <= 0)
+ return 1;
+
+ if (title) {
+ BIO_printf(bp, "%*s%s:\n", indent, "", title);
+ indent += 4;
+ }
+
+ for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
+ ASN1_OBJECT *obj;
+ X509_EXTENSION *ex;
+ ex = sk_X509_EXTENSION_value(exts, i);
+ if (indent && BIO_printf(bp, "%*s", indent, "") <= 0)
+ return 0;
+ obj = X509_EXTENSION_get_object(ex);
+ i2a_ASN1_OBJECT(bp, obj);
+ j = X509_EXTENSION_get_critical(ex);
+ if (BIO_printf(bp, ": %s\n", j ? "critical" : "") <= 0)
+ return 0;
+ if (!X509V3_EXT_print(bp, ex, flag, indent + 4)) {
+ BIO_printf(bp, "%*s", indent + 4, "");
+ M_ASN1_OCTET_STRING_print(bp, ex->value);
+ }
+ if (BIO_write(bp, "\n", 1) <= 0)
+ return 0;
+ }
+ return 1;
}
-static int unknown_ext_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, int indent, int supported)
+static int unknown_ext_print(BIO *out, X509_EXTENSION *ext,
+ unsigned long flag, int indent, int supported)
{
- switch(flag & X509V3_EXT_UNKNOWN_MASK) {
-
- case X509V3_EXT_DEFAULT:
- return 0;
-
- case X509V3_EXT_ERROR_UNKNOWN:
- if(supported)
- BIO_printf(out, "%*s<Parse Error>", indent, "");
- else
- BIO_printf(out, "%*s<Not Supported>", indent, "");
- return 1;
-
- case X509V3_EXT_PARSE_UNKNOWN:
- return ASN1_parse_dump(out,
- ext->value->data, ext->value->length, indent, -1);
- case X509V3_EXT_DUMP_UNKNOWN:
- return BIO_hexdump(out, ext->value->data, ext->value->length, indent);
-
- default:
- return 1;
- }
+ switch (flag & X509V3_EXT_UNKNOWN_MASK) {
+
+ case X509V3_EXT_DEFAULT:
+ return 0;
+
+ case X509V3_EXT_ERROR_UNKNOWN:
+ if (supported)
+ BIO_printf(out, "%*s<Parse Error>", indent, "");
+ else
+ BIO_printf(out, "%*s<Not Supported>", indent, "");
+ return 1;
+
+ case X509V3_EXT_PARSE_UNKNOWN:
+ return ASN1_parse_dump(out,
+ ext->value->data, ext->value->length, indent,
+ -1);
+ case X509V3_EXT_DUMP_UNKNOWN:
+ return BIO_hexdump(out, ext->value->data, ext->value->length, indent);
+
+ default:
+ return 1;
+ }
}
-
#ifndef OPENSSL_NO_FP_API
int X509V3_EXT_print_fp(FILE *fp, X509_EXTENSION *ext, int flag, int indent)
{
- BIO *bio_tmp;
- int ret;
- if(!(bio_tmp = BIO_new_fp(fp, BIO_NOCLOSE))) return 0;
- ret = X509V3_EXT_print(bio_tmp, ext, flag, indent);
- BIO_free(bio_tmp);
- return ret;
+ BIO *bio_tmp;
+ int ret;
+ if (!(bio_tmp = BIO_new_fp(fp, BIO_NOCLOSE)))
+ return 0;
+ ret = X509V3_EXT_print(bio_tmp, ext, flag, indent);
+ BIO_free(bio_tmp);
+ return ret;
}
#endif
diff --git a/src/crypto/x509v3/v3_purp.c b/src/crypto/x509v3/v3_purp.c
index 9a0a7bc4..85bc15b7 100644
--- a/src/crypto/x509v3/v3_purp.c
+++ b/src/crypto/x509v3/v3_purp.c
@@ -1,6 +1,7 @@
/* v3_purp.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2001.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2001.
*/
/* ====================================================================
* Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved.
@@ -10,7 +11,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -69,26 +70,32 @@
#include "../internal.h"
-
#define V1_ROOT (EXFLAG_V1|EXFLAG_SS)
#define ku_reject(x, usage) \
- (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage)))
+ (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage)))
#define xku_reject(x, usage) \
- (((x)->ex_flags & EXFLAG_XKUSAGE) && !((x)->ex_xkusage & (usage)))
+ (((x)->ex_flags & EXFLAG_XKUSAGE) && !((x)->ex_xkusage & (usage)))
#define ns_reject(x, usage) \
- (((x)->ex_flags & EXFLAG_NSCERT) && !((x)->ex_nscert & (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);
-static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, int ca);
-static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca);
-static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca);
+static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x,
+ int ca);
+static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x,
+ int ca);
+static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x,
+ int ca);
static int purpose_smime(const X509 *x, int ca);
-static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, int ca);
-static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, int ca);
-static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, int ca);
-static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x, int ca);
+static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x,
+ int ca);
+static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x,
+ int ca);
+static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x,
+ int ca);
+static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x,
+ int ca);
static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca);
static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca);
@@ -96,15 +103,29 @@ static int xp_cmp(const X509_PURPOSE **a, const X509_PURPOSE **b);
static void xptable_free(X509_PURPOSE *p);
static X509_PURPOSE xstandard[] = {
- {X509_PURPOSE_SSL_CLIENT, X509_TRUST_SSL_CLIENT, 0, check_purpose_ssl_client, (char *) "SSL client", (char *) "sslclient", NULL},
- {X509_PURPOSE_SSL_SERVER, X509_TRUST_SSL_SERVER, 0, check_purpose_ssl_server, (char *) "SSL server", (char *) "sslserver", NULL},
- {X509_PURPOSE_NS_SSL_SERVER, X509_TRUST_SSL_SERVER, 0, check_purpose_ns_ssl_server, (char *) "Netscape SSL server", (char *) "nssslserver", NULL},
- {X509_PURPOSE_SMIME_SIGN, X509_TRUST_EMAIL, 0, check_purpose_smime_sign, (char *) "S/MIME signing", (char *) "smimesign", NULL},
- {X509_PURPOSE_SMIME_ENCRYPT, X509_TRUST_EMAIL, 0, check_purpose_smime_encrypt, (char *) "S/MIME encryption", (char *) "smimeencrypt", NULL},
- {X509_PURPOSE_CRL_SIGN, X509_TRUST_COMPAT, 0, check_purpose_crl_sign, (char *) "CRL signing", (char *) "crlsign", NULL},
- {X509_PURPOSE_ANY, X509_TRUST_DEFAULT, 0, no_check, (char *) "Any Purpose", (char *) "any", NULL},
- {X509_PURPOSE_OCSP_HELPER, X509_TRUST_COMPAT, 0, ocsp_helper, (char *) "OCSP helper", (char *) "ocsphelper", NULL},
- {X509_PURPOSE_TIMESTAMP_SIGN, X509_TRUST_TSA, 0, check_purpose_timestamp_sign, (char *) "Time Stamp signing", (char *) "timestampsign", NULL},
+ {X509_PURPOSE_SSL_CLIENT, X509_TRUST_SSL_CLIENT, 0,
+ check_purpose_ssl_client, (char *)"SSL client", (char *)"sslclient",
+ NULL},
+ {X509_PURPOSE_SSL_SERVER, X509_TRUST_SSL_SERVER, 0,
+ check_purpose_ssl_server, (char *)"SSL server", (char *)"sslserver",
+ NULL},
+ {X509_PURPOSE_NS_SSL_SERVER, X509_TRUST_SSL_SERVER, 0,
+ check_purpose_ns_ssl_server, (char *)"Netscape SSL server",
+ (char *)"nssslserver", NULL},
+ {X509_PURPOSE_SMIME_SIGN, X509_TRUST_EMAIL, 0, check_purpose_smime_sign,
+ (char *)"S/MIME signing", (char *)"smimesign", NULL},
+ {X509_PURPOSE_SMIME_ENCRYPT, X509_TRUST_EMAIL, 0,
+ check_purpose_smime_encrypt, (char *)"S/MIME encryption",
+ (char *)"smimeencrypt", NULL},
+ {X509_PURPOSE_CRL_SIGN, X509_TRUST_COMPAT, 0, check_purpose_crl_sign,
+ (char *)"CRL signing", (char *)"crlsign", NULL},
+ {X509_PURPOSE_ANY, X509_TRUST_DEFAULT, 0, no_check, (char *)"Any Purpose",
+ (char *)"any", NULL},
+ {X509_PURPOSE_OCSP_HELPER, X509_TRUST_COMPAT, 0, ocsp_helper,
+ (char *)"OCSP helper", (char *)"ocsphelper", NULL},
+ {X509_PURPOSE_TIMESTAMP_SIGN, X509_TRUST_TSA, 0,
+ check_purpose_timestamp_sign, (char *)"Time Stamp signing",
+ (char *)"timestampsign", NULL},
};
#define X509_PURPOSE_COUNT (sizeof(xstandard)/sizeof(X509_PURPOSE))
@@ -113,693 +134,741 @@ static STACK_OF(X509_PURPOSE) *xptable = NULL;
static int xp_cmp(const X509_PURPOSE **a, const X509_PURPOSE **b)
{
- return (*a)->purpose - (*b)->purpose;
+ return (*a)->purpose - (*b)->purpose;
}
-/* As much as I'd like to make X509_check_purpose use a "const" X509*
- * I really can't because it does recalculate hashes and do other non-const
- * things. */
+/*
+ * As much as I'd like to make X509_check_purpose use a "const" X509* I
+ * really can't because it does recalculate hashes and do other non-const
+ * things.
+ */
int X509_check_purpose(X509 *x, int id, int ca)
{
- int idx;
- const X509_PURPOSE *pt;
- if(!(x->ex_flags & EXFLAG_SET)) {
- x509v3_cache_extensions(x);
- }
- if(id == -1) return 1;
- idx = X509_PURPOSE_get_by_id(id);
- if(idx == -1) return -1;
- pt = X509_PURPOSE_get0(idx);
- return pt->check_purpose(pt, x, ca);
+ int idx;
+ const X509_PURPOSE *pt;
+ if (!(x->ex_flags & EXFLAG_SET)) {
+ x509v3_cache_extensions(x);
+ }
+ if (id == -1)
+ return 1;
+ idx = X509_PURPOSE_get_by_id(id);
+ if (idx == -1)
+ return -1;
+ pt = X509_PURPOSE_get0(idx);
+ return pt->check_purpose(pt, x, ca);
}
int X509_PURPOSE_set(int *p, int purpose)
{
- if(X509_PURPOSE_get_by_id(purpose) == -1) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_PURPOSE);
- return 0;
- }
- *p = purpose;
- return 1;
+ if (X509_PURPOSE_get_by_id(purpose) == -1) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_PURPOSE);
+ return 0;
+ }
+ *p = purpose;
+ return 1;
}
int X509_PURPOSE_get_count(void)
{
- if(!xptable) return X509_PURPOSE_COUNT;
- return sk_X509_PURPOSE_num(xptable) + X509_PURPOSE_COUNT;
+ if (!xptable)
+ return X509_PURPOSE_COUNT;
+ return sk_X509_PURPOSE_num(xptable) + X509_PURPOSE_COUNT;
}
-X509_PURPOSE * X509_PURPOSE_get0(int idx)
+X509_PURPOSE *X509_PURPOSE_get0(int idx)
{
- if(idx < 0) return NULL;
- if(idx < (int)X509_PURPOSE_COUNT) return xstandard + idx;
- return sk_X509_PURPOSE_value(xptable, idx - X509_PURPOSE_COUNT);
+ if (idx < 0)
+ return NULL;
+ if (idx < (int)X509_PURPOSE_COUNT)
+ return xstandard + idx;
+ return sk_X509_PURPOSE_value(xptable, idx - X509_PURPOSE_COUNT);
}
int X509_PURPOSE_get_by_sname(char *sname)
{
- int i;
- X509_PURPOSE *xptmp;
- for(i = 0; i < X509_PURPOSE_get_count(); i++) {
- xptmp = X509_PURPOSE_get0(i);
- if(!strcmp(xptmp->sname, sname)) return i;
- }
- return -1;
+ int i;
+ X509_PURPOSE *xptmp;
+ for (i = 0; i < X509_PURPOSE_get_count(); i++) {
+ xptmp = X509_PURPOSE_get0(i);
+ if (!strcmp(xptmp->sname, sname))
+ return i;
+ }
+ return -1;
}
int X509_PURPOSE_get_by_id(int purpose)
{
- X509_PURPOSE tmp;
- size_t idx;
-
- if((purpose >= X509_PURPOSE_MIN) && (purpose <= X509_PURPOSE_MAX))
- return purpose - X509_PURPOSE_MIN;
- tmp.purpose = purpose;
- if(!xptable) return -1;
-
- if (!sk_X509_PURPOSE_find(xptable, &idx, &tmp))
- return -1;
- return idx + X509_PURPOSE_COUNT;
+ X509_PURPOSE tmp;
+ size_t idx;
+
+ if ((purpose >= X509_PURPOSE_MIN) && (purpose <= X509_PURPOSE_MAX))
+ return purpose - X509_PURPOSE_MIN;
+ tmp.purpose = purpose;
+ if (!xptable)
+ return -1;
+
+ if (!sk_X509_PURPOSE_find(xptable, &idx, &tmp))
+ return -1;
+ return idx + X509_PURPOSE_COUNT;
}
int X509_PURPOSE_add(int id, int trust, int flags,
- int (*ck)(const X509_PURPOSE *, const X509 *, int),
- char *name, char *sname, void *arg)
-{
- int idx;
- X509_PURPOSE *ptmp;
- char *name_dup, *sname_dup;
-
- /* This is set according to what we change: application can't set it */
- flags &= ~X509_PURPOSE_DYNAMIC;
- /* This will always be set for application modified trust entries */
- flags |= X509_PURPOSE_DYNAMIC_NAME;
- /* Get existing entry if any */
- idx = X509_PURPOSE_get_by_id(id);
- /* Need a new entry */
- if(idx == -1) {
- if(!(ptmp = OPENSSL_malloc(sizeof(X509_PURPOSE)))) {
- OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
- return 0;
- }
- ptmp->flags = X509_PURPOSE_DYNAMIC;
- } else ptmp = X509_PURPOSE_get0(idx);
-
- /* Duplicate the supplied names. */
- name_dup = BUF_strdup(name);
- sname_dup = BUF_strdup(sname);
- if (name_dup == NULL || sname_dup == NULL) {
- OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
- if (name_dup != NULL)
- OPENSSL_free(name_dup);
- if (sname_dup != NULL)
- OPENSSL_free(sname_dup);
- if (idx == -1)
- OPENSSL_free(ptmp);
- return 0;
- }
-
- /* OPENSSL_free existing name if dynamic */
- if(ptmp->flags & X509_PURPOSE_DYNAMIC_NAME) {
- OPENSSL_free(ptmp->name);
- OPENSSL_free(ptmp->sname);
- }
- /* dup supplied name */
- ptmp->name = name_dup;
- ptmp->sname = sname_dup;
- /* Keep the dynamic flag of existing entry */
- ptmp->flags &= X509_PURPOSE_DYNAMIC;
- /* Set all other flags */
- ptmp->flags |= flags;
-
- ptmp->purpose = id;
- ptmp->trust = trust;
- ptmp->check_purpose = ck;
- ptmp->usr_data = arg;
-
- /* 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, ERR_R_MALLOC_FAILURE);
- xptable_free(ptmp);
- return 0;
- }
- if (!sk_X509_PURPOSE_push(xptable, ptmp)) {
- OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
- xptable_free(ptmp);
- return 0;
- }
- }
- return 1;
+ int (*ck) (const X509_PURPOSE *, const X509 *, int),
+ char *name, char *sname, void *arg)
+{
+ int idx;
+ X509_PURPOSE *ptmp;
+ char *name_dup, *sname_dup;
+
+ /*
+ * This is set according to what we change: application can't set it
+ */
+ flags &= ~X509_PURPOSE_DYNAMIC;
+ /* This will always be set for application modified trust entries */
+ flags |= X509_PURPOSE_DYNAMIC_NAME;
+ /* Get existing entry if any */
+ idx = X509_PURPOSE_get_by_id(id);
+ /* Need a new entry */
+ if (idx == -1) {
+ if (!(ptmp = OPENSSL_malloc(sizeof(X509_PURPOSE)))) {
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ ptmp->flags = X509_PURPOSE_DYNAMIC;
+ } else
+ ptmp = X509_PURPOSE_get0(idx);
+
+ /* Duplicate the supplied names. */
+ name_dup = BUF_strdup(name);
+ sname_dup = BUF_strdup(sname);
+ if (name_dup == NULL || sname_dup == NULL) {
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+ if (name_dup != NULL)
+ OPENSSL_free(name_dup);
+ if (sname_dup != NULL)
+ OPENSSL_free(sname_dup);
+ if (idx == -1)
+ OPENSSL_free(ptmp);
+ return 0;
+ }
+
+ /* OPENSSL_free existing name if dynamic */
+ if (ptmp->flags & X509_PURPOSE_DYNAMIC_NAME) {
+ OPENSSL_free(ptmp->name);
+ OPENSSL_free(ptmp->sname);
+ }
+ /* dup supplied name */
+ ptmp->name = name_dup;
+ ptmp->sname = sname_dup;
+ /* Keep the dynamic flag of existing entry */
+ ptmp->flags &= X509_PURPOSE_DYNAMIC;
+ /* Set all other flags */
+ ptmp->flags |= flags;
+
+ ptmp->purpose = id;
+ ptmp->trust = trust;
+ ptmp->check_purpose = ck;
+ ptmp->usr_data = arg;
+
+ /* 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, ERR_R_MALLOC_FAILURE);
+ xptable_free(ptmp);
+ return 0;
+ }
+ if (!sk_X509_PURPOSE_push(xptable, ptmp)) {
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+ xptable_free(ptmp);
+ return 0;
+ }
+ }
+ return 1;
}
static void xptable_free(X509_PURPOSE *p)
- {
- if(!p) return;
- if (p->flags & X509_PURPOSE_DYNAMIC)
- {
- if (p->flags & X509_PURPOSE_DYNAMIC_NAME) {
- OPENSSL_free(p->name);
- OPENSSL_free(p->sname);
- }
- OPENSSL_free(p);
- }
- }
+{
+ if (!p)
+ return;
+ if (p->flags & X509_PURPOSE_DYNAMIC) {
+ if (p->flags & X509_PURPOSE_DYNAMIC_NAME) {
+ OPENSSL_free(p->name);
+ OPENSSL_free(p->sname);
+ }
+ OPENSSL_free(p);
+ }
+}
void X509_PURPOSE_cleanup(void)
{
- unsigned int i;
- sk_X509_PURPOSE_pop_free(xptable, xptable_free);
- for(i = 0; i < X509_PURPOSE_COUNT; i++) xptable_free(xstandard + i);
- xptable = NULL;
+ unsigned int i;
+ sk_X509_PURPOSE_pop_free(xptable, xptable_free);
+ for (i = 0; i < X509_PURPOSE_COUNT; i++)
+ xptable_free(xstandard + i);
+ xptable = NULL;
}
int X509_PURPOSE_get_id(X509_PURPOSE *xp)
{
- return xp->purpose;
+ return xp->purpose;
}
char *X509_PURPOSE_get0_name(X509_PURPOSE *xp)
{
- return xp->name;
+ return xp->name;
}
char *X509_PURPOSE_get0_sname(X509_PURPOSE *xp)
{
- return xp->sname;
+ return xp->sname;
}
int X509_PURPOSE_get_trust(X509_PURPOSE *xp)
{
- return xp->trust;
+ return xp->trust;
}
static int nid_cmp(const void *void_a, const void *void_b)
- {
- const int *a = void_a, *b = void_b;
+{
+ const int *a = void_a, *b = void_b;
- return *a - *b;
- }
+ return *a - *b;
+}
int X509_supported_extension(X509_EXTENSION *ex)
- {
- /* This table is a list of the NIDs of supported extensions:
- * that is those which are used by the verify process. If
- * an extension is critical and doesn't appear in this list
- * then the verify process will normally reject the certificate.
- * The list must be kept in numerical order because it will be
- * searched using bsearch.
- */
-
- static const int supported_nids[] = {
- NID_netscape_cert_type, /* 71 */
- NID_key_usage, /* 83 */
- NID_subject_alt_name, /* 85 */
- NID_basic_constraints, /* 87 */
- NID_certificate_policies, /* 89 */
- NID_ext_key_usage, /* 126 */
- NID_policy_constraints, /* 401 */
- NID_proxyCertInfo, /* 663 */
- NID_name_constraints, /* 666 */
- NID_policy_mappings, /* 747 */
- NID_inhibit_any_policy /* 748 */
- };
-
- int ex_nid = OBJ_obj2nid(X509_EXTENSION_get_object(ex));
-
- if (ex_nid == NID_undef)
- return 0;
-
- if (bsearch(&ex_nid, supported_nids, sizeof(supported_nids)/sizeof(int), sizeof(int), nid_cmp) != NULL)
- return 1;
- return 0;
- }
+{
+ /*
+ * This table is a list of the NIDs of supported extensions: that is
+ * those which are used by the verify process. If an extension is
+ * critical and doesn't appear in this list then the verify process will
+ * normally reject the certificate. The list must be kept in numerical
+ * order because it will be searched using bsearch.
+ */
+
+ static const int supported_nids[] = {
+ NID_netscape_cert_type, /* 71 */
+ NID_key_usage, /* 83 */
+ NID_subject_alt_name, /* 85 */
+ NID_basic_constraints, /* 87 */
+ NID_certificate_policies, /* 89 */
+ NID_ext_key_usage, /* 126 */
+ NID_policy_constraints, /* 401 */
+ NID_proxyCertInfo, /* 663 */
+ NID_name_constraints, /* 666 */
+ NID_policy_mappings, /* 747 */
+ NID_inhibit_any_policy /* 748 */
+ };
+
+ int ex_nid = OBJ_obj2nid(X509_EXTENSION_get_object(ex));
+
+ if (ex_nid == NID_undef)
+ return 0;
+
+ if (bsearch
+ (&ex_nid, supported_nids, sizeof(supported_nids) / sizeof(int),
+ sizeof(int), nid_cmp) != NULL)
+ return 1;
+ return 0;
+}
static void setup_dp(X509 *x, DIST_POINT *dp)
- {
- X509_NAME *iname = NULL;
- size_t i;
- if (dp->reasons)
- {
- if (dp->reasons->length > 0)
- dp->dp_reasons = dp->reasons->data[0];
- if (dp->reasons->length > 1)
- dp->dp_reasons |= (dp->reasons->data[1] << 8);
- dp->dp_reasons &= CRLDP_ALL_REASONS;
- }
- else
- dp->dp_reasons = CRLDP_ALL_REASONS;
- if (!dp->distpoint || (dp->distpoint->type != 1))
- return;
- for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++)
- {
- GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i);
- if (gen->type == GEN_DIRNAME)
- {
- iname = gen->d.directoryName;
- break;
- }
- }
- if (!iname)
- iname = X509_get_issuer_name(x);
-
- DIST_POINT_set_dpname(dp->distpoint, iname);
-
- }
+{
+ X509_NAME *iname = NULL;
+ size_t i;
+ if (dp->reasons) {
+ if (dp->reasons->length > 0)
+ dp->dp_reasons = dp->reasons->data[0];
+ if (dp->reasons->length > 1)
+ dp->dp_reasons |= (dp->reasons->data[1] << 8);
+ dp->dp_reasons &= CRLDP_ALL_REASONS;
+ } else
+ dp->dp_reasons = CRLDP_ALL_REASONS;
+ if (!dp->distpoint || (dp->distpoint->type != 1))
+ return;
+ for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) {
+ GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i);
+ if (gen->type == GEN_DIRNAME) {
+ iname = gen->d.directoryName;
+ break;
+ }
+ }
+ if (!iname)
+ iname = X509_get_issuer_name(x);
+
+ DIST_POINT_set_dpname(dp->distpoint, iname);
+
+}
static void setup_crldp(X509 *x)
- {
- size_t i;
- x->crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, NULL, NULL);
- for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++)
- setup_dp(x, sk_DIST_POINT_value(x->crldp, i));
- }
-
-/* g_x509_cache_extensions_lock is used to protect against concurrent calls to
- * |x509v3_cache_extensions|. Ideally this would be done with a |CRYPTO_once_t|
- * in the |X509| structure, but |CRYPTO_once_t| isn't public.
- *
+{
+ size_t i;
+ x->crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, NULL, NULL);
+ for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++)
+ setup_dp(x, sk_DIST_POINT_value(x->crldp, i));
+}
+
+/*
+ * g_x509_cache_extensions_lock is used to protect against concurrent calls
+ * to |x509v3_cache_extensions|. Ideally this would be done with a
+ * |CRYPTO_once_t| in the |X509| structure, but |CRYPTO_once_t| isn't public.
* Note: it's not entirely clear whether this lock is needed. Not all paths to
- * this function took a lock in OpenSSL. */
+ * this function took a lock in OpenSSL.
+ */
static struct CRYPTO_STATIC_MUTEX g_x509_cache_extensions_lock =
CRYPTO_STATIC_MUTEX_INIT;
static void x509v3_cache_extensions(X509 *x)
{
- BASIC_CONSTRAINTS *bs;
- PROXY_CERT_INFO_EXTENSION *pci;
- ASN1_BIT_STRING *usage;
- ASN1_BIT_STRING *ns;
- EXTENDED_KEY_USAGE *extusage;
- X509_EXTENSION *ex;
- size_t i;
- int j;
-
- CRYPTO_STATIC_MUTEX_lock_write(&g_x509_cache_extensions_lock);
-
- if(x->ex_flags & EXFLAG_SET)
- {
- CRYPTO_STATIC_MUTEX_unlock(&g_x509_cache_extensions_lock);
- return;
- }
-
- X509_digest(x, EVP_sha1(), x->sha1_hash, NULL);
- /* V1 should mean no extensions ... */
- if(!X509_get_version(x)) x->ex_flags |= EXFLAG_V1;
- /* Handle basic constraints */
- if((bs=X509_get_ext_d2i(x, NID_basic_constraints, NULL, NULL))) {
- if(bs->ca) x->ex_flags |= EXFLAG_CA;
- if(bs->pathlen) {
- if((bs->pathlen->type == V_ASN1_NEG_INTEGER)
- || !bs->ca) {
- x->ex_flags |= EXFLAG_INVALID;
- x->ex_pathlen = 0;
- } else x->ex_pathlen = ASN1_INTEGER_get(bs->pathlen);
- } else x->ex_pathlen = -1;
- BASIC_CONSTRAINTS_free(bs);
- x->ex_flags |= EXFLAG_BCONS;
- }
- /* Handle proxy certificates */
- if((pci=X509_get_ext_d2i(x, NID_proxyCertInfo, NULL, NULL))) {
- if (x->ex_flags & EXFLAG_CA
- || X509_get_ext_by_NID(x, NID_subject_alt_name, -1) >= 0
- || X509_get_ext_by_NID(x, NID_issuer_alt_name, -1) >= 0) {
- x->ex_flags |= EXFLAG_INVALID;
- }
- if (pci->pcPathLengthConstraint) {
- x->ex_pcpathlen =
- ASN1_INTEGER_get(pci->pcPathLengthConstraint);
- } else x->ex_pcpathlen = -1;
- PROXY_CERT_INFO_EXTENSION_free(pci);
- x->ex_flags |= EXFLAG_PROXY;
- }
- /* Handle key usage */
- if((usage=X509_get_ext_d2i(x, NID_key_usage, NULL, NULL))) {
- if(usage->length > 0) {
- x->ex_kusage = usage->data[0];
- if(usage->length > 1)
- x->ex_kusage |= usage->data[1] << 8;
- } else x->ex_kusage = 0;
- x->ex_flags |= EXFLAG_KUSAGE;
- ASN1_BIT_STRING_free(usage);
- }
- x->ex_xkusage = 0;
- if((extusage=X509_get_ext_d2i(x, NID_ext_key_usage, NULL, NULL))) {
- x->ex_flags |= EXFLAG_XKUSAGE;
- for(i = 0; i < sk_ASN1_OBJECT_num(extusage); i++) {
- switch(OBJ_obj2nid(sk_ASN1_OBJECT_value(extusage,i))) {
- case NID_server_auth:
- x->ex_xkusage |= XKU_SSL_SERVER;
- break;
-
- case NID_client_auth:
- x->ex_xkusage |= XKU_SSL_CLIENT;
- break;
-
- case NID_email_protect:
- x->ex_xkusage |= XKU_SMIME;
- break;
-
- case NID_code_sign:
- x->ex_xkusage |= XKU_CODE_SIGN;
- break;
-
- case NID_ms_sgc:
- case NID_ns_sgc:
- x->ex_xkusage |= XKU_SGC;
- break;
-
- case NID_OCSP_sign:
- x->ex_xkusage |= XKU_OCSP_SIGN;
- break;
-
- case NID_time_stamp:
- x->ex_xkusage |= XKU_TIMESTAMP;
- break;
-
- case NID_dvcs:
- x->ex_xkusage |= XKU_DVCS;
- break;
-
- case NID_anyExtendedKeyUsage:
- x->ex_xkusage |= XKU_ANYEKU;
- break;
- }
- }
- sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free);
- }
-
- if((ns=X509_get_ext_d2i(x, NID_netscape_cert_type, NULL, NULL))) {
- if(ns->length > 0) x->ex_nscert = ns->data[0];
- else x->ex_nscert = 0;
- x->ex_flags |= EXFLAG_NSCERT;
- ASN1_BIT_STRING_free(ns);
- }
- x->skid =X509_get_ext_d2i(x, NID_subject_key_identifier, NULL, NULL);
- x->akid =X509_get_ext_d2i(x, NID_authority_key_identifier, NULL, NULL);
- /* Does subject name match issuer ? */
- if(!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x)))
- {
- x->ex_flags |= EXFLAG_SI;
- /* If SKID matches AKID also indicate self signed */
- 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);
- x->nc = X509_get_ext_d2i(x, NID_name_constraints, &j, NULL);
- if (!x->nc && (j != -1))
- x->ex_flags |= EXFLAG_INVALID;
- setup_crldp(x);
-
- for (j = 0; j < X509_get_ext_count(x); j++)
- {
- ex = X509_get_ext(x, j);
- if (OBJ_obj2nid(X509_EXTENSION_get_object(ex))
- == NID_freshest_crl)
- x->ex_flags |= EXFLAG_FRESHEST;
- if (!X509_EXTENSION_get_critical(ex))
- continue;
- if (!X509_supported_extension(ex))
- {
- x->ex_flags |= EXFLAG_CRITICAL;
- break;
- }
- }
- x->ex_flags |= EXFLAG_SET;
-
- CRYPTO_STATIC_MUTEX_unlock(&g_x509_cache_extensions_lock);
-}
-
-/* CA checks common to all purposes
- * return codes:
- * 0 not a CA
- * 1 is a CA
- * 2 basicConstraints absent so "maybe" a CA
- * 3 basicConstraints absent but self signed V1.
- * 4 basicConstraints absent but keyUsage present and keyCertSign asserted.
+ BASIC_CONSTRAINTS *bs;
+ PROXY_CERT_INFO_EXTENSION *pci;
+ ASN1_BIT_STRING *usage;
+ ASN1_BIT_STRING *ns;
+ EXTENDED_KEY_USAGE *extusage;
+ X509_EXTENSION *ex;
+ size_t i;
+ int j;
+
+ CRYPTO_STATIC_MUTEX_lock_write(&g_x509_cache_extensions_lock);
+
+ if (x->ex_flags & EXFLAG_SET) {
+ CRYPTO_STATIC_MUTEX_unlock(&g_x509_cache_extensions_lock);
+ return;
+ }
+
+ X509_digest(x, EVP_sha1(), x->sha1_hash, NULL);
+ /* V1 should mean no extensions ... */
+ if (!X509_get_version(x))
+ x->ex_flags |= EXFLAG_V1;
+ /* Handle basic constraints */
+ if ((bs = X509_get_ext_d2i(x, NID_basic_constraints, NULL, NULL))) {
+ if (bs->ca)
+ x->ex_flags |= EXFLAG_CA;
+ if (bs->pathlen) {
+ if ((bs->pathlen->type == V_ASN1_NEG_INTEGER)
+ || !bs->ca) {
+ x->ex_flags |= EXFLAG_INVALID;
+ x->ex_pathlen = 0;
+ } else
+ x->ex_pathlen = ASN1_INTEGER_get(bs->pathlen);
+ } else
+ x->ex_pathlen = -1;
+ BASIC_CONSTRAINTS_free(bs);
+ x->ex_flags |= EXFLAG_BCONS;
+ }
+ /* Handle proxy certificates */
+ if ((pci = X509_get_ext_d2i(x, NID_proxyCertInfo, NULL, NULL))) {
+ if (x->ex_flags & EXFLAG_CA
+ || X509_get_ext_by_NID(x, NID_subject_alt_name, -1) >= 0
+ || X509_get_ext_by_NID(x, NID_issuer_alt_name, -1) >= 0) {
+ x->ex_flags |= EXFLAG_INVALID;
+ }
+ if (pci->pcPathLengthConstraint) {
+ x->ex_pcpathlen = ASN1_INTEGER_get(pci->pcPathLengthConstraint);
+ } else
+ x->ex_pcpathlen = -1;
+ PROXY_CERT_INFO_EXTENSION_free(pci);
+ x->ex_flags |= EXFLAG_PROXY;
+ }
+ /* Handle key usage */
+ if ((usage = X509_get_ext_d2i(x, NID_key_usage, NULL, NULL))) {
+ if (usage->length > 0) {
+ x->ex_kusage = usage->data[0];
+ if (usage->length > 1)
+ x->ex_kusage |= usage->data[1] << 8;
+ } else
+ x->ex_kusage = 0;
+ x->ex_flags |= EXFLAG_KUSAGE;
+ ASN1_BIT_STRING_free(usage);
+ }
+ x->ex_xkusage = 0;
+ if ((extusage = X509_get_ext_d2i(x, NID_ext_key_usage, NULL, NULL))) {
+ x->ex_flags |= EXFLAG_XKUSAGE;
+ for (i = 0; i < sk_ASN1_OBJECT_num(extusage); i++) {
+ switch (OBJ_obj2nid(sk_ASN1_OBJECT_value(extusage, i))) {
+ case NID_server_auth:
+ x->ex_xkusage |= XKU_SSL_SERVER;
+ break;
+
+ case NID_client_auth:
+ x->ex_xkusage |= XKU_SSL_CLIENT;
+ break;
+
+ case NID_email_protect:
+ x->ex_xkusage |= XKU_SMIME;
+ break;
+
+ case NID_code_sign:
+ x->ex_xkusage |= XKU_CODE_SIGN;
+ break;
+
+ case NID_ms_sgc:
+ case NID_ns_sgc:
+ x->ex_xkusage |= XKU_SGC;
+ break;
+
+ case NID_OCSP_sign:
+ x->ex_xkusage |= XKU_OCSP_SIGN;
+ break;
+
+ case NID_time_stamp:
+ x->ex_xkusage |= XKU_TIMESTAMP;
+ break;
+
+ case NID_dvcs:
+ x->ex_xkusage |= XKU_DVCS;
+ break;
+
+ case NID_anyExtendedKeyUsage:
+ x->ex_xkusage |= XKU_ANYEKU;
+ break;
+ }
+ }
+ sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free);
+ }
+
+ if ((ns = X509_get_ext_d2i(x, NID_netscape_cert_type, NULL, NULL))) {
+ if (ns->length > 0)
+ x->ex_nscert = ns->data[0];
+ else
+ x->ex_nscert = 0;
+ x->ex_flags |= EXFLAG_NSCERT;
+ ASN1_BIT_STRING_free(ns);
+ }
+ x->skid = X509_get_ext_d2i(x, NID_subject_key_identifier, NULL, NULL);
+ x->akid = X509_get_ext_d2i(x, NID_authority_key_identifier, NULL, NULL);
+ /* Does subject name match issuer ? */
+ if (!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x))) {
+ x->ex_flags |= EXFLAG_SI;
+ /* If SKID matches AKID also indicate self signed */
+ 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);
+ x->nc = X509_get_ext_d2i(x, NID_name_constraints, &j, NULL);
+ if (!x->nc && (j != -1))
+ x->ex_flags |= EXFLAG_INVALID;
+ setup_crldp(x);
+
+ for (j = 0; j < X509_get_ext_count(x); j++) {
+ ex = X509_get_ext(x, j);
+ if (OBJ_obj2nid(X509_EXTENSION_get_object(ex))
+ == NID_freshest_crl)
+ x->ex_flags |= EXFLAG_FRESHEST;
+ if (!X509_EXTENSION_get_critical(ex))
+ continue;
+ if (!X509_supported_extension(ex)) {
+ x->ex_flags |= EXFLAG_CRITICAL;
+ break;
+ }
+ }
+ x->ex_flags |= EXFLAG_SET;
+
+ CRYPTO_STATIC_MUTEX_unlock(&g_x509_cache_extensions_lock);
+}
+
+/*
+ * CA checks common to all purposes return codes: 0 not a CA 1 is a CA 2
+ * basicConstraints absent so "maybe" a CA 3 basicConstraints absent but self
+ * signed V1. 4 basicConstraints absent but keyUsage present and keyCertSign
+ * asserted.
*/
static int check_ca(const X509 *x)
{
- /* keyUsage if present should allow cert signing */
- if(ku_reject(x, KU_KEY_CERT_SIGN)) return 0;
- if(x->ex_flags & EXFLAG_BCONS) {
- if(x->ex_flags & EXFLAG_CA) return 1;
- /* If basicConstraints says not a CA then say so */
- else return 0;
- } else {
- /* we support V1 roots for... uh, I don't really know why. */
- if((x->ex_flags & V1_ROOT) == V1_ROOT) return 3;
- /* If key usage present it must have certSign so tolerate it */
- else if (x->ex_flags & EXFLAG_KUSAGE) return 4;
- /* Older certificates could have Netscape-specific CA types */
- else if (x->ex_flags & EXFLAG_NSCERT
- && x->ex_nscert & NS_ANY_CA) return 5;
- /* can this still be regarded a CA certificate? I doubt it */
- return 0;
- }
+ /* keyUsage if present should allow cert signing */
+ if (ku_reject(x, KU_KEY_CERT_SIGN))
+ return 0;
+ if (x->ex_flags & EXFLAG_BCONS) {
+ if (x->ex_flags & EXFLAG_CA)
+ return 1;
+ /* If basicConstraints says not a CA then say so */
+ else
+ return 0;
+ } else {
+ /* we support V1 roots for... uh, I don't really know why. */
+ if ((x->ex_flags & V1_ROOT) == V1_ROOT)
+ return 3;
+ /*
+ * If key usage present it must have certSign so tolerate it
+ */
+ else if (x->ex_flags & EXFLAG_KUSAGE)
+ return 4;
+ /* Older certificates could have Netscape-specific CA types */
+ else if (x->ex_flags & EXFLAG_NSCERT && x->ex_nscert & NS_ANY_CA)
+ return 5;
+ /* can this still be regarded a CA certificate? I doubt it */
+ return 0;
+ }
}
int X509_check_ca(X509 *x)
{
- if(!(x->ex_flags & EXFLAG_SET)) {
- x509v3_cache_extensions(x);
- }
+ if (!(x->ex_flags & EXFLAG_SET)) {
+ x509v3_cache_extensions(x);
+ }
- return check_ca(x);
+ return check_ca(x);
}
/* Check SSL CA: common checks for SSL client and server */
static int check_ssl_ca(const X509 *x)
{
- int ca_ret;
- ca_ret = check_ca(x);
- if(!ca_ret) return 0;
- /* check nsCertType if present */
- if(ca_ret != 5 || x->ex_nscert & NS_SSL_CA) return ca_ret;
- else return 0;
+ int ca_ret;
+ ca_ret = check_ca(x);
+ if (!ca_ret)
+ return 0;
+ /* check nsCertType if present */
+ if (ca_ret != 5 || x->ex_nscert & NS_SSL_CA)
+ return ca_ret;
+ else
+ return 0;
}
-
-static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, int ca)
+static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x,
+ int ca)
{
- if(xku_reject(x,XKU_SSL_CLIENT)) return 0;
- if(ca) return check_ssl_ca(x);
- /* We need to do digital signatures or key agreement */
- if(ku_reject(x,KU_DIGITAL_SIGNATURE|KU_KEY_AGREEMENT)) return 0;
- /* nsCertType if present should allow SSL client use */
- if(ns_reject(x, NS_SSL_CLIENT)) return 0;
- return 1;
+ if (xku_reject(x, XKU_SSL_CLIENT))
+ return 0;
+ if (ca)
+ return check_ssl_ca(x);
+ /* We need to do digital signatures or key agreement */
+ if (ku_reject(x, KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT))
+ return 0;
+ /* nsCertType if present should allow SSL client use */
+ if (ns_reject(x, NS_SSL_CLIENT))
+ return 0;
+ return 1;
}
-/* Key usage needed for TLS/SSL server: digital signature, encipherment or
+
+/*
+ * Key usage needed for TLS/SSL server: digital signature, encipherment or
* key agreement. The ssl code can check this more thoroughly for individual
* key types.
*/
#define KU_TLS \
- KU_DIGITAL_SIGNATURE|KU_KEY_ENCIPHERMENT|KU_KEY_AGREEMENT
+ KU_DIGITAL_SIGNATURE|KU_KEY_ENCIPHERMENT|KU_KEY_AGREEMENT
-static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca)
+static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x,
+ int ca)
{
- if(xku_reject(x,XKU_SSL_SERVER|XKU_SGC)) return 0;
- if(ca) return check_ssl_ca(x);
+ if (xku_reject(x, XKU_SSL_SERVER | XKU_SGC))
+ return 0;
+ if (ca)
+ return check_ssl_ca(x);
- if(ns_reject(x, NS_SSL_SERVER)) return 0;
- if(ku_reject(x, KU_TLS)) return 0;
-
- return 1;
+ if (ns_reject(x, NS_SSL_SERVER))
+ return 0;
+ if (ku_reject(x, KU_TLS))
+ return 0;
+
+ return 1;
}
-static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca)
+static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x,
+ int ca)
{
- int ret;
- ret = check_purpose_ssl_server(xp, x, ca);
- if(!ret || ca) return ret;
- /* We need to encipher or Netscape complains */
- if(ku_reject(x, KU_KEY_ENCIPHERMENT)) return 0;
- return ret;
+ int ret;
+ ret = check_purpose_ssl_server(xp, x, ca);
+ if (!ret || ca)
+ return ret;
+ /* We need to encipher or Netscape complains */
+ if (ku_reject(x, KU_KEY_ENCIPHERMENT))
+ return 0;
+ return ret;
}
/* common S/MIME checks */
static int purpose_smime(const X509 *x, int ca)
{
- if(xku_reject(x,XKU_SMIME)) return 0;
- if(ca) {
- int ca_ret;
- ca_ret = check_ca(x);
- if(!ca_ret) return 0;
- /* check nsCertType if present */
- if(ca_ret != 5 || x->ex_nscert & NS_SMIME_CA) return ca_ret;
- else return 0;
- }
- if(x->ex_flags & EXFLAG_NSCERT) {
- if(x->ex_nscert & NS_SMIME) return 1;
- /* Workaround for some buggy certificates */
- if(x->ex_nscert & NS_SSL_CLIENT) return 2;
- return 0;
- }
- return 1;
+ if (xku_reject(x, XKU_SMIME))
+ return 0;
+ if (ca) {
+ int ca_ret;
+ ca_ret = check_ca(x);
+ if (!ca_ret)
+ return 0;
+ /* check nsCertType if present */
+ if (ca_ret != 5 || x->ex_nscert & NS_SMIME_CA)
+ return ca_ret;
+ else
+ return 0;
+ }
+ if (x->ex_flags & EXFLAG_NSCERT) {
+ if (x->ex_nscert & NS_SMIME)
+ return 1;
+ /* Workaround for some buggy certificates */
+ if (x->ex_nscert & NS_SSL_CLIENT)
+ return 2;
+ return 0;
+ }
+ return 1;
}
-static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, int ca)
+static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x,
+ int ca)
{
- int ret;
- ret = purpose_smime(x, ca);
- if(!ret || ca) return ret;
- if(ku_reject(x, KU_DIGITAL_SIGNATURE|KU_NON_REPUDIATION)) return 0;
- return ret;
+ int ret;
+ ret = purpose_smime(x, ca);
+ if (!ret || ca)
+ return ret;
+ if (ku_reject(x, KU_DIGITAL_SIGNATURE | KU_NON_REPUDIATION))
+ return 0;
+ return ret;
}
-static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, int ca)
+static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x,
+ int ca)
{
- int ret;
- ret = purpose_smime(x, ca);
- if(!ret || ca) return ret;
- if(ku_reject(x, KU_KEY_ENCIPHERMENT)) return 0;
- return ret;
+ int ret;
+ ret = purpose_smime(x, ca);
+ if (!ret || ca)
+ return ret;
+ if (ku_reject(x, KU_KEY_ENCIPHERMENT))
+ return 0;
+ return ret;
}
-static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, int ca)
+static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x,
+ int ca)
{
- if(ca) {
- int ca_ret;
- if((ca_ret = check_ca(x)) != 2) return ca_ret;
- else return 0;
- }
- if(ku_reject(x, KU_CRL_SIGN)) return 0;
- return 1;
+ if (ca) {
+ int ca_ret;
+ if ((ca_ret = check_ca(x)) != 2)
+ return ca_ret;
+ else
+ return 0;
+ }
+ if (ku_reject(x, KU_CRL_SIGN))
+ return 0;
+ return 1;
}
-/* OCSP helper: this is *not* a full OCSP check. It just checks that
- * each CA is valid. Additional checks must be made on the chain.
+/*
+ * OCSP helper: this is *not* a full OCSP check. It just checks that each CA
+ * is valid. Additional checks must be made on the chain.
*/
static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca)
{
- /* Must be a valid CA. Should we really support the "I don't know"
- value (2)? */
- if(ca) return check_ca(x);
- /* leaf certificate is checked in OCSP_verify() */
- return 1;
+ /*
+ * Must be a valid CA. Should we really support the "I don't know" value
+ * (2)?
+ */
+ if (ca)
+ return check_ca(x);
+ /* leaf certificate is checked in OCSP_verify() */
+ return 1;
}
static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x,
- int ca)
+ int ca)
{
- int i_ext;
-
- /* If ca is true we must return if this is a valid CA certificate. */
- if (ca) return check_ca(x);
-
- /*
- * Check the optional key usage field:
- * if Key Usage is present, it must be one of digitalSignature
- * and/or nonRepudiation (other values are not consistent and shall
- * be rejected).
- */
- if ((x->ex_flags & EXFLAG_KUSAGE)
- && ((x->ex_kusage & ~(KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE)) ||
- !(x->ex_kusage & (KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE))))
- return 0;
-
- /* Only time stamp key usage is permitted and it's required. */
- if (!(x->ex_flags & EXFLAG_XKUSAGE) || x->ex_xkusage != XKU_TIMESTAMP)
- return 0;
-
- /* Extended Key Usage MUST be critical */
- i_ext = X509_get_ext_by_NID((X509 *) x, NID_ext_key_usage, -1);
- if (i_ext >= 0)
- {
- X509_EXTENSION *ext = X509_get_ext((X509 *) x, i_ext);
- if (!X509_EXTENSION_get_critical(ext))
- return 0;
- }
-
- return 1;
+ int i_ext;
+
+ /* If ca is true we must return if this is a valid CA certificate. */
+ if (ca)
+ return check_ca(x);
+
+ /*
+ * Check the optional key usage field:
+ * if Key Usage is present, it must be one of digitalSignature
+ * and/or nonRepudiation (other values are not consistent and shall
+ * be rejected).
+ */
+ if ((x->ex_flags & EXFLAG_KUSAGE)
+ && ((x->ex_kusage & ~(KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE)) ||
+ !(x->ex_kusage & (KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE))))
+ return 0;
+
+ /* Only time stamp key usage is permitted and it's required. */
+ if (!(x->ex_flags & EXFLAG_XKUSAGE) || x->ex_xkusage != XKU_TIMESTAMP)
+ return 0;
+
+ /* Extended Key Usage MUST be critical */
+ i_ext = X509_get_ext_by_NID((X509 *)x, NID_ext_key_usage, -1);
+ if (i_ext >= 0) {
+ X509_EXTENSION *ext = X509_get_ext((X509 *)x, i_ext);
+ if (!X509_EXTENSION_get_critical(ext))
+ return 0;
+ }
+
+ return 1;
}
static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca)
{
- return 1;
+ return 1;
}
-/* Various checks to see if one certificate issued the second.
- * This can be used to prune a set of possible issuer certificates
- * which have been looked up using some simple method such as by
- * subject name.
- * These are:
- * 1. Check issuer_name(subject) == subject_name(issuer)
- * 2. If akid(subject) exists check it matches issuer
- * 3. If key_usage(issuer) exists check it supports certificate signing
- * returns 0 for OK, positive for reason for mismatch, reasons match
- * codes for X509_verify_cert()
+/*
+ * Various checks to see if one certificate issued the second. This can be
+ * used to prune a set of possible issuer certificates which have been looked
+ * up using some simple method such as by subject name. These are: 1. Check
+ * issuer_name(subject) == subject_name(issuer) 2. If akid(subject) exists
+ * check it matches issuer 3. If key_usage(issuer) exists check it supports
+ * certificate signing returns 0 for OK, positive for reason for mismatch,
+ * reasons match codes for X509_verify_cert()
*/
int X509_check_issued(X509 *issuer, X509 *subject)
{
- if(X509_NAME_cmp(X509_get_subject_name(issuer),
- X509_get_issuer_name(subject)))
- return X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
- x509v3_cache_extensions(issuer);
- x509v3_cache_extensions(subject);
-
- if(subject->akid)
- {
- int ret = X509_check_akid(issuer, subject->akid);
- if (ret != X509_V_OK)
- return ret;
- }
-
- if(subject->ex_flags & EXFLAG_PROXY)
- {
- if(ku_reject(issuer, KU_DIGITAL_SIGNATURE))
- return X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE;
- }
- else if(ku_reject(issuer, KU_KEY_CERT_SIGN))
- return X509_V_ERR_KEYUSAGE_NO_CERTSIGN;
- return X509_V_OK;
+ if (X509_NAME_cmp(X509_get_subject_name(issuer),
+ X509_get_issuer_name(subject)))
+ return X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
+ x509v3_cache_extensions(issuer);
+ x509v3_cache_extensions(subject);
+
+ if (subject->akid) {
+ int ret = X509_check_akid(issuer, subject->akid);
+ if (ret != X509_V_OK)
+ return ret;
+ }
+
+ if (subject->ex_flags & EXFLAG_PROXY) {
+ if (ku_reject(issuer, KU_DIGITAL_SIGNATURE))
+ return X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE;
+ } else if (ku_reject(issuer, KU_KEY_CERT_SIGN))
+ return X509_V_ERR_KEYUSAGE_NO_CERTSIGN;
+ return X509_V_OK;
}
int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid)
- {
-
- if(!akid)
- return X509_V_OK;
-
- /* Check key ids (if present) */
- if(akid->keyid && issuer->skid &&
- ASN1_OCTET_STRING_cmp(akid->keyid, issuer->skid) )
- return X509_V_ERR_AKID_SKID_MISMATCH;
- /* Check serial number */
- if(akid->serial &&
- ASN1_INTEGER_cmp(X509_get_serialNumber(issuer), akid->serial))
- return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH;
- /* Check issuer name */
- if(akid->issuer)
- {
- /* Ugh, for some peculiar reason AKID includes
- * SEQUENCE OF GeneralName. So look for a DirName.
- * There may be more than one but we only take any
- * notice of the first.
- */
- GENERAL_NAMES *gens;
- GENERAL_NAME *gen;
- X509_NAME *nm = NULL;
- size_t i;
- gens = akid->issuer;
- for(i = 0; i < sk_GENERAL_NAME_num(gens); i++)
- {
- gen = sk_GENERAL_NAME_value(gens, i);
- if(gen->type == GEN_DIRNAME)
- {
- nm = gen->d.dirn;
- break;
- }
- }
- if(nm && X509_NAME_cmp(nm, X509_get_issuer_name(issuer)))
- return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH;
- }
- return X509_V_OK;
- }
+{
+ if (!akid)
+ return X509_V_OK;
+
+ /* Check key ids (if present) */
+ if (akid->keyid && issuer->skid &&
+ ASN1_OCTET_STRING_cmp(akid->keyid, issuer->skid))
+ return X509_V_ERR_AKID_SKID_MISMATCH;
+ /* Check serial number */
+ if (akid->serial &&
+ ASN1_INTEGER_cmp(X509_get_serialNumber(issuer), akid->serial))
+ return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH;
+ /* Check issuer name */
+ if (akid->issuer) {
+ /*
+ * Ugh, for some peculiar reason AKID includes SEQUENCE OF
+ * GeneralName. So look for a DirName. There may be more than one but
+ * we only take any notice of the first.
+ */
+ GENERAL_NAMES *gens;
+ GENERAL_NAME *gen;
+ X509_NAME *nm = NULL;
+ size_t i;
+ gens = akid->issuer;
+ for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
+ gen = sk_GENERAL_NAME_value(gens, i);
+ if (gen->type == GEN_DIRNAME) {
+ nm = gen->d.dirn;
+ break;
+ }
+ }
+ if (nm && X509_NAME_cmp(nm, X509_get_issuer_name(issuer)))
+ return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH;
+ }
+ return X509_V_OK;
+}
diff --git a/src/crypto/x509v3/v3_skey.c b/src/crypto/x509v3/v3_skey.c
index e396f054..65f8287c 100644
--- a/src/crypto/x509v3/v3_skey.c
+++ b/src/crypto/x509v3/v3_skey.c
@@ -1,6 +1,7 @@
/* v3_skey.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
*/
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
@@ -10,7 +11,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -54,7 +55,6 @@
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com). */
-
#include <stdio.h>
#include <string.h>
@@ -63,86 +63,90 @@
#include <openssl/obj.h>
#include <openssl/x509v3.h>
-
-static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str);
-const X509V3_EXT_METHOD v3_skey_id = {
-NID_subject_key_identifier, 0, ASN1_ITEM_ref(ASN1_OCTET_STRING),
-0,0,0,0,
-(X509V3_EXT_I2S)i2s_ASN1_OCTET_STRING,
-(X509V3_EXT_S2I)s2i_skey_id,
-0,0,0,0,
-NULL};
-
-char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method,
- ASN1_OCTET_STRING *oct)
+static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method,
+ X509V3_CTX *ctx, char *str);
+const X509V3_EXT_METHOD v3_skey_id = {
+ NID_subject_key_identifier, 0, ASN1_ITEM_ref(ASN1_OCTET_STRING),
+ 0, 0, 0, 0,
+ (X509V3_EXT_I2S)i2s_ASN1_OCTET_STRING,
+ (X509V3_EXT_S2I)s2i_skey_id,
+ 0, 0, 0, 0,
+ NULL
+};
+
+char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, ASN1_OCTET_STRING *oct)
{
- return hex_to_string(oct->data, oct->length);
+ return hex_to_string(oct->data, oct->length);
}
ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method,
- X509V3_CTX *ctx, char *str)
+ X509V3_CTX *ctx, char *str)
{
- ASN1_OCTET_STRING *oct;
- long length;
+ ASN1_OCTET_STRING *oct;
+ long length;
- if(!(oct = M_ASN1_OCTET_STRING_new())) {
- OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
+ if (!(oct = M_ASN1_OCTET_STRING_new())) {
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
- if(!(oct->data = string_to_hex(str, &length))) {
- M_ASN1_OCTET_STRING_free(oct);
- return NULL;
- }
+ if (!(oct->data = string_to_hex(str, &length))) {
+ M_ASN1_OCTET_STRING_free(oct);
+ return NULL;
+ }
- oct->length = length;
+ oct->length = length;
- return oct;
+ return oct;
}
static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method,
- X509V3_CTX *ctx, char *str)
+ X509V3_CTX *ctx, char *str)
{
- ASN1_OCTET_STRING *oct;
- ASN1_BIT_STRING *pk;
- unsigned char pkey_dig[EVP_MAX_MD_SIZE];
- unsigned int diglen;
-
- if(strcmp(str, "hash")) return s2i_ASN1_OCTET_STRING(method, ctx, str);
-
- if(!(oct = M_ASN1_OCTET_STRING_new())) {
- 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, X509V3_R_NO_PUBLIC_KEY);
- goto err;
- }
-
- if(ctx->subject_req)
- pk = ctx->subject_req->req_info->pubkey->public_key;
- else pk = ctx->subject_cert->cert_info->key->public_key;
-
- if(!pk) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_PUBLIC_KEY);
- goto err;
- }
-
- if (!EVP_Digest(pk->data, pk->length, pkey_dig, &diglen, EVP_sha1(), NULL))
- goto err;
-
- if(!M_ASN1_OCTET_STRING_set(oct, pkey_dig, diglen)) {
- OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
- goto err;
- }
-
- return oct;
-
- err:
- M_ASN1_OCTET_STRING_free(oct);
- return NULL;
+ ASN1_OCTET_STRING *oct;
+ ASN1_BIT_STRING *pk;
+ unsigned char pkey_dig[EVP_MAX_MD_SIZE];
+ unsigned int diglen;
+
+ if (strcmp(str, "hash"))
+ return s2i_ASN1_OCTET_STRING(method, ctx, str);
+
+ if (!(oct = M_ASN1_OCTET_STRING_new())) {
+ 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, X509V3_R_NO_PUBLIC_KEY);
+ goto err;
+ }
+
+ if (ctx->subject_req)
+ pk = ctx->subject_req->req_info->pubkey->public_key;
+ else
+ pk = ctx->subject_cert->cert_info->key->public_key;
+
+ if (!pk) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_PUBLIC_KEY);
+ goto err;
+ }
+
+ if (!EVP_Digest
+ (pk->data, pk->length, pkey_dig, &diglen, EVP_sha1(), NULL))
+ goto err;
+
+ if (!M_ASN1_OCTET_STRING_set(oct, pkey_dig, diglen)) {
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ return oct;
+
+ err:
+ M_ASN1_OCTET_STRING_free(oct);
+ return NULL;
}
diff --git a/src/crypto/x509v3/v3_sxnet.c b/src/crypto/x509v3/v3_sxnet.c
index 4dd5bfc1..51c5a676 100644
--- a/src/crypto/x509v3/v3_sxnet.c
+++ b/src/crypto/x509v3/v3_sxnet.c
@@ -1,6 +1,7 @@
/* v3_sxnet.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999.
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
*/
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
@@ -10,7 +11,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -67,200 +68,207 @@
#include <openssl/obj.h>
#include <openssl/x509v3.h>
-
/* Support for Thawte strong extranet extension */
#define SXNET_TEST
-static int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out, int indent);
+static int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out,
+ int indent);
#ifdef SXNET_TEST
-static SXNET * sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
- STACK_OF(CONF_VALUE) *nval);
+static SXNET *sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
+ STACK_OF(CONF_VALUE) *nval);
#endif
const X509V3_EXT_METHOD v3_sxnet = {
-NID_sxnet, X509V3_EXT_MULTILINE, ASN1_ITEM_ref(SXNET),
-0,0,0,0,
-0,0,
-0,
+ NID_sxnet, X509V3_EXT_MULTILINE, ASN1_ITEM_ref(SXNET),
+ 0, 0, 0, 0,
+ 0, 0,
+ 0,
#ifdef SXNET_TEST
-(X509V3_EXT_V2I)sxnet_v2i,
+ (X509V3_EXT_V2I)sxnet_v2i,
#else
-0,
+ 0,
#endif
-(X509V3_EXT_I2R)sxnet_i2r,
-0,
-NULL
+ (X509V3_EXT_I2R)sxnet_i2r,
+ 0,
+ NULL
};
ASN1_SEQUENCE(SXNETID) = {
- ASN1_SIMPLE(SXNETID, zone, ASN1_INTEGER),
- ASN1_SIMPLE(SXNETID, user, ASN1_OCTET_STRING)
+ ASN1_SIMPLE(SXNETID, zone, ASN1_INTEGER),
+ ASN1_SIMPLE(SXNETID, user, ASN1_OCTET_STRING)
} ASN1_SEQUENCE_END(SXNETID)
IMPLEMENT_ASN1_FUNCTIONS(SXNETID)
ASN1_SEQUENCE(SXNET) = {
- ASN1_SIMPLE(SXNET, version, ASN1_INTEGER),
- ASN1_SEQUENCE_OF(SXNET, ids, SXNETID)
+ ASN1_SIMPLE(SXNET, version, ASN1_INTEGER),
+ ASN1_SEQUENCE_OF(SXNET, ids, SXNETID)
} ASN1_SEQUENCE_END(SXNET)
IMPLEMENT_ASN1_FUNCTIONS(SXNET)
static int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out,
- int indent)
+ int indent)
{
- long v;
- char *tmp;
- SXNETID *id;
- size_t i;
- v = ASN1_INTEGER_get(sx->version);
- BIO_printf(out, "%*sVersion: %ld (0x%lX)", indent, "", v + 1, v);
- for(i = 0; i < sk_SXNETID_num(sx->ids); i++) {
- id = sk_SXNETID_value(sx->ids, i);
- tmp = i2s_ASN1_INTEGER(NULL, id->zone);
- BIO_printf(out, "\n%*sZone: %s, User: ", indent, "", tmp);
- OPENSSL_free(tmp);
- M_ASN1_OCTET_STRING_print(out, id->user);
- }
- return 1;
+ long v;
+ char *tmp;
+ SXNETID *id;
+ size_t i;
+ v = ASN1_INTEGER_get(sx->version);
+ BIO_printf(out, "%*sVersion: %ld (0x%lX)", indent, "", v + 1, v);
+ for (i = 0; i < sk_SXNETID_num(sx->ids); i++) {
+ id = sk_SXNETID_value(sx->ids, i);
+ tmp = i2s_ASN1_INTEGER(NULL, id->zone);
+ BIO_printf(out, "\n%*sZone: %s, User: ", indent, "", tmp);
+ OPENSSL_free(tmp);
+ M_ASN1_OCTET_STRING_print(out, id->user);
+ }
+ return 1;
}
#ifdef SXNET_TEST
-/* NBB: this is used for testing only. It should *not* be used for anything
+/*
+ * NBB: this is used for testing only. It should *not* be used for anything
* else because it will just take static IDs from the configuration file and
* they should really be separate values for each user.
*/
-
-static SXNET * sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
- STACK_OF(CONF_VALUE) *nval)
+static SXNET *sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
+ STACK_OF(CONF_VALUE) *nval)
{
- CONF_VALUE *cnf;
- SXNET *sx = NULL;
- size_t i;
- for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
- cnf = sk_CONF_VALUE_value(nval, i);
- if(!SXNET_add_id_asc(&sx, cnf->name, cnf->value, -1))
- return NULL;
- }
- return sx;
+ CONF_VALUE *cnf;
+ SXNET *sx = NULL;
+ size_t i;
+ for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+ cnf = sk_CONF_VALUE_value(nval, i);
+ if (!SXNET_add_id_asc(&sx, cnf->name, cnf->value, -1))
+ return NULL;
+ }
+ return sx;
}
-
-
+
#endif
/* Strong Extranet utility functions */
/* Add an id given the zone as an ASCII number */
-int SXNET_add_id_asc(SXNET **psx, char *zone, char *user,
- int userlen)
+int SXNET_add_id_asc(SXNET **psx, char *zone, char *user, int userlen)
{
- ASN1_INTEGER *izone = NULL;
- if(!(izone = s2i_ASN1_INTEGER(NULL, zone))) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_ERROR_CONVERTING_ZONE);
- return 0;
- }
- return SXNET_add_id_INTEGER(psx, izone, user, userlen);
+ ASN1_INTEGER *izone = NULL;
+ if (!(izone = s2i_ASN1_INTEGER(NULL, zone))) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_ERROR_CONVERTING_ZONE);
+ return 0;
+ }
+ return SXNET_add_id_INTEGER(psx, izone, user, userlen);
}
/* Add an id given the zone as an unsigned long */
int SXNET_add_id_ulong(SXNET **psx, unsigned long lzone, char *user,
- int userlen)
+ int userlen)
{
- ASN1_INTEGER *izone = NULL;
- if(!(izone = M_ASN1_INTEGER_new()) || !ASN1_INTEGER_set(izone, lzone)) {
- OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
- M_ASN1_INTEGER_free(izone);
- return 0;
- }
- return SXNET_add_id_INTEGER(psx, izone, user, userlen);
-
+ ASN1_INTEGER *izone = NULL;
+ if (!(izone = M_ASN1_INTEGER_new()) || !ASN1_INTEGER_set(izone, lzone)) {
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+ M_ASN1_INTEGER_free(izone);
+ return 0;
+ }
+ return SXNET_add_id_INTEGER(psx, izone, user, userlen);
+
}
-/* Add an id given the zone as an ASN1_INTEGER.
- * Note this version uses the passed integer and doesn't make a copy so don't
- * free it up afterwards.
+/*
+ * Add an id given the zone as an ASN1_INTEGER. Note this version uses the
+ * passed integer and doesn't make a copy so don't free it up afterwards.
*/
int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *zone, char *user,
- int userlen)
+ int userlen)
{
- SXNET *sx = NULL;
- SXNETID *id = NULL;
- if(!psx || !zone || !user) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_ARGUMENT);
- return 0;
- }
- if(userlen == -1) userlen = strlen(user);
- if(userlen > 64) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_USER_TOO_LONG);
- return 0;
- }
- if(!*psx) {
- if(!(sx = SXNET_new())) goto err;
- if(!ASN1_INTEGER_set(sx->version, 0)) goto err;
- *psx = sx;
- } else sx = *psx;
- if(SXNET_get_id_INTEGER(sx, zone)) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_DUPLICATE_ZONE_ID);
- return 0;
- }
+ SXNET *sx = NULL;
+ SXNETID *id = NULL;
+ if (!psx || !zone || !user) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_ARGUMENT);
+ return 0;
+ }
+ if (userlen == -1)
+ userlen = strlen(user);
+ if (userlen > 64) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_USER_TOO_LONG);
+ return 0;
+ }
+ if (!*psx) {
+ if (!(sx = SXNET_new()))
+ goto err;
+ if (!ASN1_INTEGER_set(sx->version, 0))
+ goto err;
+ *psx = sx;
+ } else
+ sx = *psx;
+ if (SXNET_get_id_INTEGER(sx, zone)) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_DUPLICATE_ZONE_ID);
+ return 0;
+ }
+
+ if (!(id = SXNETID_new()))
+ goto err;
+ if (userlen == -1)
+ userlen = strlen(user);
+
+ if (!M_ASN1_OCTET_STRING_set(id->user, user, userlen))
+ goto err;
+ if (!sk_SXNETID_push(sx->ids, id))
+ goto err;
+ id->zone = zone;
+ return 1;
- if(!(id = SXNETID_new())) goto err;
- if(userlen == -1) userlen = strlen(user);
-
- if(!M_ASN1_OCTET_STRING_set(id->user, user, userlen)) goto err;
- if(!sk_SXNETID_push(sx->ids, id)) goto err;
- id->zone = zone;
- return 1;
-
- err:
- OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
- SXNETID_free(id);
- SXNET_free(sx);
- *psx = NULL;
- return 0;
+ err:
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+ SXNETID_free(id);
+ SXNET_free(sx);
+ *psx = NULL;
+ return 0;
}
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, X509V3_R_ERROR_CONVERTING_ZONE);
- return NULL;
- }
- oct = SXNET_get_id_INTEGER(sx, izone);
- M_ASN1_INTEGER_free(izone);
- return oct;
+ ASN1_INTEGER *izone = NULL;
+ ASN1_OCTET_STRING *oct;
+ if (!(izone = s2i_ASN1_INTEGER(NULL, zone))) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_ERROR_CONVERTING_ZONE);
+ return NULL;
+ }
+ oct = SXNET_get_id_INTEGER(sx, izone);
+ M_ASN1_INTEGER_free(izone);
+ return oct;
}
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, ERR_R_MALLOC_FAILURE);
- M_ASN1_INTEGER_free(izone);
- return NULL;
- }
- oct = SXNET_get_id_INTEGER(sx, izone);
- M_ASN1_INTEGER_free(izone);
- return oct;
+ ASN1_INTEGER *izone = NULL;
+ ASN1_OCTET_STRING *oct;
+ if (!(izone = M_ASN1_INTEGER_new()) || !ASN1_INTEGER_set(izone, lzone)) {
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+ M_ASN1_INTEGER_free(izone);
+ return NULL;
+ }
+ oct = SXNET_get_id_INTEGER(sx, izone);
+ M_ASN1_INTEGER_free(izone);
+ return oct;
}
ASN1_OCTET_STRING *SXNET_get_id_INTEGER(SXNET *sx, ASN1_INTEGER *zone)
{
- SXNETID *id;
- size_t i;
- for(i = 0; i < sk_SXNETID_num(sx->ids); i++) {
- id = sk_SXNETID_value(sx->ids, i);
- if(!M_ASN1_INTEGER_cmp(id->zone, zone)) return id->user;
- }
- return NULL;
+ SXNETID *id;
+ size_t i;
+ for (i = 0; i < sk_SXNETID_num(sx->ids); i++) {
+ id = sk_SXNETID_value(sx->ids, i);
+ if (!M_ASN1_INTEGER_cmp(id->zone, zone))
+ return id->user;
+ }
+ return NULL;
}
IMPLEMENT_ASN1_SET_OF(SXNETID)
diff --git a/src/crypto/x509v3/v3_utl.c b/src/crypto/x509v3/v3_utl.c
index 6bcb6dab..a238a20e 100644
--- a/src/crypto/x509v3/v3_utl.c
+++ b/src/crypto/x509v3/v3_utl.c
@@ -1,5 +1,6 @@
/* v3_utl.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project.
*/
/* ====================================================================
@@ -10,7 +11,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -57,7 +58,6 @@
*/
/* X509 v3 extension utilities */
-
#include <ctype.h>
#include <stdio.h>
#include <string.h>
@@ -72,10 +72,10 @@
#include "../conf/internal.h"
-
static char *strip_spaces(char *name);
static int sk_strcmp(const OPENSSL_STRING *a, const OPENSSL_STRING *b);
-static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name, GENERAL_NAMES *gens);
+static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name,
+ GENERAL_NAMES *gens);
static void str_free(OPENSSL_STRING str);
static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, ASN1_IA5STRING *email);
@@ -87,1236 +87,1241 @@ static int ipv6_hex(unsigned char *out, const char *in, int inlen);
/* Add a CONF_VALUE name value pair to stack */
int X509V3_add_value(const char *name, const char *value,
- STACK_OF(CONF_VALUE) **extlist)
+ STACK_OF(CONF_VALUE) **extlist)
{
- CONF_VALUE *vtmp = NULL;
- 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_new())) goto err;
- if(!*extlist && !(*extlist = sk_CONF_VALUE_new_null())) goto err;
- vtmp->section = NULL;
- vtmp->name = tname;
- vtmp->value = tvalue;
- if(!sk_CONF_VALUE_push(*extlist, vtmp)) goto err;
- return 1;
- err:
- OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
- if(vtmp) OPENSSL_free(vtmp);
- if(tname) OPENSSL_free(tname);
- if(tvalue) OPENSSL_free(tvalue);
- return 0;
+ CONF_VALUE *vtmp = NULL;
+ 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_new()))
+ goto err;
+ if (!*extlist && !(*extlist = sk_CONF_VALUE_new_null()))
+ goto err;
+ vtmp->section = NULL;
+ vtmp->name = tname;
+ vtmp->value = tvalue;
+ if (!sk_CONF_VALUE_push(*extlist, vtmp))
+ goto err;
+ return 1;
+ err:
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+ if (vtmp)
+ OPENSSL_free(vtmp);
+ if (tname)
+ OPENSSL_free(tname);
+ if (tvalue)
+ OPENSSL_free(tvalue);
+ return 0;
}
int X509V3_add_value_uchar(const char *name, const unsigned char *value,
- STACK_OF(CONF_VALUE) **extlist)
- {
- return X509V3_add_value(name,(const char *)value,extlist);
- }
+ STACK_OF(CONF_VALUE) **extlist)
+{
+ return X509V3_add_value(name, (const char *)value, extlist);
+}
/* Free function for STACK_OF(CONF_VALUE) */
void X509V3_conf_free(CONF_VALUE *conf)
{
- if(!conf) return;
- if(conf->name) OPENSSL_free(conf->name);
- if(conf->value) OPENSSL_free(conf->value);
- if(conf->section) OPENSSL_free(conf->section);
- OPENSSL_free(conf);
+ if (!conf)
+ return;
+ if (conf->name)
+ OPENSSL_free(conf->name);
+ if (conf->value)
+ OPENSSL_free(conf->value);
+ if (conf->section)
+ OPENSSL_free(conf->section);
+ OPENSSL_free(conf);
}
int X509V3_add_value_bool(const char *name, int asn1_bool,
- STACK_OF(CONF_VALUE) **extlist)
+ STACK_OF(CONF_VALUE) **extlist)
{
- if(asn1_bool) return X509V3_add_value(name, "TRUE", extlist);
- return X509V3_add_value(name, "FALSE", extlist);
+ if (asn1_bool)
+ return X509V3_add_value(name, "TRUE", extlist);
+ return X509V3_add_value(name, "FALSE", extlist);
}
int X509V3_add_value_bool_nf(char *name, int asn1_bool,
- STACK_OF(CONF_VALUE) **extlist)
+ STACK_OF(CONF_VALUE) **extlist)
{
- if(asn1_bool) return X509V3_add_value(name, "TRUE", extlist);
- return 1;
+ if (asn1_bool)
+ return X509V3_add_value(name, "TRUE", extlist);
+ return 1;
}
-
char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *method, ASN1_ENUMERATED *a)
{
- BIGNUM *bntmp = NULL;
- char *strtmp = NULL;
- if(!a) return NULL;
- if(!(bntmp = ASN1_ENUMERATED_to_BN(a, NULL)) ||
- !(strtmp = BN_bn2dec(bntmp)) )
- OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
- BN_free(bntmp);
- return strtmp;
+ BIGNUM *bntmp = NULL;
+ char *strtmp = NULL;
+ if (!a)
+ return NULL;
+ if (!(bntmp = ASN1_ENUMERATED_to_BN(a, NULL)) ||
+ !(strtmp = BN_bn2dec(bntmp)))
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+ BN_free(bntmp);
+ return strtmp;
}
char *i2s_ASN1_INTEGER(X509V3_EXT_METHOD *method, ASN1_INTEGER *a)
{
- BIGNUM *bntmp = NULL;
- char *strtmp = NULL;
- if(!a) return NULL;
- if(!(bntmp = ASN1_INTEGER_to_BN(a, NULL)) ||
- !(strtmp = BN_bn2dec(bntmp)) )
- OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
- BN_free(bntmp);
- return strtmp;
+ BIGNUM *bntmp = NULL;
+ char *strtmp = NULL;
+ if (!a)
+ return NULL;
+ if (!(bntmp = ASN1_INTEGER_to_BN(a, NULL)) ||
+ !(strtmp = BN_bn2dec(bntmp)))
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+ BN_free(bntmp);
+ return strtmp;
}
ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *method, char *value)
{
- BIGNUM *bn = NULL;
- ASN1_INTEGER *aint;
- int isneg, ishex;
- int ret;
- if (!value) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_VALUE);
- return 0;
- }
- bn = BN_new();
- if (value[0] == '-') {
- value++;
- isneg = 1;
- } else isneg = 0;
-
- if (value[0] == '0' && ((value[1] == 'x') || (value[1] == 'X'))) {
- value += 2;
- ishex = 1;
- } else ishex = 0;
-
- if (ishex) ret = BN_hex2bn(&bn, value);
- else ret = BN_dec2bn(&bn, value);
-
- if (!ret || value[ret]) {
- BN_free(bn);
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_BN_DEC2BN_ERROR);
- return 0;
- }
-
- if (isneg && BN_is_zero(bn)) isneg = 0;
-
- aint = BN_to_ASN1_INTEGER(bn, NULL);
- BN_free(bn);
- if (!aint) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_BN_TO_ASN1_INTEGER_ERROR);
- return 0;
- }
- if (isneg) aint->type |= V_ASN1_NEG;
- return aint;
+ BIGNUM *bn = NULL;
+ ASN1_INTEGER *aint;
+ int isneg, ishex;
+ int ret;
+ if (!value) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_VALUE);
+ return 0;
+ }
+ bn = BN_new();
+ if (value[0] == '-') {
+ value++;
+ isneg = 1;
+ } else
+ isneg = 0;
+
+ if (value[0] == '0' && ((value[1] == 'x') || (value[1] == 'X'))) {
+ value += 2;
+ ishex = 1;
+ } else
+ ishex = 0;
+
+ if (ishex)
+ ret = BN_hex2bn(&bn, value);
+ else
+ ret = BN_dec2bn(&bn, value);
+
+ if (!ret || value[ret]) {
+ BN_free(bn);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_BN_DEC2BN_ERROR);
+ return 0;
+ }
+
+ if (isneg && BN_is_zero(bn))
+ isneg = 0;
+
+ aint = BN_to_ASN1_INTEGER(bn, NULL);
+ BN_free(bn);
+ if (!aint) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_BN_TO_ASN1_INTEGER_ERROR);
+ return 0;
+ }
+ if (isneg)
+ aint->type |= V_ASN1_NEG;
+ return aint;
}
int X509V3_add_value_int(const char *name, ASN1_INTEGER *aint,
- STACK_OF(CONF_VALUE) **extlist)
+ STACK_OF(CONF_VALUE) **extlist)
{
- char *strtmp;
- int ret;
- if(!aint) return 1;
- if(!(strtmp = i2s_ASN1_INTEGER(NULL, aint))) return 0;
- ret = X509V3_add_value(name, strtmp, extlist);
- OPENSSL_free(strtmp);
- return ret;
+ char *strtmp;
+ int ret;
+ if (!aint)
+ return 1;
+ if (!(strtmp = i2s_ASN1_INTEGER(NULL, aint)))
+ return 0;
+ ret = X509V3_add_value(name, strtmp, extlist);
+ OPENSSL_free(strtmp);
+ return ret;
}
int X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool)
{
- char *btmp;
- if(!(btmp = value->value)) goto err;
- if(!strcmp(btmp, "TRUE") || !strcmp(btmp, "true")
- || !strcmp(btmp, "Y") || !strcmp(btmp, "y")
- || !strcmp(btmp, "YES") || !strcmp(btmp, "yes")) {
- *asn1_bool = 0xff;
- return 1;
- } else if(!strcmp(btmp, "FALSE") || !strcmp(btmp, "false")
- || !strcmp(btmp, "N") || !strcmp(btmp, "n")
- || !strcmp(btmp, "NO") || !strcmp(btmp, "no")) {
- *asn1_bool = 0;
- return 1;
- }
- err:
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_BOOLEAN_STRING);
- X509V3_conf_err(value);
- return 0;
+ char *btmp;
+ if (!(btmp = value->value))
+ goto err;
+ if (!strcmp(btmp, "TRUE") || !strcmp(btmp, "true")
+ || !strcmp(btmp, "Y") || !strcmp(btmp, "y")
+ || !strcmp(btmp, "YES") || !strcmp(btmp, "yes")) {
+ *asn1_bool = 0xff;
+ return 1;
+ } else if (!strcmp(btmp, "FALSE") || !strcmp(btmp, "false")
+ || !strcmp(btmp, "N") || !strcmp(btmp, "n")
+ || !strcmp(btmp, "NO") || !strcmp(btmp, "no")) {
+ *asn1_bool = 0;
+ return 1;
+ }
+ err:
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_BOOLEAN_STRING);
+ X509V3_conf_err(value);
+ return 0;
}
int X509V3_get_value_int(CONF_VALUE *value, ASN1_INTEGER **aint)
{
- ASN1_INTEGER *itmp;
- if(!(itmp = s2i_ASN1_INTEGER(NULL, value->value))) {
- X509V3_conf_err(value);
- return 0;
- }
- *aint = itmp;
- return 1;
+ ASN1_INTEGER *itmp;
+ if (!(itmp = s2i_ASN1_INTEGER(NULL, value->value))) {
+ X509V3_conf_err(value);
+ return 0;
+ }
+ *aint = itmp;
+ return 1;
}
-#define HDR_NAME 1
-#define HDR_VALUE 2
+#define HDR_NAME 1
+#define HDR_VALUE 2
-/*#define DEBUG*/
+/*
+ * #define DEBUG
+ */
STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line)
{
- char *p, *q, c;
- char *ntmp, *vtmp;
- STACK_OF(CONF_VALUE) *values = NULL;
- char *linebuf;
- int state;
- /* We are going to modify the line so copy it first */
- linebuf = BUF_strdup(line);
- if (linebuf == NULL)
- {
- OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- state = HDR_NAME;
- ntmp = NULL;
- /* Go through all characters */
- for(p = linebuf, q = linebuf; (c = *p) && (c!='\r') && (c!='\n'); p++) {
-
- switch(state) {
- case HDR_NAME:
- if(c == ':') {
- state = HDR_VALUE;
- *p = 0;
- ntmp = strip_spaces(q);
- if(!ntmp) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_NAME);
- goto err;
- }
- q = p + 1;
- } else if(c == ',') {
- *p = 0;
- ntmp = strip_spaces(q);
- q = p + 1;
+ char *p, *q, c;
+ char *ntmp, *vtmp;
+ STACK_OF(CONF_VALUE) *values = NULL;
+ char *linebuf;
+ int state;
+ /* We are going to modify the line so copy it first */
+ linebuf = BUF_strdup(line);
+ if (linebuf == NULL) {
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ state = HDR_NAME;
+ ntmp = NULL;
+ /* Go through all characters */
+ for (p = linebuf, q = linebuf; (c = *p) && (c != '\r') && (c != '\n');
+ p++) {
+
+ switch (state) {
+ case HDR_NAME:
+ if (c == ':') {
+ state = HDR_VALUE;
+ *p = 0;
+ ntmp = strip_spaces(q);
+ if (!ntmp) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_NAME);
+ goto err;
+ }
+ q = p + 1;
+ } else if (c == ',') {
+ *p = 0;
+ ntmp = strip_spaces(q);
+ q = p + 1;
#if 0
- printf("%s\n", ntmp);
+ printf("%s\n", ntmp);
#endif
- if(!ntmp) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_NAME);
- goto err;
- }
- X509V3_add_value(ntmp, NULL, &values);
- }
- break ;
-
- case HDR_VALUE:
- if(c == ',') {
- state = HDR_NAME;
- *p = 0;
- vtmp = strip_spaces(q);
+ if (!ntmp) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_NAME);
+ goto err;
+ }
+ X509V3_add_value(ntmp, NULL, &values);
+ }
+ break;
+
+ case HDR_VALUE:
+ if (c == ',') {
+ state = HDR_NAME;
+ *p = 0;
+ vtmp = strip_spaces(q);
#if 0
- printf("%s\n", ntmp);
+ printf("%s\n", ntmp);
#endif
- if(!vtmp) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_VALUE);
- goto err;
- }
- X509V3_add_value(ntmp, vtmp, &values);
- ntmp = NULL;
- q = p + 1;
- }
-
- }
- }
-
- if(state == HDR_VALUE) {
- vtmp = strip_spaces(q);
+ if (!vtmp) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_VALUE);
+ goto err;
+ }
+ X509V3_add_value(ntmp, vtmp, &values);
+ ntmp = NULL;
+ q = p + 1;
+ }
+
+ }
+ }
+
+ if (state == HDR_VALUE) {
+ vtmp = strip_spaces(q);
#if 0
- printf("%s=%s\n", ntmp, vtmp);
+ printf("%s=%s\n", ntmp, vtmp);
#endif
- if(!vtmp) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_VALUE);
- goto err;
- }
- X509V3_add_value(ntmp, vtmp, &values);
- } else {
- ntmp = strip_spaces(q);
+ if (!vtmp) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_VALUE);
+ goto err;
+ }
+ X509V3_add_value(ntmp, vtmp, &values);
+ } else {
+ ntmp = strip_spaces(q);
#if 0
- printf("%s\n", ntmp);
+ printf("%s\n", ntmp);
#endif
- if(!ntmp) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_NAME);
- goto err;
- }
- X509V3_add_value(ntmp, NULL, &values);
- }
-OPENSSL_free(linebuf);
-return values;
-
-err:
-OPENSSL_free(linebuf);
-sk_CONF_VALUE_pop_free(values, X509V3_conf_free);
-return NULL;
+ if (!ntmp) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_NAME);
+ goto err;
+ }
+ X509V3_add_value(ntmp, NULL, &values);
+ }
+ OPENSSL_free(linebuf);
+ return values;
+
+ err:
+ OPENSSL_free(linebuf);
+ sk_CONF_VALUE_pop_free(values, X509V3_conf_free);
+ return NULL;
}
/* Delete leading and trailing spaces from a string */
static char *strip_spaces(char *name)
{
- char *p, *q;
- /* Skip over leading spaces */
- p = name;
- while(*p && isspace((unsigned char)*p)) p++;
- if(!*p) return NULL;
- q = p + strlen(p) - 1;
- while((q != p) && isspace((unsigned char)*q)) q--;
- if(p != q) q[1] = 0;
- if(!*p) return NULL;
- return p;
+ char *p, *q;
+ /* Skip over leading spaces */
+ p = name;
+ while (*p && isspace((unsigned char)*p))
+ p++;
+ if (!*p)
+ return NULL;
+ q = p + strlen(p) - 1;
+ while ((q != p) && isspace((unsigned char)*q))
+ q--;
+ if (p != q)
+ q[1] = 0;
+ if (!*p)
+ return NULL;
+ return p;
}
/* hex string utilities */
-/* Given a buffer of length 'len' return a OPENSSL_malloc'ed string with its
- * hex representation
- * @@@ (Contents of buffer are always kept in ASCII, also on EBCDIC machines)
+/*
+ * Given a buffer of length 'len' return a OPENSSL_malloc'ed string with its
+ * hex representation @@@ (Contents of buffer are always kept in ASCII, also
+ * on EBCDIC machines)
*/
char *hex_to_string(const unsigned char *buffer, long len)
{
- char *tmp, *q;
- const unsigned char *p;
- int i;
- static const char hexdig[] = "0123456789ABCDEF";
- if(!buffer || !len) return NULL;
- if(!(tmp = OPENSSL_malloc(len * 3 + 1))) {
- OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
- q = tmp;
- for(i = 0, p = buffer; i < len; i++,p++) {
- *q++ = hexdig[(*p >> 4) & 0xf];
- *q++ = hexdig[*p & 0xf];
- *q++ = ':';
- }
- q[-1] = 0;
-
- return tmp;
+ char *tmp, *q;
+ const unsigned char *p;
+ int i;
+ static const char hexdig[] = "0123456789ABCDEF";
+ if (!buffer || !len)
+ return NULL;
+ if (!(tmp = OPENSSL_malloc(len * 3 + 1))) {
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ q = tmp;
+ for (i = 0, p = buffer; i < len; i++, p++) {
+ *q++ = hexdig[(*p >> 4) & 0xf];
+ *q++ = hexdig[*p & 0xf];
+ *q++ = ':';
+ }
+ q[-1] = 0;
+
+ return tmp;
}
-/* Give a string of hex digits convert to
- * a buffer
+/*
+ * Give a string of hex digits convert to a buffer
*/
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, X509V3_R_INVALID_NULL_ARGUMENT);
- return NULL;
- }
- if(!(hexbuf = OPENSSL_malloc(strlen(str) >> 1))) goto err;
- for(p = (unsigned char *)str, q = hexbuf; *p;) {
- ch = *p++;
- if(ch == ':') continue;
- cl = *p++;
- if(!cl) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_ODD_NUMBER_OF_DIGITS);
- OPENSSL_free(hexbuf);
- return NULL;
- }
- if(isupper(ch)) ch = tolower(ch);
- if(isupper(cl)) cl = tolower(cl);
-
- if((ch >= '0') && (ch <= '9')) ch -= '0';
- else if ((ch >= 'a') && (ch <= 'f')) ch -= 'a' - 10;
- else goto badhex;
-
- if((cl >= '0') && (cl <= '9')) cl -= '0';
- else if ((cl >= 'a') && (cl <= 'f')) cl -= 'a' - 10;
- else goto badhex;
-
- *q++ = (ch << 4) | cl;
- }
-
- if(len) *len = q - hexbuf;
-
- return hexbuf;
-
- err:
- if(hexbuf) OPENSSL_free(hexbuf);
- OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
- return NULL;
-
- badhex:
- OPENSSL_free(hexbuf);
- OPENSSL_PUT_ERROR(X509V3, X509V3_R_ILLEGAL_HEX_DIGIT);
- return NULL;
+ unsigned char *hexbuf, *q;
+ unsigned char ch, cl, *p;
+ if (!str) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_ARGUMENT);
+ return NULL;
+ }
+ if (!(hexbuf = OPENSSL_malloc(strlen(str) >> 1)))
+ goto err;
+ for (p = (unsigned char *)str, q = hexbuf; *p;) {
+ ch = *p++;
+ if (ch == ':')
+ continue;
+ cl = *p++;
+ if (!cl) {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_ODD_NUMBER_OF_DIGITS);
+ OPENSSL_free(hexbuf);
+ return NULL;
+ }
+ if (isupper(ch))
+ ch = tolower(ch);
+ if (isupper(cl))
+ cl = tolower(cl);
+
+ if ((ch >= '0') && (ch <= '9'))
+ ch -= '0';
+ else if ((ch >= 'a') && (ch <= 'f'))
+ ch -= 'a' - 10;
+ else
+ goto badhex;
+
+ if ((cl >= '0') && (cl <= '9'))
+ cl -= '0';
+ else if ((cl >= 'a') && (cl <= 'f'))
+ cl -= 'a' - 10;
+ else
+ goto badhex;
+
+ *q++ = (ch << 4) | cl;
+ }
+
+ if (len)
+ *len = q - hexbuf;
+
+ return hexbuf;
+
+ err:
+ if (hexbuf)
+ OPENSSL_free(hexbuf);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
+ return NULL;
+
+ badhex:
+ OPENSSL_free(hexbuf);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_ILLEGAL_HEX_DIGIT);
+ return NULL;
}
-/* V2I name comparison function: returns zero if 'name' matches
- * cmp or cmp.*
+/*
+ * V2I name comparison function: returns zero if 'name' matches cmp or cmp.*
*/
int name_cmp(const char *name, const char *cmp)
{
- int len, ret;
- char c;
- len = strlen(cmp);
- if((ret = strncmp(name, cmp, len))) return ret;
- c = name[len];
- if(!c || (c=='.')) return 0;
- return 1;
+ int len, ret;
+ char c;
+ len = strlen(cmp);
+ if ((ret = strncmp(name, cmp, len)))
+ return ret;
+ c = name[len];
+ if (!c || (c == '.'))
+ return 0;
+ return 1;
}
static int sk_strcmp(const OPENSSL_STRING *a, const OPENSSL_STRING *b)
{
- return strcmp(*a, *b);
+ return strcmp(*a, *b);
}
STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x)
{
- GENERAL_NAMES *gens;
- STACK_OF(OPENSSL_STRING) *ret;
+ GENERAL_NAMES *gens;
+ STACK_OF(OPENSSL_STRING) *ret;
- gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
- ret = get_email(X509_get_subject_name(x), gens);
- sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
- return ret;
+ gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
+ ret = get_email(X509_get_subject_name(x), gens);
+ sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
+ return ret;
}
STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x)
{
- AUTHORITY_INFO_ACCESS *info;
- STACK_OF(OPENSSL_STRING) *ret = NULL;
- size_t i;
-
- info = X509_get_ext_d2i(x, NID_info_access, NULL, NULL);
- if (!info)
- return NULL;
- for (i = 0; i < sk_ACCESS_DESCRIPTION_num(info); i++)
- {
- ACCESS_DESCRIPTION *ad = sk_ACCESS_DESCRIPTION_value(info, i);
- if (OBJ_obj2nid(ad->method) == NID_ad_OCSP)
- {
- if (ad->location->type == GEN_URI)
- {
- if (!append_ia5(&ret, ad->location->d.uniformResourceIdentifier))
- break;
- }
- }
- }
- AUTHORITY_INFO_ACCESS_free(info);
- return ret;
+ AUTHORITY_INFO_ACCESS *info;
+ STACK_OF(OPENSSL_STRING) *ret = NULL;
+ size_t i;
+
+ info = X509_get_ext_d2i(x, NID_info_access, NULL, NULL);
+ if (!info)
+ return NULL;
+ for (i = 0; i < sk_ACCESS_DESCRIPTION_num(info); i++) {
+ ACCESS_DESCRIPTION *ad = sk_ACCESS_DESCRIPTION_value(info, i);
+ if (OBJ_obj2nid(ad->method) == NID_ad_OCSP) {
+ if (ad->location->type == GEN_URI) {
+ if (!append_ia5
+ (&ret, ad->location->d.uniformResourceIdentifier))
+ break;
+ }
+ }
+ }
+ AUTHORITY_INFO_ACCESS_free(info);
+ return ret;
}
STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x)
{
- GENERAL_NAMES *gens;
- STACK_OF(X509_EXTENSION) *exts;
- STACK_OF(OPENSSL_STRING) *ret;
-
- exts = X509_REQ_get_extensions(x);
- gens = X509V3_get_d2i(exts, NID_subject_alt_name, NULL, NULL);
- ret = get_email(X509_REQ_get_subject_name(x), gens);
- sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
- sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
- return ret;
+ GENERAL_NAMES *gens;
+ STACK_OF(X509_EXTENSION) *exts;
+ STACK_OF(OPENSSL_STRING) *ret;
+
+ exts = X509_REQ_get_extensions(x);
+ gens = X509V3_get_d2i(exts, NID_subject_alt_name, NULL, NULL);
+ ret = get_email(X509_REQ_get_subject_name(x), gens);
+ sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
+ sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
+ return ret;
}
-
-static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name, GENERAL_NAMES *gens)
+static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name,
+ GENERAL_NAMES *gens)
{
- STACK_OF(OPENSSL_STRING) *ret = NULL;
- X509_NAME_ENTRY *ne;
- ASN1_IA5STRING *email;
- GENERAL_NAME *gen;
- int i;
- size_t j;
- /* Now add any email address(es) to STACK */
- i = -1;
- /* First supplied X509_NAME */
- while((i = X509_NAME_get_index_by_NID(name,
- NID_pkcs9_emailAddress, i)) >= 0) {
- ne = X509_NAME_get_entry(name, i);
- email = X509_NAME_ENTRY_get_data(ne);
- if(!append_ia5(&ret, email)) return NULL;
- }
- for(j = 0; j < sk_GENERAL_NAME_num(gens); j++)
- {
- gen = sk_GENERAL_NAME_value(gens, j);
- if(gen->type != GEN_EMAIL) continue;
- if(!append_ia5(&ret, gen->d.ia5)) return NULL;
- }
- return ret;
+ STACK_OF(OPENSSL_STRING) *ret = NULL;
+ X509_NAME_ENTRY *ne;
+ ASN1_IA5STRING *email;
+ GENERAL_NAME *gen;
+ int i;
+ size_t j;
+ /* Now add any email address(es) to STACK */
+ i = -1;
+ /* First supplied X509_NAME */
+ while ((i = X509_NAME_get_index_by_NID(name,
+ NID_pkcs9_emailAddress, i)) >= 0) {
+ ne = X509_NAME_get_entry(name, i);
+ email = X509_NAME_ENTRY_get_data(ne);
+ if (!append_ia5(&ret, email))
+ return NULL;
+ }
+ for (j = 0; j < sk_GENERAL_NAME_num(gens); j++) {
+ gen = sk_GENERAL_NAME_value(gens, j);
+ if (gen->type != GEN_EMAIL)
+ continue;
+ if (!append_ia5(&ret, gen->d.ia5))
+ return NULL;
+ }
+ return ret;
}
static void str_free(OPENSSL_STRING str)
{
- OPENSSL_free(str);
+ OPENSSL_free(str);
}
static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, ASN1_IA5STRING *email)
{
- char *emtmp;
- /* First some sanity checks */
- if(email->type != V_ASN1_IA5STRING) return 1;
- if(!email->data || !email->length) return 1;
- if(!*sk) *sk = sk_OPENSSL_STRING_new(sk_strcmp);
- if(!*sk) return 0;
- /* Don't add duplicates */
- if(sk_OPENSSL_STRING_find(*sk, NULL, (char *)email->data)) return 1;
- emtmp = BUF_strdup((char *)email->data);
- if(!emtmp || !sk_OPENSSL_STRING_push(*sk, emtmp)) {
- X509_email_free(*sk);
- *sk = NULL;
- return 0;
- }
- return 1;
+ char *emtmp;
+ /* First some sanity checks */
+ if (email->type != V_ASN1_IA5STRING)
+ return 1;
+ if (!email->data || !email->length)
+ return 1;
+ if (!*sk)
+ *sk = sk_OPENSSL_STRING_new(sk_strcmp);
+ if (!*sk)
+ return 0;
+ /* Don't add duplicates */
+ if (sk_OPENSSL_STRING_find(*sk, NULL, (char *)email->data))
+ return 1;
+ emtmp = BUF_strdup((char *)email->data);
+ if (!emtmp || !sk_OPENSSL_STRING_push(*sk, emtmp)) {
+ X509_email_free(*sk);
+ *sk = NULL;
+ return 0;
+ }
+ return 1;
}
void X509_email_free(STACK_OF(OPENSSL_STRING) *sk)
{
- sk_OPENSSL_STRING_pop_free(sk, str_free);
+ sk_OPENSSL_STRING_pop_free(sk, str_free);
}
-typedef int (*equal_fn)(const unsigned char *pattern, size_t pattern_len,
- const unsigned char *subject, size_t subject_len,
- unsigned int flags);
+typedef int (*equal_fn) (const unsigned char *pattern, size_t pattern_len,
+ const unsigned char *subject, size_t subject_len,
+ unsigned int flags);
/* Skip pattern prefix to match "wildcard" subject */
static void skip_prefix(const unsigned char **p, size_t *plen,
- const unsigned char *subject, size_t subject_len,
- unsigned int flags)
- {
- const unsigned char *pattern = *p;
- size_t pattern_len = *plen;
-
- /*
- * If subject starts with a leading '.' followed by more octets, and
- * pattern is longer, compare just an equal-length suffix with the
- * full subject (starting at the '.'), provided the prefix contains
- * no NULs.
- */
- if ((flags & _X509_CHECK_FLAG_DOT_SUBDOMAINS) == 0)
- return;
-
- while (pattern_len > subject_len && *pattern)
- {
- if ((flags & X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS) &&
- *pattern == '.')
- break;
- ++pattern;
- --pattern_len;
- }
-
- /* Skip if entire prefix acceptable */
- if (pattern_len == subject_len)
- {
- *p = pattern;
- *plen = pattern_len;
- }
- }
+ const unsigned char *subject, size_t subject_len,
+ unsigned int flags)
+{
+ const unsigned char *pattern = *p;
+ size_t pattern_len = *plen;
+
+ /*
+ * If subject starts with a leading '.' followed by more octets, and
+ * pattern is longer, compare just an equal-length suffix with the
+ * full subject (starting at the '.'), provided the prefix contains
+ * no NULs.
+ */
+ if ((flags & _X509_CHECK_FLAG_DOT_SUBDOMAINS) == 0)
+ return;
+
+ while (pattern_len > subject_len && *pattern) {
+ if ((flags & X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS) &&
+ *pattern == '.')
+ break;
+ ++pattern;
+ --pattern_len;
+ }
+
+ /* Skip if entire prefix acceptable */
+ if (pattern_len == subject_len) {
+ *p = pattern;
+ *plen = pattern_len;
+ }
+}
/* Compare while ASCII ignoring case. */
static int equal_nocase(const unsigned char *pattern, size_t pattern_len,
- const unsigned char *subject, size_t subject_len,
- unsigned int flags)
- {
- skip_prefix(&pattern, &pattern_len, subject, subject_len, flags);
- if (pattern_len != subject_len)
- return 0;
- while (pattern_len)
- {
- unsigned char l = *pattern;
- unsigned char r = *subject;
- /* The pattern must not contain NUL characters. */
- if (l == 0)
- return 0;
- if (l != r)
- {
- if ('A' <= l && l <= 'Z')
- l = (l - 'A') + 'a';
- if ('A' <= r && r <= 'Z')
- r = (r - 'A') + 'a';
- if (l != r)
- return 0;
- }
- ++pattern;
- ++subject;
- --pattern_len;
- }
- return 1;
- }
+ const unsigned char *subject, size_t subject_len,
+ unsigned int flags)
+{
+ skip_prefix(&pattern, &pattern_len, subject, subject_len, flags);
+ if (pattern_len != subject_len)
+ return 0;
+ while (pattern_len) {
+ unsigned char l = *pattern;
+ unsigned char r = *subject;
+ /* The pattern must not contain NUL characters. */
+ if (l == 0)
+ return 0;
+ if (l != r) {
+ if ('A' <= l && l <= 'Z')
+ l = (l - 'A') + 'a';
+ if ('A' <= r && r <= 'Z')
+ r = (r - 'A') + 'a';
+ if (l != r)
+ return 0;
+ }
+ ++pattern;
+ ++subject;
+ --pattern_len;
+ }
+ return 1;
+}
/* Compare using memcmp. */
static int equal_case(const unsigned char *pattern, size_t pattern_len,
- const unsigned char *subject, size_t subject_len,
- unsigned int flags)
+ const unsigned char *subject, size_t subject_len,
+ unsigned int flags)
{
- skip_prefix(&pattern, &pattern_len, subject, subject_len, flags);
- if (pattern_len != subject_len)
- return 0;
- return !memcmp(pattern, subject, pattern_len);
+ skip_prefix(&pattern, &pattern_len, subject, subject_len, flags);
+ if (pattern_len != subject_len)
+ return 0;
+ return !memcmp(pattern, subject, pattern_len);
}
-/* RFC 5280, section 7.5, requires that only the domain is compared in
- a case-insensitive manner. */
+/*
+ * RFC 5280, section 7.5, requires that only the domain is compared in a
+ * case-insensitive manner.
+ */
static int equal_email(const unsigned char *a, size_t a_len,
- const unsigned char *b, size_t b_len,
- unsigned int unused_flags)
- {
- size_t i = a_len;
- if (a_len != b_len)
- return 0;
- /* We search backwards for the '@' character, so that we do
- not have to deal with quoted local-parts. The domain part
- is compared in a case-insensitive manner. */
- while (i > 0)
- {
- --i;
- if (a[i] == '@' || b[i] == '@')
- {
- if (!equal_nocase(a + i, a_len - i,
- b + i, a_len - i, 0))
- return 0;
- break;
- }
- }
- if (i == 0)
- i = a_len;
- return equal_case(a, i, b, i, 0);
- }
-
-/* Compare the prefix and suffix with the subject, and check that the
- characters in-between are valid. */
+ const unsigned char *b, size_t b_len,
+ unsigned int unused_flags)
+{
+ size_t i = a_len;
+ if (a_len != b_len)
+ return 0;
+ /*
+ * We search backwards for the '@' character, so that we do not have to
+ * deal with quoted local-parts. The domain part is compared in a
+ * case-insensitive manner.
+ */
+ while (i > 0) {
+ --i;
+ if (a[i] == '@' || b[i] == '@') {
+ if (!equal_nocase(a + i, a_len - i, b + i, a_len - i, 0))
+ return 0;
+ break;
+ }
+ }
+ if (i == 0)
+ i = a_len;
+ return equal_case(a, i, b, i, 0);
+}
+
+/*
+ * Compare the prefix and suffix with the subject, and check that the
+ * characters in-between are valid.
+ */
static int wildcard_match(const unsigned char *prefix, size_t prefix_len,
- const unsigned char *suffix, size_t suffix_len,
- const unsigned char *subject, size_t subject_len,
- unsigned int flags)
- {
- const unsigned char *wildcard_start;
- const unsigned char *wildcard_end;
- const unsigned char *p;
- int allow_multi = 0;
- int allow_idna = 0;
-
- if (subject_len < prefix_len + suffix_len)
- return 0;
- if (!equal_nocase(prefix, prefix_len, subject, prefix_len, flags))
- return 0;
- wildcard_start = subject + prefix_len;
- wildcard_end = subject + (subject_len - suffix_len);
- if (!equal_nocase(wildcard_end, suffix_len, suffix, suffix_len, flags))
- return 0;
- /*
- * If the wildcard makes up the entire first label, it must match at
- * least one character.
- */
- if (prefix_len == 0 && *suffix == '.')
- {
- if (wildcard_start == wildcard_end)
- return 0;
- allow_idna = 1;
- if (flags & X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS)
- allow_multi = 1;
- }
- /* IDNA labels cannot match partial wildcards */
- if (!allow_idna &&
- subject_len >= 4 && OPENSSL_strncasecmp((char *)subject, "xn--", 4) == 0)
- return 0;
- /* The wildcard may match a literal '*' */
- if (wildcard_end == wildcard_start + 1 && *wildcard_start == '*')
- return 1;
- /*
- * Check that the part matched by the wildcard contains only
- * permitted characters and only matches a single label unless
- * allow_multi is set.
- */
- for (p = wildcard_start; p != wildcard_end; ++p)
- if (!(('0' <= *p && *p <= '9') ||
- ('A' <= *p && *p <= 'Z') ||
- ('a' <= *p && *p <= 'z') ||
- *p == '-' || (allow_multi && *p == '.')))
- return 0;
- return 1;
- }
-
-#define LABEL_START (1 << 0)
-#define LABEL_END (1 << 1)
-#define LABEL_HYPHEN (1 << 2)
-#define LABEL_IDNA (1 << 3)
+ const unsigned char *suffix, size_t suffix_len,
+ const unsigned char *subject, size_t subject_len,
+ unsigned int flags)
+{
+ const unsigned char *wildcard_start;
+ const unsigned char *wildcard_end;
+ const unsigned char *p;
+ int allow_multi = 0;
+ int allow_idna = 0;
+
+ if (subject_len < prefix_len + suffix_len)
+ return 0;
+ if (!equal_nocase(prefix, prefix_len, subject, prefix_len, flags))
+ return 0;
+ wildcard_start = subject + prefix_len;
+ wildcard_end = subject + (subject_len - suffix_len);
+ if (!equal_nocase(wildcard_end, suffix_len, suffix, suffix_len, flags))
+ return 0;
+ /*
+ * If the wildcard makes up the entire first label, it must match at
+ * least one character.
+ */
+ if (prefix_len == 0 && *suffix == '.') {
+ if (wildcard_start == wildcard_end)
+ return 0;
+ allow_idna = 1;
+ if (flags & X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS)
+ allow_multi = 1;
+ }
+ /* IDNA labels cannot match partial wildcards */
+ if (!allow_idna &&
+ subject_len >= 4
+ && OPENSSL_strncasecmp((char *)subject, "xn--", 4) == 0)
+ return 0;
+ /* The wildcard may match a literal '*' */
+ if (wildcard_end == wildcard_start + 1 && *wildcard_start == '*')
+ return 1;
+ /*
+ * Check that the part matched by the wildcard contains only
+ * permitted characters and only matches a single label unless
+ * allow_multi is set.
+ */
+ for (p = wildcard_start; p != wildcard_end; ++p)
+ if (!(('0' <= *p && *p <= '9') ||
+ ('A' <= *p && *p <= 'Z') ||
+ ('a' <= *p && *p <= 'z') ||
+ *p == '-' || (allow_multi && *p == '.')))
+ return 0;
+ return 1;
+}
+
+#define LABEL_START (1 << 0)
+#define LABEL_END (1 << 1)
+#define LABEL_HYPHEN (1 << 2)
+#define LABEL_IDNA (1 << 3)
static const unsigned char *valid_star(const unsigned char *p, size_t len,
- unsigned int flags)
- {
- const unsigned char *star = 0;
- size_t i;
- int state = LABEL_START;
- int dots = 0;
- for (i = 0; i < len; ++i)
- {
- /*
- * Locate first and only legal wildcard, either at the start
- * or end of a non-IDNA first and not final label.
- */
- if (p[i] == '*')
- {
- int atstart = (state & LABEL_START);
- int atend = (i == len - 1 || p[i+1] == '.');
- /*
- * At most one wildcard per pattern.
- * No wildcards in IDNA labels.
- * No wildcards after the first label.
- */
- if (star != NULL || (state & LABEL_IDNA) != 0 || dots)
- return NULL;
- /* Only full-label '*.example.com' wildcards? */
- if ((flags & X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS)
- && (!atstart || !atend))
- return NULL;
- /* No 'foo*bar' wildcards */
- if (!atstart && !atend)
- return NULL;
- star = &p[i];
- state &= ~LABEL_START;
- }
- else if ((state & LABEL_START) != 0)
- {
- /*
- * At the start of a label, skip any "xn--" and
- * remain in the LABEL_START state, but set the
- * IDNA label state
- */
- if ((state & LABEL_IDNA) == 0 && len - i >= 4
- && OPENSSL_strncasecmp((char *)&p[i], "xn--", 4) == 0)
- {
- i += 3;
- state |= LABEL_IDNA;
- continue;
- }
- /* Labels must start with a letter or digit */
- state &= ~LABEL_START;
- if (('a' <= p[i] && p[i] <= 'z')
- || ('A' <= p[i] && p[i] <= 'Z')
- || ('0' <= p[i] && p[i] <= '9'))
- continue;
- return NULL;
- }
- else if (('a' <= p[i] && p[i] <= 'z')
- || ('A' <= p[i] && p[i] <= 'Z')
- || ('0' <= p[i] && p[i] <= '9'))
- {
- state &= LABEL_IDNA;
- continue;
- }
- else if (p[i] == '.')
- {
- if (state & (LABEL_HYPHEN | LABEL_START))
- return NULL;
- state = LABEL_START;
- ++dots;
- }
- else if (p[i] == '-')
- {
- if (state & LABEL_HYPHEN)
- return NULL;
- state |= LABEL_HYPHEN;
- }
- else
- return NULL;
- }
-
- /*
- * The final label must not end in a hyphen or ".", and
- * there must be at least two dots after the star.
- */
- if ((state & (LABEL_START | LABEL_HYPHEN)) != 0
- || dots < 2)
- return NULL;
- return star;
- }
+ unsigned int flags)
+{
+ const unsigned char *star = 0;
+ size_t i;
+ int state = LABEL_START;
+ int dots = 0;
+ for (i = 0; i < len; ++i) {
+ /*
+ * Locate first and only legal wildcard, either at the start
+ * or end of a non-IDNA first and not final label.
+ */
+ if (p[i] == '*') {
+ int atstart = (state & LABEL_START);
+ int atend = (i == len - 1 || p[i + 1] == '.');
+ /*
+ * At most one wildcard per pattern.
+ * No wildcards in IDNA labels.
+ * No wildcards after the first label.
+ */
+ if (star != NULL || (state & LABEL_IDNA) != 0 || dots)
+ return NULL;
+ /* Only full-label '*.example.com' wildcards? */
+ if ((flags & X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS)
+ && (!atstart || !atend))
+ return NULL;
+ /* No 'foo*bar' wildcards */
+ if (!atstart && !atend)
+ return NULL;
+ star = &p[i];
+ state &= ~LABEL_START;
+ } else if ((state & LABEL_START) != 0) {
+ /*
+ * At the start of a label, skip any "xn--" and
+ * remain in the LABEL_START state, but set the
+ * IDNA label state
+ */
+ if ((state & LABEL_IDNA) == 0 && len - i >= 4
+ && OPENSSL_strncasecmp((char *)&p[i], "xn--", 4) == 0) {
+ i += 3;
+ state |= LABEL_IDNA;
+ continue;
+ }
+ /* Labels must start with a letter or digit */
+ state &= ~LABEL_START;
+ if (('a' <= p[i] && p[i] <= 'z')
+ || ('A' <= p[i] && p[i] <= 'Z')
+ || ('0' <= p[i] && p[i] <= '9'))
+ continue;
+ return NULL;
+ } else if (('a' <= p[i] && p[i] <= 'z')
+ || ('A' <= p[i] && p[i] <= 'Z')
+ || ('0' <= p[i] && p[i] <= '9')) {
+ state &= LABEL_IDNA;
+ continue;
+ } else if (p[i] == '.') {
+ if (state & (LABEL_HYPHEN | LABEL_START))
+ return NULL;
+ state = LABEL_START;
+ ++dots;
+ } else if (p[i] == '-') {
+ /* no domain/subdomain starts with '-' */
+ if ((state & LABEL_START) != 0)
+ return NULL;
+ state |= LABEL_HYPHEN;
+ } else
+ return NULL;
+ }
+
+ /*
+ * The final label must not end in a hyphen or ".", and
+ * there must be at least two dots after the star.
+ */
+ if ((state & (LABEL_START | LABEL_HYPHEN)) != 0 || dots < 2)
+ return NULL;
+ return star;
+}
/* Compare using wildcards. */
static int equal_wildcard(const unsigned char *pattern, size_t pattern_len,
- const unsigned char *subject, size_t subject_len,
- unsigned int flags)
- {
- const unsigned char *star = NULL;
-
- /*
- * Subject names starting with '.' can only match a wildcard pattern
- * via a subject sub-domain pattern suffix match.
- */
- if (!(subject_len > 1 && subject[0] == '.'))
- star = valid_star(pattern, pattern_len, flags);
- if (star == NULL)
- return equal_nocase(pattern, pattern_len,
- subject, subject_len, flags);
- return wildcard_match(pattern, star - pattern,
- star + 1, (pattern + pattern_len) - star - 1,
- subject, subject_len, flags);
- }
-
-/* Compare an ASN1_STRING to a supplied string. If they match
- * return 1. If cmp_type > 0 only compare if string matches the
- * type, otherwise convert it to UTF8.
+ const unsigned char *subject, size_t subject_len,
+ unsigned int flags)
+{
+ const unsigned char *star = NULL;
+
+ /*
+ * Subject names starting with '.' can only match a wildcard pattern
+ * via a subject sub-domain pattern suffix match.
+ */
+ if (!(subject_len > 1 && subject[0] == '.'))
+ star = valid_star(pattern, pattern_len, flags);
+ if (star == NULL)
+ return equal_nocase(pattern, pattern_len,
+ subject, subject_len, flags);
+ return wildcard_match(pattern, star - pattern,
+ star + 1, (pattern + pattern_len) - star - 1,
+ subject, subject_len, flags);
+}
+
+/*
+ * Compare an ASN1_STRING to a supplied string. If they match return 1. If
+ * cmp_type > 0 only compare if string matches the type, otherwise convert it
+ * to UTF8.
*/
static int do_check_string(ASN1_STRING *a, int cmp_type, equal_fn equal,
- unsigned int flags, const char *b, size_t blen,
- char **peername)
- {
- int rv = 0;
-
- if (!a->data || !a->length)
- return 0;
- if (cmp_type > 0)
- {
- if (cmp_type != a->type)
- return 0;
- if (cmp_type == V_ASN1_IA5STRING)
- rv = equal(a->data, a->length,
- (unsigned char *)b, blen, flags);
- else if (a->length == (int)blen && !memcmp(a->data, b, blen))
- rv = 1;
- if (rv > 0 && peername)
- *peername = BUF_strndup((char *)a->data, a->length);
- }
- else
- {
- int astrlen;
- unsigned char *astr;
- astrlen = ASN1_STRING_to_UTF8(&astr, a);
- if (astrlen < 0)
- return -1;
- rv = equal(astr, astrlen, (unsigned char *)b, blen, flags);
- if (rv > 0 && peername)
- *peername = BUF_strndup((char *)astr, astrlen);
- OPENSSL_free(astr);
- }
- return rv;
- }
+ unsigned int flags, const char *b, size_t blen,
+ char **peername)
+{
+ int rv = 0;
+
+ if (!a->data || !a->length)
+ return 0;
+ if (cmp_type > 0) {
+ if (cmp_type != a->type)
+ return 0;
+ if (cmp_type == V_ASN1_IA5STRING)
+ rv = equal(a->data, a->length, (unsigned char *)b, blen, flags);
+ else if (a->length == (int)blen && !memcmp(a->data, b, blen))
+ rv = 1;
+ if (rv > 0 && peername)
+ *peername = BUF_strndup((char *)a->data, a->length);
+ } else {
+ int astrlen;
+ unsigned char *astr;
+ astrlen = ASN1_STRING_to_UTF8(&astr, a);
+ if (astrlen < 0)
+ return -1;
+ rv = equal(astr, astrlen, (unsigned char *)b, blen, flags);
+ if (rv > 0 && peername)
+ *peername = BUF_strndup((char *)astr, astrlen);
+ OPENSSL_free(astr);
+ }
+ return rv;
+}
static int do_x509_check(X509 *x, const char *chk, size_t chklen,
- unsigned int flags, int check_type,
- char **peername)
- {
- GENERAL_NAMES *gens = NULL;
- X509_NAME *name = NULL;
- size_t i;
- int j;
- int cnid = NID_undef;
- int alt_type;
- int san_present = 0;
- int rv = 0;
- equal_fn equal;
-
- /* See below, this flag is internal-only */
- flags &= ~_X509_CHECK_FLAG_DOT_SUBDOMAINS;
- if (check_type == GEN_EMAIL)
- {
- cnid = NID_pkcs9_emailAddress;
- alt_type = V_ASN1_IA5STRING;
- equal = equal_email;
- }
- else if (check_type == GEN_DNS)
- {
- cnid = NID_commonName;
- /* Implicit client-side DNS sub-domain pattern */
- if (chklen > 1 && chk[0] == '.')
- flags |= _X509_CHECK_FLAG_DOT_SUBDOMAINS;
- alt_type = V_ASN1_IA5STRING;
- if (flags & X509_CHECK_FLAG_NO_WILDCARDS)
- equal = equal_nocase;
- else
- equal = equal_wildcard;
- }
- else
- {
- alt_type = V_ASN1_OCTET_STRING;
- equal = equal_case;
- }
-
- gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
- if (gens)
- {
- for (i = 0; i < sk_GENERAL_NAME_num(gens); i++)
- {
- GENERAL_NAME *gen;
- ASN1_STRING *cstr;
- gen = sk_GENERAL_NAME_value(gens, i);
- if (gen->type != check_type)
- continue;
- san_present = 1;
- if (check_type == GEN_EMAIL)
- cstr = gen->d.rfc822Name;
- else if (check_type == GEN_DNS)
- cstr = gen->d.dNSName;
- else
- cstr = gen->d.iPAddress;
- /* Positive on success, negative on error! */
- if ((rv = do_check_string(cstr, alt_type, equal, flags,
- chk, chklen, peername)) != 0)
- break;
- }
- GENERAL_NAMES_free(gens);
- if (rv != 0)
- return rv;
- 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)
- {
- X509_NAME_ENTRY *ne;
- ASN1_STRING *str;
- ne = X509_NAME_get_entry(name, j);
- str = X509_NAME_ENTRY_get_data(ne);
- /* Positive on success, negative on error! */
- if ((rv = do_check_string(str, -1, equal, flags,
- chk, chklen, peername)) != 0)
- return rv;
- }
- return 0;
- }
+ unsigned int flags, int check_type, char **peername)
+{
+ GENERAL_NAMES *gens = NULL;
+ X509_NAME *name = NULL;
+ size_t i;
+ int j;
+ int cnid = NID_undef;
+ int alt_type;
+ int san_present = 0;
+ int rv = 0;
+ equal_fn equal;
+
+ /* See below, this flag is internal-only */
+ flags &= ~_X509_CHECK_FLAG_DOT_SUBDOMAINS;
+ if (check_type == GEN_EMAIL) {
+ cnid = NID_pkcs9_emailAddress;
+ alt_type = V_ASN1_IA5STRING;
+ equal = equal_email;
+ } else if (check_type == GEN_DNS) {
+ cnid = NID_commonName;
+ /* Implicit client-side DNS sub-domain pattern */
+ if (chklen > 1 && chk[0] == '.')
+ flags |= _X509_CHECK_FLAG_DOT_SUBDOMAINS;
+ alt_type = V_ASN1_IA5STRING;
+ if (flags & X509_CHECK_FLAG_NO_WILDCARDS)
+ equal = equal_nocase;
+ else
+ equal = equal_wildcard;
+ } else {
+ alt_type = V_ASN1_OCTET_STRING;
+ equal = equal_case;
+ }
+
+ gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
+ if (gens) {
+ for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
+ GENERAL_NAME *gen;
+ ASN1_STRING *cstr;
+ gen = sk_GENERAL_NAME_value(gens, i);
+ if (gen->type != check_type)
+ continue;
+ san_present = 1;
+ if (check_type == GEN_EMAIL)
+ cstr = gen->d.rfc822Name;
+ else if (check_type == GEN_DNS)
+ cstr = gen->d.dNSName;
+ else
+ cstr = gen->d.iPAddress;
+ /* Positive on success, negative on error! */
+ if ((rv = do_check_string(cstr, alt_type, equal, flags,
+ chk, chklen, peername)) != 0)
+ break;
+ }
+ GENERAL_NAMES_free(gens);
+ if (rv != 0)
+ return rv;
+ 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) {
+ X509_NAME_ENTRY *ne;
+ ASN1_STRING *str;
+ ne = X509_NAME_get_entry(name, j);
+ str = X509_NAME_ENTRY_get_data(ne);
+ /* Positive on success, negative on error! */
+ if ((rv = do_check_string(str, -1, equal, flags,
+ chk, chklen, peername)) != 0)
+ return rv;
+ }
+ return 0;
+}
int X509_check_host(X509 *x, const char *chk, size_t chklen,
- unsigned int flags, char **peername)
- {
- if (chk == NULL)
- return -2;
- if (memchr(chk, '\0', chklen))
- return -2;
- return do_x509_check(x, chk, chklen, flags, GEN_DNS, peername);
- }
+ unsigned int flags, char **peername)
+{
+ if (chk == NULL)
+ return -2;
+ if (memchr(chk, '\0', chklen))
+ return -2;
+ return do_x509_check(x, chk, chklen, flags, GEN_DNS, peername);
+}
int X509_check_email(X509 *x, const char *chk, size_t chklen,
- unsigned int flags)
- {
- if (chk == NULL)
- return -2;
- if (memchr(chk, '\0', chklen))
- return -2;
- return do_x509_check(x, chk, chklen, flags, GEN_EMAIL, NULL);
- }
+ unsigned int flags)
+{
+ if (chk == NULL)
+ return -2;
+ if (memchr(chk, '\0', chklen))
+ return -2;
+ return do_x509_check(x, chk, chklen, flags, GEN_EMAIL, NULL);
+}
int X509_check_ip(X509 *x, const unsigned char *chk, size_t chklen,
- unsigned int flags)
- {
- if (chk == NULL)
- return -2;
- return do_x509_check(x, (char *)chk, chklen, flags, GEN_IPADD, NULL);
- }
+ unsigned int flags)
+{
+ if (chk == NULL)
+ return -2;
+ return do_x509_check(x, (char *)chk, chklen, flags, GEN_IPADD, NULL);
+}
int X509_check_ip_asc(X509 *x, const char *ipasc, unsigned int flags)
- {
- unsigned char ipout[16];
- size_t iplen;
-
- if (ipasc == NULL)
- return -2;
- iplen = (size_t) a2i_ipadd(ipout, ipasc);
- if (iplen == 0)
- return -2;
- return do_x509_check(x, (char *)ipout, iplen, flags, GEN_IPADD, NULL);
- }
-
-/* Convert IP addresses both IPv4 and IPv6 into an
- * OCTET STRING compatible with RFC3280.
+{
+ unsigned char ipout[16];
+ size_t iplen;
+
+ if (ipasc == NULL)
+ return -2;
+ iplen = (size_t)a2i_ipadd(ipout, ipasc);
+ if (iplen == 0)
+ return -2;
+ return do_x509_check(x, (char *)ipout, iplen, flags, GEN_IPADD, NULL);
+}
+
+/*
+ * Convert IP addresses both IPv4 and IPv6 into an OCTET STRING compatible
+ * with RFC3280.
*/
ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc)
- {
- unsigned char ipout[16];
- ASN1_OCTET_STRING *ret;
- int iplen;
+{
+ unsigned char ipout[16];
+ ASN1_OCTET_STRING *ret;
+ int iplen;
- /* If string contains a ':' assume IPv6 */
+ /* If string contains a ':' assume IPv6 */
- iplen = a2i_ipadd(ipout, ipasc);
+ iplen = a2i_ipadd(ipout, ipasc);
- if (!iplen)
- return NULL;
+ if (!iplen)
+ return NULL;
- ret = ASN1_OCTET_STRING_new();
- if (!ret)
- return NULL;
- if (!ASN1_OCTET_STRING_set(ret, ipout, iplen))
- {
- ASN1_OCTET_STRING_free(ret);
- return NULL;
- }
- return ret;
- }
+ ret = ASN1_OCTET_STRING_new();
+ if (!ret)
+ return NULL;
+ if (!ASN1_OCTET_STRING_set(ret, ipout, iplen)) {
+ ASN1_OCTET_STRING_free(ret);
+ return NULL;
+ }
+ return ret;
+}
ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc)
- {
- ASN1_OCTET_STRING *ret = NULL;
- unsigned char ipout[32];
- char *iptmp = NULL, *p;
- int iplen1, iplen2;
- p = strchr(ipasc,'/');
- if (!p)
- return NULL;
- iptmp = BUF_strdup(ipasc);
- if (!iptmp)
- return NULL;
- p = iptmp + (p - ipasc);
- *p++ = 0;
-
- iplen1 = a2i_ipadd(ipout, iptmp);
-
- if (!iplen1)
- goto err;
-
- iplen2 = a2i_ipadd(ipout + iplen1, p);
-
- OPENSSL_free(iptmp);
- iptmp = NULL;
-
- if (!iplen2 || (iplen1 != iplen2))
- goto err;
-
- ret = ASN1_OCTET_STRING_new();
- if (!ret)
- goto err;
- if (!ASN1_OCTET_STRING_set(ret, ipout, iplen1 + iplen2))
- goto err;
-
- return ret;
-
- err:
- if (iptmp)
- OPENSSL_free(iptmp);
- if (ret)
- ASN1_OCTET_STRING_free(ret);
- return NULL;
- }
-
+{
+ ASN1_OCTET_STRING *ret = NULL;
+ unsigned char ipout[32];
+ char *iptmp = NULL, *p;
+ int iplen1, iplen2;
+ p = strchr(ipasc, '/');
+ if (!p)
+ return NULL;
+ iptmp = BUF_strdup(ipasc);
+ if (!iptmp)
+ return NULL;
+ p = iptmp + (p - ipasc);
+ *p++ = 0;
+
+ iplen1 = a2i_ipadd(ipout, iptmp);
+
+ if (!iplen1)
+ goto err;
+
+ iplen2 = a2i_ipadd(ipout + iplen1, p);
+
+ OPENSSL_free(iptmp);
+ iptmp = NULL;
+
+ if (!iplen2 || (iplen1 != iplen2))
+ goto err;
+
+ ret = ASN1_OCTET_STRING_new();
+ if (!ret)
+ goto err;
+ if (!ASN1_OCTET_STRING_set(ret, ipout, iplen1 + iplen2))
+ goto err;
+
+ return ret;
+
+ err:
+ if (iptmp)
+ OPENSSL_free(iptmp);
+ if (ret)
+ ASN1_OCTET_STRING_free(ret);
+ return NULL;
+}
int a2i_ipadd(unsigned char *ipout, const char *ipasc)
- {
- /* If string contains a ':' assume IPv6 */
-
- if (strchr(ipasc, ':'))
- {
- if (!ipv6_from_asc(ipout, ipasc))
- return 0;
- return 16;
- }
- else
- {
- if (!ipv4_from_asc(ipout, ipasc))
- return 0;
- return 4;
- }
- }
+{
+ /* If string contains a ':' assume IPv6 */
+
+ if (strchr(ipasc, ':')) {
+ if (!ipv6_from_asc(ipout, ipasc))
+ return 0;
+ return 16;
+ } else {
+ if (!ipv4_from_asc(ipout, ipasc))
+ return 0;
+ return 4;
+ }
+}
static int ipv4_from_asc(unsigned char *v4, const char *in)
- {
- int a0, a1, a2, a3;
- if (sscanf(in, "%d.%d.%d.%d", &a0, &a1, &a2, &a3) != 4)
- return 0;
- if ((a0 < 0) || (a0 > 255) || (a1 < 0) || (a1 > 255)
- || (a2 < 0) || (a2 > 255) || (a3 < 0) || (a3 > 255))
- return 0;
- v4[0] = a0;
- v4[1] = a1;
- v4[2] = a2;
- v4[3] = a3;
- return 1;
- }
+{
+ int a0, a1, a2, a3;
+ if (sscanf(in, "%d.%d.%d.%d", &a0, &a1, &a2, &a3) != 4)
+ return 0;
+ if ((a0 < 0) || (a0 > 255) || (a1 < 0) || (a1 > 255)
+ || (a2 < 0) || (a2 > 255) || (a3 < 0) || (a3 > 255))
+ return 0;
+ v4[0] = a0;
+ v4[1] = a1;
+ v4[2] = a2;
+ v4[3] = a3;
+ return 1;
+}
typedef struct {
- /* Temporary store for IPV6 output */
- unsigned char tmp[16];
- /* Total number of bytes in tmp */
- int total;
- /* The position of a zero (corresponding to '::') */
- int zero_pos;
- /* Number of zeroes */
- int zero_cnt;
- } IPV6_STAT;
-
+ /* Temporary store for IPV6 output */
+ unsigned char tmp[16];
+ /* Total number of bytes in tmp */
+ int total;
+ /* The position of a zero (corresponding to '::') */
+ int zero_pos;
+ /* Number of zeroes */
+ int zero_cnt;
+} IPV6_STAT;
static int ipv6_from_asc(unsigned char *v6, const char *in)
- {
- IPV6_STAT v6stat;
- v6stat.total = 0;
- v6stat.zero_pos = -1;
- v6stat.zero_cnt = 0;
- /* Treat the IPv6 representation as a list of values
- * separated by ':'. The presence of a '::' will parse
- * as one, two or three zero length elements.
- */
- if (!CONF_parse_list(in, ':', 0, ipv6_cb, &v6stat))
- return 0;
-
- /* Now for some sanity checks */
-
- if (v6stat.zero_pos == -1)
- {
- /* If no '::' must have exactly 16 bytes */
- if (v6stat.total != 16)
- return 0;
- }
- else
- {
- /* If '::' must have less than 16 bytes */
- if (v6stat.total == 16)
- return 0;
- /* More than three zeroes is an error */
- if (v6stat.zero_cnt > 3)
- return 0;
- /* Can only have three zeroes if nothing else present */
- else if (v6stat.zero_cnt == 3)
- {
- if (v6stat.total > 0)
- return 0;
- }
- /* Can only have two zeroes if at start or end */
- else if (v6stat.zero_cnt == 2)
- {
- if ((v6stat.zero_pos != 0)
- && (v6stat.zero_pos != v6stat.total))
- return 0;
- }
- else
- /* Can only have one zero if *not* start or end */
- {
- if ((v6stat.zero_pos == 0)
- || (v6stat.zero_pos == v6stat.total))
- return 0;
- }
- }
-
- /* Format result */
-
- if (v6stat.zero_pos >= 0)
- {
- /* Copy initial part */
- memcpy(v6, v6stat.tmp, v6stat.zero_pos);
- /* Zero middle */
- memset(v6 + v6stat.zero_pos, 0, 16 - v6stat.total);
- /* Copy final part */
- if (v6stat.total != v6stat.zero_pos)
- memcpy(v6 + v6stat.zero_pos + 16 - v6stat.total,
- v6stat.tmp + v6stat.zero_pos,
- v6stat.total - v6stat.zero_pos);
- }
- else
- memcpy(v6, v6stat.tmp, 16);
-
- return 1;
- }
+{
+ IPV6_STAT v6stat;
+ v6stat.total = 0;
+ v6stat.zero_pos = -1;
+ v6stat.zero_cnt = 0;
+ /*
+ * Treat the IPv6 representation as a list of values separated by ':'.
+ * The presence of a '::' will parse as one, two or three zero length
+ * elements.
+ */
+ if (!CONF_parse_list(in, ':', 0, ipv6_cb, &v6stat))
+ return 0;
+
+ /* Now for some sanity checks */
+
+ if (v6stat.zero_pos == -1) {
+ /* If no '::' must have exactly 16 bytes */
+ if (v6stat.total != 16)
+ return 0;
+ } else {
+ /* If '::' must have less than 16 bytes */
+ if (v6stat.total == 16)
+ return 0;
+ /* More than three zeroes is an error */
+ if (v6stat.zero_cnt > 3)
+ return 0;
+ /* Can only have three zeroes if nothing else present */
+ else if (v6stat.zero_cnt == 3) {
+ if (v6stat.total > 0)
+ return 0;
+ }
+ /* Can only have two zeroes if at start or end */
+ else if (v6stat.zero_cnt == 2) {
+ if ((v6stat.zero_pos != 0)
+ && (v6stat.zero_pos != v6stat.total))
+ return 0;
+ } else
+ /* Can only have one zero if *not* start or end */
+ {
+ if ((v6stat.zero_pos == 0)
+ || (v6stat.zero_pos == v6stat.total))
+ return 0;
+ }
+ }
+
+ /* Format result */
+
+ if (v6stat.zero_pos >= 0) {
+ /* Copy initial part */
+ memcpy(v6, v6stat.tmp, v6stat.zero_pos);
+ /* Zero middle */
+ memset(v6 + v6stat.zero_pos, 0, 16 - v6stat.total);
+ /* Copy final part */
+ if (v6stat.total != v6stat.zero_pos)
+ memcpy(v6 + v6stat.zero_pos + 16 - v6stat.total,
+ v6stat.tmp + v6stat.zero_pos,
+ v6stat.total - v6stat.zero_pos);
+ } else
+ memcpy(v6, v6stat.tmp, 16);
+
+ return 1;
+}
static int ipv6_cb(const char *elem, int len, void *usr)
- {
- IPV6_STAT *s = usr;
- /* Error if 16 bytes written */
- if (s->total == 16)
- return 0;
- if (len == 0)
- {
- /* Zero length element, corresponds to '::' */
- if (s->zero_pos == -1)
- s->zero_pos = s->total;
- /* If we've already got a :: its an error */
- else if (s->zero_pos != s->total)
- return 0;
- s->zero_cnt++;
- }
- else
- {
- /* If more than 4 characters could be final a.b.c.d form */
- if (len > 4)
- {
- /* Need at least 4 bytes left */
- if (s->total > 12)
- return 0;
- /* Must be end of string */
- if (elem[len])
- return 0;
- if (!ipv4_from_asc(s->tmp + s->total, elem))
- return 0;
- s->total += 4;
- }
- else
- {
- if (!ipv6_hex(s->tmp + s->total, elem, len))
- return 0;
- s->total += 2;
- }
- }
- return 1;
- }
-
-/* Convert a string of up to 4 hex digits into the corresponding
- * IPv6 form.
+{
+ IPV6_STAT *s = usr;
+ /* Error if 16 bytes written */
+ if (s->total == 16)
+ return 0;
+ if (len == 0) {
+ /* Zero length element, corresponds to '::' */
+ if (s->zero_pos == -1)
+ s->zero_pos = s->total;
+ /* If we've already got a :: its an error */
+ else if (s->zero_pos != s->total)
+ return 0;
+ s->zero_cnt++;
+ } else {
+ /* If more than 4 characters could be final a.b.c.d form */
+ if (len > 4) {
+ /* Need at least 4 bytes left */
+ if (s->total > 12)
+ return 0;
+ /* Must be end of string */
+ if (elem[len])
+ return 0;
+ if (!ipv4_from_asc(s->tmp + s->total, elem))
+ return 0;
+ s->total += 4;
+ } else {
+ if (!ipv6_hex(s->tmp + s->total, elem, len))
+ return 0;
+ s->total += 2;
+ }
+ }
+ return 1;
+}
+
+/*
+ * Convert a string of up to 4 hex digits into the corresponding IPv6 form.
*/
static int ipv6_hex(unsigned char *out, const char *in, int inlen)
- {
- unsigned char c;
- unsigned int num = 0;
- if (inlen > 4)
- return 0;
- while(inlen--)
- {
- c = *in++;
- num <<= 4;
- if ((c >= '0') && (c <= '9'))
- num |= c - '0';
- else if ((c >= 'A') && (c <= 'F'))
- num |= c - 'A' + 10;
- else if ((c >= 'a') && (c <= 'f'))
- num |= c - 'a' + 10;
- else
- return 0;
- }
- out[0] = num >> 8;
- out[1] = num & 0xff;
- return 1;
- }
-
-
-int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE)*dn_sk,
- unsigned long chtype)
- {
- CONF_VALUE *v;
- int mval;
- size_t i;
- char *p, *type;
- if (!nm)
- return 0;
-
- for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++)
- {
- v=sk_CONF_VALUE_value(dn_sk,i);
- type=v->name;
- /* Skip past any leading X. X: X, etc to allow for
- * multiple instances
- */
- for(p = type; *p ; p++)
- if ((*p == ':') || (*p == ',') || (*p == '.'))
- {
- p++;
- if(*p) type = p;
- break;
- }
- if (*type == '+')
- {
- mval = -1;
- type++;
- }
- else
- mval = 0;
- if (!X509_NAME_add_entry_by_txt(nm,type, chtype,
- (unsigned char *) v->value,-1,-1,mval))
- return 0;
-
- }
- return 1;
- }
+{
+ unsigned char c;
+ unsigned int num = 0;
+ if (inlen > 4)
+ return 0;
+ while (inlen--) {
+ c = *in++;
+ num <<= 4;
+ if ((c >= '0') && (c <= '9'))
+ num |= c - '0';
+ else if ((c >= 'A') && (c <= 'F'))
+ num |= c - 'A' + 10;
+ else if ((c >= 'a') && (c <= 'f'))
+ num |= c - 'a' + 10;
+ else
+ return 0;
+ }
+ out[0] = num >> 8;
+ out[1] = num & 0xff;
+ return 1;
+}
+
+int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF (CONF_VALUE) * dn_sk,
+ unsigned long chtype)
+{
+ CONF_VALUE *v;
+ int mval;
+ size_t i;
+ char *p, *type;
+ if (!nm)
+ return 0;
+
+ for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) {
+ v = sk_CONF_VALUE_value(dn_sk, i);
+ type = v->name;
+ /*
+ * Skip past any leading X. X: X, etc to allow for multiple instances
+ */
+ for (p = type; *p; p++)
+ if ((*p == ':') || (*p == ',') || (*p == '.')) {
+ p++;
+ if (*p)
+ type = p;
+ break;
+ }
+ if (*type == '+') {
+ mval = -1;
+ type++;
+ } else
+ mval = 0;
+ if (!X509_NAME_add_entry_by_txt(nm, type, chtype,
+ (unsigned char *)v->value, -1, -1,
+ mval))
+ return 0;
+
+ }
+ return 1;
+}
diff --git a/src/crypto/x509v3/v3name_test.c b/src/crypto/x509v3/v3name_test.c
index f9f70871..dadf488f 100644
--- a/src/crypto/x509v3/v3name_test.c
+++ b/src/crypto/x509v3/v3name_test.c
@@ -1,5 +1,7 @@
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999. */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
/* ====================================================================
* Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved.
*
@@ -8,7 +10,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -60,363 +62,349 @@
#include <openssl/x509.h>
#include <openssl/x509v3.h>
-
-static const char *const names[] =
- {
- "a", "b", ".", "*", "@",
- ".a", "a.", ".b", "b.", ".*", "*.", "*@", "@*", "a@", "@a", "b@", "..",
- "@@", "**", "*.com", "*com", "*.*.com", "*com", "com*", "*example.com",
- "*@example.com", "test@*.example.com", "example.com", "www.example.com",
- "test.www.example.com", "*.example.com", "*.www.example.com",
- "test.*.example.com", "www.*.com",
- ".www.example.com", "*www.example.com",
- "example.net", "xn--rger-koa.example.com",
- "a.example.com", "b.example.com",
- "postmaster@example.com", "Postmaster@example.com",
- "postmaster@EXAMPLE.COM",
- NULL
- };
-
-static const char *const exceptions[] =
- {
- "set CN: host: [*.example.com] matches [a.example.com]",
- "set CN: host: [*.example.com] matches [b.example.com]",
- "set CN: host: [*.example.com] matches [www.example.com]",
- "set CN: host: [*.example.com] matches [xn--rger-koa.example.com]",
- "set CN: host: [*.www.example.com] matches [test.www.example.com]",
- "set CN: host: [*.www.example.com] matches [.www.example.com]",
- "set CN: host: [*www.example.com] matches [www.example.com]",
- "set CN: host: [test.www.example.com] matches [.www.example.com]",
- "set CN: host-no-wildcards: [*.www.example.com] matches [.www.example.com]",
- "set CN: host-no-wildcards: [test.www.example.com] matches [.www.example.com]",
- "set emailAddress: email: [postmaster@example.com] does not match [Postmaster@example.com]",
- "set emailAddress: email: [postmaster@EXAMPLE.COM] does not match [Postmaster@example.com]",
- "set emailAddress: email: [Postmaster@example.com] does not match [postmaster@example.com]",
- "set emailAddress: email: [Postmaster@example.com] does not match [postmaster@EXAMPLE.COM]",
- "set dnsName: host: [*.example.com] matches [www.example.com]",
- "set dnsName: host: [*.example.com] matches [a.example.com]",
- "set dnsName: host: [*.example.com] matches [b.example.com]",
- "set dnsName: host: [*.example.com] matches [xn--rger-koa.example.com]",
- "set dnsName: host: [*.www.example.com] matches [test.www.example.com]",
- "set dnsName: host-no-wildcards: [*.www.example.com] matches [.www.example.com]",
- "set dnsName: host-no-wildcards: [test.www.example.com] matches [.www.example.com]",
- "set dnsName: host: [*.www.example.com] matches [.www.example.com]",
- "set dnsName: host: [*www.example.com] matches [www.example.com]",
- "set dnsName: host: [test.www.example.com] matches [.www.example.com]",
- "set rfc822Name: email: [postmaster@example.com] does not match [Postmaster@example.com]",
- "set rfc822Name: email: [Postmaster@example.com] does not match [postmaster@example.com]",
- "set rfc822Name: email: [Postmaster@example.com] does not match [postmaster@EXAMPLE.COM]",
- "set rfc822Name: email: [postmaster@EXAMPLE.COM] does not match [Postmaster@example.com]",
- NULL
- };
+static const char *const names[] = {
+ "a", "b", ".", "*", "@",
+ ".a", "a.", ".b", "b.", ".*", "*.", "*@", "@*", "a@", "@a", "b@", "..",
+ "-example.com", "example-.com",
+ "@@", "**", "*.com", "*com", "*.*.com", "*com", "com*", "*example.com",
+ "*@example.com", "test@*.example.com", "example.com", "www.example.com",
+ "test.www.example.com", "*.example.com", "*.www.example.com",
+ "test.*.example.com", "www.*.com",
+ ".www.example.com", "*www.example.com",
+ "example.net", "xn--rger-koa.example.com",
+ "*.xn--rger-koa.example.com", "www.xn--rger-koa.example.com",
+ "*.good--example.com", "www.good--example.com",
+ "*.xn--bar.com", "xn--foo.xn--bar.com",
+ "a.example.com", "b.example.com",
+ "postmaster@example.com", "Postmaster@example.com",
+ "postmaster@EXAMPLE.COM",
+ NULL
+};
+
+static const char *const exceptions[] = {
+ "set CN: host: [*.example.com] matches [a.example.com]",
+ "set CN: host: [*.example.com] matches [b.example.com]",
+ "set CN: host: [*.example.com] matches [www.example.com]",
+ "set CN: host: [*.example.com] matches [xn--rger-koa.example.com]",
+ "set CN: host: [*.www.example.com] matches [test.www.example.com]",
+ "set CN: host: [*.www.example.com] matches [.www.example.com]",
+ "set CN: host: [*www.example.com] matches [www.example.com]",
+ "set CN: host: [test.www.example.com] matches [.www.example.com]",
+ "set CN: host: [*.xn--rger-koa.example.com] matches [www.xn--rger-koa.example.com]",
+ "set CN: host: [*.xn--bar.com] matches [xn--foo.xn--bar.com]",
+ "set CN: host: [*.good--example.com] matches [www.good--example.com]",
+ "set CN: host-no-wildcards: [*.www.example.com] matches [.www.example.com]",
+ "set CN: host-no-wildcards: [test.www.example.com] matches [.www.example.com]",
+ "set emailAddress: email: [postmaster@example.com] does not match [Postmaster@example.com]",
+ "set emailAddress: email: [postmaster@EXAMPLE.COM] does not match [Postmaster@example.com]",
+ "set emailAddress: email: [Postmaster@example.com] does not match [postmaster@example.com]",
+ "set emailAddress: email: [Postmaster@example.com] does not match [postmaster@EXAMPLE.COM]",
+ "set dnsName: host: [*.example.com] matches [www.example.com]",
+ "set dnsName: host: [*.example.com] matches [a.example.com]",
+ "set dnsName: host: [*.example.com] matches [b.example.com]",
+ "set dnsName: host: [*.example.com] matches [xn--rger-koa.example.com]",
+ "set dnsName: host: [*.www.example.com] matches [test.www.example.com]",
+ "set dnsName: host-no-wildcards: [*.www.example.com] matches [.www.example.com]",
+ "set dnsName: host-no-wildcards: [test.www.example.com] matches [.www.example.com]",
+ "set dnsName: host: [*.www.example.com] matches [.www.example.com]",
+ "set dnsName: host: [*www.example.com] matches [www.example.com]",
+ "set dnsName: host: [test.www.example.com] matches [.www.example.com]",
+ "set dnsName: host: [*.xn--rger-koa.example.com] matches [www.xn--rger-koa.example.com]",
+ "set dnsName: host: [*.xn--bar.com] matches [xn--foo.xn--bar.com]",
+ "set dnsName: host: [*.good--example.com] matches [www.good--example.com]",
+ "set rfc822Name: email: [postmaster@example.com] does not match [Postmaster@example.com]",
+ "set rfc822Name: email: [Postmaster@example.com] does not match [postmaster@example.com]",
+ "set rfc822Name: email: [Postmaster@example.com] does not match [postmaster@EXAMPLE.COM]",
+ "set rfc822Name: email: [postmaster@EXAMPLE.COM] does not match [Postmaster@example.com]",
+ NULL
+};
static int is_exception(const char *msg)
- {
- const char *const *p;
- for (p = exceptions; *p; ++p)
- if (strcmp(msg, *p) == 0)
- return 1;
- return 0;
- }
+{
+ const char *const *p;
+ for (p = exceptions; *p; ++p)
+ if (strcmp(msg, *p) == 0)
+ return 1;
+ return 0;
+}
static int set_cn(X509 *crt, ...)
- {
- int ret = 0;
- X509_NAME *n = NULL;
- va_list ap;
- va_start(ap, crt);
- n = X509_NAME_new();
- if (n == NULL)
- goto out;
- while (1) {
- int nid;
- const char *name;
- nid = va_arg(ap, int);
- if (nid == 0)
- break;
- name = va_arg(ap, const char *);
- if (!X509_NAME_add_entry_by_NID(n, nid, MBSTRING_ASC,
- (unsigned char *)name,
- -1, -1, 1))
- goto out;
- }
- if (!X509_set_subject_name(crt, n))
- goto out;
- ret = 1;
+{
+ int ret = 0;
+ X509_NAME *n = NULL;
+ va_list ap;
+ va_start(ap, crt);
+ n = X509_NAME_new();
+ if (n == NULL)
+ goto out;
+ while (1) {
+ int nid;
+ const char *name;
+ nid = va_arg(ap, int);
+ if (nid == 0)
+ break;
+ name = va_arg(ap, const char *);
+ if (!X509_NAME_add_entry_by_NID(n, nid, MBSTRING_ASC,
+ (unsigned char *)name, -1, -1, 1))
+ goto out;
+ }
+ if (!X509_set_subject_name(crt, n))
+ goto out;
+ ret = 1;
out:
- X509_NAME_free(n);
- va_end(ap);
- return ret;
- }
+ X509_NAME_free(n);
+ va_end(ap);
+ return ret;
+}
/*
-int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc);
-X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex,
- int nid, int crit, ASN1_OCTET_STRING *data);
-int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc);
-*/
+ * int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc); X509_EXTENSION
+ * *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, int nid, int crit,
+ * ASN1_OCTET_STRING *data); int X509_add_ext(X509 *x, X509_EXTENSION *ex,
+ * int loc);
+ */
static int set_altname(X509 *crt, ...)
- {
- int ret = 0;
- GENERAL_NAMES *gens = NULL;
- GENERAL_NAME *gen = NULL;
- ASN1_IA5STRING *ia5 = NULL;
- va_list ap;
- va_start(ap, crt);
- gens = sk_GENERAL_NAME_new_null();
- if (gens == NULL)
- goto out;
- while (1) {
- int type;
- const char *name;
- type = va_arg(ap, int);
- if (type == 0)
- break;
- name = va_arg(ap, const char *);
-
- gen = GENERAL_NAME_new();
- if (gen == NULL)
- goto out;
- ia5 = ASN1_IA5STRING_new();
- if (ia5 == NULL)
- goto out;
- if (!ASN1_STRING_set(ia5, name, -1))
- goto out;
- switch (type)
- {
- case GEN_EMAIL:
- case GEN_DNS:
- GENERAL_NAME_set0_value(gen, type, ia5);
- ia5 = NULL;
- break;
- default:
- abort();
- }
- sk_GENERAL_NAME_push(gens, gen);
- gen = NULL;
- }
- if (!X509_add1_ext_i2d(crt, NID_subject_alt_name, gens, 0, 0))
- goto out;
- ret = 1;
+{
+ int ret = 0;
+ GENERAL_NAMES *gens = NULL;
+ GENERAL_NAME *gen = NULL;
+ ASN1_IA5STRING *ia5 = NULL;
+ va_list ap;
+ va_start(ap, crt);
+ gens = sk_GENERAL_NAME_new_null();
+ if (gens == NULL)
+ goto out;
+ while (1) {
+ int type;
+ const char *name;
+ type = va_arg(ap, int);
+ if (type == 0)
+ break;
+ name = va_arg(ap, const char *);
+
+ gen = GENERAL_NAME_new();
+ if (gen == NULL)
+ goto out;
+ ia5 = ASN1_IA5STRING_new();
+ if (ia5 == NULL)
+ goto out;
+ if (!ASN1_STRING_set(ia5, name, -1))
+ goto out;
+ switch (type) {
+ case GEN_EMAIL:
+ case GEN_DNS:
+ GENERAL_NAME_set0_value(gen, type, ia5);
+ ia5 = NULL;
+ break;
+ default:
+ abort();
+ }
+ sk_GENERAL_NAME_push(gens, gen);
+ gen = NULL;
+ }
+ if (!X509_add1_ext_i2d(crt, NID_subject_alt_name, gens, 0, 0))
+ goto out;
+ ret = 1;
out:
- ASN1_IA5STRING_free(ia5);
- GENERAL_NAME_free(gen);
- GENERAL_NAMES_free(gens);
- va_end(ap);
- return ret;
- }
+ ASN1_IA5STRING_free(ia5);
+ GENERAL_NAME_free(gen);
+ GENERAL_NAMES_free(gens);
+ va_end(ap);
+ return ret;
+}
static int set_cn1(X509 *crt, const char *name)
- {
- return set_cn(crt, NID_commonName, name, 0);
- }
-
+{
+ return set_cn(crt, NID_commonName, name, 0);
+}
static int set_cn_and_email(X509 *crt, const char *name)
- {
- return set_cn(crt, NID_commonName, name,
- NID_pkcs9_emailAddress, "dummy@example.com", 0);
- }
+{
+ return set_cn(crt, NID_commonName, name,
+ NID_pkcs9_emailAddress, "dummy@example.com", 0);
+}
static int set_cn2(X509 *crt, const char *name)
- {
- return set_cn(crt, NID_commonName, "dummy value",
- NID_commonName, name, 0);
- }
+{
+ return set_cn(crt, NID_commonName, "dummy value",
+ NID_commonName, name, 0);
+}
static int set_cn3(X509 *crt, const char *name)
- {
- return set_cn(crt, NID_commonName, name,
- NID_commonName, "dummy value", 0);
- }
+{
+ return set_cn(crt, NID_commonName, name,
+ NID_commonName, "dummy value", 0);
+}
static int set_email1(X509 *crt, const char *name)
- {
- return set_cn(crt, NID_pkcs9_emailAddress, name, 0);
- }
+{
+ return set_cn(crt, NID_pkcs9_emailAddress, name, 0);
+}
static int set_email2(X509 *crt, const char *name)
- {
- return set_cn(crt, NID_pkcs9_emailAddress, "dummy@example.com",
- NID_pkcs9_emailAddress, name, 0);
- }
+{
+ return set_cn(crt, NID_pkcs9_emailAddress, "dummy@example.com",
+ NID_pkcs9_emailAddress, name, 0);
+}
static int set_email3(X509 *crt, const char *name)
- {
- return set_cn(crt, NID_pkcs9_emailAddress, name,
- NID_pkcs9_emailAddress, "dummy@example.com", 0);
- }
+{
+ return set_cn(crt, NID_pkcs9_emailAddress, name,
+ NID_pkcs9_emailAddress, "dummy@example.com", 0);
+}
static int set_email_and_cn(X509 *crt, const char *name)
- {
- return set_cn(crt, NID_pkcs9_emailAddress, name,
- NID_commonName, "www.example.org", 0);
- }
+{
+ return set_cn(crt, NID_pkcs9_emailAddress, name,
+ NID_commonName, "www.example.org", 0);
+}
static int set_altname_dns(X509 *crt, const char *name)
- {
- return set_altname(crt, GEN_DNS, name, 0);
- }
+{
+ return set_altname(crt, GEN_DNS, name, 0);
+}
static int set_altname_email(X509 *crt, const char *name)
- {
- return set_altname(crt, GEN_EMAIL, name, 0);
- }
-
-struct set_name_fn
- {
- int (*fn)(X509 *, const char *);
- const char *name;
- int host;
- int email;
- };
-
-static const struct set_name_fn name_fns[] =
- {
- {set_cn1, "set CN", 1, 0},
- {set_cn2, "set CN", 1, 0},
- {set_cn3, "set CN", 1, 0},
- {set_cn_and_email, "set CN", 1, 0},
- {set_email1, "set emailAddress", 0, 1},
- {set_email2, "set emailAddress", 0, 1},
- {set_email3, "set emailAddress", 0, 1},
- {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, 0},
- };
+{
+ return set_altname(crt, GEN_EMAIL, name, 0);
+}
+
+struct set_name_fn {
+ int (*fn) (X509 *, const char *);
+ const char *name;
+ int host;
+ int email;
+};
+
+static const struct set_name_fn name_fns[] = {
+ {set_cn1, "set CN", 1, 0},
+ {set_cn2, "set CN", 1, 0},
+ {set_cn3, "set CN", 1, 0},
+ {set_cn_and_email, "set CN", 1, 0},
+ {set_email1, "set emailAddress", 0, 1},
+ {set_email2, "set emailAddress", 0, 1},
+ {set_email3, "set emailAddress", 0, 1},
+ {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, 0},
+};
static X509 *make_cert(void)
- {
- X509 *ret = NULL;
- X509 *crt = NULL;
- X509_NAME *issuer = NULL;
- crt = X509_new();
- if (crt == NULL)
- goto out;
- if (!X509_set_version(crt, 3))
- goto out;
- ret = crt;
- crt = NULL;
+{
+ X509 *ret = NULL;
+ X509 *crt = NULL;
+ X509_NAME *issuer = NULL;
+ crt = X509_new();
+ if (crt == NULL)
+ goto out;
+ if (!X509_set_version(crt, 3))
+ goto out;
+ ret = crt;
+ crt = NULL;
out:
- X509_NAME_free(issuer);
- return ret;
- }
+ X509_NAME_free(issuer);
+ return ret;
+}
static int errors;
static void check_message(const struct set_name_fn *fn, const char *op,
- const char *nameincert, int match, const char *name)
- {
- char msg[1024];
- if (match < 0)
- return;
- BIO_snprintf(msg, sizeof(msg), "%s: %s: [%s] %s [%s]",
- fn->name, op, nameincert,
- match ? "matches" : "does not match", name);
- if (is_exception(msg))
- return;
- puts(msg);
- ++errors;
- }
+ const char *nameincert, int match, const char *name)
+{
+ char msg[1024];
+ if (match < 0)
+ return;
+ BIO_snprintf(msg, sizeof(msg), "%s: %s: [%s] %s [%s]",
+ fn->name, op, nameincert,
+ match ? "matches" : "does not match", name);
+ if (is_exception(msg))
+ return;
+ puts(msg);
+ ++errors;
+}
static void run_cert(X509 *crt, const char *nameincert,
- const struct set_name_fn *fn)
- {
- const char *const *pname = names;
- while (*pname)
- {
- int samename = OPENSSL_strcasecmp(nameincert, *pname) == 0;
- size_t namelen = strlen(*pname);
- char *name = malloc(namelen);
- int match, ret;
- memcpy(name, *pname, namelen);
-
- ret = X509_check_host(crt, name, namelen, 0, NULL);
- match = -1;
- if (ret < 0)
- {
- fprintf(stderr, "internal error in X509_check_host");
- ++errors;
- }
- else if (fn->host)
- {
- if (ret == 1 && !samename)
- match = 1;
- if (ret == 0 && samename)
- match = 0;
- }
- else if (ret == 1)
- match = 1;
- check_message(fn, "host", nameincert, match, *pname);
-
- ret = X509_check_host(crt, name, namelen,
- X509_CHECK_FLAG_NO_WILDCARDS, NULL);
- match = -1;
- if (ret < 0)
- {
- fprintf(stderr, "internal error in X509_check_host");
- ++errors;
- }
- else if (fn->host)
- {
- if (ret == 1 && !samename)
- match = 1;
- if (ret == 0 && samename)
- match = 0;
- }
- else if (ret == 1)
- match = 1;
- check_message(fn, "host-no-wildcards",
- nameincert, match, *pname);
-
- ret = X509_check_email(crt, name, namelen, 0);
- match = -1;
- if (fn->email)
- {
- if (ret && !samename)
- match = 1;
- if (!ret && samename && strchr(nameincert, '@') != NULL)
- match = 0;
- }
- else if (ret)
- match = 1;
- check_message(fn, "email", nameincert, match, *pname);
- ++pname;
- free(name);
- }
- }
-
-int
-main(void)
- {
- CRYPTO_library_init();
-
- const struct set_name_fn *pfn = name_fns;
- while (pfn->name) {
- const char *const *pname = names;
- while (*pname)
- {
- X509 *crt = make_cert();
- if (crt == NULL)
- {
- fprintf(stderr, "make_cert failed\n");
- return 1;
- }
- if (!pfn->fn(crt, *pname))
- {
- fprintf(stderr, "X509 name setting failed\n");
- return 1;
- }
- run_cert(crt, *pname, pfn);
- X509_free(crt);
- ++pname;
- }
- ++pfn;
- }
- if (errors == 0) {
- printf("PASS\n");
- }
- return errors > 0 ? 1 : 0;
- }
+ const struct set_name_fn *fn)
+{
+ const char *const *pname = names;
+ while (*pname) {
+ int samename = OPENSSL_strcasecmp(nameincert, *pname) == 0;
+ size_t namelen = strlen(*pname);
+ char *name = malloc(namelen);
+ int match, ret;
+ memcpy(name, *pname, namelen);
+
+ ret = X509_check_host(crt, name, namelen, 0, NULL);
+ match = -1;
+ if (ret < 0) {
+ fprintf(stderr, "internal error in X509_check_host");
+ ++errors;
+ } else if (fn->host) {
+ if (ret == 1 && !samename)
+ match = 1;
+ if (ret == 0 && samename)
+ match = 0;
+ } else if (ret == 1)
+ match = 1;
+ check_message(fn, "host", nameincert, match, *pname);
+
+ ret = X509_check_host(crt, name, namelen,
+ X509_CHECK_FLAG_NO_WILDCARDS, NULL);
+ match = -1;
+ if (ret < 0) {
+ fprintf(stderr, "internal error in X509_check_host");
+ ++errors;
+ } else if (fn->host) {
+ if (ret == 1 && !samename)
+ match = 1;
+ if (ret == 0 && samename)
+ match = 0;
+ } else if (ret == 1)
+ match = 1;
+ check_message(fn, "host-no-wildcards", nameincert, match, *pname);
+
+ ret = X509_check_email(crt, name, namelen, 0);
+ match = -1;
+ if (fn->email) {
+ if (ret && !samename)
+ match = 1;
+ if (!ret && samename && strchr(nameincert, '@') != NULL)
+ match = 0;
+ } else if (ret)
+ match = 1;
+ check_message(fn, "email", nameincert, match, *pname);
+ ++pname;
+ free(name);
+ }
+}
+
+int main(void)
+{
+ CRYPTO_library_init();
+
+ const struct set_name_fn *pfn = name_fns;
+ while (pfn->name) {
+ const char *const *pname = names;
+ while (*pname) {
+ X509 *crt = make_cert();
+ if (crt == NULL) {
+ fprintf(stderr, "make_cert failed\n");
+ return 1;
+ }
+ if (!pfn->fn(crt, *pname)) {
+ fprintf(stderr, "X509 name setting failed\n");
+ return 1;
+ }
+ run_cert(crt, *pname, pfn);
+ X509_free(crt);
+ ++pname;
+ }
+ ++pfn;
+ }
+ if (errors == 0) {
+ printf("PASS\n");
+ }
+ return errors > 0 ? 1 : 0;
+}
diff --git a/src/decrepit/CMakeLists.txt b/src/decrepit/CMakeLists.txt
index 0773f9a6..6a5462c2 100644
--- a/src/decrepit/CMakeLists.txt
+++ b/src/decrepit/CMakeLists.txt
@@ -2,7 +2,15 @@ add_subdirectory(bio)
add_subdirectory(blowfish)
add_subdirectory(cast)
add_subdirectory(des)
+add_subdirectory(dh)
+add_subdirectory(dsa)
+add_subdirectory(evp)
+add_subdirectory(obj)
+add_subdirectory(rc4)
+add_subdirectory(ripemd)
add_subdirectory(rsa)
+add_subdirectory(ssl)
+add_subdirectory(x509)
add_subdirectory(xts)
add_library(
@@ -12,8 +20,16 @@ add_library(
$<TARGET_OBJECTS:blowfish>
$<TARGET_OBJECTS:cast>
$<TARGET_OBJECTS:des_decrepit>
+ $<TARGET_OBJECTS:dh_decrepit>
+ $<TARGET_OBJECTS:dsa_decrepit>
+ $<TARGET_OBJECTS:evp_decrepit>
+ $<TARGET_OBJECTS:obj_decrepit>
+ $<TARGET_OBJECTS:rc4_decrepit>
+ $<TARGET_OBJECTS:ripemd_decrepit>
$<TARGET_OBJECTS:rsa_decrepit>
+ $<TARGET_OBJECTS:ssl_decrepit>
+ $<TARGET_OBJECTS:x509_decrepit>
$<TARGET_OBJECTS:xts>
)
-target_link_libraries(decrepit crypto)
+target_link_libraries(decrepit crypto ssl)
diff --git a/src/decrepit/dh/CMakeLists.txt b/src/decrepit/dh/CMakeLists.txt
new file mode 100644
index 00000000..fb862b51
--- /dev/null
+++ b/src/decrepit/dh/CMakeLists.txt
@@ -0,0 +1,9 @@
+include_directories(../../include)
+
+add_library(
+ dh_decrepit
+
+ OBJECT
+
+ dh_decrepit.c
+)
diff --git a/src/decrepit/dh/dh_decrepit.c b/src/decrepit/dh/dh_decrepit.c
new file mode 100644
index 00000000..1d38c12e
--- /dev/null
+++ b/src/decrepit/dh/dh_decrepit.c
@@ -0,0 +1,103 @@
+/* ====================================================================
+ * 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/bn.h>
+#include <openssl/dh.h>
+
+
+struct wrapped_callback {
+ void (*callback)(int, int, void *);
+ void *arg;
+};
+
+/* callback_wrapper converts an “old” style generation callback to the newer
+ * |BN_GENCB| form. */
+static int callback_wrapper(int event, int n, BN_GENCB *gencb) {
+ struct wrapped_callback *wrapped = (struct wrapped_callback *) gencb->arg;
+ wrapped->callback(event, n, wrapped->arg);
+ return 1;
+}
+
+DH *DH_generate_parameters(int prime_len, int generator,
+ void (*callback)(int, int, void *), void *cb_arg) {
+ if (prime_len < 0 || generator < 0) {
+ return NULL;
+ }
+
+ DH *ret = DH_new();
+ if (ret == NULL) {
+ return NULL;
+ }
+
+ BN_GENCB gencb_storage;
+ BN_GENCB *cb = NULL;
+
+ struct wrapped_callback wrapped;
+
+ if (callback != NULL) {
+ wrapped.callback = callback;
+ wrapped.arg = cb_arg;
+
+ cb = &gencb_storage;
+ BN_GENCB_set(cb, callback_wrapper, &wrapped);
+ }
+
+ if (!DH_generate_parameters_ex(ret, prime_len, generator, cb)) {
+ goto err;
+ }
+
+ return ret;
+
+err:
+ DH_free(ret);
+ return NULL;
+}
diff --git a/src/decrepit/dsa/CMakeLists.txt b/src/decrepit/dsa/CMakeLists.txt
new file mode 100644
index 00000000..cc64b604
--- /dev/null
+++ b/src/decrepit/dsa/CMakeLists.txt
@@ -0,0 +1,9 @@
+include_directories(../../include)
+
+add_library(
+ dsa_decrepit
+
+ OBJECT
+
+ dsa_decrepit.c
+)
diff --git a/src/decrepit/dsa/dsa_decrepit.c b/src/decrepit/dsa/dsa_decrepit.c
new file mode 100644
index 00000000..aef8056b
--- /dev/null
+++ b/src/decrepit/dsa/dsa_decrepit.c
@@ -0,0 +1,105 @@
+/* ====================================================================
+ * 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/bn.h>
+#include <openssl/dsa.h>
+
+
+struct wrapped_callback {
+ void (*callback)(int, int, void *);
+ void *arg;
+};
+
+/* callback_wrapper converts an “old” style generation callback to the newer
+ * |BN_GENCB| form. */
+static int callback_wrapper(int event, int n, BN_GENCB *gencb) {
+ struct wrapped_callback *wrapped = (struct wrapped_callback *) gencb->arg;
+ wrapped->callback(event, n, wrapped->arg);
+ return 1;
+}
+
+DSA *DSA_generate_parameters(int bits, uint8_t *seed_in, int seed_len,
+ int *counter_ret, unsigned long *h_ret,
+ void (*callback)(int, int, void *), void *cb_arg) {
+ if (bits < 0 || seed_len < 0) {
+ return NULL;
+ }
+
+ DSA *ret = DSA_new();
+ if (ret == NULL) {
+ return NULL;
+ }
+
+ BN_GENCB gencb_storage;
+ BN_GENCB *cb = NULL;
+
+ struct wrapped_callback wrapped;
+
+ if (callback != NULL) {
+ wrapped.callback = callback;
+ wrapped.arg = cb_arg;
+
+ cb = &gencb_storage;
+ BN_GENCB_set(cb, callback_wrapper, &wrapped);
+ }
+
+ if (!DSA_generate_parameters_ex(ret, bits, seed_in, seed_len, counter_ret,
+ h_ret, cb)) {
+ goto err;
+ }
+
+ return ret;
+
+err:
+ DSA_free(ret);
+ return NULL;
+}
diff --git a/src/decrepit/evp/CMakeLists.txt b/src/decrepit/evp/CMakeLists.txt
new file mode 100644
index 00000000..ee3bf33b
--- /dev/null
+++ b/src/decrepit/evp/CMakeLists.txt
@@ -0,0 +1,9 @@
+include_directories(../../include)
+
+add_library(
+ evp_decrepit
+
+ OBJECT
+
+ evp_do_all.c
+)
diff --git a/src/decrepit/evp/evp_do_all.c b/src/decrepit/evp/evp_do_all.c
new file mode 100644
index 00000000..621c0b11
--- /dev/null
+++ b/src/decrepit/evp/evp_do_all.c
@@ -0,0 +1,77 @@
+/* Copyright (c) 2016, 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/evp.h>
+
+
+void EVP_CIPHER_do_all_sorted(void (*callback)(const EVP_CIPHER *cipher,
+ const char *name,
+ const char *unused, void *arg),
+ void *arg) {
+ callback(EVP_aes_128_cbc(), "AES-128-CBC", NULL, arg);
+ callback(EVP_aes_128_ctr(), "AES-128-CTR", NULL, arg);
+ callback(EVP_aes_128_ecb(), "AES-128-ECB", NULL, arg);
+ callback(EVP_aes_128_ofb(), "AES-128-OFB", NULL, arg);
+ callback(EVP_aes_256_cbc(), "AES-256-CBC", NULL, arg);
+ callback(EVP_aes_256_ctr(), "AES-256-CTR", NULL, arg);
+ callback(EVP_aes_256_ecb(), "AES-256-ECB", NULL, arg);
+ callback(EVP_aes_256_ofb(), "AES-256-OFB", NULL, arg);
+ callback(EVP_aes_256_xts(), "AES-256-XTS", NULL, arg);
+ callback(EVP_des_cbc(), "DES-CBC", NULL, arg);
+ callback(EVP_des_ecb(), "DES-ECB", NULL, arg);
+ callback(EVP_des_ede(), "DES-EDE", NULL, arg);
+ callback(EVP_des_ede_cbc(), "DES-EDE-CBC", NULL, arg);
+ callback(EVP_des_ede3_cbc(), "DES-EDE3-CBC", NULL, arg);
+ callback(EVP_rc2_cbc(), "RC2-CBC", NULL, arg);
+ callback(EVP_rc4(), "RC4", NULL, arg);
+
+ /* OpenSSL returns everything twice, the second time in lower case. */
+ callback(EVP_aes_128_cbc(), "aes-128-cbc", NULL, arg);
+ callback(EVP_aes_128_ctr(), "aes-128-ctr", NULL, arg);
+ callback(EVP_aes_128_ecb(), "aes-128-ecb", NULL, arg);
+ callback(EVP_aes_128_ofb(), "aes-128-ofb", NULL, arg);
+ callback(EVP_aes_256_cbc(), "aes-256-cbc", NULL, arg);
+ callback(EVP_aes_256_ctr(), "aes-256-ctr", NULL, arg);
+ callback(EVP_aes_256_ecb(), "aes-256-ecb", NULL, arg);
+ callback(EVP_aes_256_ofb(), "aes-256-ofb", NULL, arg);
+ callback(EVP_aes_256_xts(), "aes-256-xts", NULL, arg);
+ callback(EVP_des_cbc(), "des-cbc", NULL, arg);
+ callback(EVP_des_ecb(), "des-ecb", NULL, arg);
+ callback(EVP_des_ede(), "des-ede", NULL, arg);
+ callback(EVP_des_ede_cbc(), "des-ede-cbc", NULL, arg);
+ callback(EVP_des_ede3_cbc(), "des-ede3-cbc", NULL, arg);
+ callback(EVP_rc2_cbc(), "rc2-cbc", NULL, arg);
+ callback(EVP_rc4(), "rc4", NULL, arg);
+}
+
+void EVP_MD_do_all_sorted(void (*callback)(const EVP_MD *cipher,
+ const char *name, const char *unused,
+ void *arg),
+ void *arg) {
+ callback(EVP_md4(), "MD4", NULL, arg);
+ callback(EVP_md5(), "MD5", NULL, arg);
+ callback(EVP_sha1(), "SHA1", NULL, arg);
+ callback(EVP_sha224(), "SHA224", NULL, arg);
+ callback(EVP_sha256(), "SHA256", NULL, arg);
+ callback(EVP_sha384(), "SHA384", NULL, arg);
+ callback(EVP_sha512(), "SHA512", NULL, arg);
+
+ callback(EVP_md4(), "md4", NULL, arg);
+ callback(EVP_md5(), "md5", NULL, arg);
+ callback(EVP_sha1(), "sha1", NULL, arg);
+ callback(EVP_sha224(), "sha224", NULL, arg);
+ callback(EVP_sha256(), "sha256", NULL, arg);
+ callback(EVP_sha384(), "sha384", NULL, arg);
+ callback(EVP_sha512(), "sha512", NULL, arg);
+}
diff --git a/src/decrepit/obj/CMakeLists.txt b/src/decrepit/obj/CMakeLists.txt
new file mode 100644
index 00000000..caaecd32
--- /dev/null
+++ b/src/decrepit/obj/CMakeLists.txt
@@ -0,0 +1,9 @@
+include_directories(../../include)
+
+add_library(
+ obj_decrepit
+
+ OBJECT
+
+ obj_decrepit.c
+)
diff --git a/src/decrepit/obj/obj_decrepit.c b/src/decrepit/obj/obj_decrepit.c
new file mode 100644
index 00000000..06051f11
--- /dev/null
+++ b/src/decrepit/obj/obj_decrepit.c
@@ -0,0 +1,71 @@
+/* Copyright (c) 2016, 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/obj.h>
+
+#include <assert.h>
+#include <string.h>
+
+#include <openssl/evp.h>
+
+
+struct wrapped_callback {
+ void (*callback)(const OBJ_NAME *, void *arg);
+ void *arg;
+};
+
+static void cipher_callback(const EVP_CIPHER *cipher, const char *name,
+ const char *unused, void *arg) {
+ const struct wrapped_callback *wrapped = (struct wrapped_callback *)arg;
+ OBJ_NAME obj_name;
+
+ memset(&obj_name, 0, sizeof(obj_name));
+ obj_name.type = OBJ_NAME_TYPE_CIPHER_METH;
+ obj_name.name = name;
+
+ wrapped->callback(&obj_name, wrapped->arg);
+}
+
+static void md_callback(const EVP_MD *md, const char *name, const char *unused,
+ void *arg) {
+ const struct wrapped_callback *wrapped = (struct wrapped_callback*) arg;
+ OBJ_NAME obj_name;
+
+ memset(&obj_name, 0, sizeof(obj_name));
+ obj_name.type = OBJ_NAME_TYPE_MD_METH;
+ obj_name.name = name;
+
+ wrapped->callback(&obj_name, wrapped->arg);
+}
+
+void OBJ_NAME_do_all_sorted(int type,
+ void (*callback)(const OBJ_NAME *, void *arg),
+ void *arg) {
+ struct wrapped_callback wrapped;
+ wrapped.callback = callback;
+ wrapped.arg = arg;
+
+ if (type == OBJ_NAME_TYPE_CIPHER_METH) {
+ EVP_CIPHER_do_all_sorted(cipher_callback, &wrapped);
+ } else if (type == OBJ_NAME_TYPE_MD_METH) {
+ EVP_MD_do_all_sorted(md_callback, &wrapped);
+ } else {
+ assert(0);
+ }
+}
+
+void OBJ_NAME_do_all(int type, void (*callback)(const OBJ_NAME *, void *arg),
+ void *arg) {
+ OBJ_NAME_do_all_sorted(type, callback, arg);
+}
diff --git a/src/decrepit/rc4/CMakeLists.txt b/src/decrepit/rc4/CMakeLists.txt
new file mode 100644
index 00000000..459b24e2
--- /dev/null
+++ b/src/decrepit/rc4/CMakeLists.txt
@@ -0,0 +1,9 @@
+include_directories(../../include)
+
+add_library(
+ rc4_decrepit
+
+ OBJECT
+
+ rc4_decrepit.c
+)
diff --git a/src/crypto/dsa/internal.h b/src/decrepit/rc4/rc4_decrepit.c
index ef991585..140e15d6 100644
--- a/src/crypto/dsa/internal.h
+++ b/src/decrepit/rc4/rc4_decrepit.c
@@ -52,27 +52,11 @@
* 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>. */
-
-#ifndef OPENSSL_HEADER_DSA_INTERNAL_H
-#define OPENSSL_HEADER_DSA_INTERNAL_H
-
-#include <openssl/base.h>
-
-#include <openssl/bn.h>
-#include <openssl/ex_data.h>
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
+ * [including the GNU Public Licence.] */
+#include <openssl/rc4.h>
-#if defined(__cplusplus)
-} /* extern C */
-#endif
-#endif /* OPENSSL_HEADER_DSA_INTERNAL_H */
+const char *RC4_options(void) {
+ return "rc4(ptr,int)";
+}
diff --git a/src/decrepit/ripemd/CMakeLists.txt b/src/decrepit/ripemd/CMakeLists.txt
new file mode 100644
index 00000000..0714a8f0
--- /dev/null
+++ b/src/decrepit/ripemd/CMakeLists.txt
@@ -0,0 +1,21 @@
+include_directories(../../include)
+
+add_library(
+ ripemd_decrepit
+
+ OBJECT
+
+ ripemd.c
+)
+
+add_executable(
+ ripemd_test
+
+ ripemd_test.cc
+
+ $<TARGET_OBJECTS:test_support>
+)
+
+target_link_libraries(ripemd_test crypto)
+target_link_libraries(ripemd_test decrepit)
+add_dependencies(all_tests ripemd_test)
diff --git a/src/decrepit/ripemd/internal.h b/src/decrepit/ripemd/internal.h
new file mode 100644
index 00000000..c4db4b23
--- /dev/null
+++ b/src/decrepit/ripemd/internal.h
@@ -0,0 +1,493 @@
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.] */
+
+#ifndef OPENSSL_HEADER_BN_INTERNAL_H
+#define OPENSSL_HEADER_BN_INTERNAL_H
+
+#include <openssl/base.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+static void ripemd160_block_data_order(uint32_t h[5], const uint8_t *data,
+ size_t num);
+
+#define DATA_ORDER_IS_LITTLE_ENDIAN
+
+#define HASH_LONG uint32_t
+#define HASH_CTX RIPEMD160_CTX
+#define HASH_CBLOCK RIPEMD160_CBLOCK
+#define HASH_UPDATE RIPEMD160_Update
+#define HASH_TRANSFORM RIPEMD160_Transform
+#define HASH_FINAL RIPEMD160_Final
+#define HASH_MAKE_STRING(c, s) \
+ do { \
+ unsigned long ll; \
+ ll = (c)->h[0]; \
+ (void)HOST_l2c(ll, (s)); \
+ ll = (c)->h[1]; \
+ (void)HOST_l2c(ll, (s)); \
+ ll = (c)->h[2]; \
+ (void)HOST_l2c(ll, (s)); \
+ ll = (c)->h[3]; \
+ (void)HOST_l2c(ll, (s)); \
+ ll = (c)->h[4]; \
+ (void)HOST_l2c(ll, (s)); \
+ } while (0)
+#define HASH_BLOCK_DATA_ORDER ripemd160_block_data_order
+
+#include "../../crypto/digest/md32_common.h"
+
+/* Transformed F2 and F4 are courtesy of Wei Dai <weidai@eskimo.com> */
+#define F1(x, y, z) ((x) ^ (y) ^ (z))
+#define F2(x, y, z) ((((y) ^ (z)) & (x)) ^ (z))
+#define F3(x, y, z) (((~(y)) | (x)) ^ (z))
+#define F4(x, y, z) ((((x) ^ (y)) & (z)) ^ (y))
+#define F5(x, y, z) (((~(z)) | (y)) ^ (x))
+
+#define RIPEMD160_A 0x67452301L
+#define RIPEMD160_B 0xEFCDAB89L
+#define RIPEMD160_C 0x98BADCFEL
+#define RIPEMD160_D 0x10325476L
+#define RIPEMD160_E 0xC3D2E1F0L
+
+#define ROTATE(a, n) (((a) << (n)) | (((a)&0xffffffff) >> (32 - (n))))
+
+#define RIP1(a, b, c, d, e, w, s) \
+ { \
+ a += F1(b, c, d) + X(w); \
+ a = ROTATE(a, s) + e; \
+ c = ROTATE(c, 10); \
+ }
+
+#define RIP2(a, b, c, d, e, w, s, K) \
+ { \
+ a += F2(b, c, d) + X(w) + K; \
+ a = ROTATE(a, s) + e; \
+ c = ROTATE(c, 10); \
+ }
+
+#define RIP3(a, b, c, d, e, w, s, K) \
+ { \
+ a += F3(b, c, d) + X(w) + K; \
+ a = ROTATE(a, s) + e; \
+ c = ROTATE(c, 10); \
+ }
+
+#define RIP4(a, b, c, d, e, w, s, K) \
+ { \
+ a += F4(b, c, d) + X(w) + K; \
+ a = ROTATE(a, s) + e; \
+ c = ROTATE(c, 10); \
+ }
+
+#define RIP5(a, b, c, d, e, w, s, K) \
+ { \
+ a += F5(b, c, d) + X(w) + K; \
+ a = ROTATE(a, s) + e; \
+ c = ROTATE(c, 10); \
+ }
+
+#define KL0 0x00000000L
+#define KL1 0x5A827999L
+#define KL2 0x6ED9EBA1L
+#define KL3 0x8F1BBCDCL
+#define KL4 0xA953FD4EL
+
+#define KR0 0x50A28BE6L
+#define KR1 0x5C4DD124L
+#define KR2 0x6D703EF3L
+#define KR3 0x7A6D76E9L
+#define KR4 0x00000000L
+
+#define WL00 0
+#define SL00 11
+#define WL01 1
+#define SL01 14
+#define WL02 2
+#define SL02 15
+#define WL03 3
+#define SL03 12
+#define WL04 4
+#define SL04 5
+#define WL05 5
+#define SL05 8
+#define WL06 6
+#define SL06 7
+#define WL07 7
+#define SL07 9
+#define WL08 8
+#define SL08 11
+#define WL09 9
+#define SL09 13
+#define WL10 10
+#define SL10 14
+#define WL11 11
+#define SL11 15
+#define WL12 12
+#define SL12 6
+#define WL13 13
+#define SL13 7
+#define WL14 14
+#define SL14 9
+#define WL15 15
+#define SL15 8
+
+#define WL16 7
+#define SL16 7
+#define WL17 4
+#define SL17 6
+#define WL18 13
+#define SL18 8
+#define WL19 1
+#define SL19 13
+#define WL20 10
+#define SL20 11
+#define WL21 6
+#define SL21 9
+#define WL22 15
+#define SL22 7
+#define WL23 3
+#define SL23 15
+#define WL24 12
+#define SL24 7
+#define WL25 0
+#define SL25 12
+#define WL26 9
+#define SL26 15
+#define WL27 5
+#define SL27 9
+#define WL28 2
+#define SL28 11
+#define WL29 14
+#define SL29 7
+#define WL30 11
+#define SL30 13
+#define WL31 8
+#define SL31 12
+
+#define WL32 3
+#define SL32 11
+#define WL33 10
+#define SL33 13
+#define WL34 14
+#define SL34 6
+#define WL35 4
+#define SL35 7
+#define WL36 9
+#define SL36 14
+#define WL37 15
+#define SL37 9
+#define WL38 8
+#define SL38 13
+#define WL39 1
+#define SL39 15
+#define WL40 2
+#define SL40 14
+#define WL41 7
+#define SL41 8
+#define WL42 0
+#define SL42 13
+#define WL43 6
+#define SL43 6
+#define WL44 13
+#define SL44 5
+#define WL45 11
+#define SL45 12
+#define WL46 5
+#define SL46 7
+#define WL47 12
+#define SL47 5
+
+#define WL48 1
+#define SL48 11
+#define WL49 9
+#define SL49 12
+#define WL50 11
+#define SL50 14
+#define WL51 10
+#define SL51 15
+#define WL52 0
+#define SL52 14
+#define WL53 8
+#define SL53 15
+#define WL54 12
+#define SL54 9
+#define WL55 4
+#define SL55 8
+#define WL56 13
+#define SL56 9
+#define WL57 3
+#define SL57 14
+#define WL58 7
+#define SL58 5
+#define WL59 15
+#define SL59 6
+#define WL60 14
+#define SL60 8
+#define WL61 5
+#define SL61 6
+#define WL62 6
+#define SL62 5
+#define WL63 2
+#define SL63 12
+
+#define WL64 4
+#define SL64 9
+#define WL65 0
+#define SL65 15
+#define WL66 5
+#define SL66 5
+#define WL67 9
+#define SL67 11
+#define WL68 7
+#define SL68 6
+#define WL69 12
+#define SL69 8
+#define WL70 2
+#define SL70 13
+#define WL71 10
+#define SL71 12
+#define WL72 14
+#define SL72 5
+#define WL73 1
+#define SL73 12
+#define WL74 3
+#define SL74 13
+#define WL75 8
+#define SL75 14
+#define WL76 11
+#define SL76 11
+#define WL77 6
+#define SL77 8
+#define WL78 15
+#define SL78 5
+#define WL79 13
+#define SL79 6
+
+#define WR00 5
+#define SR00 8
+#define WR01 14
+#define SR01 9
+#define WR02 7
+#define SR02 9
+#define WR03 0
+#define SR03 11
+#define WR04 9
+#define SR04 13
+#define WR05 2
+#define SR05 15
+#define WR06 11
+#define SR06 15
+#define WR07 4
+#define SR07 5
+#define WR08 13
+#define SR08 7
+#define WR09 6
+#define SR09 7
+#define WR10 15
+#define SR10 8
+#define WR11 8
+#define SR11 11
+#define WR12 1
+#define SR12 14
+#define WR13 10
+#define SR13 14
+#define WR14 3
+#define SR14 12
+#define WR15 12
+#define SR15 6
+
+#define WR16 6
+#define SR16 9
+#define WR17 11
+#define SR17 13
+#define WR18 3
+#define SR18 15
+#define WR19 7
+#define SR19 7
+#define WR20 0
+#define SR20 12
+#define WR21 13
+#define SR21 8
+#define WR22 5
+#define SR22 9
+#define WR23 10
+#define SR23 11
+#define WR24 14
+#define SR24 7
+#define WR25 15
+#define SR25 7
+#define WR26 8
+#define SR26 12
+#define WR27 12
+#define SR27 7
+#define WR28 4
+#define SR28 6
+#define WR29 9
+#define SR29 15
+#define WR30 1
+#define SR30 13
+#define WR31 2
+#define SR31 11
+
+#define WR32 15
+#define SR32 9
+#define WR33 5
+#define SR33 7
+#define WR34 1
+#define SR34 15
+#define WR35 3
+#define SR35 11
+#define WR36 7
+#define SR36 8
+#define WR37 14
+#define SR37 6
+#define WR38 6
+#define SR38 6
+#define WR39 9
+#define SR39 14
+#define WR40 11
+#define SR40 12
+#define WR41 8
+#define SR41 13
+#define WR42 12
+#define SR42 5
+#define WR43 2
+#define SR43 14
+#define WR44 10
+#define SR44 13
+#define WR45 0
+#define SR45 13
+#define WR46 4
+#define SR46 7
+#define WR47 13
+#define SR47 5
+
+#define WR48 8
+#define SR48 15
+#define WR49 6
+#define SR49 5
+#define WR50 4
+#define SR50 8
+#define WR51 1
+#define SR51 11
+#define WR52 3
+#define SR52 14
+#define WR53 11
+#define SR53 14
+#define WR54 15
+#define SR54 6
+#define WR55 0
+#define SR55 14
+#define WR56 5
+#define SR56 6
+#define WR57 12
+#define SR57 9
+#define WR58 2
+#define SR58 12
+#define WR59 13
+#define SR59 9
+#define WR60 9
+#define SR60 12
+#define WR61 7
+#define SR61 5
+#define WR62 10
+#define SR62 15
+#define WR63 14
+#define SR63 8
+
+#define WR64 12
+#define SR64 8
+#define WR65 15
+#define SR65 5
+#define WR66 10
+#define SR66 12
+#define WR67 4
+#define SR67 9
+#define WR68 1
+#define SR68 12
+#define WR69 5
+#define SR69 5
+#define WR70 8
+#define SR70 14
+#define WR71 7
+#define SR71 6
+#define WR72 6
+#define SR72 8
+#define WR73 2
+#define SR73 13
+#define WR74 13
+#define SR74 6
+#define WR75 14
+#define SR75 5
+#define WR76 0
+#define SR76 15
+#define WR77 3
+#define SR77 13
+#define WR78 9
+#define SR78 11
+#define WR79 11
+#define SR79 11
+
+
+#if defined(__cplusplus)
+} /* extern C */
+#endif
+
+#endif /* OPENSSL_HEADER_BN_INTERNAL_H */
diff --git a/src/decrepit/ripemd/ripemd.c b/src/decrepit/ripemd/ripemd.c
new file mode 100644
index 00000000..6ed7816c
--- /dev/null
+++ b/src/decrepit/ripemd/ripemd.c
@@ -0,0 +1,324 @@
+/* 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/ripemd.h>
+
+#include <string.h>
+
+#include "internal.h"
+
+
+int RIPEMD160_Init(RIPEMD160_CTX *ctx) {
+ memset(ctx, 0, sizeof(*ctx));
+ ctx->h[0] = RIPEMD160_A;
+ ctx->h[1] = RIPEMD160_B;
+ ctx->h[2] = RIPEMD160_C;
+ ctx->h[3] = RIPEMD160_D;
+ ctx->h[4] = RIPEMD160_E;
+ return 1;
+}
+
+static void ripemd160_block_data_order(uint32_t h[5], const uint8_t *data,
+ size_t num) {
+ uint32_t A, B, C, D, E;
+ uint32_t a, b, c, d, e, l;
+ uint32_t XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, XX8, XX9, XX10, XX11, XX12,
+ XX13, XX14, XX15;
+#define X(i) XX##i
+
+ for (; num--;) {
+ A = h[0];
+ B = h[1];
+ C = h[2];
+ D = h[3];
+ E = h[4];
+
+ (void)HOST_c2l(data, l);
+ X(0) = l;
+ (void)HOST_c2l(data, l);
+ X(1) = l;
+ RIP1(A, B, C, D, E, WL00, SL00);
+ (void)HOST_c2l(data, l);
+ X(2) = l;
+ RIP1(E, A, B, C, D, WL01, SL01);
+ (void)HOST_c2l(data, l);
+ X(3) = l;
+ RIP1(D, E, A, B, C, WL02, SL02);
+ (void)HOST_c2l(data, l);
+ X(4) = l;
+ RIP1(C, D, E, A, B, WL03, SL03);
+ (void)HOST_c2l(data, l);
+ X(5) = l;
+ RIP1(B, C, D, E, A, WL04, SL04);
+ (void)HOST_c2l(data, l);
+ X(6) = l;
+ RIP1(A, B, C, D, E, WL05, SL05);
+ (void)HOST_c2l(data, l);
+ X(7) = l;
+ RIP1(E, A, B, C, D, WL06, SL06);
+ (void)HOST_c2l(data, l);
+ X(8) = l;
+ RIP1(D, E, A, B, C, WL07, SL07);
+ (void)HOST_c2l(data, l);
+ X(9) = l;
+ RIP1(C, D, E, A, B, WL08, SL08);
+ (void)HOST_c2l(data, l);
+ X(10) = l;
+ RIP1(B, C, D, E, A, WL09, SL09);
+ (void)HOST_c2l(data, l);
+ X(11) = l;
+ RIP1(A, B, C, D, E, WL10, SL10);
+ (void)HOST_c2l(data, l);
+ X(12) = l;
+ RIP1(E, A, B, C, D, WL11, SL11);
+ (void)HOST_c2l(data, l);
+ X(13) = l;
+ RIP1(D, E, A, B, C, WL12, SL12);
+ (void)HOST_c2l(data, l);
+ X(14) = l;
+ RIP1(C, D, E, A, B, WL13, SL13);
+ (void)HOST_c2l(data, l);
+ X(15) = l;
+ RIP1(B, C, D, E, A, WL14, SL14);
+ RIP1(A, B, C, D, E, WL15, SL15);
+
+ RIP2(E, A, B, C, D, WL16, SL16, KL1);
+ RIP2(D, E, A, B, C, WL17, SL17, KL1);
+ RIP2(C, D, E, A, B, WL18, SL18, KL1);
+ RIP2(B, C, D, E, A, WL19, SL19, KL1);
+ RIP2(A, B, C, D, E, WL20, SL20, KL1);
+ RIP2(E, A, B, C, D, WL21, SL21, KL1);
+ RIP2(D, E, A, B, C, WL22, SL22, KL1);
+ RIP2(C, D, E, A, B, WL23, SL23, KL1);
+ RIP2(B, C, D, E, A, WL24, SL24, KL1);
+ RIP2(A, B, C, D, E, WL25, SL25, KL1);
+ RIP2(E, A, B, C, D, WL26, SL26, KL1);
+ RIP2(D, E, A, B, C, WL27, SL27, KL1);
+ RIP2(C, D, E, A, B, WL28, SL28, KL1);
+ RIP2(B, C, D, E, A, WL29, SL29, KL1);
+ RIP2(A, B, C, D, E, WL30, SL30, KL1);
+ RIP2(E, A, B, C, D, WL31, SL31, KL1);
+
+ RIP3(D, E, A, B, C, WL32, SL32, KL2);
+ RIP3(C, D, E, A, B, WL33, SL33, KL2);
+ RIP3(B, C, D, E, A, WL34, SL34, KL2);
+ RIP3(A, B, C, D, E, WL35, SL35, KL2);
+ RIP3(E, A, B, C, D, WL36, SL36, KL2);
+ RIP3(D, E, A, B, C, WL37, SL37, KL2);
+ RIP3(C, D, E, A, B, WL38, SL38, KL2);
+ RIP3(B, C, D, E, A, WL39, SL39, KL2);
+ RIP3(A, B, C, D, E, WL40, SL40, KL2);
+ RIP3(E, A, B, C, D, WL41, SL41, KL2);
+ RIP3(D, E, A, B, C, WL42, SL42, KL2);
+ RIP3(C, D, E, A, B, WL43, SL43, KL2);
+ RIP3(B, C, D, E, A, WL44, SL44, KL2);
+ RIP3(A, B, C, D, E, WL45, SL45, KL2);
+ RIP3(E, A, B, C, D, WL46, SL46, KL2);
+ RIP3(D, E, A, B, C, WL47, SL47, KL2);
+
+ RIP4(C, D, E, A, B, WL48, SL48, KL3);
+ RIP4(B, C, D, E, A, WL49, SL49, KL3);
+ RIP4(A, B, C, D, E, WL50, SL50, KL3);
+ RIP4(E, A, B, C, D, WL51, SL51, KL3);
+ RIP4(D, E, A, B, C, WL52, SL52, KL3);
+ RIP4(C, D, E, A, B, WL53, SL53, KL3);
+ RIP4(B, C, D, E, A, WL54, SL54, KL3);
+ RIP4(A, B, C, D, E, WL55, SL55, KL3);
+ RIP4(E, A, B, C, D, WL56, SL56, KL3);
+ RIP4(D, E, A, B, C, WL57, SL57, KL3);
+ RIP4(C, D, E, A, B, WL58, SL58, KL3);
+ RIP4(B, C, D, E, A, WL59, SL59, KL3);
+ RIP4(A, B, C, D, E, WL60, SL60, KL3);
+ RIP4(E, A, B, C, D, WL61, SL61, KL3);
+ RIP4(D, E, A, B, C, WL62, SL62, KL3);
+ RIP4(C, D, E, A, B, WL63, SL63, KL3);
+
+ RIP5(B, C, D, E, A, WL64, SL64, KL4);
+ RIP5(A, B, C, D, E, WL65, SL65, KL4);
+ RIP5(E, A, B, C, D, WL66, SL66, KL4);
+ RIP5(D, E, A, B, C, WL67, SL67, KL4);
+ RIP5(C, D, E, A, B, WL68, SL68, KL4);
+ RIP5(B, C, D, E, A, WL69, SL69, KL4);
+ RIP5(A, B, C, D, E, WL70, SL70, KL4);
+ RIP5(E, A, B, C, D, WL71, SL71, KL4);
+ RIP5(D, E, A, B, C, WL72, SL72, KL4);
+ RIP5(C, D, E, A, B, WL73, SL73, KL4);
+ RIP5(B, C, D, E, A, WL74, SL74, KL4);
+ RIP5(A, B, C, D, E, WL75, SL75, KL4);
+ RIP5(E, A, B, C, D, WL76, SL76, KL4);
+ RIP5(D, E, A, B, C, WL77, SL77, KL4);
+ RIP5(C, D, E, A, B, WL78, SL78, KL4);
+ RIP5(B, C, D, E, A, WL79, SL79, KL4);
+
+ a = A;
+ b = B;
+ c = C;
+ d = D;
+ e = E;
+ /* Do other half */
+ A = h[0];
+ B = h[1];
+ C = h[2];
+ D = h[3];
+ E = h[4];
+
+ RIP5(A, B, C, D, E, WR00, SR00, KR0);
+ RIP5(E, A, B, C, D, WR01, SR01, KR0);
+ RIP5(D, E, A, B, C, WR02, SR02, KR0);
+ RIP5(C, D, E, A, B, WR03, SR03, KR0);
+ RIP5(B, C, D, E, A, WR04, SR04, KR0);
+ RIP5(A, B, C, D, E, WR05, SR05, KR0);
+ RIP5(E, A, B, C, D, WR06, SR06, KR0);
+ RIP5(D, E, A, B, C, WR07, SR07, KR0);
+ RIP5(C, D, E, A, B, WR08, SR08, KR0);
+ RIP5(B, C, D, E, A, WR09, SR09, KR0);
+ RIP5(A, B, C, D, E, WR10, SR10, KR0);
+ RIP5(E, A, B, C, D, WR11, SR11, KR0);
+ RIP5(D, E, A, B, C, WR12, SR12, KR0);
+ RIP5(C, D, E, A, B, WR13, SR13, KR0);
+ RIP5(B, C, D, E, A, WR14, SR14, KR0);
+ RIP5(A, B, C, D, E, WR15, SR15, KR0);
+
+ RIP4(E, A, B, C, D, WR16, SR16, KR1);
+ RIP4(D, E, A, B, C, WR17, SR17, KR1);
+ RIP4(C, D, E, A, B, WR18, SR18, KR1);
+ RIP4(B, C, D, E, A, WR19, SR19, KR1);
+ RIP4(A, B, C, D, E, WR20, SR20, KR1);
+ RIP4(E, A, B, C, D, WR21, SR21, KR1);
+ RIP4(D, E, A, B, C, WR22, SR22, KR1);
+ RIP4(C, D, E, A, B, WR23, SR23, KR1);
+ RIP4(B, C, D, E, A, WR24, SR24, KR1);
+ RIP4(A, B, C, D, E, WR25, SR25, KR1);
+ RIP4(E, A, B, C, D, WR26, SR26, KR1);
+ RIP4(D, E, A, B, C, WR27, SR27, KR1);
+ RIP4(C, D, E, A, B, WR28, SR28, KR1);
+ RIP4(B, C, D, E, A, WR29, SR29, KR1);
+ RIP4(A, B, C, D, E, WR30, SR30, KR1);
+ RIP4(E, A, B, C, D, WR31, SR31, KR1);
+
+ RIP3(D, E, A, B, C, WR32, SR32, KR2);
+ RIP3(C, D, E, A, B, WR33, SR33, KR2);
+ RIP3(B, C, D, E, A, WR34, SR34, KR2);
+ RIP3(A, B, C, D, E, WR35, SR35, KR2);
+ RIP3(E, A, B, C, D, WR36, SR36, KR2);
+ RIP3(D, E, A, B, C, WR37, SR37, KR2);
+ RIP3(C, D, E, A, B, WR38, SR38, KR2);
+ RIP3(B, C, D, E, A, WR39, SR39, KR2);
+ RIP3(A, B, C, D, E, WR40, SR40, KR2);
+ RIP3(E, A, B, C, D, WR41, SR41, KR2);
+ RIP3(D, E, A, B, C, WR42, SR42, KR2);
+ RIP3(C, D, E, A, B, WR43, SR43, KR2);
+ RIP3(B, C, D, E, A, WR44, SR44, KR2);
+ RIP3(A, B, C, D, E, WR45, SR45, KR2);
+ RIP3(E, A, B, C, D, WR46, SR46, KR2);
+ RIP3(D, E, A, B, C, WR47, SR47, KR2);
+
+ RIP2(C, D, E, A, B, WR48, SR48, KR3);
+ RIP2(B, C, D, E, A, WR49, SR49, KR3);
+ RIP2(A, B, C, D, E, WR50, SR50, KR3);
+ RIP2(E, A, B, C, D, WR51, SR51, KR3);
+ RIP2(D, E, A, B, C, WR52, SR52, KR3);
+ RIP2(C, D, E, A, B, WR53, SR53, KR3);
+ RIP2(B, C, D, E, A, WR54, SR54, KR3);
+ RIP2(A, B, C, D, E, WR55, SR55, KR3);
+ RIP2(E, A, B, C, D, WR56, SR56, KR3);
+ RIP2(D, E, A, B, C, WR57, SR57, KR3);
+ RIP2(C, D, E, A, B, WR58, SR58, KR3);
+ RIP2(B, C, D, E, A, WR59, SR59, KR3);
+ RIP2(A, B, C, D, E, WR60, SR60, KR3);
+ RIP2(E, A, B, C, D, WR61, SR61, KR3);
+ RIP2(D, E, A, B, C, WR62, SR62, KR3);
+ RIP2(C, D, E, A, B, WR63, SR63, KR3);
+
+ RIP1(B, C, D, E, A, WR64, SR64);
+ RIP1(A, B, C, D, E, WR65, SR65);
+ RIP1(E, A, B, C, D, WR66, SR66);
+ RIP1(D, E, A, B, C, WR67, SR67);
+ RIP1(C, D, E, A, B, WR68, SR68);
+ RIP1(B, C, D, E, A, WR69, SR69);
+ RIP1(A, B, C, D, E, WR70, SR70);
+ RIP1(E, A, B, C, D, WR71, SR71);
+ RIP1(D, E, A, B, C, WR72, SR72);
+ RIP1(C, D, E, A, B, WR73, SR73);
+ RIP1(B, C, D, E, A, WR74, SR74);
+ RIP1(A, B, C, D, E, WR75, SR75);
+ RIP1(E, A, B, C, D, WR76, SR76);
+ RIP1(D, E, A, B, C, WR77, SR77);
+ RIP1(C, D, E, A, B, WR78, SR78);
+ RIP1(B, C, D, E, A, WR79, SR79);
+
+ D = h[1] + c + D;
+ h[1] = h[2] + d + E;
+ h[2] = h[3] + e + A;
+ h[3] = h[4] + a + B;
+ h[4] = h[0] + b + C;
+ h[0] = D;
+ }
+
+#undef X
+}
+
+uint8_t *RIPEMD160(const uint8_t *data, size_t len, unsigned char *out) {
+ RIPEMD160_CTX ctx;
+
+ if (!RIPEMD160_Init(&ctx)) {
+ return NULL;
+ }
+
+ RIPEMD160_Update(&ctx, data, len);
+ RIPEMD160_Final(out, &ctx);
+ return out;
+}
diff --git a/src/decrepit/ripemd/ripemd_test.cc b/src/decrepit/ripemd/ripemd_test.cc
new file mode 100644
index 00000000..ebcabdfb
--- /dev/null
+++ b/src/decrepit/ripemd/ripemd_test.cc
@@ -0,0 +1,119 @@
+/* Copyright (c) 2016, 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/ripemd.h>
+
+#include <memory>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "../../crypto/test/test_util.h"
+
+
+struct RIPEMDTestCase {
+ const char *input;
+ uint8_t expected[RIPEMD160_DIGEST_LENGTH];
+};
+
+static const RIPEMDTestCase kRIPEMDTestCases[] = {
+ {"", {0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
+ 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31}},
+ {"a", {0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
+ 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe}},
+ {"abc", {0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
+ 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc}},
+ {"message digest",
+ {0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
+ 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36}},
+ {"abcdefghijklmnopqrstuvwxyz",
+ {0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
+ 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc}},
+ {"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ {0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
+ 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b}},
+ {"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+ {0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
+ 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89}},
+ {"1234567890123456789012345678901234567890123456789012345678901234567890123"
+ "4567890",
+ {0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
+ 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb}},
+};
+
+int main(void) {
+ unsigned test_num = 0;
+ int ok = 1;
+
+ for (const auto &test : kRIPEMDTestCases) {
+ test_num++;
+
+ const size_t input_len = strlen(test.input);
+
+ for (size_t stride = 0; stride <= input_len; stride++) {
+ uint8_t digest[RIPEMD160_DIGEST_LENGTH];
+
+ if (stride == 0) {
+ RIPEMD160(reinterpret_cast<const uint8_t *>(test.input), input_len,
+ digest);
+ } else {
+ RIPEMD160_CTX ctx;
+ RIPEMD160_Init(&ctx);
+
+ for (size_t done = 0; done < input_len;) {
+ const size_t remaining = input_len - done;
+ size_t todo = stride;
+ if (todo > remaining) {
+ todo = remaining;
+ }
+
+ RIPEMD160_Update(&ctx, &test.input[done], todo);
+ done += todo;
+ }
+
+ RIPEMD160_Final(digest, &ctx);
+ }
+
+ if (memcmp(digest, test.expected, sizeof(digest)) != 0) {
+ fprintf(stderr, "#%u: bad result with stride %u: ", test_num,
+ static_cast<unsigned>(stride));
+ hexdump(stderr, "", digest, sizeof(digest));
+ ok = 0;
+ }
+ }
+ }
+
+ static const size_t kLargeBufSize = 1000000;
+ std::unique_ptr<uint8_t[]> buf(new uint8_t[kLargeBufSize]);
+ memset(buf.get(), 'a', kLargeBufSize);
+ uint8_t digest[RIPEMD160_DIGEST_LENGTH];
+ RIPEMD160(buf.get(), kLargeBufSize, digest);
+
+ static const uint8_t kMillionADigest[RIPEMD160_DIGEST_LENGTH] = {
+ 0x52, 0x78, 0x32, 0x43, 0xc1, 0x69, 0x7b, 0xdb, 0xe1, 0x6d,
+ 0x37, 0xf9, 0x7f, 0x68, 0xf0, 0x83, 0x25, 0xdc, 0x15, 0x28};
+
+ if (memcmp(digest, kMillionADigest, sizeof(digest)) != 0) {
+ fprintf(stderr, "Digest incorrect for “million a's” test: ");
+ hexdump(stderr, "", digest, sizeof(digest));
+ ok = 0;
+ }
+
+ if (!ok) {
+ return 1;
+ }
+
+ printf("PASS\n");
+ return 0;
+}
diff --git a/src/decrepit/rsa/rsa_decrepit.c b/src/decrepit/rsa/rsa_decrepit.c
index c238f468..0d7c5f66 100644
--- a/src/decrepit/rsa/rsa_decrepit.c
+++ b/src/decrepit/rsa/rsa_decrepit.c
@@ -84,3 +84,20 @@ err:
RSA_free(rsa);
return NULL;
}
+
+int RSA_padding_add_PKCS1_PSS(RSA *rsa, uint8_t *EM, const uint8_t *mHash,
+ const EVP_MD *Hash, int sLen) {
+ return RSA_padding_add_PKCS1_PSS_mgf1(rsa, EM, mHash, Hash, NULL, sLen);
+}
+
+int RSA_verify_PKCS1_PSS(RSA *rsa, const uint8_t *mHash, const EVP_MD *Hash,
+ const uint8_t *EM, int sLen) {
+ return RSA_verify_PKCS1_PSS_mgf1(rsa, mHash, Hash, NULL, EM, sLen);
+}
+
+int RSA_padding_add_PKCS1_OAEP(uint8_t *to, unsigned to_len,
+ const uint8_t *from, unsigned from_len,
+ const uint8_t *param, unsigned param_len) {
+ return RSA_padding_add_PKCS1_OAEP_mgf1(to, to_len, from, from_len, param,
+ param_len, NULL, NULL);
+}
diff --git a/src/decrepit/ssl/CMakeLists.txt b/src/decrepit/ssl/CMakeLists.txt
new file mode 100644
index 00000000..fba0234d
--- /dev/null
+++ b/src/decrepit/ssl/CMakeLists.txt
@@ -0,0 +1,9 @@
+include_directories(../../include)
+
+add_library(
+ ssl_decrepit
+
+ OBJECT
+
+ ssl_decrepit.c
+)
diff --git a/src/decrepit/ssl/ssl_decrepit.c b/src/decrepit/ssl/ssl_decrepit.c
new file mode 100644
index 00000000..e25cbf31
--- /dev/null
+++ b/src/decrepit/ssl/ssl_decrepit.c
@@ -0,0 +1,225 @@
+/* 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>
+
+#if !defined(OPENSSL_WINDOWS) && !defined(OPENSSL_PNACL)
+
+#include <dirent.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/err.h>
+#include <openssl/mem.h>
+
+
+typedef struct {
+ DIR *dir;
+ struct dirent dirent;
+} OPENSSL_DIR_CTX;
+
+static const char *OPENSSL_DIR_read(OPENSSL_DIR_CTX **ctx,
+ const char *directory) {
+ struct dirent *dirent;
+
+ if (ctx == NULL || directory == NULL) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ errno = 0;
+ if (*ctx == NULL) {
+ *ctx = malloc(sizeof(OPENSSL_DIR_CTX));
+ if (*ctx == NULL) {
+ errno = ENOMEM;
+ return 0;
+ }
+ memset(*ctx, 0, sizeof(OPENSSL_DIR_CTX));
+
+ (*ctx)->dir = opendir(directory);
+ if ((*ctx)->dir == NULL) {
+ int save_errno = errno; /* Probably not needed, but I'm paranoid */
+ free(*ctx);
+ *ctx = NULL;
+ errno = save_errno;
+ return 0;
+ }
+ }
+
+ if (readdir_r((*ctx)->dir, &(*ctx)->dirent, &dirent) != 0 ||
+ dirent == NULL) {
+ return 0;
+ }
+
+ return (*ctx)->dirent.d_name;
+}
+
+static int OPENSSL_DIR_end(OPENSSL_DIR_CTX **ctx) {
+ if (ctx != NULL && *ctx != NULL) {
+ int r = closedir((*ctx)->dir);
+ free(*ctx);
+ *ctx = NULL;
+ return r == 0;
+ }
+
+ errno = EINVAL;
+ return 0;
+}
+
+
+/* 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;
+}
+
+#endif /* !WINDOWS && !PNACL */
diff --git a/src/decrepit/x509/CMakeLists.txt b/src/decrepit/x509/CMakeLists.txt
new file mode 100644
index 00000000..930912d1
--- /dev/null
+++ b/src/decrepit/x509/CMakeLists.txt
@@ -0,0 +1,9 @@
+include_directories(../../include)
+
+add_library(
+ x509_decrepit
+
+ OBJECT
+
+ x509_decrepit.c
+)
diff --git a/src/decrepit/x509/x509_decrepit.c b/src/decrepit/x509/x509_decrepit.c
new file mode 100644
index 00000000..5714b40a
--- /dev/null
+++ b/src/decrepit/x509/x509_decrepit.c
@@ -0,0 +1,42 @@
+/* Copyright (c) 2016, 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/conf.h>
+#include <openssl/x509v3.h>
+
+
+X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf,
+ X509V3_CTX *ctx, int ext_nid, char *value) {
+ CONF *nconf = NULL;
+ LHASH_OF(CONF_VALUE) *orig_data = NULL;
+
+ if (conf != NULL) {
+ nconf = NCONF_new(NULL /* no method */);
+ if (nconf == NULL) {
+ return NULL;
+ }
+
+ orig_data = nconf->data;
+ nconf->data = conf;
+ }
+
+ X509_EXTENSION *ret = X509V3_EXT_nconf_nid(nconf, ctx, ext_nid, value);
+
+ if (nconf != NULL) {
+ nconf->data = orig_data;
+ NCONF_free(nconf);
+ }
+
+ return ret;
+}
diff --git a/src/include/openssl/aead.h b/src/include/openssl/aead.h
index 092d2f62..d9a640c3 100644
--- a/src/include/openssl/aead.h
+++ b/src/include/openssl/aead.h
@@ -135,49 +135,6 @@ OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_ctr_hmac_sha256(void);
OPENSSL_EXPORT int EVP_has_aes_hardware(void);
-/* TLS-specific AEAD algorithms.
- *
- * These AEAD primitives do not meet the definition of generic AEADs. They are
- * all specific to TLS and should not be used outside of that context. They must
- * be initialized with |EVP_AEAD_CTX_init_with_direction|, are stateful, and may
- * not be used concurrently. Any nonces are used as IVs, so they must be
- * unpredictable. They only accept an |ad| parameter of length 11 (the standard
- * TLS one with length omitted). */
-
-OPENSSL_EXPORT const EVP_AEAD *EVP_aead_rc4_md5_tls(void);
-OPENSSL_EXPORT const EVP_AEAD *EVP_aead_rc4_sha1_tls(void);
-
-OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_tls(void);
-OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_tls_implicit_iv(void);
-OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_cbc_sha256_tls(void);
-
-OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_tls(void);
-OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_tls_implicit_iv(void);
-OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_cbc_sha256_tls(void);
-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.
- *
- * These AEAD primitives do not meet the definition of generic AEADs. They are
- * all specific to SSLv3 and should not be used outside of that context. They
- * must be initialized with |EVP_AEAD_CTX_init_with_direction|, are stateful,
- * and may not be used concurrently. They only accept an |ad| parameter of
- * length 9 (the standard TLS one with length and version omitted). */
-
-OPENSSL_EXPORT const EVP_AEAD *EVP_aead_rc4_md5_ssl3(void);
-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. */
/* EVP_AEAD_key_length returns the length, in bytes, of the keys used by
@@ -226,12 +183,6 @@ typedef struct evp_aead_ctx_st {
* be used. */
#define EVP_AEAD_DEFAULT_TAG_LENGTH 0
-/* evp_aead_direction_t denotes the direction of an AEAD operation. */
-enum evp_aead_direction_t {
- evp_aead_open,
- evp_aead_seal,
-};
-
/* 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
@@ -251,13 +202,6 @@ OPENSSL_EXPORT 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);
-/* EVP_AEAD_CTX_init_with_direction calls |EVP_AEAD_CTX_init| for normal
- * AEADs. For TLS-specific and SSL3-specific AEADs, it initializes |ctx| for a
- * given direction. */
-OPENSSL_EXPORT int EVP_AEAD_CTX_init_with_direction(
- EVP_AEAD_CTX *ctx, const EVP_AEAD *aead, const uint8_t *key, size_t key_len,
- size_t tag_len, enum evp_aead_direction_t dir);
-
/* EVP_AEAD_CTX_cleanup frees any data allocated by |ctx|. It is a no-op to
* call |EVP_AEAD_CTX_cleanup| on a |EVP_AEAD_CTX| that has been |memset| to
* all zeros. */
@@ -315,8 +259,64 @@ OPENSSL_EXPORT int EVP_AEAD_CTX_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
const uint8_t *ad, size_t ad_len);
+/* TLS-specific AEAD algorithms.
+ *
+ * These AEAD primitives do not meet the definition of generic AEADs. They are
+ * all specific to TLS and should not be used outside of that context. They must
+ * be initialized with |EVP_AEAD_CTX_init_with_direction|, are stateful, and may
+ * not be used concurrently. Any nonces are used as IVs, so they must be
+ * unpredictable. They only accept an |ad| parameter of length 11 (the standard
+ * TLS one with length omitted). */
+
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_rc4_md5_tls(void);
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_rc4_sha1_tls(void);
+
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_tls(void);
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_tls_implicit_iv(void);
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_cbc_sha256_tls(void);
+
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_tls(void);
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_tls_implicit_iv(void);
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_cbc_sha256_tls(void);
+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.
+ *
+ * These AEAD primitives do not meet the definition of generic AEADs. They are
+ * all specific to SSLv3 and should not be used outside of that context. They
+ * must be initialized with |EVP_AEAD_CTX_init_with_direction|, are stateful,
+ * and may not be used concurrently. They only accept an |ad| parameter of
+ * length 9 (the standard TLS one with length and version omitted). */
+
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_rc4_md5_ssl3(void);
+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);
+
+
/* Obscure functions. */
+/* evp_aead_direction_t denotes the direction of an AEAD operation. */
+enum evp_aead_direction_t {
+ evp_aead_open,
+ evp_aead_seal,
+};
+
+/* EVP_AEAD_CTX_init_with_direction calls |EVP_AEAD_CTX_init| for normal
+ * AEADs. For TLS-specific and SSL3-specific AEADs, it initializes |ctx| for a
+ * given direction. */
+OPENSSL_EXPORT int EVP_AEAD_CTX_init_with_direction(
+ EVP_AEAD_CTX *ctx, const EVP_AEAD *aead, const uint8_t *key, size_t key_len,
+ size_t tag_len, enum evp_aead_direction_t dir);
+
/* EVP_AEAD_CTX_get_rc4_state sets |*out_key| to point to an RC4 key structure.
* It returns one on success or zero if |ctx| doesn't have an RC4 key. */
OPENSSL_EXPORT int EVP_AEAD_CTX_get_rc4_state(const EVP_AEAD_CTX *ctx,
@@ -331,14 +331,6 @@ OPENSSL_EXPORT int EVP_AEAD_CTX_get_iv(const EVP_AEAD_CTX *ctx,
const uint8_t **out_iv, size_t *out_len);
-/* Deprecated functions. */
-
-/* EVP_aead_chacha20_poly1305_rfc7539 calls |EVP_aead_chacha20_poly1305|.
- *
- * TODO(davidben): Remove this. */
-OPENSSL_EXPORT const EVP_AEAD *EVP_aead_chacha20_poly1305_rfc7539(void);
-
-
#if defined(__cplusplus)
} /* extern C */
#endif
diff --git a/src/include/openssl/arm_arch.h b/src/include/openssl/arm_arch.h
index 1471db90..e7010f40 100644
--- a/src/include/openssl/arm_arch.h
+++ b/src/include/openssl/arm_arch.h
@@ -105,12 +105,6 @@
/* ARMV7_NEON is true when a NEON unit is present in the current CPU. */
#define ARMV7_NEON (1 << 0)
-/* ARMV7_NEON_FUNCTIONAL is true when the NEON unit doesn't contain subtle bugs.
- * The Poly1305 NEON code is known to trigger bugs in the NEON units of some
- * phones. If this bit isn't set then the Poly1305 NEON code won't be used.
- * See https://code.google.com/p/chromium/issues/detail?id=341598. */
-#define ARMV7_NEON_FUNCTIONAL (1 << 10)
-
/* ARMV8_AES indicates support for hardware AES instructions. */
#define ARMV8_AES (1 << 2)
diff --git a/src/include/openssl/asn1.h b/src/include/openssl/asn1.h
index 63bde181..22b62820 100644
--- a/src/include/openssl/asn1.h
+++ b/src/include/openssl/asn1.h
@@ -85,6 +85,9 @@ extern "C" {
#define V_ASN1_ANY -4 /* used in ASN1 template code */
#define V_ASN1_NEG 0x100 /* negative flag */
+/* No supported universal tags may exceed this value, to avoid ambiguity with
+ * V_ASN1_NEG. */
+#define V_ASN1_MAX_UNIVERSAL 0xff
#define V_ASN1_UNDEF -1
#define V_ASN1_EOC 0
@@ -966,7 +969,6 @@ OPENSSL_EXPORT int ASN1_GENERALIZEDTIME_print(BIO *fp, const ASN1_GENERALIZEDTIM
OPENSSL_EXPORT int ASN1_TIME_print(BIO *fp, const ASN1_TIME *a);
OPENSSL_EXPORT int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v);
OPENSSL_EXPORT int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags);
-OPENSSL_EXPORT int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num, unsigned char *buf, int off);
OPENSSL_EXPORT int ASN1_parse(BIO *bp,const unsigned char *pp,long len,int indent);
OPENSSL_EXPORT int ASN1_parse_dump(BIO *bp,const unsigned char *pp,long len,int indent,int dump);
OPENSSL_EXPORT const char *ASN1_tag2str(int tag);
@@ -1084,84 +1086,89 @@ OPENSSL_EXPORT int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix, asn1_ps_f
#define ASN1_R_BN_LIB 105
#define ASN1_R_BOOLEAN_IS_WRONG_LENGTH 106
#define ASN1_R_BUFFER_TOO_SMALL 107
-#define ASN1_R_DECODE_ERROR 108
-#define ASN1_R_DEPTH_EXCEEDED 109
-#define ASN1_R_ENCODE_ERROR 110
-#define ASN1_R_ERROR_GETTING_TIME 111
-#define ASN1_R_EXPECTING_AN_ASN1_SEQUENCE 112
-#define ASN1_R_EXPECTING_AN_INTEGER 113
-#define ASN1_R_EXPECTING_AN_OBJECT 114
-#define ASN1_R_EXPECTING_A_BOOLEAN 115
-#define ASN1_R_EXPECTING_A_TIME 116
-#define ASN1_R_EXPLICIT_LENGTH_MISMATCH 117
-#define ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED 118
-#define ASN1_R_FIELD_MISSING 119
-#define ASN1_R_FIRST_NUM_TOO_LARGE 120
-#define ASN1_R_HEADER_TOO_LONG 121
-#define ASN1_R_ILLEGAL_BITSTRING_FORMAT 122
-#define ASN1_R_ILLEGAL_BOOLEAN 123
-#define ASN1_R_ILLEGAL_CHARACTERS 124
-#define ASN1_R_ILLEGAL_FORMAT 125
-#define ASN1_R_ILLEGAL_HEX 126
-#define ASN1_R_ILLEGAL_IMPLICIT_TAG 127
-#define ASN1_R_ILLEGAL_INTEGER 128
-#define ASN1_R_ILLEGAL_NESTED_TAGGING 129
-#define ASN1_R_ILLEGAL_NULL 130
-#define ASN1_R_ILLEGAL_NULL_VALUE 131
-#define ASN1_R_ILLEGAL_OBJECT 132
-#define ASN1_R_ILLEGAL_OPTIONAL_ANY 133
-#define ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE 134
-#define ASN1_R_ILLEGAL_TAGGED_ANY 135
-#define ASN1_R_ILLEGAL_TIME_VALUE 136
-#define ASN1_R_INTEGER_NOT_ASCII_FORMAT 137
-#define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG 138
-#define ASN1_R_INVALID_BIT_STRING_BITS_LEFT 139
-#define ASN1_R_INVALID_BMPSTRING_LENGTH 140
-#define ASN1_R_INVALID_DIGIT 141
-#define ASN1_R_INVALID_MODIFIER 142
-#define ASN1_R_INVALID_NUMBER 143
-#define ASN1_R_INVALID_OBJECT_ENCODING 144
-#define ASN1_R_INVALID_SEPARATOR 145
-#define ASN1_R_INVALID_TIME_FORMAT 146
-#define ASN1_R_INVALID_UNIVERSALSTRING_LENGTH 147
-#define ASN1_R_INVALID_UTF8STRING 148
-#define ASN1_R_LIST_ERROR 149
-#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
+#define ASN1_R_CONTEXT_NOT_INITIALISED 108
+#define ASN1_R_DECODE_ERROR 109
+#define ASN1_R_DEPTH_EXCEEDED 110
+#define ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED 111
+#define ASN1_R_ENCODE_ERROR 112
+#define ASN1_R_ERROR_GETTING_TIME 113
+#define ASN1_R_EXPECTING_AN_ASN1_SEQUENCE 114
+#define ASN1_R_EXPECTING_AN_INTEGER 115
+#define ASN1_R_EXPECTING_AN_OBJECT 116
+#define ASN1_R_EXPECTING_A_BOOLEAN 117
+#define ASN1_R_EXPECTING_A_TIME 118
+#define ASN1_R_EXPLICIT_LENGTH_MISMATCH 119
+#define ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED 120
+#define ASN1_R_FIELD_MISSING 121
+#define ASN1_R_FIRST_NUM_TOO_LARGE 122
+#define ASN1_R_HEADER_TOO_LONG 123
+#define ASN1_R_ILLEGAL_BITSTRING_FORMAT 124
+#define ASN1_R_ILLEGAL_BOOLEAN 125
+#define ASN1_R_ILLEGAL_CHARACTERS 126
+#define ASN1_R_ILLEGAL_FORMAT 127
+#define ASN1_R_ILLEGAL_HEX 128
+#define ASN1_R_ILLEGAL_IMPLICIT_TAG 129
+#define ASN1_R_ILLEGAL_INTEGER 130
+#define ASN1_R_ILLEGAL_NESTED_TAGGING 131
+#define ASN1_R_ILLEGAL_NULL 132
+#define ASN1_R_ILLEGAL_NULL_VALUE 133
+#define ASN1_R_ILLEGAL_OBJECT 134
+#define ASN1_R_ILLEGAL_OPTIONAL_ANY 135
+#define ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE 136
+#define ASN1_R_ILLEGAL_TAGGED_ANY 137
+#define ASN1_R_ILLEGAL_TIME_VALUE 138
+#define ASN1_R_INTEGER_NOT_ASCII_FORMAT 139
+#define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG 140
+#define ASN1_R_INVALID_BIT_STRING_BITS_LEFT 141
+#define ASN1_R_INVALID_BMPSTRING_LENGTH 142
+#define ASN1_R_INVALID_DIGIT 143
+#define ASN1_R_INVALID_MODIFIER 144
+#define ASN1_R_INVALID_NUMBER 145
+#define ASN1_R_INVALID_OBJECT_ENCODING 146
+#define ASN1_R_INVALID_SEPARATOR 147
+#define ASN1_R_INVALID_TIME_FORMAT 148
+#define ASN1_R_INVALID_UNIVERSALSTRING_LENGTH 149
+#define ASN1_R_INVALID_UTF8STRING 150
+#define ASN1_R_LIST_ERROR 151
+#define ASN1_R_MISSING_ASN1_EOS 152
+#define ASN1_R_MISSING_EOC 153
+#define ASN1_R_MISSING_SECOND_NUMBER 154
+#define ASN1_R_MISSING_VALUE 155
+#define ASN1_R_MSTRING_NOT_UNIVERSAL 156
+#define ASN1_R_MSTRING_WRONG_TAG 157
+#define ASN1_R_NESTED_ASN1_ERROR 158
+#define ASN1_R_NESTED_ASN1_STRING 159
+#define ASN1_R_NON_HEX_CHARACTERS 160
+#define ASN1_R_NOT_ASCII_FORMAT 161
+#define ASN1_R_NOT_ENOUGH_DATA 162
+#define ASN1_R_NO_MATCHING_CHOICE_TYPE 163
+#define ASN1_R_NULL_IS_WRONG_LENGTH 164
+#define ASN1_R_OBJECT_NOT_ASCII_FORMAT 165
+#define ASN1_R_ODD_NUMBER_OF_CHARS 166
+#define ASN1_R_SECOND_NUMBER_TOO_LARGE 167
+#define ASN1_R_SEQUENCE_LENGTH_MISMATCH 168
+#define ASN1_R_SEQUENCE_NOT_CONSTRUCTED 169
+#define ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG 170
+#define ASN1_R_SHORT_LINE 171
+#define ASN1_R_STREAMING_NOT_SUPPORTED 172
+#define ASN1_R_STRING_TOO_LONG 173
+#define ASN1_R_STRING_TOO_SHORT 174
+#define ASN1_R_TAG_VALUE_TOO_HIGH 175
+#define ASN1_R_TIME_NOT_ASCII_FORMAT 176
+#define ASN1_R_TOO_LONG 177
+#define ASN1_R_TYPE_NOT_CONSTRUCTED 178
+#define ASN1_R_TYPE_NOT_PRIMITIVE 179
+#define ASN1_R_UNEXPECTED_EOC 180
+#define ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH 181
+#define ASN1_R_UNKNOWN_FORMAT 182
+#define ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM 183
+#define ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM 184
+#define ASN1_R_UNKNOWN_TAG 185
+#define ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE 186
+#define ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE 187
+#define ASN1_R_UNSUPPORTED_TYPE 188
+#define ASN1_R_WRONG_PUBLIC_KEY_TYPE 189
+#define ASN1_R_WRONG_TAG 190
+#define ASN1_R_WRONG_TYPE 191
#endif
diff --git a/src/include/openssl/base.h b/src/include/openssl/base.h
index 47b3ccb9..22119205 100644
--- a/src/include/openssl/base.h
+++ b/src/include/openssl/base.h
@@ -60,7 +60,11 @@
#include <stdint.h>
#include <sys/types.h>
-#include <openssl/opensslfeatures.h>
+#include <openssl/opensslconf.h>
+
+#if defined(BORINGSSL_PREFIX)
+#include <boringssl_prefix_symbols.h>
+#endif
#if defined(__cplusplus)
extern "C" {
@@ -108,7 +112,8 @@ extern "C" {
#endif
#define OPENSSL_IS_BORINGSSL
-#define BORINGSSL_201510
+#define BORINGSSL_201512
+#define BORINGSSL_201603
#define OPENSSL_VERSION_NUMBER 0x10002000
#define SSLEAY_VERSION_NUMBER OPENSSL_VERSION_NUMBER
@@ -138,6 +143,15 @@ extern "C" {
#endif /* defined(BORINGSSL_SHARED_LIBRARY) */
+
+#if defined(__GNUC__)
+#define OPENSSL_PRINTF_FORMAT_FUNC(string_index, first_to_check) \
+ __attribute__((__format__(__printf__, string_index, first_to_check)))
+#else
+#define OPENSSL_PRINTF_FORMAT_FUNC(string_index, first_to_check)
+#endif
+
+
/* CRYPTO_THREADID is a dummy value. */
typedef int CRYPTO_THREADID;
@@ -173,6 +187,7 @@ typedef struct Netscape_spki_st NETSCAPE_SPKI;
typedef struct PBE2PARAM_st PBE2PARAM;
typedef struct PBEPARAM_st PBEPARAM;
typedef struct PBKDF2PARAM_st PBKDF2PARAM;
+typedef struct RIPEMD160state_st RIPEMD160_CTX;
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;
@@ -221,6 +236,7 @@ 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 newhope_poly_st NEWHOPE_POLY;
typedef struct pkcs12_st PKCS12;
typedef struct pkcs8_priv_key_info_st PKCS8_PRIV_KEY_INFO;
typedef struct private_key_st X509_PKEY;
@@ -231,6 +247,7 @@ 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 spake2_ctx_st SPAKE2_CTX;
typedef struct srtp_protection_profile_st SRTP_PROTECTION_PROFILE;
typedef struct ssl_cipher_st SSL_CIPHER;
typedef struct ssl_ctx_st SSL_CTX;
diff --git a/src/include/openssl/bio.h b/src/include/openssl/bio.h
index c88a3e18..a7fe2617 100644
--- a/src/include/openssl/bio.h
+++ b/src/include/openssl/bio.h
@@ -61,6 +61,7 @@
#include <stdio.h> /* For FILE */
+#include <openssl/buffer.h>
#include <openssl/err.h> /* for ERR_print_errors_fp */
#include <openssl/ex_data.h>
#include <openssl/stack.h>
@@ -308,18 +309,12 @@ OPENSSL_EXPORT BIO *BIO_find_type(BIO *bio, int type);
OPENSSL_EXPORT void BIO_copy_next_retry(BIO *bio);
-/* Printf functions.
- *
- * These functions are versions of printf functions that output to a BIO rather
- * than a FILE. */
-#ifdef __GNUC__
-#define __bio_h__attr__ __attribute__
-#else
-#define __bio_h__attr__(x)
-#endif
+/* Printf functions. */
+
+/* BIO_printf behaves like |printf| but outputs to |bio| rather than a |FILE|.
+ * It returns the number of bytes written or a negative number on error. */
OPENSSL_EXPORT int BIO_printf(BIO *bio, const char *format, ...)
- __bio_h__attr__((__format__(__printf__, 2, 3)));
-#undef __bio_h__attr__
+ OPENSSL_PRINTF_FORMAT_FUNC(2, 3);
/* Utility functions. */
@@ -374,12 +369,12 @@ OPENSSL_EXPORT int BIO_read_asn1(BIO *bio, uint8_t **out, size_t *out_len,
/* BIO_s_mem returns a |BIO_METHOD| that uses a in-memory buffer. */
OPENSSL_EXPORT const BIO_METHOD *BIO_s_mem(void);
-/* BIO_new_mem_buf creates BIO that reads and writes from |len| bytes at |buf|.
+/* BIO_new_mem_buf creates read-only BIO that reads from |len| bytes at |buf|.
* It does not take ownership of |buf|. It returns the BIO or NULL on error.
*
* If |len| is negative, then |buf| is treated as a NUL-terminated string, but
* don't depend on this in new code. */
-OPENSSL_EXPORT BIO *BIO_new_mem_buf(void *buf, int len);
+OPENSSL_EXPORT BIO *BIO_new_mem_buf(const void *buf, int len);
/* BIO_mem_contents sets |*out_contents| to point to the current contents of
* |bio| and |*out_len| to contain the length of that data. It returns one on
@@ -441,12 +436,18 @@ OPENSSL_EXPORT BIO *BIO_new_fd(int fd, int close_flag);
/* BIO_set_fd sets the file descriptor of |bio| to |fd|. If |close_flag| is
* non-zero then |fd| will be closed when |bio| is. It returns one on success
- * or zero on error. */
+ * or zero on error.
+ *
+ * This function may also be used with socket BIOs (see |BIO_s_socket| and
+ * |BIO_new_socket|). */
OPENSSL_EXPORT int BIO_set_fd(BIO *bio, int fd, int close_flag);
/* 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. */
+ * |out_fd| is not NULL, it also sets |*out_fd| to the file descriptor.
+ *
+ * This function may also be used with socket BIOs (see |BIO_s_socket| and
+ * |BIO_new_socket|). */
OPENSSL_EXPORT int BIO_get_fd(BIO *bio, int *out_fd);
@@ -526,7 +527,17 @@ OPENSSL_EXPORT int BIO_set_read_buffer_size(BIO *bio, int buffer_size);
OPENSSL_EXPORT int BIO_set_write_buffer_size(BIO *bio, int buffer_size);
-/* Socket BIOs. */
+/* Socket BIOs.
+ *
+ * Socket BIOs behave like file descriptor BIOs but, on Windows systems, wrap
+ * the system's |recv| and |send| functions instead of |read| and |write|. On
+ * Windows, file descriptors are provided by C runtime and are not
+ * interchangeable with sockets.
+ *
+ * Socket BIOs may be used with |BIO_set_fd| and |BIO_get_fd|.
+ *
+ * TODO(davidben): Add separate APIs and fix the internals to use |SOCKET|s
+ * around rather than rely on int casts. */
OPENSSL_EXPORT const BIO_METHOD *BIO_s_socket(void);
@@ -567,6 +578,10 @@ OPENSSL_EXPORT int BIO_set_conn_port(BIO *bio, const char *port_str);
* returns one on success and zero otherwise. */
OPENSSL_EXPORT int BIO_set_nbio(BIO *bio, int on);
+/* BIO_do_connect connects |bio| if it has not been connected yet. It returns
+ * one on success and <= 0 otherwise. */
+OPENSSL_EXPORT int BIO_do_connect(BIO *bio);
+
/* Datagram BIOs.
*
@@ -717,6 +732,11 @@ OPENSSL_EXPORT int BIO_zero_copy_get_write_buf_done(BIO* bio,
#define BIO_CTRL_GET_CALLBACK 15 /* opt - set callback function */
#define BIO_CTRL_SET_FILENAME 30 /* BIO_s_file special */
+/* These are never used, but exist to allow code to compile more easily. */
+#define BIO_CTRL_DUP 100
+#define BIO_CTRL_PUSH 101
+#define BIO_CTRL_POP 102
+
/* Android compatibility section.
*
diff --git a/src/include/openssl/bn.h b/src/include/openssl/bn.h
index 6e971e48..1dea3c5d 100644
--- a/src/include/openssl/bn.h
+++ b/src/include/openssl/bn.h
@@ -303,17 +303,17 @@ 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_parse_asn1_unsigned 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_parse_asn1_unsigned(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_parse_asn1_unsigned_buggy acts like |BN_parse_asn1_unsigned| but tolerates
+ * some invalid encodings. Do not use this function. */
+OPENSSL_EXPORT int BN_parse_asn1_unsigned_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);
+/* BN_marshal_asn1 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_marshal_asn1(CBB *cbb, const BIGNUM *bn);
/* Internal functions.
@@ -749,11 +749,11 @@ OPENSSL_EXPORT int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod,
/* BN_MONT_CTX_set_locked takes |lock| and checks whether |*pmont| is NULL. If
* so, it creates a new |BN_MONT_CTX| and sets the modulus for it to |mod|. It
- * then stores it as |*pmont| and returns it, or NULL on error.
+ * then stores it as |*pmont|. It returns one on success and zero on error.
*
- * If |*pmont| is already non-NULL then the existing value is returned. */
-BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, CRYPTO_MUTEX *lock,
- const BIGNUM *mod, BN_CTX *bn_ctx);
+ * If |*pmont| is already non-NULL then it does nothing and returns one. */
+int BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, CRYPTO_MUTEX *lock,
+ const BIGNUM *mod, BN_CTX *bn_ctx);
/* BN_to_montgomery sets |ret| equal to |a| in the Montgomery domain. It
* returns one on success and zero on error. */
@@ -852,15 +852,6 @@ OPENSSL_EXPORT unsigned BN_num_bits_word(BN_ULONG l);
#define BN_FLG_CONSTTIME 0x04
-/* Android compatibility section.
- *
- * These functions are declared, temporarily, for Android because
- * wpa_supplicant will take a little time to sync with upstream. Outside of
- * Android they'll have no definition. */
-
-OPENSSL_EXPORT BIGNUM *get_rfc3526_prime_1536(BIGNUM *bn);
-
-
#if defined(__cplusplus)
} /* extern C */
#endif
diff --git a/src/include/openssl/buf.h b/src/include/openssl/buf.h
index 76e3795e..f4e315cd 100644
--- a/src/include/openssl/buf.h
+++ b/src/include/openssl/buf.h
@@ -67,7 +67,7 @@ extern "C" {
/* Memory and string functions, see also mem.h. */
-/* BUF_MEM is a generic buffer object used by OpenSSL. */
+/* buf_mem_st (aka |BUF_MEM|) is a generic buffer object used by OpenSSL. */
struct buf_mem_st {
size_t length; /* current number of bytes */
char *data;
diff --git a/src/include/openssl/bytestring.h b/src/include/openssl/bytestring.h
index 9193e11f..68ede2dc 100644
--- a/src/include/openssl/bytestring.h
+++ b/src/include/openssl/bytestring.h
@@ -128,9 +128,21 @@ OPENSSL_EXPORT int CBS_get_u24_length_prefixed(CBS *cbs, CBS *out);
#define CBS_ASN1_NULL 0x5
#define CBS_ASN1_OBJECT 0x6
#define CBS_ASN1_ENUMERATED 0xa
+#define CBS_ASN1_UTF8STRING 0xc
#define CBS_ASN1_SEQUENCE (0x10 | CBS_ASN1_CONSTRUCTED)
#define CBS_ASN1_SET (0x11 | CBS_ASN1_CONSTRUCTED)
+#define CBS_ASN1_NUMERICSTRING 0x12
+#define CBS_ASN1_PRINTABLESTRING 0x13
+#define CBS_ASN1_T16STRING 0x14
+#define CBS_ASN1_VIDEOTEXSTRING 0x15
+#define CBS_ASN1_IA5STRING 0x16
+#define CBS_ASN1_UTCTIME 0x17
#define CBS_ASN1_GENERALIZEDTIME 0x18
+#define CBS_ASN1_GRAPHICSTRING 0x19
+#define CBS_ASN1_VISIBLESTRING 0x1a
+#define CBS_ASN1_GENERALSTRING 0x1b
+#define CBS_ASN1_UNIVERSALSTRING 0x1c
+#define CBS_ASN1_BMPSTRING 0x1e
#define CBS_ASN1_CONSTRUCTED 0x20
#define CBS_ASN1_CONTEXT_SPECIFIC 0x80
diff --git a/src/include/openssl/cipher.h b/src/include/openssl/cipher.h
index fb7171f0..53123086 100644
--- a/src/include/openssl/cipher.h
+++ b/src/include/openssl/cipher.h
@@ -481,7 +481,7 @@ struct evp_cipher_ctx_st {
/* num contains the number of bytes of |iv| which are valid for modes that
* manage partial blocks themselves. */
- int num;
+ unsigned num;
/* final_used is non-zero if the |final| buffer contains plaintext. */
int final_used;
diff --git a/src/include/openssl/conf.h b/src/include/openssl/conf.h
index a2741a8a..2aa3b79e 100644
--- a/src/include/openssl/conf.h
+++ b/src/include/openssl/conf.h
@@ -92,10 +92,10 @@ struct conf_st {
/* NCONF_new returns a fresh, empty |CONF|, or NULL on error. The |method|
* argument must be NULL. */
-CONF *NCONF_new(void *method);
+OPENSSL_EXPORT CONF *NCONF_new(void *method);
/* NCONF_free frees all the data owned by |conf| and then |conf| itself. */
-void NCONF_free(CONF *conf);
+OPENSSL_EXPORT void NCONF_free(CONF *conf);
/* NCONF_load parses the file named |filename| and adds the values found to
* |conf|. It returns one on success and zero on error. In the event of an
@@ -131,6 +131,31 @@ int CONF_parse_list(const char *list, char sep, int remove_whitespace,
int (*list_cb)(const char *elem, int len, void *usr),
void *arg);
+
+/* Deprecated functions */
+
+/* These defines do nothing but are provided to make old code easier to
+ * compile. */
+#define CONF_MFLAGS_DEFAULT_SECTION 0
+#define CONF_MFLAGS_IGNORE_MISSING_FILE 0
+
+typedef struct conf_must_be_null_st CONF_MUST_BE_NULL;
+
+/* CONF_modules_load_file returns one. |filename| was originally a string, with
+ * NULL indicating the default. BoringSSL does not support configuration files,
+ * so this stub emulates the "default" no-op file but intentionally breaks
+ * compilation of consumers actively attempting to use this subsystem. */
+OPENSSL_EXPORT int CONF_modules_load_file(CONF_MUST_BE_NULL *filename,
+ const char *appname,
+ unsigned long flags);
+
+/* CONF_modules_free does nothing. */
+OPENSSL_EXPORT void CONF_modules_free(void);
+
+/* OPENSSL_config does nothing. */
+OPENSSL_EXPORT void OPENSSL_config(CONF_MUST_BE_NULL *config_name);
+
+
#if defined(__cplusplus)
} /* extern C */
#endif
diff --git a/src/include/openssl/cpu.h b/src/include/openssl/cpu.h
index e946304a..55be4c1f 100644
--- a/src/include/openssl/cpu.h
+++ b/src/include/openssl/cpu.h
@@ -110,30 +110,23 @@ 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__)
+ /* Only statically skip the runtime lookup on aarch64. On arm, one CPU is
+ * known to have a broken NEON unit which is known to fail with on some
+ * hand-written NEON assembly. For now, continue to apply the workaround even
+ * when the compiler is instructed to freely emit NEON code. See
+ * https://crbug.com/341598 and https://crbug.com/606629. */
+#if defined(__ARM_NEON__) && !defined(OPENSSL_ARM)
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
- * not to be present. It is not autodetected. Calling this with a zero
- * argument also causes |CRYPTO_is_NEON_functional| to return false. */
-OPENSSL_EXPORT void CRYPTO_set_NEON_capable(char neon_capable);
-
-/* CRYPTO_is_NEON_functional returns true if the current CPU has a /working/
- * NEON unit. Some phones have a NEON unit, but the Poly1305 NEON code causes
- * it to fail. See https://code.google.com/p/chromium/issues/detail?id=341598 */
-OPENSSL_EXPORT char CRYPTO_is_NEON_functional(void);
-
-/* CRYPTO_set_NEON_functional sets the "NEON functional" flag. For
- * |CRYPTO_is_NEON_functional| to return true, both this flag and the NEON flag
- * must be true. By default NEON is assumed to be functional if the code was
- * 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);
+#if defined(OPENSSL_ARM)
+/* CRYPTO_has_broken_NEON returns one if the current CPU is known to have a
+ * broken NEON unit. See https://crbug.com/341598. */
+OPENSSL_EXPORT int CRYPTO_has_broken_NEON(void);
+#endif
/* CRYPTO_is_ARMv8_AES_capable returns true if the current CPU supports the
* ARMv8 AES instruction. */
@@ -153,10 +146,6 @@ static inline int CRYPTO_is_NEON_capable(void) {
#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;
@@ -174,7 +163,7 @@ static inline int CRYPTO_is_ARMv8_PMULL_capable(void) {
}
#endif /* OPENSSL_STATIC_ARMCAP */
-#endif /* OPENSSL_ARM */
+#endif /* OPENSSL_ARM || OPENSSL_AARCH64 */
#if defined(__cplusplus)
diff --git a/src/include/openssl/crypto.h b/src/include/openssl/crypto.h
index b4218847..b52bcf80 100644
--- a/src/include/openssl/crypto.h
+++ b/src/include/openssl/crypto.h
@@ -36,13 +36,19 @@ extern "C" {
/* CRYPTO_library_init initializes the crypto library. It must be called if the
* library is built with BORINGSSL_NO_STATIC_INITIALIZER. Otherwise, it does
- * nothing and a static initializer is used instead. */
+ * nothing and a static initializer is used instead. It is safe to call this
+ * function multiple times and concurrently from multiple threads.
+ *
+ * On some ARM configurations, this function may require filesystem access and
+ * should be called before entering a sandbox. */
OPENSSL_EXPORT void CRYPTO_library_init(void);
/* Deprecated functions. */
-#define OPENSSL_VERSION_TEXT "BoringSSL"
+/* OPENSSL_VERSION_TEXT contains a string the identifies the version of
+ * “OpenSSL”. node.js requires a version number in this text. */
+#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2 (compatible; BoringSSL)"
#define SSLEAY_VERSION 0
@@ -60,6 +66,12 @@ OPENSSL_EXPORT int CRYPTO_malloc_init(void);
/* ENGINE_load_builtin_engines does nothing. */
OPENSSL_EXPORT void ENGINE_load_builtin_engines(void);
+/* OPENSSL_load_builtin_modules does nothing. */
+OPENSSL_EXPORT void OPENSSL_load_builtin_modules(void);
+
+/* FIPS_mode returns zero. */
+OPENSSL_EXPORT int FIPS_mode(void);
+
#if defined(__cplusplus)
} /* extern C */
diff --git a/src/include/openssl/curve25519.h b/src/include/openssl/curve25519.h
index 30c64701..a9441cd4 100644
--- a/src/include/openssl/curve25519.h
+++ b/src/include/openssl/curve25519.h
@@ -24,16 +24,14 @@ extern "C" {
/* Curve25519.
*
- * Curve25519 is an elliptic curve. See
- * https://tools.ietf.org/html/draft-irtf-cfrg-curves-11. */
+ * Curve25519 is an elliptic curve. See https://tools.ietf.org/html/rfc7748. */
/* 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 is the Diffie-Hellman primitive built from curve25519. It is
+ * sometimes referred to as “curve25519”, but “X25519” is a more precise name.
+ * See http://cr.yp.to/ecdh.html and https://tools.ietf.org/html/rfc7748. */
/* X25519_keypair sets |out_public_value| and |out_private_key| to a freshly
* generated, public–private key pair. */
@@ -85,6 +83,88 @@ OPENSSL_EXPORT int ED25519_verify(const uint8_t *message, size_t message_len,
const uint8_t public_key[32]);
+/* SPAKE2.
+ *
+ * SPAKE2 is a password-authenticated key-exchange. It allows two parties,
+ * who share a low-entropy secret (i.e. password), to agree on a shared key.
+ * An attacker can only make one guess of the password per execution of the
+ * protocol.
+ *
+ * See https://tools.ietf.org/html/draft-irtf-cfrg-spake2-02. */
+
+/* spake2_role_t enumerates the different “roles” in SPAKE2. The protocol
+ * requires that the symmetry of the two parties be broken so one participant
+ * must be “Alice” and the other be “Bob”. */
+enum spake2_role_t {
+ spake2_role_alice,
+ spake2_role_bob,
+};
+
+/* SPAKE2_CTX_new creates a new |SPAKE2_CTX| (which can only be used for a
+ * single execution of the protocol). SPAKE2 requires the symmetry of the two
+ * parties to be broken which is indicated via |my_role| – each party must pass
+ * a different value for this argument.
+ *
+ * The |my_name| and |their_name| arguments allow optional, opaque names to be
+ * bound into the protocol. For example MAC addresses, hostnames, usernames
+ * etc. These values are not exposed and can avoid context-confusion attacks
+ * when a password is shared between several devices. */
+OPENSSL_EXPORT SPAKE2_CTX *SPAKE2_CTX_new(
+ enum spake2_role_t my_role,
+ const uint8_t *my_name, size_t my_name_len,
+ const uint8_t *their_name, size_t their_name_len);
+
+/* SPAKE2_CTX_free frees |ctx| and all the resources that it has allocated. */
+OPENSSL_EXPORT void SPAKE2_CTX_free(SPAKE2_CTX *ctx);
+
+/* SPAKE2_MAX_MSG_SIZE is the maximum size of a SPAKE2 message. */
+#define SPAKE2_MAX_MSG_SIZE 32
+
+/* SPAKE2_generate_msg generates a SPAKE2 message given |password|, writes
+ * it to |out| and sets |*out_len| to the number of bytes written.
+ *
+ * At most |max_out_len| bytes are written to |out| and, in order to ensure
+ * success, |max_out_len| should be at least |SPAKE2_MAX_MSG_SIZE| bytes.
+ *
+ * This function can only be called once for a given |SPAKE2_CTX|.
+ *
+ * It returns one on success and zero on error. */
+OPENSSL_EXPORT int SPAKE2_generate_msg(SPAKE2_CTX *ctx, uint8_t *out,
+ size_t *out_len, size_t max_out_len,
+ const uint8_t *password,
+ size_t password_len);
+
+/* SPAKE2_MAX_KEY_SIZE is the maximum amount of key material that SPAKE2 will
+ * produce. */
+#define SPAKE2_MAX_KEY_SIZE 64
+
+/* SPAKE2_process_msg completes the SPAKE2 exchange given the peer's message in
+ * |their_msg|, writes at most |max_out_key_len| bytes to |out_key| and sets
+ * |*out_key_len| to the number of bytes written.
+ *
+ * The resulting keying material is suitable for:
+ * a) Using directly in a key-confirmation step: i.e. each side could
+ * transmit a hash of their role, a channel-binding value and the key
+ * material to prove to the other side that they know the shared key.
+ * b) Using as input keying material to HKDF to generate a variety of subkeys
+ * for encryption etc.
+ *
+ * If |max_out_key_key| is smaller than the amount of key material generated
+ * then the key is silently truncated. If you want to ensure that no truncation
+ * occurs then |max_out_key| should be at least |SPAKE2_MAX_KEY_SIZE|.
+ *
+ * You must call |SPAKE2_generate_msg| on a given |SPAKE2_CTX| before calling
+ * this function. On successful return, |ctx| is complete and calling
+ * |SPAKE2_CTX_free| is the only acceptable operation on it.
+ *
+ * Returns one on success or zero on error. */
+OPENSSL_EXPORT int SPAKE2_process_msg(SPAKE2_CTX *ctx, uint8_t *out_key,
+ size_t *out_key_len,
+ size_t max_out_key_len,
+ const uint8_t *their_msg,
+ size_t their_msg_len);
+
+
#if defined(__cplusplus)
} /* extern C */
#endif
diff --git a/src/include/openssl/dh.h b/src/include/openssl/dh.h
index 2c49fc83..5cdeb86e 100644
--- a/src/include/openssl/dh.h
+++ b/src/include/openssl/dh.h
@@ -156,8 +156,9 @@ OPENSSL_EXPORT unsigned DH_num_bits(const DH *dh);
* Note: these checks may be quite computationally expensive. */
OPENSSL_EXPORT int DH_check(const DH *dh, int *out_flags);
-#define DH_CHECK_PUBKEY_TOO_SMALL 1
-#define DH_CHECK_PUBKEY_TOO_LARGE 2
+#define DH_CHECK_PUBKEY_TOO_SMALL 0x1
+#define DH_CHECK_PUBKEY_TOO_LARGE 0x2
+#define DH_CHECK_PUBKEY_INVALID 0x4
/* DH_check_pub_key checks the suitability of |pub_key| as a public key for the
* DH group in |dh| and sets |DH_CHECK_PUBKEY_*| flags in |*out_flags| if it
@@ -177,7 +178,10 @@ OPENSSL_EXPORT DH *DHparams_dup(const DH *dh);
* structure from |len| bytes at |*inp|. If |ret| is not NULL then, on exit, a
* pointer to the result is in |*ret|. If |*ret| is already non-NULL on entry
* then the result is written directly into |*ret|, otherwise a fresh |DH| is
- * allocated. On successful exit, |*inp| is advanced past the DER structure. It
+ * allocated. However, one should not depend on writing into |*ret| because
+ * this behaviour is likely to change in the future.
+ *
+ * On successful exit, |*inp| is advanced past the DER structure. It
* returns the result or NULL on error. */
OPENSSL_EXPORT DH *d2i_DHparams(DH **ret, const unsigned char **inp, long len);
@@ -200,6 +204,16 @@ OPENSSL_EXPORT int DH_set_ex_data(DH *d, int idx, void *arg);
OPENSSL_EXPORT void *DH_get_ex_data(DH *d, int idx);
+/* Deprecated functions. */
+
+/* DH_generate_parameters behaves like |DH_generate_parameters_ex|, which is
+ * what you should use instead. It returns NULL on error, or a newly-allocated
+ * |DH| on success. This function is provided for compatibility only. */
+OPENSSL_EXPORT DH *DH_generate_parameters(int prime_len, int generator,
+ void (*callback)(int, int, void *),
+ void *cb_arg);
+
+
struct dh_st {
BIGNUM *p;
BIGNUM *g;
diff --git a/src/include/openssl/digest.h b/src/include/openssl/digest.h
index 80028efd..db3ead71 100644
--- a/src/include/openssl/digest.h
+++ b/src/include/openssl/digest.h
@@ -143,6 +143,9 @@ OPENSSL_EXPORT int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data,
* at least this much space. */
#define EVP_MAX_MD_SIZE 64 /* SHA-512 is the longest so far. */
+/* EVP_MAX_MD_BLOCK_SIZE is the largest digest block size supported, in bytes. */
+#define EVP_MAX_MD_BLOCK_SIZE 128 /* SHA-512 is the longest so far. */
+
/* EVP_DigestFinal_ex finishes the digest in |ctx| and writes the output to
* |md_out|. At most |EVP_MAX_MD_SIZE| bytes are written. If |out_size| is not
* NULL then |*out_size| is set to the number of bytes written. It returns one.
@@ -218,11 +221,11 @@ OPENSSL_EXPORT const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *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);
+OPENSSL_EXPORT size_t 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|, 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);
+OPENSSL_EXPORT size_t EVP_MD_CTX_block_size(const EVP_MD_CTX *ctx);
/* EVP_MD_CTX_type returns a NID describing the digest function used by |ctx|.
* (For example, |NID_sha256|.) It will crash if a digest hasn't been set on
diff --git a/src/include/openssl/dsa.h b/src/include/openssl/dsa.h
index 2045fe73..0077a722 100644
--- a/src/include/openssl/dsa.h
+++ b/src/include/openssl/dsa.h
@@ -128,7 +128,7 @@ OPENSSL_EXPORT int DSA_generate_key(DSA *dsa);
/* Signatures. */
-/* DSA_SIG contains a DSA signature as a pair of integers. */
+/* DSA_SIG_st (aka |DSA_SIG|) contains a DSA signature as a pair of integers. */
typedef struct DSA_SIG_st {
BIGNUM *r, *s;
} DSA_SIG;
@@ -218,62 +218,41 @@ OPENSSL_EXPORT int DSA_size(const DSA *dsa);
/* ASN.1 encoding. */
-/* d2i_DSA_SIG parses an ASN.1, DER-encoded, DSA signature from |len| bytes at
- * |*inp|. If |out_sig| is not NULL then, on exit, a pointer to the result is
- * in |*out_sig|. If |*out_sig| is already non-NULL on entry then the result is
- * written directly into |*out_sig|, otherwise a fresh |DSA_SIG| is allocated.
- * On successful exit, |*inp| is advanced past the DER structure. It returns
- * the result or NULL on error. */
-OPENSSL_EXPORT DSA_SIG *d2i_DSA_SIG(DSA_SIG **out_sig, const uint8_t **inp,
- long len);
+/* DSA_SIG_parse parses a DER-encoded DSA-Sig-Value structure from |cbs| and
+ * advances |cbs|. It returns a newly-allocated |DSA_SIG| or NULL on error. */
+OPENSSL_EXPORT DSA_SIG *DSA_SIG_parse(CBS *cbs);
-/* i2d_DSA_SIG 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_DSA_SIG(const DSA_SIG *in, uint8_t **outp);
+/* DSA_SIG_marshal marshals |sig| as a DER-encoded DSA-Sig-Value and appends the
+ * result to |cbb|. It returns one on success and zero on error. */
+OPENSSL_EXPORT int DSA_SIG_marshal(CBB *cbb, const DSA_SIG *sig);
-/* d2i_DSAPublicKey parses an ASN.1, DER-encoded, DSA 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 |DSA| is allocated. On
- * successful exit, |*inp| is advanced past the DER structure. It returns the
- * result or NULL on error. */
-OPENSSL_EXPORT DSA *d2i_DSAPublicKey(DSA **out, const uint8_t **inp, long len);
+/* DSA_parse_public_key parses a DER-encoded DSA public key from |cbs| and
+ * advances |cbs|. It returns a newly-allocated |DSA| or NULL on error. */
+OPENSSL_EXPORT DSA *DSA_parse_public_key(CBS *cbs);
-/* i2d_DSAPublicKey marshals a public key from |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_DSAPublicKey(const DSA *in, unsigned char **outp);
+/* DSA_marshal_public_key marshals |dsa| as a DER-encoded DSA public key and
+ * appends the result to |cbb|. It returns one on success and zero on
+ * failure. */
+OPENSSL_EXPORT int DSA_marshal_public_key(CBB *cbb, const DSA *dsa);
-/* d2i_DSAPrivateKey parses an ASN.1, DER-encoded, DSA 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 |DSA| is allocated. On
- * successful exit, |*inp| is advanced past the DER structure. It returns the
- * result or NULL on error. */
-OPENSSL_EXPORT DSA *d2i_DSAPrivateKey(DSA **out, const uint8_t **inp, long len);
+/* DSA_parse_private_key parses a DER-encoded DSA private key from |cbs| and
+ * advances |cbs|. It returns a newly-allocated |DSA| or NULL on error. */
+OPENSSL_EXPORT DSA *DSA_parse_private_key(CBS *cbs);
-/* i2d_DSAPrivateKey marshals a private key from |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_DSAPrivateKey(const DSA *in, unsigned char **outp);
+/* DSA_marshal_private_key marshals |dsa| as a DER-encoded DSA private key and
+ * appends the result to |cbb|. It returns one on success and zero on
+ * failure. */
+OPENSSL_EXPORT int DSA_marshal_private_key(CBB *cbb, const DSA *dsa);
-/* d2i_DSAparams parses ASN.1, DER-encoded, DSA parameters 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 |DSA| is allocated. On successful
- * exit, |*inp| is advanced past the DER structure. It returns the result or
- * NULL on error. */
-OPENSSL_EXPORT DSA *d2i_DSAparams(DSA **out, const uint8_t **inp, long len);
+/* DSA_parse_parameters parses a DER-encoded Dss-Parms structure (RFC 3279)
+ * from |cbs| and advances |cbs|. It returns a newly-allocated |DSA| or NULL on
+ * error. */
+OPENSSL_EXPORT DSA *DSA_parse_parameters(CBS *cbs);
-/* i2d_DSAparams marshals DSA parameters from |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_DSAparams(const DSA *in, unsigned char **outp);
+/* DSA_marshal_parameters marshals |dsa| as a DER-encoded Dss-Parms structure
+ * (RFC 3447) and appends the result to |cbb|. It returns one on success and
+ * zero on failure. */
+OPENSSL_EXPORT int DSA_marshal_parameters(CBB *cbb, const DSA *dsa);
/* Precomputation. */
@@ -309,9 +288,93 @@ 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);
+/* Deprecated functions. */
+
+/* d2i_DSA_SIG parses an ASN.1, DER-encoded, DSA signature from |len| bytes at
+ * |*inp|. If |out_sig| is not NULL then, on exit, a pointer to the result is
+ * in |*out_sig|. Note that, even if |*out_sig| is already non-NULL on entry, it
+ * will not be written to. Rather, a fresh |DSA_SIG| is allocated and the
+ * previous one is freed. On successful exit, |*inp| is advanced past the DER
+ * structure. It returns the result or NULL on error.
+ *
+ * Use |DSA_SIG_parse| instead. */
+OPENSSL_EXPORT DSA_SIG *d2i_DSA_SIG(DSA_SIG **out_sig, const uint8_t **inp,
+ long len);
+
+/* i2d_DSA_SIG 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.
+ *
+ * Use |DSA_SIG_marshal| instead. */
+OPENSSL_EXPORT int i2d_DSA_SIG(const DSA_SIG *in, uint8_t **outp);
+
+/* d2i_DSAPublicKey parses an ASN.1, DER-encoded, DSA public key from |len|
+ * bytes at |*inp|. If |out| is not NULL then, on exit, a pointer to the result
+ * is in |*out|. Note that, even if |*ou| is already non-NULL on entry, it will
+ * not be written to. Rather, a fresh |DSA| is allocated and the previous one is
+ * freed. On successful exit, |*inp| is advanced past the DER structure. It
+ * returns the result or NULL on error.
+ *
+ * Use |DSA_parse_public_key| instead. */
+OPENSSL_EXPORT DSA *d2i_DSAPublicKey(DSA **out, const uint8_t **inp, long len);
+
+/* i2d_DSAPublicKey marshals a public key from |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.
+ *
+ * Use |DSA_marshal_public_key| instead. */
+OPENSSL_EXPORT int i2d_DSAPublicKey(const DSA *in, uint8_t **outp);
+
+/* d2i_DSAPrivateKey parses an ASN.1, DER-encoded, DSA private key from |len|
+ * bytes at |*inp|. If |out| is not NULL then, on exit, a pointer to the result
+ * is in |*out|. Note that, even if |*out| is already non-NULL on entry, it will
+ * not be written to. Rather, a fresh |DSA| is allocated and the previous one is
+ * freed. On successful exit, |*inp| is advanced past the DER structure. It
+ * returns the result or NULL on error.
+ *
+ * Use |DSA_parse_private_key| instead. */
+OPENSSL_EXPORT DSA *d2i_DSAPrivateKey(DSA **out, const uint8_t **inp, long len);
+
+/* i2d_DSAPrivateKey marshals a private key from |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.
+ *
+ * Use |DSA_marshal_private_key| instead. */
+OPENSSL_EXPORT int i2d_DSAPrivateKey(const DSA *in, uint8_t **outp);
+
+/* d2i_DSAparams parses ASN.1, DER-encoded, DSA parameters from |len| bytes at
+ * |*inp|. If |out| is not NULL then, on exit, a pointer to the result is in
+ * |*out|. Note that, even if |*out| is already non-NULL on entry, it will not
+ * be written to. Rather, a fresh |DSA| is allocated and the previous one is
+ * freed. On successful exit, |*inp| is advanced past the DER structure. It
+ * returns the result or NULL on error.
+ *
+ * Use |DSA_parse_parameters| instead. */
+OPENSSL_EXPORT DSA *d2i_DSAparams(DSA **out, const uint8_t **inp, long len);
+
+/* i2d_DSAparams marshals DSA parameters from |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.
+ *
+ * Use |DSA_marshal_parameters| instead. */
+OPENSSL_EXPORT int i2d_DSAparams(const DSA *in, uint8_t **outp);
+
+/* DSA_generate_parameters is a deprecated version of
+ * |DSA_generate_parameters_ex| that creates and returns a |DSA*|. Don't use
+ * it. */
+OPENSSL_EXPORT DSA *DSA_generate_parameters(int bits, unsigned char *seed,
+ int seed_len, int *counter_ret,
+ unsigned long *h_ret,
+ void (*callback)(int, int, void *),
+ void *cb_arg);
+
+
struct dsa_st {
long version;
- int write_params;
BIGNUM *p;
BIGNUM *q; /* == 20 */
BIGNUM *g;
@@ -339,5 +402,8 @@ struct dsa_st {
#define DSA_R_MISSING_PARAMETERS 101
#define DSA_R_MODULUS_TOO_LARGE 102
#define DSA_R_NEED_NEW_SETUP_VALUES 103
+#define DSA_R_BAD_VERSION 104
+#define DSA_R_DECODE_ERROR 105
+#define DSA_R_ENCODE_ERROR 106
#endif /* OPENSSL_HEADER_DSA_H */
diff --git a/src/include/openssl/ec.h b/src/include/openssl/ec.h
index 667be3b3..143aa96c 100644
--- a/src/include/openssl/ec.h
+++ b/src/include/openssl/ec.h
@@ -81,14 +81,24 @@ extern "C" {
typedef struct ec_group_st EC_GROUP;
typedef struct ec_point_st EC_POINT;
-/** Enum for the point conversion form as defined in X9.62 (ECDSA)
- * for the encoding of a elliptic curve point (x,y) */
+/* point_conversion_form_t enumerates forms, as defined in X9.62 (ECDSA), for
+ * the encoding of a elliptic curve point (x,y) */
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 0x04 */
- POINT_CONVERSION_UNCOMPRESSED = 4
+ /* POINT_CONVERSION_COMPRESSED indicates that the point is encoded as z||x,
+ * where the octet z specifies which solution of the quadratic equation y
+ * is. */
+ POINT_CONVERSION_COMPRESSED = 2,
+
+ /* POINT_CONVERSION_COMPRESSED indicates that the point is encoded as
+ * z||x||y, where z is the octet 0x04. */
+ POINT_CONVERSION_UNCOMPRESSED = 4,
+
+ /* POINT_CONVERSION_HYBRID indicates that the point is encoded as z||x||y,
+ * where z specifies which solution of the quadratic equation y is. This is
+ * not supported by the code and has never been observed in use.
+ *
+ * TODO(agl): remove once node.js no longer references this. */
+ POINT_CONVERSION_HYBRID = 6,
} point_conversion_form_t;
@@ -179,12 +189,13 @@ OPENSSL_EXPORT int EC_POINT_is_at_infinity(const EC_GROUP *group,
const EC_POINT *point);
/* EC_POINT_is_on_curve returns one if |point| is an element of |group| and
- * zero otheriwse. If |ctx| is non-NULL, it may be used. */
+ * and zero otherwise or when an error occurs. This is different from OpenSSL,
+ * which returns -1 on error. If |ctx| is non-NULL, it may be used. */
OPENSSL_EXPORT int EC_POINT_is_on_curve(const EC_GROUP *group,
const EC_POINT *point, BN_CTX *ctx);
-/* EC_POINT_cmp returns zero if |a| is equal to |b|, greater than zero is
- * non-equal and -1 on error. If |ctx| is not NULL, it may be used. */
+/* EC_POINT_cmp returns zero if |a| is equal to |b|, greater than zero if
+ * not equal and -1 on error. If |ctx| is not NULL, it may be used. */
OPENSSL_EXPORT int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a,
const EC_POINT *b, BN_CTX *ctx);
@@ -210,10 +221,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_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. */
+/* EC_POINT_set_affine_coordinates_GFp sets the value of |point| 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,
@@ -229,6 +240,13 @@ OPENSSL_EXPORT size_t EC_POINT_point2oct(const EC_GROUP *group,
point_conversion_form_t form,
uint8_t *buf, size_t len, BN_CTX *ctx);
+/* EC_POINT_point2cbb behaves like |EC_POINT_point2oct| but appends the
+ * serialised point to |cbb|. It returns one on success and zero on error. */
+OPENSSL_EXPORT int EC_POINT_point2cbb(CBB *out, const EC_GROUP *group,
+ const EC_POINT *point,
+ point_conversion_form_t form,
+ BN_CTX *ctx);
+
/* EC_POINT_oct2point sets |point| from |len| bytes of X9.62 format
* serialisation in |buf|. It returns one on success and zero otherwise. The
* |ctx| argument may be used if not NULL. */
@@ -275,27 +293,43 @@ OPENSSL_EXPORT int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r,
* on the equation y² = x³ + a·x + b. It returns the new group or NULL on
* error.
*
+ * This new group has no generator. It is an error to use a generator-less group
+ * with any functions except for |EC_GROUP_free|, |EC_POINT_new|,
+ * |EC_POINT_set_affine_coordinates_GFp|, and |EC_GROUP_set_generator|.
+ *
* |EC_GROUP|s returned by this function will always compare as unequal via
* |EC_GROUP_cmp| (even to themselves). |EC_GROUP_get_curve_name| will always
- * return |NID_undef|. */
+ * return |NID_undef|.
+ *
+ * Avoid using arbitrary curves and use |EC_GROUP_new_by_curve_name| instead. */
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|. */
+ * must have the given order and cofactor. It may only be used with |EC_GROUP|
+ * objects returned by |EC_GROUP_new_curve_GFp| and may only be used once on
+ * each group. */
OPENSSL_EXPORT int EC_GROUP_set_generator(EC_GROUP *group,
const EC_POINT *generator,
const BIGNUM *order,
const BIGNUM *cofactor);
+/* EC_GROUP_new_arbitrary calls |EC_GROUP_new_curve_GFp| and
+ * |EC_GROUP_set_generator|.
+ *
+ * TODO(davidben): Remove this once
+ * https://android-review.googlesource.com/#/c/207990/ has cycled in. */
+OPENSSL_EXPORT EC_GROUP *EC_GROUP_new_arbitrary(
+ const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, const BIGNUM *gx,
+ const BIGNUM *gy, const BIGNUM *order, const BIGNUM *cofactor);
+
+/* 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_asn1_flag does nothing. */
OPENSSL_EXPORT void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag);
@@ -314,6 +348,19 @@ OPENSSL_EXPORT int EC_METHOD_get_field_type(const EC_METHOD *meth);
OPENSSL_EXPORT void EC_GROUP_set_point_conversion_form(
EC_GROUP *group, point_conversion_form_t form);
+/* EC_builtin_curve describes a supported elliptic curve. */
+typedef struct {
+ int nid;
+ const char *comment;
+} EC_builtin_curve;
+
+/* EC_get_builtin_curves writes at most |max_num_curves| elements to
+ * |out_curves| and returns the total number that it would have written, had
+ * |max_num_curves| been large enough.
+ *
+ * The |EC_builtin_curve| items describe the supported elliptic curves. */
+OPENSSL_EXPORT size_t EC_get_builtin_curves(EC_builtin_curve *out_curves,
+ size_t max_num_curves);
/* Old code expects to get EC_KEY from ec.h. */
#include <openssl/ec_key.h>
@@ -351,5 +398,8 @@ OPENSSL_EXPORT void EC_GROUP_set_point_conversion_form(
#define EC_R_WRONG_ORDER 125
#define EC_R_BIGNUM_OUT_OF_RANGE 126
#define EC_R_WRONG_CURVE_PARAMETERS 127
+#define EC_R_DECODE_ERROR 128
+#define EC_R_ENCODE_ERROR 129
+#define EC_R_GROUP_MISMATCH 130
#endif /* OPENSSL_HEADER_EC_H */
diff --git a/src/include/openssl/ec_key.h b/src/include/openssl/ec_key.h
index afd95d6a..63554a78 100644
--- a/src/include/openssl/ec_key.h
+++ b/src/include/openssl/ec_key.h
@@ -177,48 +177,37 @@ OPENSSL_EXPORT int EC_KEY_generate_key(EC_KEY *key);
/* Serialisation. */
-/* d2i_ECPrivateKey parses an ASN.1, DER-encoded, private key from |len| bytes
- * at |*inp|. If |out_key| is not NULL then, on exit, a pointer to the result
- * is in |*out_key|. If |*out_key| is already non-NULL on entry then the result
- * is written directly into |*out_key|, otherwise a fresh |EC_KEY| is
- * allocated. On successful exit, |*inp| is advanced past the DER structure. It
- * returns the result or NULL on error. */
-OPENSSL_EXPORT EC_KEY *d2i_ECPrivateKey(EC_KEY **out_key, const uint8_t **inp,
- long len);
-
-/* 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. */
-OPENSSL_EXPORT int i2d_ECPrivateKey(const EC_KEY *key, uint8_t **outp);
-
-/* d2i_ECParameters parses an ASN.1, DER-encoded, set of EC parameters from
- * |len| bytes at |*inp|. If |out_key| is not NULL then, on exit, a pointer to
- * the result is in |*out_key|. If |*out_key| is already non-NULL on entry then
- * the result is written directly into |*out_key|, otherwise a fresh |EC_KEY|
- * is allocated. On successful exit, |*inp| is advanced past the DER structure.
- * It returns the result or NULL on error. */
-OPENSSL_EXPORT EC_KEY *d2i_ECParameters(EC_KEY **out_key, const uint8_t **inp,
- long len);
-
-/* i2d_ECParameters marshals EC parameters 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. */
-OPENSSL_EXPORT int i2d_ECParameters(const EC_KEY *key, uint8_t **outp);
+/* EC_KEY_parse_private_key parses a DER-encoded ECPrivateKey structure (RFC
+ * 5915) from |cbs| and advances |cbs|. It returns a newly-allocated |EC_KEY| or
+ * NULL on error. If |group| is non-null, the parameters field of the
+ * ECPrivateKey may be omitted (but must match |group| if present). Otherwise,
+ * the parameters field is required. */
+OPENSSL_EXPORT EC_KEY *EC_KEY_parse_private_key(CBS *cbs,
+ const EC_GROUP *group);
+
+/* EC_KEY_marshal_private_key marshals |key| as a DER-encoded ECPrivateKey
+ * structure (RFC 5915) and appends the result to |cbb|. It returns one on
+ * success and zero on failure. |enc_flags| is a combination of |EC_PKEY_*|
+ * values and controls whether corresponding fields are omitted. */
+OPENSSL_EXPORT int EC_KEY_marshal_private_key(CBB *cbb, const EC_KEY *key,
+ unsigned enc_flags);
+
+/* EC_KEY_parse_curve_name parses a DER-encoded OBJECT IDENTIFIER as a curve
+ * name from |cbs| and advances |cbs|. It returns a newly-allocated |EC_GROUP|
+ * or NULL on error. */
+OPENSSL_EXPORT EC_GROUP *EC_KEY_parse_curve_name(CBS *cbs);
-/* 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 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);
+/* EC_KEY_marshal_curve_name marshals |group| as a DER-encoded OBJECT IDENTIFIER
+ * and appends the result to |cbb|. It returns one on success and zero on
+ * failure. */
+OPENSSL_EXPORT int EC_KEY_marshal_curve_name(CBB *cbb, const EC_GROUP *group);
-/* i2o_ECPublicKey marshals an EC point from |key|. 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 i2o_ECPublicKey(const EC_KEY *key, unsigned char **outp);
+/* EC_KEY_parse_parameters parses a DER-encoded ECParameters structure (RFC
+ * 5480) from |cbs| and advances |cbs|. It returns a newly-allocated |EC_GROUP|
+ * or NULL on error. It supports the namedCurve and specifiedCurve options, but
+ * use of specifiedCurve is deprecated. Use |EC_KEY_parse_curve_name|
+ * instead. */
+OPENSSL_EXPORT EC_GROUP *EC_KEY_parse_parameters(CBS *cbs);
/* ex_data functions.
@@ -259,7 +248,7 @@ struct ecdsa_method_st {
int (*sign)(const uint8_t *digest, size_t digest_len, uint8_t *sig,
unsigned int *sig_len, EC_KEY *eckey);
- /* verify matches the arguments and behaviour of |ECDSA_verify|. */
+ /* Ignored. Set this to NULL. */
int (*verify)(const uint8_t *digest, size_t digest_len, const uint8_t *sig,
size_t sig_len, EC_KEY *eckey);
@@ -272,6 +261,64 @@ struct ecdsa_method_st {
/* EC_KEY_set_asn1_flag does nothing. */
OPENSSL_EXPORT void EC_KEY_set_asn1_flag(EC_KEY *key, int flag);
+/* d2i_ECPrivateKey parses an ASN.1, DER-encoded, private key from |len| bytes
+ * at |*inp|. If |out_key| is not NULL then, on exit, a pointer to the result
+ * is in |*out_key|. Note that, even if |*out_key| is already non-NULL on entry,
+ * it * will not be written to. Rather, a fresh |EC_KEY| is allocated and the
+ * previous * one is freed. On successful exit, |*inp| is advanced past the DER
+ * structure. It returns the result or NULL on error.
+ *
+ * On input, if |*out_key| is non-NULL and has a group configured, the
+ * parameters field may be omitted but must match that group if present.
+ *
+ * Use |EC_KEY_parse_private_key| instead. */
+OPENSSL_EXPORT EC_KEY *d2i_ECPrivateKey(EC_KEY **out_key, const uint8_t **inp,
+ long len);
+
+/* 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.
+ *
+ * Use |EC_KEY_marshal_private_key| instead. */
+OPENSSL_EXPORT int i2d_ECPrivateKey(const EC_KEY *key, uint8_t **outp);
+
+/* d2i_ECParameters parses an ASN.1, DER-encoded, set of EC parameters from
+ * |len| bytes at |*inp|. If |out_key| is not NULL then, on exit, a pointer to
+ * the result is in |*out_key|. Note that, even if |*out_key| is already
+ * non-NULL on entry, it will not be written to. Rather, a fresh |EC_KEY| is
+ * allocated and the previous one is freed. On successful exit, |*inp| is
+ * advanced past the DER structure. It returns the result or NULL on error.
+ *
+ * Use |EC_KEY_parse_parameters| or |EC_KEY_parse_curve_name| instead. */
+OPENSSL_EXPORT EC_KEY *d2i_ECParameters(EC_KEY **out_key, const uint8_t **inp,
+ long len);
+
+/* i2d_ECParameters marshals EC parameters 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.
+ *
+ * Use |EC_KEY_marshal_curve_name| instead. */
+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 with a group set. On successful exit, |*inp| is advanced by
+ * |len| bytes. It returns |*out_key| or NULL on error.
+ *
+ * Use |EC_POINT_oct2point| instead. */
+OPENSSL_EXPORT EC_KEY *o2i_ECPublicKey(EC_KEY **out_key, const uint8_t **inp,
+ long len);
+
+/* i2o_ECPublicKey marshals an EC point from |key|. 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.
+ *
+ * Use |EC_POINT_point2cbb| instead. */
+OPENSSL_EXPORT int i2o_ECPublicKey(const EC_KEY *key, unsigned char **outp);
+
#if defined(__cplusplus)
} /* extern C */
diff --git a/src/include/openssl/ecdsa.h b/src/include/openssl/ecdsa.h
index f3f68eb2..a060eab3 100644
--- a/src/include/openssl/ecdsa.h
+++ b/src/include/openssl/ecdsa.h
@@ -178,10 +178,10 @@ OPENSSL_EXPORT size_t ECDSA_SIG_max_len(size_t order_len);
/* 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
- * directly into |*out|, otherwise a fresh |ECDSA_SIG| is allocated. On
- * successful exit, |*inp| is advanced past the DER structure. It returns the
- * result or NULL on error. */
+ * |*out|. Note that, even if |*out| is already non-NULL on entry, it will not
+ * be written to. Rather, a fresh |ECDSA_SIG| is allocated and the previous one
+ * is freed. On successful exit, |*inp| is advanced past the DER structure. It
+ * returns the result or NULL on error. */
OPENSSL_EXPORT ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **out, const uint8_t **inp,
long len);
diff --git a/src/include/openssl/err.h b/src/include/openssl/err.h
index 40361d79..cac50e0f 100644
--- a/src/include/openssl/err.h
+++ b/src/include/openssl/err.h
@@ -317,7 +317,8 @@ OPENSSL_EXPORT void ERR_add_error_data(unsigned count, ...);
/* ERR_add_error_dataf takes a printf-style format and arguments, and sets the
* result as the data on the most recent error. */
-OPENSSL_EXPORT void ERR_add_error_dataf(const char *format, ...);
+OPENSSL_EXPORT void ERR_add_error_dataf(const char *format, ...)
+ OPENSSL_PRINTF_FORMAT_FUNC(1, 2);
/* ERR_set_mark "marks" the most recent error for use with |ERR_pop_to_mark|.
* It returns one if an error was marked and zero if there are no errors. */
@@ -367,7 +368,7 @@ struct err_error_st {
/* ERR_NUM_ERRORS is the limit of the number of errors in the queue. */
#define ERR_NUM_ERRORS 16
-/* ERR_STATE contains the per-thread, error queue. */
+/* err_state_st (aka |ERR_STATE|) contains the per-thread, error queue. */
typedef struct err_state_st {
/* errors contains the ERR_NUM_ERRORS most recent errors, organised as a ring
* buffer. */
diff --git a/src/include/openssl/evp.h b/src/include/openssl/evp.h
index be2ea332..398c7414 100644
--- a/src/include/openssl/evp.h
+++ b/src/include/openssl/evp.h
@@ -69,7 +69,7 @@
#include <openssl/base64.h>
#include <openssl/cipher.h>
#include <openssl/digest.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
#if defined(__cplusplus)
extern "C" {
@@ -133,8 +133,8 @@ OPENSSL_EXPORT int EVP_PKEY_bits(EVP_PKEY *pkey);
* values. */
OPENSSL_EXPORT int EVP_PKEY_id(const EVP_PKEY *pkey);
-/* EVP_PKEY_type returns a canonicalised form of |NID|. For example,
- * |EVP_PKEY_RSA2| will be turned into |EVP_PKEY_RSA|. */
+/* EVP_PKEY_type returns |nid| if |nid| is a known key type and |NID_undef|
+ * otherwise. */
OPENSSL_EXPORT int EVP_PKEY_type(int nid);
@@ -165,7 +165,6 @@ 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_EC NID_X9_62_id_ecPublicKey
@@ -189,34 +188,37 @@ OPENSSL_EXPORT int EVP_PKEY_cmp_parameters(const EVP_PKEY *a,
/* ASN.1 functions */
-/* d2i_PrivateKey parses an ASN.1, DER-encoded, 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 |EVP_PKEY| is allocated. On
- * successful exit, |*inp| is advanced past the DER structure. It returns the
- * result or NULL on error. */
-OPENSSL_EXPORT EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **out,
- const uint8_t **inp, long len);
-
-/* d2i_AutoPrivateKey acts the same as |d2i_PrivateKey|, but detects the type
- * of the private key. */
-OPENSSL_EXPORT EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **out, const uint8_t **inp,
- long len);
+/* EVP_parse_public_key decodes a DER-encoded SubjectPublicKeyInfo structure
+ * (RFC 5280) from |cbs| and advances |cbs|. It returns a newly-allocated
+ * |EVP_PKEY| or NULL on error.
+ *
+ * The caller must check the type of the parsed public key to ensure it is
+ * suitable and validate other desired key properties such as RSA modulus size
+ * or EC curve. */
+OPENSSL_EXPORT EVP_PKEY *EVP_parse_public_key(CBS *cbs);
-/* i2d_PrivateKey marshals a 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. */
-OPENSSL_EXPORT int i2d_PrivateKey(const EVP_PKEY *key, uint8_t **outp);
+/* EVP_marshal_public_key marshals |key| as a DER-encoded SubjectPublicKeyInfo
+ * structure (RFC 5280) and appends the result to |cbb|. It returns one on
+ * success and zero on error. */
+OPENSSL_EXPORT int EVP_marshal_public_key(CBB *cbb, const EVP_PKEY *key);
-/* 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.
+/* EVP_parse_private_key decodes a DER-encoded PrivateKeyInfo structure (RFC
+ * 5208) from |cbs| and advances |cbs|. It returns a newly-allocated |EVP_PKEY|
+ * or NULL 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);
+ * The caller must check the type of the parsed private key to ensure it is
+ * suitable and validate other desired key properties such as RSA modulus size
+ * or EC curve.
+ *
+ * A PrivateKeyInfo ends with an optional set of attributes. These are not
+ * processed and so this function will silently ignore any trailing data in the
+ * structure. */
+OPENSSL_EXPORT EVP_PKEY *EVP_parse_private_key(CBS *cbs);
+
+/* EVP_marshal_private_key marshals |key| as a DER-encoded PrivateKeyInfo
+ * structure (RFC 5208) and appends the result to |cbb|. It returns one on
+ * success and zero on error. */
+OPENSSL_EXPORT int EVP_marshal_private_key(CBB *cbb, const EVP_PKEY *key);
/* Signing */
@@ -248,15 +250,6 @@ OPENSSL_EXPORT int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data,
OPENSSL_EXPORT int EVP_DigestSignFinal(EVP_MD_CTX *ctx, uint8_t *out_sig,
size_t *out_sig_len);
-/* EVP_DigestSignAlgorithm encodes the signing parameters of |ctx| as an
- * AlgorithmIdentifer and saves the result in |algor|.
- *
- * It returns one on success, or zero on error.
- *
- * TODO(davidben): This API should eventually lose the dependency on
- * crypto/asn1/. */
-OPENSSL_EXPORT int EVP_DigestSignAlgorithm(EVP_MD_CTX *ctx, X509_ALGOR *algor);
-
/* Verifying */
@@ -271,18 +264,6 @@ OPENSSL_EXPORT int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
const EVP_MD *type, ENGINE *e,
EVP_PKEY *pkey);
-/* EVP_DigestVerifyInitFromAlgorithm sets up |ctx| for a signature verification
- * operation with public key |pkey| and parameters from |algor|. The |ctx|
- * argument must have been initialised with |EVP_MD_CTX_init|.
- *
- * It returns one on success, or zero on error.
- *
- * TODO(davidben): This API should eventually lose the dependency on
- * crypto/asn1/. */
-OPENSSL_EXPORT int EVP_DigestVerifyInitFromAlgorithm(EVP_MD_CTX *ctx,
- X509_ALGOR *algor,
- EVP_PKEY *pkey);
-
/* EVP_DigestVerifyUpdate appends |len| bytes from |data| to the data which
* will be verified by |EVP_DigestVerifyFinal|. It returns one. */
OPENSSL_EXPORT int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data,
@@ -427,14 +408,6 @@ OPENSSL_EXPORT EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *ctx);
/* EVP_PKEY_CTX_get0_pkey returns the |EVP_PKEY| associated with |ctx|. */
OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx);
-/* EVP_PKEY_CTX_set_app_data sets an opaque pointer on |ctx|. */
-OPENSSL_EXPORT void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data);
-
-/* EVP_PKEY_CTX_get_app_data returns the opaque pointer from |ctx| that was
- * previously set with |EVP_PKEY_CTX_set_app_data|, or NULL if none has been
- * set. */
-OPENSSL_EXPORT void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx);
-
/* EVP_PKEY_sign_init initialises an |EVP_PKEY_CTX| for a signing operation. It
* should be called before |EVP_PKEY_sign|.
*
@@ -510,6 +483,34 @@ OPENSSL_EXPORT int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, uint8_t *out,
size_t *out_len, const uint8_t *in,
size_t in_len);
+/* EVP_PKEY_verify_recover_init initialises an |EVP_PKEY_CTX| for a public-key
+ * decryption operation. It should be called before |EVP_PKEY_verify_recover|.
+ *
+ * Public-key decryption is a very obscure operation that is only implemented
+ * by RSA keys. It is effectively a signature verification operation that
+ * returns the signed message directly. It is almost certainly not what you
+ * want.
+ *
+ * It returns one on success or zero on error. */
+OPENSSL_EXPORT int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx);
+
+/* EVP_PKEY_verify_recover decrypts |sig_len| bytes from |sig|. If |out| is
+ * NULL, the maximum size of the plaintext is written to |out_len|. Otherwise,
+ * |*out_len| must contain the number of bytes of space available at |out|. If
+ * sufficient, the ciphertext will be written to |out| and |*out_len| updated
+ * with the true length.
+ *
+ * WARNING: Setting |out| to NULL only gives the maximum size of the
+ * plaintext. The actual plaintext may be smaller.
+ *
+ * See the warning about this operation in |EVP_PKEY_verify_recover_init|. It
+ * is probably not what you want.
+ *
+ * It returns one on success or zero on error. */
+OPENSSL_EXPORT int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, uint8_t *out,
+ size_t *out_len, const uint8_t *sig,
+ size_t siglen);
+
/* EVP_PKEY_derive_init initialises an |EVP_PKEY_CTX| for a key derivation
* operation. It should be called before |EVP_PKEY_derive_set_peer| and
* |EVP_PKEY_derive|.
@@ -628,7 +629,7 @@ OPENSSL_EXPORT int EVP_PKEY_CTX_get_rsa_mgf1_md(EVP_PKEY_CTX *ctx,
*
* Returns one on success or zero on error. */
OPENSSL_EXPORT int EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX *ctx,
- const uint8_t *label,
+ uint8_t *label,
size_t label_len);
/* EVP_PKEY_CTX_get0_rsa_oaep_label sets |*out_label| to point to the internal
@@ -646,6 +647,10 @@ OPENSSL_EXPORT int EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx,
* |EVP_PKEY| of that type. */
#define EVP_PKEY_DH NID_dhKeyAgreement
+/* EVP_PKEY_RSA2 was historically an alternate form for RSA public keys (OID
+ * 2.5.8.1.1), but is no longer accepted. */
+#define EVP_PKEY_RSA2 NID_rsa
+
/* OpenSSL_add_all_algorithms does nothing. */
OPENSSL_EXPORT void OpenSSL_add_all_algorithms(void);
@@ -658,22 +663,63 @@ OPENSSL_EXPORT void OpenSSL_add_all_digests(void);
/* EVP_cleanup does nothing. */
OPENSSL_EXPORT void EVP_cleanup(void);
+OPENSSL_EXPORT void EVP_CIPHER_do_all_sorted(
+ void (*callback)(const EVP_CIPHER *cipher, const char *name,
+ const char *unused, void *arg),
+ void *arg);
+
+OPENSSL_EXPORT void EVP_MD_do_all_sorted(void (*callback)(const EVP_MD *cipher,
+ const char *name,
+ const char *unused,
+ void *arg),
+ void *arg);
+
+/* i2d_PrivateKey marshals a 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.
+ *
+ * RSA keys are serialized as a DER-encoded RSAPublicKey (RFC 3447) structure.
+ * EC keys are serialized as a DER-encoded ECPrivateKey (RFC 5915) structure.
+ *
+ * Use |RSA_marshal_private_key| or |EC_marshal_private_key| instead. */
+OPENSSL_EXPORT int i2d_PrivateKey(const EVP_PKEY *key, uint8_t **outp);
-/* Private functions */
+/* 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.
+ *
+ * RSA keys are serialized as a DER-encoded RSAPublicKey (RFC 3447) structure.
+ * EC keys are serialized as an EC point per SEC 1.
+ *
+ * Use |RSA_marshal_public_key| or |EC_POINT_point2cbb| instead. */
+OPENSSL_EXPORT int i2d_PublicKey(EVP_PKEY *key, uint8_t **outp);
-/* 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);
+/* d2i_PrivateKey parses an ASN.1, DER-encoded, private key from |len| bytes at
+ * |*inp|. If |out| is not NULL then, on exit, a pointer to the result is in
+ * |*out|. Note that, even if |*out| is already non-NULL on entry, it will not
+ * be written to. Rather, a fresh |EVP_PKEY| is allocated and the previous one
+ * is freed. On successful exit, |*inp| is advanced past the DER structure. It
+ * returns the result or NULL on error.
+ *
+ * This function tries to detect one of several formats. Instead, use
+ * |EVP_parse_private_key| for a PrivateKeyInfo, |RSA_parse_private_key| for an
+ * RSAPrivateKey, and |EC_parse_private_key| for an ECPrivateKey. */
+OPENSSL_EXPORT EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **out,
+ const uint8_t **inp, long len);
-/* 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.
+/* d2i_AutoPrivateKey acts the same as |d2i_PrivateKey|, but detects the type
+ * of the private key.
*
- * 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);
+ * This function tries to detect one of several formats. Instead, use
+ * |EVP_parse_private_key| for a PrivateKeyInfo, |RSA_parse_private_key| for an
+ * RSAPrivateKey, and |EC_parse_private_key| for an ECPrivateKey. */
+OPENSSL_EXPORT EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **out, const uint8_t **inp,
+ long len);
+
+
+/* Private structures. */
struct evp_pkey_st {
CRYPTO_refcount_t references;
@@ -702,49 +748,33 @@ struct evp_pkey_st {
#define EVP_R_BUFFER_TOO_SMALL 100
#define EVP_R_COMMAND_NOT_SUPPORTED 101
-#define EVP_R_DIFFERENT_KEY_TYPES 104
-#define EVP_R_DIFFERENT_PARAMETERS 105
-#define EVP_R_EXPECTING_AN_EC_KEY_KEY 107
-#define EVP_R_EXPECTING_A_DH_KEY 109
-#define EVP_R_EXPECTING_A_DSA_KEY 110
-#define EVP_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE 111
-#define EVP_R_INVALID_CURVE 112
-#define EVP_R_INVALID_DIGEST_LENGTH 113
-#define EVP_R_INVALID_DIGEST_TYPE 114
-#define EVP_R_INVALID_KEYBITS 115
-#define EVP_R_INVALID_MGF1_MD 116
-#define EVP_R_INVALID_PADDING_MODE 118
-#define EVP_R_INVALID_PSS_PARAMETERS 119
-#define EVP_R_INVALID_SALT_LENGTH 121
-#define EVP_R_INVALID_TRAILER 122
-#define EVP_R_KEYS_NOT_SET 123
-#define EVP_R_MISSING_PARAMETERS 124
-#define EVP_R_NO_DEFAULT_DIGEST 125
-#define EVP_R_NO_KEY_SET 126
-#define EVP_R_NO_MDC2_SUPPORT 127
-#define EVP_R_NO_NID_FOR_CURVE 128
-#define EVP_R_NO_OPERATION_SET 129
-#define EVP_R_NO_PARAMETERS_SET 130
-#define EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 131
-#define EVP_R_OPERATON_NOT_INITIALIZED 132
-#define EVP_R_UNKNOWN_DIGEST 133
-#define EVP_R_UNKNOWN_MASK_DIGEST 134
-#define EVP_R_UNSUPPORTED_ALGORITHM 138
-#define EVP_R_UNSUPPORTED_MASK_ALGORITHM 139
-#define EVP_R_UNSUPPORTED_MASK_PARAMETER 140
-#define EVP_R_EXPECTING_AN_RSA_KEY 141
-#define EVP_R_INVALID_OPERATION 142
-#define EVP_R_DECODE_ERROR 143
-#define EVP_R_INVALID_PSS_SALTLEN 144
-#define EVP_R_UNKNOWN_PUBLIC_KEY_TYPE 145
-#define EVP_R_CONTEXT_NOT_INITIALISED 146
-#define EVP_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED 147
-#define EVP_R_WRONG_PUBLIC_KEY_TYPE 148
-#define EVP_R_UNKNOWN_SIGNATURE_ALGORITHM 149
-#define EVP_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM 150
-#define EVP_R_BN_DECODE_ERROR 151
-#define EVP_R_PARAMETER_ENCODING_ERROR 152
-#define EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE 153
-#define EVP_R_UNSUPPORTED_SIGNATURE_TYPE 154
+#define EVP_R_DECODE_ERROR 102
+#define EVP_R_DIFFERENT_KEY_TYPES 103
+#define EVP_R_DIFFERENT_PARAMETERS 104
+#define EVP_R_ENCODE_ERROR 105
+#define EVP_R_EXPECTING_AN_EC_KEY_KEY 106
+#define EVP_R_EXPECTING_AN_RSA_KEY 107
+#define EVP_R_EXPECTING_A_DSA_KEY 108
+#define EVP_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE 109
+#define EVP_R_INVALID_DIGEST_LENGTH 110
+#define EVP_R_INVALID_DIGEST_TYPE 111
+#define EVP_R_INVALID_KEYBITS 112
+#define EVP_R_INVALID_MGF1_MD 113
+#define EVP_R_INVALID_OPERATION 114
+#define EVP_R_INVALID_PADDING_MODE 115
+#define EVP_R_INVALID_PSS_SALTLEN 116
+#define EVP_R_KEYS_NOT_SET 117
+#define EVP_R_MISSING_PARAMETERS 118
+#define EVP_R_NO_DEFAULT_DIGEST 119
+#define EVP_R_NO_KEY_SET 120
+#define EVP_R_NO_MDC2_SUPPORT 121
+#define EVP_R_NO_NID_FOR_CURVE 122
+#define EVP_R_NO_OPERATION_SET 123
+#define EVP_R_NO_PARAMETERS_SET 124
+#define EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 125
+#define EVP_R_OPERATON_NOT_INITIALIZED 126
+#define EVP_R_UNKNOWN_PUBLIC_KEY_TYPE 127
+#define EVP_R_UNSUPPORTED_ALGORITHM 128
+#define EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE 129
#endif /* OPENSSL_HEADER_EVP_H */
diff --git a/src/include/openssl/hkdf.h b/src/include/openssl/hkdf.h
index b7a0dc25..8c96c4c2 100644
--- a/src/include/openssl/hkdf.h
+++ b/src/include/openssl/hkdf.h
@@ -17,14 +17,17 @@
#include <openssl/base.h>
-#ifdef __cplusplus
+#if defined(__cplusplus)
extern "C" {
#endif
-/* Computes HKDF (as specified by RFC 5869) of initial keying material |secret|
- * with |salt| and |info| using |digest|, and outputs |out_len| bytes to
- * |out_key|. It returns one on success and zero on error.
+/* HKDF. */
+
+
+/* HKDF computes HKDF (as specified by RFC 5869) of initial keying material
+ * |secret| with |salt| and |info| using |digest|, and outputs |out_len| bytes
+ * to |out_key|. It returns one on success and zero on error.
*
* HKDF is an Extract-and-Expand algorithm. It does not do any key stretching,
* and as such, is not suited to be used alone to generate a key from a
diff --git a/src/include/openssl/hmac.h b/src/include/openssl/hmac.h
index e521212d..5a4e9c7f 100644
--- a/src/include/openssl/hmac.h
+++ b/src/include/openssl/hmac.h
@@ -143,8 +143,6 @@ OPENSSL_EXPORT int HMAC_CTX_copy(HMAC_CTX *dest, const HMAC_CTX *src);
/* Private functions */
-#define HMAC_MAX_MD_CBLOCK 128 /* largest known is SHA512 */
-
struct hmac_ctx_st {
const EVP_MD *md;
EVP_MD_CTX md_ctx;
diff --git a/src/include/openssl/md4.h b/src/include/openssl/md4.h
index 93c7af83..b66fcb0f 100644
--- a/src/include/openssl/md4.h
+++ b/src/include/openssl/md4.h
@@ -83,6 +83,10 @@ OPENSSL_EXPORT int MD4_Update(MD4_CTX *md4, const void *data, size_t len);
* returns one. */
OPENSSL_EXPORT int MD4_Final(uint8_t *md, MD4_CTX *md4);
+/* MD4 writes the digest of |len| bytes from |data| to |out| and returns |out|.
+ * There must be at least |MD4_DIGEST_LENGTH| bytes of space in |out|. */
+OPENSSL_EXPORT uint8_t *MD4(const uint8_t *data, size_t len, uint8_t *out);
+
/* MD4_Transform is a low-level function that performs a single, MD4 block
* transformation using the state from |md4| and 64 bytes from |block|. */
OPENSSL_EXPORT void MD4_Transform(MD4_CTX *md4, const uint8_t *block);
diff --git a/src/include/openssl/mem.h b/src/include/openssl/mem.h
index c8e2b3ef..31756f03 100644
--- a/src/include/openssl/mem.h
+++ b/src/include/openssl/mem.h
@@ -114,23 +114,21 @@ OPENSSL_EXPORT int OPENSSL_strncasecmp(const char *a, const char *b, size_t n);
* representation of the given type. */
#define DECIMAL_SIZE(type) ((sizeof(type)*8+2)/3+1)
-/* Printf functions.
- *
- * These functions are either OpenSSL wrappers for standard functions (i.e.
- * |BIO_snprintf| and |BIO_vsnprintf|) which don't exist in C89, or are
- * versions of printf functions that output to a BIO rather than a FILE. */
-#ifdef __GNUC__
-#define __bio_h__attr__ __attribute__
-#else
-#define __bio_h__attr__(x)
-#endif
+/* BIO_snprintf has the same behavior as snprintf(3). */
OPENSSL_EXPORT int BIO_snprintf(char *buf, size_t n, const char *format, ...)
- __bio_h__attr__((__format__(__printf__, 3, 4)));
+ OPENSSL_PRINTF_FORMAT_FUNC(3, 4);
+/* BIO_vsnprintf has the same behavior as vsnprintf(3). */
OPENSSL_EXPORT int BIO_vsnprintf(char *buf, size_t n, const char *format,
va_list args)
- __bio_h__attr__((__format__(__printf__, 3, 0)));
-#undef __bio_h__attr__
+ OPENSSL_PRINTF_FORMAT_FUNC(3, 0);
+
+
+/* Deprecated functions. */
+
+#define CRYPTO_malloc OPENSSL_malloc
+#define CRYPTO_realloc OPENSSL_realloc
+#define CRYPTO_free OPENSSL_free
#if defined(__cplusplus)
diff --git a/src/include/openssl/newhope.h b/src/include/openssl/newhope.h
new file mode 100644
index 00000000..af573bae
--- /dev/null
+++ b/src/include/openssl/newhope.h
@@ -0,0 +1,78 @@
+/* Copyright (c) 2016, 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_NEWHOPE_H
+#define OPENSSL_HEADER_NEWHOPE_H
+
+#include <openssl/base.h>
+#include <openssl/sha.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+/* Post-quantum key agreement, based upon the reference
+ * implementation. Note: this implementation does not interoperate
+ * with the reference implementation!
+ *
+ * Source: https://github.com/tpoeppelmann/newhope
+ *
+ * The authors' permission to use their code is gratefully acknowledged. */
+
+
+/* NEWHOPE_POLY_new returns a new |NEWHOPE_POLY| object, or NULL on error. */
+OPENSSL_EXPORT NEWHOPE_POLY *NEWHOPE_POLY_new(void);
+
+/* NEWHOPE_POLY_free frees |p|. */
+OPENSSL_EXPORT void NEWHOPE_POLY_free(NEWHOPE_POLY *p);
+
+/* NEWHOPE_SERVERMSG_LENGTH is the length of the server's message to the
+ * client. */
+#define NEWHOPE_SERVERMSG_LENGTH (((1024 * 14) / 8) + 32)
+
+/* NEWHOPE_CLIENTMSG_LENGTH is the length of the client's message to the
+ * server. */
+#define NEWHOPE_CLIENTMSG_LENGTH (((1024 * 14) / 8) + 1024 / 4)
+
+/* NEWHOPE_keygen initializes |out_msg| and |out_sk| for a new key
+ * exchange. |msg| must have room for |NEWHOPE_SERVERMSG_LENGTH| bytes. Neither
+ * output may be cached. */
+OPENSSL_EXPORT void NEWHOPE_keygen(uint8_t out_msg[NEWHOPE_SERVERMSG_LENGTH],
+ NEWHOPE_POLY *out_sk);
+
+/* NEWHOPE_server_compute_key completes a key exchange given a client message
+ * |msg| and the previously generated server secret |sk|. The result of the
+ * key exchange is written to |out_key|, which must have space for
+ * |SHA256_DIGEST_LENGTH| bytes. Returns 1 on success and 0 on error. */
+OPENSSL_EXPORT int NEWHOPE_server_compute_key(
+ uint8_t out_key[SHA256_DIGEST_LENGTH], const NEWHOPE_POLY *sk,
+ const uint8_t msg[NEWHOPE_CLIENTMSG_LENGTH], size_t msg_len);
+
+/* NEWHOPE_client_compute_key completes a key exchange given a server message
+ * |msg|. The result of the key exchange is written to |out_key|, which must
+ * have space for |SHA256_DIGEST_LENGTH| bytes. The message to be send to the
+ * client is written to |out_msg|, which must have room for
+ * |NEWHOPE_CLIENTMSG_LENGTH| bytes. Returns 1 on success and 0 on error. */
+OPENSSL_EXPORT int NEWHOPE_client_compute_key(
+ uint8_t out_key[SHA256_DIGEST_LENGTH],
+ uint8_t out_msg[NEWHOPE_CLIENTMSG_LENGTH],
+ const uint8_t msg[NEWHOPE_SERVERMSG_LENGTH], size_t msg_len);
+
+
+#if defined(__cplusplus)
+} /* extern "C" */
+#endif
+
+#endif /* OPENSSL_HEADER_NEWHOPE_H */
diff --git a/src/include/openssl/nid.h b/src/include/openssl/nid.h
new file mode 100644
index 00000000..d51a67c3
--- /dev/null
+++ b/src/include/openssl/nid.h
@@ -0,0 +1,4163 @@
+/* THIS FILE IS GENERATED FROM objects.txt by objects.pl via the
+ * following command:
+ * perl objects.pl objects.txt obj_mac.num ../../include/openssl/nid.h */
+
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef OPENSSL_HEADER_NID_H
+#define OPENSSL_HEADER_NID_H
+
+
+/* The nid library provides numbered values for ASN.1 object identifiers and
+ * other symbols. These values are used by other libraries to identify
+ * cryptographic primitives.
+ *
+ * A separate objects library, obj.h, provides functions for converting between
+ * nids and object identifiers. However it depends on large internal tables with
+ * the encodings of every nid defind. Consumers concerned with binary size
+ * should instead embed the encodings of the few consumed OIDs and compare
+ * against those.
+ *
+ * These values should not be used outside of a single process; they are not
+ * stable identifiers. */
+
+
+#define SN_undef "UNDEF"
+#define LN_undef "undefined"
+#define NID_undef 0
+#define OBJ_undef 0L
+
+#define SN_itu_t "ITU-T"
+#define LN_itu_t "itu-t"
+#define NID_itu_t 645
+#define OBJ_itu_t 0L
+
+#define NID_ccitt 404
+#define OBJ_ccitt OBJ_itu_t
+
+#define SN_iso "ISO"
+#define LN_iso "iso"
+#define NID_iso 181
+#define OBJ_iso 1L
+
+#define SN_joint_iso_itu_t "JOINT-ISO-ITU-T"
+#define LN_joint_iso_itu_t "joint-iso-itu-t"
+#define NID_joint_iso_itu_t 646
+#define OBJ_joint_iso_itu_t 2L
+
+#define NID_joint_iso_ccitt 393
+#define OBJ_joint_iso_ccitt OBJ_joint_iso_itu_t
+
+#define SN_member_body "member-body"
+#define LN_member_body "ISO Member Body"
+#define NID_member_body 182
+#define OBJ_member_body OBJ_iso,2L
+
+#define SN_identified_organization "identified-organization"
+#define NID_identified_organization 676
+#define OBJ_identified_organization OBJ_iso,3L
+
+#define SN_hmac_md5 "HMAC-MD5"
+#define LN_hmac_md5 "hmac-md5"
+#define NID_hmac_md5 780
+#define OBJ_hmac_md5 OBJ_identified_organization,6L,1L,5L,5L,8L,1L,1L
+
+#define SN_hmac_sha1 "HMAC-SHA1"
+#define LN_hmac_sha1 "hmac-sha1"
+#define NID_hmac_sha1 781
+#define OBJ_hmac_sha1 OBJ_identified_organization,6L,1L,5L,5L,8L,1L,2L
+
+#define SN_certicom_arc "certicom-arc"
+#define NID_certicom_arc 677
+#define OBJ_certicom_arc OBJ_identified_organization,132L
+
+#define SN_international_organizations "international-organizations"
+#define LN_international_organizations "International Organizations"
+#define NID_international_organizations 647
+#define OBJ_international_organizations OBJ_joint_iso_itu_t,23L
+
+#define SN_wap "wap"
+#define NID_wap 678
+#define OBJ_wap OBJ_international_organizations,43L
+
+#define SN_wap_wsg "wap-wsg"
+#define NID_wap_wsg 679
+#define OBJ_wap_wsg OBJ_wap,1L
+
+#define SN_selected_attribute_types "selected-attribute-types"
+#define LN_selected_attribute_types "Selected Attribute Types"
+#define NID_selected_attribute_types 394
+#define OBJ_selected_attribute_types OBJ_joint_iso_itu_t,5L,1L,5L
+
+#define SN_clearance "clearance"
+#define NID_clearance 395
+#define OBJ_clearance OBJ_selected_attribute_types,55L
+
+#define SN_ISO_US "ISO-US"
+#define LN_ISO_US "ISO US Member Body"
+#define NID_ISO_US 183
+#define OBJ_ISO_US OBJ_member_body,840L
+
+#define SN_X9_57 "X9-57"
+#define LN_X9_57 "X9.57"
+#define NID_X9_57 184
+#define OBJ_X9_57 OBJ_ISO_US,10040L
+
+#define SN_X9cm "X9cm"
+#define LN_X9cm "X9.57 CM ?"
+#define NID_X9cm 185
+#define OBJ_X9cm OBJ_X9_57,4L
+
+#define SN_dsa "DSA"
+#define LN_dsa "dsaEncryption"
+#define NID_dsa 116
+#define OBJ_dsa OBJ_X9cm,1L
+
+#define SN_dsaWithSHA1 "DSA-SHA1"
+#define LN_dsaWithSHA1 "dsaWithSHA1"
+#define NID_dsaWithSHA1 113
+#define OBJ_dsaWithSHA1 OBJ_X9cm,3L
+
+#define SN_ansi_X9_62 "ansi-X9-62"
+#define LN_ansi_X9_62 "ANSI X9.62"
+#define NID_ansi_X9_62 405
+#define OBJ_ansi_X9_62 OBJ_ISO_US,10045L
+
+#define OBJ_X9_62_id_fieldType OBJ_ansi_X9_62,1L
+
+#define SN_X9_62_prime_field "prime-field"
+#define NID_X9_62_prime_field 406
+#define OBJ_X9_62_prime_field OBJ_X9_62_id_fieldType,1L
+
+#define SN_X9_62_characteristic_two_field "characteristic-two-field"
+#define NID_X9_62_characteristic_two_field 407
+#define OBJ_X9_62_characteristic_two_field OBJ_X9_62_id_fieldType,2L
+
+#define SN_X9_62_id_characteristic_two_basis "id-characteristic-two-basis"
+#define NID_X9_62_id_characteristic_two_basis 680
+#define OBJ_X9_62_id_characteristic_two_basis OBJ_X9_62_characteristic_two_field,3L
+
+#define SN_X9_62_onBasis "onBasis"
+#define NID_X9_62_onBasis 681
+#define OBJ_X9_62_onBasis OBJ_X9_62_id_characteristic_two_basis,1L
+
+#define SN_X9_62_tpBasis "tpBasis"
+#define NID_X9_62_tpBasis 682
+#define OBJ_X9_62_tpBasis OBJ_X9_62_id_characteristic_two_basis,2L
+
+#define SN_X9_62_ppBasis "ppBasis"
+#define NID_X9_62_ppBasis 683
+#define OBJ_X9_62_ppBasis OBJ_X9_62_id_characteristic_two_basis,3L
+
+#define OBJ_X9_62_id_publicKeyType OBJ_ansi_X9_62,2L
+
+#define SN_X9_62_id_ecPublicKey "id-ecPublicKey"
+#define NID_X9_62_id_ecPublicKey 408
+#define OBJ_X9_62_id_ecPublicKey OBJ_X9_62_id_publicKeyType,1L
+
+#define OBJ_X9_62_ellipticCurve OBJ_ansi_X9_62,3L
+
+#define OBJ_X9_62_c_TwoCurve OBJ_X9_62_ellipticCurve,0L
+
+#define SN_X9_62_c2pnb163v1 "c2pnb163v1"
+#define NID_X9_62_c2pnb163v1 684
+#define OBJ_X9_62_c2pnb163v1 OBJ_X9_62_c_TwoCurve,1L
+
+#define SN_X9_62_c2pnb163v2 "c2pnb163v2"
+#define NID_X9_62_c2pnb163v2 685
+#define OBJ_X9_62_c2pnb163v2 OBJ_X9_62_c_TwoCurve,2L
+
+#define SN_X9_62_c2pnb163v3 "c2pnb163v3"
+#define NID_X9_62_c2pnb163v3 686
+#define OBJ_X9_62_c2pnb163v3 OBJ_X9_62_c_TwoCurve,3L
+
+#define SN_X9_62_c2pnb176v1 "c2pnb176v1"
+#define NID_X9_62_c2pnb176v1 687
+#define OBJ_X9_62_c2pnb176v1 OBJ_X9_62_c_TwoCurve,4L
+
+#define SN_X9_62_c2tnb191v1 "c2tnb191v1"
+#define NID_X9_62_c2tnb191v1 688
+#define OBJ_X9_62_c2tnb191v1 OBJ_X9_62_c_TwoCurve,5L
+
+#define SN_X9_62_c2tnb191v2 "c2tnb191v2"
+#define NID_X9_62_c2tnb191v2 689
+#define OBJ_X9_62_c2tnb191v2 OBJ_X9_62_c_TwoCurve,6L
+
+#define SN_X9_62_c2tnb191v3 "c2tnb191v3"
+#define NID_X9_62_c2tnb191v3 690
+#define OBJ_X9_62_c2tnb191v3 OBJ_X9_62_c_TwoCurve,7L
+
+#define SN_X9_62_c2onb191v4 "c2onb191v4"
+#define NID_X9_62_c2onb191v4 691
+#define OBJ_X9_62_c2onb191v4 OBJ_X9_62_c_TwoCurve,8L
+
+#define SN_X9_62_c2onb191v5 "c2onb191v5"
+#define NID_X9_62_c2onb191v5 692
+#define OBJ_X9_62_c2onb191v5 OBJ_X9_62_c_TwoCurve,9L
+
+#define SN_X9_62_c2pnb208w1 "c2pnb208w1"
+#define NID_X9_62_c2pnb208w1 693
+#define OBJ_X9_62_c2pnb208w1 OBJ_X9_62_c_TwoCurve,10L
+
+#define SN_X9_62_c2tnb239v1 "c2tnb239v1"
+#define NID_X9_62_c2tnb239v1 694
+#define OBJ_X9_62_c2tnb239v1 OBJ_X9_62_c_TwoCurve,11L
+
+#define SN_X9_62_c2tnb239v2 "c2tnb239v2"
+#define NID_X9_62_c2tnb239v2 695
+#define OBJ_X9_62_c2tnb239v2 OBJ_X9_62_c_TwoCurve,12L
+
+#define SN_X9_62_c2tnb239v3 "c2tnb239v3"
+#define NID_X9_62_c2tnb239v3 696
+#define OBJ_X9_62_c2tnb239v3 OBJ_X9_62_c_TwoCurve,13L
+
+#define SN_X9_62_c2onb239v4 "c2onb239v4"
+#define NID_X9_62_c2onb239v4 697
+#define OBJ_X9_62_c2onb239v4 OBJ_X9_62_c_TwoCurve,14L
+
+#define SN_X9_62_c2onb239v5 "c2onb239v5"
+#define NID_X9_62_c2onb239v5 698
+#define OBJ_X9_62_c2onb239v5 OBJ_X9_62_c_TwoCurve,15L
+
+#define SN_X9_62_c2pnb272w1 "c2pnb272w1"
+#define NID_X9_62_c2pnb272w1 699
+#define OBJ_X9_62_c2pnb272w1 OBJ_X9_62_c_TwoCurve,16L
+
+#define SN_X9_62_c2pnb304w1 "c2pnb304w1"
+#define NID_X9_62_c2pnb304w1 700
+#define OBJ_X9_62_c2pnb304w1 OBJ_X9_62_c_TwoCurve,17L
+
+#define SN_X9_62_c2tnb359v1 "c2tnb359v1"
+#define NID_X9_62_c2tnb359v1 701
+#define OBJ_X9_62_c2tnb359v1 OBJ_X9_62_c_TwoCurve,18L
+
+#define SN_X9_62_c2pnb368w1 "c2pnb368w1"
+#define NID_X9_62_c2pnb368w1 702
+#define OBJ_X9_62_c2pnb368w1 OBJ_X9_62_c_TwoCurve,19L
+
+#define SN_X9_62_c2tnb431r1 "c2tnb431r1"
+#define NID_X9_62_c2tnb431r1 703
+#define OBJ_X9_62_c2tnb431r1 OBJ_X9_62_c_TwoCurve,20L
+
+#define OBJ_X9_62_primeCurve OBJ_X9_62_ellipticCurve,1L
+
+#define SN_X9_62_prime192v1 "prime192v1"
+#define NID_X9_62_prime192v1 409
+#define OBJ_X9_62_prime192v1 OBJ_X9_62_primeCurve,1L
+
+#define SN_X9_62_prime192v2 "prime192v2"
+#define NID_X9_62_prime192v2 410
+#define OBJ_X9_62_prime192v2 OBJ_X9_62_primeCurve,2L
+
+#define SN_X9_62_prime192v3 "prime192v3"
+#define NID_X9_62_prime192v3 411
+#define OBJ_X9_62_prime192v3 OBJ_X9_62_primeCurve,3L
+
+#define SN_X9_62_prime239v1 "prime239v1"
+#define NID_X9_62_prime239v1 412
+#define OBJ_X9_62_prime239v1 OBJ_X9_62_primeCurve,4L
+
+#define SN_X9_62_prime239v2 "prime239v2"
+#define NID_X9_62_prime239v2 413
+#define OBJ_X9_62_prime239v2 OBJ_X9_62_primeCurve,5L
+
+#define SN_X9_62_prime239v3 "prime239v3"
+#define NID_X9_62_prime239v3 414
+#define OBJ_X9_62_prime239v3 OBJ_X9_62_primeCurve,6L
+
+#define SN_X9_62_prime256v1 "prime256v1"
+#define NID_X9_62_prime256v1 415
+#define OBJ_X9_62_prime256v1 OBJ_X9_62_primeCurve,7L
+
+#define OBJ_X9_62_id_ecSigType OBJ_ansi_X9_62,4L
+
+#define SN_ecdsa_with_SHA1 "ecdsa-with-SHA1"
+#define NID_ecdsa_with_SHA1 416
+#define OBJ_ecdsa_with_SHA1 OBJ_X9_62_id_ecSigType,1L
+
+#define SN_ecdsa_with_Recommended "ecdsa-with-Recommended"
+#define NID_ecdsa_with_Recommended 791
+#define OBJ_ecdsa_with_Recommended OBJ_X9_62_id_ecSigType,2L
+
+#define SN_ecdsa_with_Specified "ecdsa-with-Specified"
+#define NID_ecdsa_with_Specified 792
+#define OBJ_ecdsa_with_Specified OBJ_X9_62_id_ecSigType,3L
+
+#define SN_ecdsa_with_SHA224 "ecdsa-with-SHA224"
+#define NID_ecdsa_with_SHA224 793
+#define OBJ_ecdsa_with_SHA224 OBJ_ecdsa_with_Specified,1L
+
+#define SN_ecdsa_with_SHA256 "ecdsa-with-SHA256"
+#define NID_ecdsa_with_SHA256 794
+#define OBJ_ecdsa_with_SHA256 OBJ_ecdsa_with_Specified,2L
+
+#define SN_ecdsa_with_SHA384 "ecdsa-with-SHA384"
+#define NID_ecdsa_with_SHA384 795
+#define OBJ_ecdsa_with_SHA384 OBJ_ecdsa_with_Specified,3L
+
+#define SN_ecdsa_with_SHA512 "ecdsa-with-SHA512"
+#define NID_ecdsa_with_SHA512 796
+#define OBJ_ecdsa_with_SHA512 OBJ_ecdsa_with_Specified,4L
+
+#define OBJ_secg_ellipticCurve OBJ_certicom_arc,0L
+
+#define SN_secp112r1 "secp112r1"
+#define NID_secp112r1 704
+#define OBJ_secp112r1 OBJ_secg_ellipticCurve,6L
+
+#define SN_secp112r2 "secp112r2"
+#define NID_secp112r2 705
+#define OBJ_secp112r2 OBJ_secg_ellipticCurve,7L
+
+#define SN_secp128r1 "secp128r1"
+#define NID_secp128r1 706
+#define OBJ_secp128r1 OBJ_secg_ellipticCurve,28L
+
+#define SN_secp128r2 "secp128r2"
+#define NID_secp128r2 707
+#define OBJ_secp128r2 OBJ_secg_ellipticCurve,29L
+
+#define SN_secp160k1 "secp160k1"
+#define NID_secp160k1 708
+#define OBJ_secp160k1 OBJ_secg_ellipticCurve,9L
+
+#define SN_secp160r1 "secp160r1"
+#define NID_secp160r1 709
+#define OBJ_secp160r1 OBJ_secg_ellipticCurve,8L
+
+#define SN_secp160r2 "secp160r2"
+#define NID_secp160r2 710
+#define OBJ_secp160r2 OBJ_secg_ellipticCurve,30L
+
+#define SN_secp192k1 "secp192k1"
+#define NID_secp192k1 711
+#define OBJ_secp192k1 OBJ_secg_ellipticCurve,31L
+
+#define SN_secp224k1 "secp224k1"
+#define NID_secp224k1 712
+#define OBJ_secp224k1 OBJ_secg_ellipticCurve,32L
+
+#define SN_secp224r1 "secp224r1"
+#define NID_secp224r1 713
+#define OBJ_secp224r1 OBJ_secg_ellipticCurve,33L
+
+#define SN_secp256k1 "secp256k1"
+#define NID_secp256k1 714
+#define OBJ_secp256k1 OBJ_secg_ellipticCurve,10L
+
+#define SN_secp384r1 "secp384r1"
+#define NID_secp384r1 715
+#define OBJ_secp384r1 OBJ_secg_ellipticCurve,34L
+
+#define SN_secp521r1 "secp521r1"
+#define NID_secp521r1 716
+#define OBJ_secp521r1 OBJ_secg_ellipticCurve,35L
+
+#define SN_sect113r1 "sect113r1"
+#define NID_sect113r1 717
+#define OBJ_sect113r1 OBJ_secg_ellipticCurve,4L
+
+#define SN_sect113r2 "sect113r2"
+#define NID_sect113r2 718
+#define OBJ_sect113r2 OBJ_secg_ellipticCurve,5L
+
+#define SN_sect131r1 "sect131r1"
+#define NID_sect131r1 719
+#define OBJ_sect131r1 OBJ_secg_ellipticCurve,22L
+
+#define SN_sect131r2 "sect131r2"
+#define NID_sect131r2 720
+#define OBJ_sect131r2 OBJ_secg_ellipticCurve,23L
+
+#define SN_sect163k1 "sect163k1"
+#define NID_sect163k1 721
+#define OBJ_sect163k1 OBJ_secg_ellipticCurve,1L
+
+#define SN_sect163r1 "sect163r1"
+#define NID_sect163r1 722
+#define OBJ_sect163r1 OBJ_secg_ellipticCurve,2L
+
+#define SN_sect163r2 "sect163r2"
+#define NID_sect163r2 723
+#define OBJ_sect163r2 OBJ_secg_ellipticCurve,15L
+
+#define SN_sect193r1 "sect193r1"
+#define NID_sect193r1 724
+#define OBJ_sect193r1 OBJ_secg_ellipticCurve,24L
+
+#define SN_sect193r2 "sect193r2"
+#define NID_sect193r2 725
+#define OBJ_sect193r2 OBJ_secg_ellipticCurve,25L
+
+#define SN_sect233k1 "sect233k1"
+#define NID_sect233k1 726
+#define OBJ_sect233k1 OBJ_secg_ellipticCurve,26L
+
+#define SN_sect233r1 "sect233r1"
+#define NID_sect233r1 727
+#define OBJ_sect233r1 OBJ_secg_ellipticCurve,27L
+
+#define SN_sect239k1 "sect239k1"
+#define NID_sect239k1 728
+#define OBJ_sect239k1 OBJ_secg_ellipticCurve,3L
+
+#define SN_sect283k1 "sect283k1"
+#define NID_sect283k1 729
+#define OBJ_sect283k1 OBJ_secg_ellipticCurve,16L
+
+#define SN_sect283r1 "sect283r1"
+#define NID_sect283r1 730
+#define OBJ_sect283r1 OBJ_secg_ellipticCurve,17L
+
+#define SN_sect409k1 "sect409k1"
+#define NID_sect409k1 731
+#define OBJ_sect409k1 OBJ_secg_ellipticCurve,36L
+
+#define SN_sect409r1 "sect409r1"
+#define NID_sect409r1 732
+#define OBJ_sect409r1 OBJ_secg_ellipticCurve,37L
+
+#define SN_sect571k1 "sect571k1"
+#define NID_sect571k1 733
+#define OBJ_sect571k1 OBJ_secg_ellipticCurve,38L
+
+#define SN_sect571r1 "sect571r1"
+#define NID_sect571r1 734
+#define OBJ_sect571r1 OBJ_secg_ellipticCurve,39L
+
+#define OBJ_wap_wsg_idm_ecid OBJ_wap_wsg,4L
+
+#define SN_wap_wsg_idm_ecid_wtls1 "wap-wsg-idm-ecid-wtls1"
+#define NID_wap_wsg_idm_ecid_wtls1 735
+#define OBJ_wap_wsg_idm_ecid_wtls1 OBJ_wap_wsg_idm_ecid,1L
+
+#define SN_wap_wsg_idm_ecid_wtls3 "wap-wsg-idm-ecid-wtls3"
+#define NID_wap_wsg_idm_ecid_wtls3 736
+#define OBJ_wap_wsg_idm_ecid_wtls3 OBJ_wap_wsg_idm_ecid,3L
+
+#define SN_wap_wsg_idm_ecid_wtls4 "wap-wsg-idm-ecid-wtls4"
+#define NID_wap_wsg_idm_ecid_wtls4 737
+#define OBJ_wap_wsg_idm_ecid_wtls4 OBJ_wap_wsg_idm_ecid,4L
+
+#define SN_wap_wsg_idm_ecid_wtls5 "wap-wsg-idm-ecid-wtls5"
+#define NID_wap_wsg_idm_ecid_wtls5 738
+#define OBJ_wap_wsg_idm_ecid_wtls5 OBJ_wap_wsg_idm_ecid,5L
+
+#define SN_wap_wsg_idm_ecid_wtls6 "wap-wsg-idm-ecid-wtls6"
+#define NID_wap_wsg_idm_ecid_wtls6 739
+#define OBJ_wap_wsg_idm_ecid_wtls6 OBJ_wap_wsg_idm_ecid,6L
+
+#define SN_wap_wsg_idm_ecid_wtls7 "wap-wsg-idm-ecid-wtls7"
+#define NID_wap_wsg_idm_ecid_wtls7 740
+#define OBJ_wap_wsg_idm_ecid_wtls7 OBJ_wap_wsg_idm_ecid,7L
+
+#define SN_wap_wsg_idm_ecid_wtls8 "wap-wsg-idm-ecid-wtls8"
+#define NID_wap_wsg_idm_ecid_wtls8 741
+#define OBJ_wap_wsg_idm_ecid_wtls8 OBJ_wap_wsg_idm_ecid,8L
+
+#define SN_wap_wsg_idm_ecid_wtls9 "wap-wsg-idm-ecid-wtls9"
+#define NID_wap_wsg_idm_ecid_wtls9 742
+#define OBJ_wap_wsg_idm_ecid_wtls9 OBJ_wap_wsg_idm_ecid,9L
+
+#define SN_wap_wsg_idm_ecid_wtls10 "wap-wsg-idm-ecid-wtls10"
+#define NID_wap_wsg_idm_ecid_wtls10 743
+#define OBJ_wap_wsg_idm_ecid_wtls10 OBJ_wap_wsg_idm_ecid,10L
+
+#define SN_wap_wsg_idm_ecid_wtls11 "wap-wsg-idm-ecid-wtls11"
+#define NID_wap_wsg_idm_ecid_wtls11 744
+#define OBJ_wap_wsg_idm_ecid_wtls11 OBJ_wap_wsg_idm_ecid,11L
+
+#define SN_wap_wsg_idm_ecid_wtls12 "wap-wsg-idm-ecid-wtls12"
+#define NID_wap_wsg_idm_ecid_wtls12 745
+#define OBJ_wap_wsg_idm_ecid_wtls12 OBJ_wap_wsg_idm_ecid,12L
+
+#define SN_cast5_cbc "CAST5-CBC"
+#define LN_cast5_cbc "cast5-cbc"
+#define NID_cast5_cbc 108
+#define OBJ_cast5_cbc OBJ_ISO_US,113533L,7L,66L,10L
+
+#define SN_cast5_ecb "CAST5-ECB"
+#define LN_cast5_ecb "cast5-ecb"
+#define NID_cast5_ecb 109
+
+#define SN_cast5_cfb64 "CAST5-CFB"
+#define LN_cast5_cfb64 "cast5-cfb"
+#define NID_cast5_cfb64 110
+
+#define SN_cast5_ofb64 "CAST5-OFB"
+#define LN_cast5_ofb64 "cast5-ofb"
+#define NID_cast5_ofb64 111
+
+#define LN_pbeWithMD5AndCast5_CBC "pbeWithMD5AndCast5CBC"
+#define NID_pbeWithMD5AndCast5_CBC 112
+#define OBJ_pbeWithMD5AndCast5_CBC OBJ_ISO_US,113533L,7L,66L,12L
+
+#define SN_id_PasswordBasedMAC "id-PasswordBasedMAC"
+#define LN_id_PasswordBasedMAC "password based MAC"
+#define NID_id_PasswordBasedMAC 782
+#define OBJ_id_PasswordBasedMAC OBJ_ISO_US,113533L,7L,66L,13L
+
+#define SN_id_DHBasedMac "id-DHBasedMac"
+#define LN_id_DHBasedMac "Diffie-Hellman based MAC"
+#define NID_id_DHBasedMac 783
+#define OBJ_id_DHBasedMac OBJ_ISO_US,113533L,7L,66L,30L
+
+#define SN_rsadsi "rsadsi"
+#define LN_rsadsi "RSA Data Security, Inc."
+#define NID_rsadsi 1
+#define OBJ_rsadsi OBJ_ISO_US,113549L
+
+#define SN_pkcs "pkcs"
+#define LN_pkcs "RSA Data Security, Inc. PKCS"
+#define NID_pkcs 2
+#define OBJ_pkcs OBJ_rsadsi,1L
+
+#define SN_pkcs1 "pkcs1"
+#define NID_pkcs1 186
+#define OBJ_pkcs1 OBJ_pkcs,1L
+
+#define LN_rsaEncryption "rsaEncryption"
+#define NID_rsaEncryption 6
+#define OBJ_rsaEncryption OBJ_pkcs1,1L
+
+#define SN_md2WithRSAEncryption "RSA-MD2"
+#define LN_md2WithRSAEncryption "md2WithRSAEncryption"
+#define NID_md2WithRSAEncryption 7
+#define OBJ_md2WithRSAEncryption OBJ_pkcs1,2L
+
+#define SN_md4WithRSAEncryption "RSA-MD4"
+#define LN_md4WithRSAEncryption "md4WithRSAEncryption"
+#define NID_md4WithRSAEncryption 396
+#define OBJ_md4WithRSAEncryption OBJ_pkcs1,3L
+
+#define SN_md5WithRSAEncryption "RSA-MD5"
+#define LN_md5WithRSAEncryption "md5WithRSAEncryption"
+#define NID_md5WithRSAEncryption 8
+#define OBJ_md5WithRSAEncryption OBJ_pkcs1,4L
+
+#define SN_sha1WithRSAEncryption "RSA-SHA1"
+#define LN_sha1WithRSAEncryption "sha1WithRSAEncryption"
+#define NID_sha1WithRSAEncryption 65
+#define OBJ_sha1WithRSAEncryption OBJ_pkcs1,5L
+
+#define SN_rsaesOaep "RSAES-OAEP"
+#define LN_rsaesOaep "rsaesOaep"
+#define NID_rsaesOaep 919
+#define OBJ_rsaesOaep OBJ_pkcs1,7L
+
+#define SN_mgf1 "MGF1"
+#define LN_mgf1 "mgf1"
+#define NID_mgf1 911
+#define OBJ_mgf1 OBJ_pkcs1,8L
+
+#define SN_pSpecified "PSPECIFIED"
+#define LN_pSpecified "pSpecified"
+#define NID_pSpecified 935
+#define OBJ_pSpecified OBJ_pkcs1,9L
+
+#define SN_rsassaPss "RSASSA-PSS"
+#define LN_rsassaPss "rsassaPss"
+#define NID_rsassaPss 912
+#define OBJ_rsassaPss OBJ_pkcs1,10L
+
+#define SN_sha256WithRSAEncryption "RSA-SHA256"
+#define LN_sha256WithRSAEncryption "sha256WithRSAEncryption"
+#define NID_sha256WithRSAEncryption 668
+#define OBJ_sha256WithRSAEncryption OBJ_pkcs1,11L
+
+#define SN_sha384WithRSAEncryption "RSA-SHA384"
+#define LN_sha384WithRSAEncryption "sha384WithRSAEncryption"
+#define NID_sha384WithRSAEncryption 669
+#define OBJ_sha384WithRSAEncryption OBJ_pkcs1,12L
+
+#define SN_sha512WithRSAEncryption "RSA-SHA512"
+#define LN_sha512WithRSAEncryption "sha512WithRSAEncryption"
+#define NID_sha512WithRSAEncryption 670
+#define OBJ_sha512WithRSAEncryption OBJ_pkcs1,13L
+
+#define SN_sha224WithRSAEncryption "RSA-SHA224"
+#define LN_sha224WithRSAEncryption "sha224WithRSAEncryption"
+#define NID_sha224WithRSAEncryption 671
+#define OBJ_sha224WithRSAEncryption OBJ_pkcs1,14L
+
+#define SN_pkcs3 "pkcs3"
+#define NID_pkcs3 27
+#define OBJ_pkcs3 OBJ_pkcs,3L
+
+#define LN_dhKeyAgreement "dhKeyAgreement"
+#define NID_dhKeyAgreement 28
+#define OBJ_dhKeyAgreement OBJ_pkcs3,1L
+
+#define SN_pkcs5 "pkcs5"
+#define NID_pkcs5 187
+#define OBJ_pkcs5 OBJ_pkcs,5L
+
+#define SN_pbeWithMD2AndDES_CBC "PBE-MD2-DES"
+#define LN_pbeWithMD2AndDES_CBC "pbeWithMD2AndDES-CBC"
+#define NID_pbeWithMD2AndDES_CBC 9
+#define OBJ_pbeWithMD2AndDES_CBC OBJ_pkcs5,1L
+
+#define SN_pbeWithMD5AndDES_CBC "PBE-MD5-DES"
+#define LN_pbeWithMD5AndDES_CBC "pbeWithMD5AndDES-CBC"
+#define NID_pbeWithMD5AndDES_CBC 10
+#define OBJ_pbeWithMD5AndDES_CBC OBJ_pkcs5,3L
+
+#define SN_pbeWithMD2AndRC2_CBC "PBE-MD2-RC2-64"
+#define LN_pbeWithMD2AndRC2_CBC "pbeWithMD2AndRC2-CBC"
+#define NID_pbeWithMD2AndRC2_CBC 168
+#define OBJ_pbeWithMD2AndRC2_CBC OBJ_pkcs5,4L
+
+#define SN_pbeWithMD5AndRC2_CBC "PBE-MD5-RC2-64"
+#define LN_pbeWithMD5AndRC2_CBC "pbeWithMD5AndRC2-CBC"
+#define NID_pbeWithMD5AndRC2_CBC 169
+#define OBJ_pbeWithMD5AndRC2_CBC OBJ_pkcs5,6L
+
+#define SN_pbeWithSHA1AndDES_CBC "PBE-SHA1-DES"
+#define LN_pbeWithSHA1AndDES_CBC "pbeWithSHA1AndDES-CBC"
+#define NID_pbeWithSHA1AndDES_CBC 170
+#define OBJ_pbeWithSHA1AndDES_CBC OBJ_pkcs5,10L
+
+#define SN_pbeWithSHA1AndRC2_CBC "PBE-SHA1-RC2-64"
+#define LN_pbeWithSHA1AndRC2_CBC "pbeWithSHA1AndRC2-CBC"
+#define NID_pbeWithSHA1AndRC2_CBC 68
+#define OBJ_pbeWithSHA1AndRC2_CBC OBJ_pkcs5,11L
+
+#define LN_id_pbkdf2 "PBKDF2"
+#define NID_id_pbkdf2 69
+#define OBJ_id_pbkdf2 OBJ_pkcs5,12L
+
+#define LN_pbes2 "PBES2"
+#define NID_pbes2 161
+#define OBJ_pbes2 OBJ_pkcs5,13L
+
+#define LN_pbmac1 "PBMAC1"
+#define NID_pbmac1 162
+#define OBJ_pbmac1 OBJ_pkcs5,14L
+
+#define SN_pkcs7 "pkcs7"
+#define NID_pkcs7 20
+#define OBJ_pkcs7 OBJ_pkcs,7L
+
+#define LN_pkcs7_data "pkcs7-data"
+#define NID_pkcs7_data 21
+#define OBJ_pkcs7_data OBJ_pkcs7,1L
+
+#define LN_pkcs7_signed "pkcs7-signedData"
+#define NID_pkcs7_signed 22
+#define OBJ_pkcs7_signed OBJ_pkcs7,2L
+
+#define LN_pkcs7_enveloped "pkcs7-envelopedData"
+#define NID_pkcs7_enveloped 23
+#define OBJ_pkcs7_enveloped OBJ_pkcs7,3L
+
+#define LN_pkcs7_signedAndEnveloped "pkcs7-signedAndEnvelopedData"
+#define NID_pkcs7_signedAndEnveloped 24
+#define OBJ_pkcs7_signedAndEnveloped OBJ_pkcs7,4L
+
+#define LN_pkcs7_digest "pkcs7-digestData"
+#define NID_pkcs7_digest 25
+#define OBJ_pkcs7_digest OBJ_pkcs7,5L
+
+#define LN_pkcs7_encrypted "pkcs7-encryptedData"
+#define NID_pkcs7_encrypted 26
+#define OBJ_pkcs7_encrypted OBJ_pkcs7,6L
+
+#define SN_pkcs9 "pkcs9"
+#define NID_pkcs9 47
+#define OBJ_pkcs9 OBJ_pkcs,9L
+
+#define LN_pkcs9_emailAddress "emailAddress"
+#define NID_pkcs9_emailAddress 48
+#define OBJ_pkcs9_emailAddress OBJ_pkcs9,1L
+
+#define LN_pkcs9_unstructuredName "unstructuredName"
+#define NID_pkcs9_unstructuredName 49
+#define OBJ_pkcs9_unstructuredName OBJ_pkcs9,2L
+
+#define LN_pkcs9_contentType "contentType"
+#define NID_pkcs9_contentType 50
+#define OBJ_pkcs9_contentType OBJ_pkcs9,3L
+
+#define LN_pkcs9_messageDigest "messageDigest"
+#define NID_pkcs9_messageDigest 51
+#define OBJ_pkcs9_messageDigest OBJ_pkcs9,4L
+
+#define LN_pkcs9_signingTime "signingTime"
+#define NID_pkcs9_signingTime 52
+#define OBJ_pkcs9_signingTime OBJ_pkcs9,5L
+
+#define LN_pkcs9_countersignature "countersignature"
+#define NID_pkcs9_countersignature 53
+#define OBJ_pkcs9_countersignature OBJ_pkcs9,6L
+
+#define LN_pkcs9_challengePassword "challengePassword"
+#define NID_pkcs9_challengePassword 54
+#define OBJ_pkcs9_challengePassword OBJ_pkcs9,7L
+
+#define LN_pkcs9_unstructuredAddress "unstructuredAddress"
+#define NID_pkcs9_unstructuredAddress 55
+#define OBJ_pkcs9_unstructuredAddress OBJ_pkcs9,8L
+
+#define LN_pkcs9_extCertAttributes "extendedCertificateAttributes"
+#define NID_pkcs9_extCertAttributes 56
+#define OBJ_pkcs9_extCertAttributes OBJ_pkcs9,9L
+
+#define SN_ext_req "extReq"
+#define LN_ext_req "Extension Request"
+#define NID_ext_req 172
+#define OBJ_ext_req OBJ_pkcs9,14L
+
+#define SN_SMIMECapabilities "SMIME-CAPS"
+#define LN_SMIMECapabilities "S/MIME Capabilities"
+#define NID_SMIMECapabilities 167
+#define OBJ_SMIMECapabilities OBJ_pkcs9,15L
+
+#define SN_SMIME "SMIME"
+#define LN_SMIME "S/MIME"
+#define NID_SMIME 188
+#define OBJ_SMIME OBJ_pkcs9,16L
+
+#define SN_id_smime_mod "id-smime-mod"
+#define NID_id_smime_mod 189
+#define OBJ_id_smime_mod OBJ_SMIME,0L
+
+#define SN_id_smime_ct "id-smime-ct"
+#define NID_id_smime_ct 190
+#define OBJ_id_smime_ct OBJ_SMIME,1L
+
+#define SN_id_smime_aa "id-smime-aa"
+#define NID_id_smime_aa 191
+#define OBJ_id_smime_aa OBJ_SMIME,2L
+
+#define SN_id_smime_alg "id-smime-alg"
+#define NID_id_smime_alg 192
+#define OBJ_id_smime_alg OBJ_SMIME,3L
+
+#define SN_id_smime_cd "id-smime-cd"
+#define NID_id_smime_cd 193
+#define OBJ_id_smime_cd OBJ_SMIME,4L
+
+#define SN_id_smime_spq "id-smime-spq"
+#define NID_id_smime_spq 194
+#define OBJ_id_smime_spq OBJ_SMIME,5L
+
+#define SN_id_smime_cti "id-smime-cti"
+#define NID_id_smime_cti 195
+#define OBJ_id_smime_cti OBJ_SMIME,6L
+
+#define SN_id_smime_mod_cms "id-smime-mod-cms"
+#define NID_id_smime_mod_cms 196
+#define OBJ_id_smime_mod_cms OBJ_id_smime_mod,1L
+
+#define SN_id_smime_mod_ess "id-smime-mod-ess"
+#define NID_id_smime_mod_ess 197
+#define OBJ_id_smime_mod_ess OBJ_id_smime_mod,2L
+
+#define SN_id_smime_mod_oid "id-smime-mod-oid"
+#define NID_id_smime_mod_oid 198
+#define OBJ_id_smime_mod_oid OBJ_id_smime_mod,3L
+
+#define SN_id_smime_mod_msg_v3 "id-smime-mod-msg-v3"
+#define NID_id_smime_mod_msg_v3 199
+#define OBJ_id_smime_mod_msg_v3 OBJ_id_smime_mod,4L
+
+#define SN_id_smime_mod_ets_eSignature_88 "id-smime-mod-ets-eSignature-88"
+#define NID_id_smime_mod_ets_eSignature_88 200
+#define OBJ_id_smime_mod_ets_eSignature_88 OBJ_id_smime_mod,5L
+
+#define SN_id_smime_mod_ets_eSignature_97 "id-smime-mod-ets-eSignature-97"
+#define NID_id_smime_mod_ets_eSignature_97 201
+#define OBJ_id_smime_mod_ets_eSignature_97 OBJ_id_smime_mod,6L
+
+#define SN_id_smime_mod_ets_eSigPolicy_88 "id-smime-mod-ets-eSigPolicy-88"
+#define NID_id_smime_mod_ets_eSigPolicy_88 202
+#define OBJ_id_smime_mod_ets_eSigPolicy_88 OBJ_id_smime_mod,7L
+
+#define SN_id_smime_mod_ets_eSigPolicy_97 "id-smime-mod-ets-eSigPolicy-97"
+#define NID_id_smime_mod_ets_eSigPolicy_97 203
+#define OBJ_id_smime_mod_ets_eSigPolicy_97 OBJ_id_smime_mod,8L
+
+#define SN_id_smime_ct_receipt "id-smime-ct-receipt"
+#define NID_id_smime_ct_receipt 204
+#define OBJ_id_smime_ct_receipt OBJ_id_smime_ct,1L
+
+#define SN_id_smime_ct_authData "id-smime-ct-authData"
+#define NID_id_smime_ct_authData 205
+#define OBJ_id_smime_ct_authData OBJ_id_smime_ct,2L
+
+#define SN_id_smime_ct_publishCert "id-smime-ct-publishCert"
+#define NID_id_smime_ct_publishCert 206
+#define OBJ_id_smime_ct_publishCert OBJ_id_smime_ct,3L
+
+#define SN_id_smime_ct_TSTInfo "id-smime-ct-TSTInfo"
+#define NID_id_smime_ct_TSTInfo 207
+#define OBJ_id_smime_ct_TSTInfo OBJ_id_smime_ct,4L
+
+#define SN_id_smime_ct_TDTInfo "id-smime-ct-TDTInfo"
+#define NID_id_smime_ct_TDTInfo 208
+#define OBJ_id_smime_ct_TDTInfo OBJ_id_smime_ct,5L
+
+#define SN_id_smime_ct_contentInfo "id-smime-ct-contentInfo"
+#define NID_id_smime_ct_contentInfo 209
+#define OBJ_id_smime_ct_contentInfo OBJ_id_smime_ct,6L
+
+#define SN_id_smime_ct_DVCSRequestData "id-smime-ct-DVCSRequestData"
+#define NID_id_smime_ct_DVCSRequestData 210
+#define OBJ_id_smime_ct_DVCSRequestData OBJ_id_smime_ct,7L
+
+#define SN_id_smime_ct_DVCSResponseData "id-smime-ct-DVCSResponseData"
+#define NID_id_smime_ct_DVCSResponseData 211
+#define OBJ_id_smime_ct_DVCSResponseData OBJ_id_smime_ct,8L
+
+#define SN_id_smime_ct_compressedData "id-smime-ct-compressedData"
+#define NID_id_smime_ct_compressedData 786
+#define OBJ_id_smime_ct_compressedData OBJ_id_smime_ct,9L
+
+#define SN_id_ct_asciiTextWithCRLF "id-ct-asciiTextWithCRLF"
+#define NID_id_ct_asciiTextWithCRLF 787
+#define OBJ_id_ct_asciiTextWithCRLF OBJ_id_smime_ct,27L
+
+#define SN_id_smime_aa_receiptRequest "id-smime-aa-receiptRequest"
+#define NID_id_smime_aa_receiptRequest 212
+#define OBJ_id_smime_aa_receiptRequest OBJ_id_smime_aa,1L
+
+#define SN_id_smime_aa_securityLabel "id-smime-aa-securityLabel"
+#define NID_id_smime_aa_securityLabel 213
+#define OBJ_id_smime_aa_securityLabel OBJ_id_smime_aa,2L
+
+#define SN_id_smime_aa_mlExpandHistory "id-smime-aa-mlExpandHistory"
+#define NID_id_smime_aa_mlExpandHistory 214
+#define OBJ_id_smime_aa_mlExpandHistory OBJ_id_smime_aa,3L
+
+#define SN_id_smime_aa_contentHint "id-smime-aa-contentHint"
+#define NID_id_smime_aa_contentHint 215
+#define OBJ_id_smime_aa_contentHint OBJ_id_smime_aa,4L
+
+#define SN_id_smime_aa_msgSigDigest "id-smime-aa-msgSigDigest"
+#define NID_id_smime_aa_msgSigDigest 216
+#define OBJ_id_smime_aa_msgSigDigest OBJ_id_smime_aa,5L
+
+#define SN_id_smime_aa_encapContentType "id-smime-aa-encapContentType"
+#define NID_id_smime_aa_encapContentType 217
+#define OBJ_id_smime_aa_encapContentType OBJ_id_smime_aa,6L
+
+#define SN_id_smime_aa_contentIdentifier "id-smime-aa-contentIdentifier"
+#define NID_id_smime_aa_contentIdentifier 218
+#define OBJ_id_smime_aa_contentIdentifier OBJ_id_smime_aa,7L
+
+#define SN_id_smime_aa_macValue "id-smime-aa-macValue"
+#define NID_id_smime_aa_macValue 219
+#define OBJ_id_smime_aa_macValue OBJ_id_smime_aa,8L
+
+#define SN_id_smime_aa_equivalentLabels "id-smime-aa-equivalentLabels"
+#define NID_id_smime_aa_equivalentLabels 220
+#define OBJ_id_smime_aa_equivalentLabels OBJ_id_smime_aa,9L
+
+#define SN_id_smime_aa_contentReference "id-smime-aa-contentReference"
+#define NID_id_smime_aa_contentReference 221
+#define OBJ_id_smime_aa_contentReference OBJ_id_smime_aa,10L
+
+#define SN_id_smime_aa_encrypKeyPref "id-smime-aa-encrypKeyPref"
+#define NID_id_smime_aa_encrypKeyPref 222
+#define OBJ_id_smime_aa_encrypKeyPref OBJ_id_smime_aa,11L
+
+#define SN_id_smime_aa_signingCertificate "id-smime-aa-signingCertificate"
+#define NID_id_smime_aa_signingCertificate 223
+#define OBJ_id_smime_aa_signingCertificate OBJ_id_smime_aa,12L
+
+#define SN_id_smime_aa_smimeEncryptCerts "id-smime-aa-smimeEncryptCerts"
+#define NID_id_smime_aa_smimeEncryptCerts 224
+#define OBJ_id_smime_aa_smimeEncryptCerts OBJ_id_smime_aa,13L
+
+#define SN_id_smime_aa_timeStampToken "id-smime-aa-timeStampToken"
+#define NID_id_smime_aa_timeStampToken 225
+#define OBJ_id_smime_aa_timeStampToken OBJ_id_smime_aa,14L
+
+#define SN_id_smime_aa_ets_sigPolicyId "id-smime-aa-ets-sigPolicyId"
+#define NID_id_smime_aa_ets_sigPolicyId 226
+#define OBJ_id_smime_aa_ets_sigPolicyId OBJ_id_smime_aa,15L
+
+#define SN_id_smime_aa_ets_commitmentType "id-smime-aa-ets-commitmentType"
+#define NID_id_smime_aa_ets_commitmentType 227
+#define OBJ_id_smime_aa_ets_commitmentType OBJ_id_smime_aa,16L
+
+#define SN_id_smime_aa_ets_signerLocation "id-smime-aa-ets-signerLocation"
+#define NID_id_smime_aa_ets_signerLocation 228
+#define OBJ_id_smime_aa_ets_signerLocation OBJ_id_smime_aa,17L
+
+#define SN_id_smime_aa_ets_signerAttr "id-smime-aa-ets-signerAttr"
+#define NID_id_smime_aa_ets_signerAttr 229
+#define OBJ_id_smime_aa_ets_signerAttr OBJ_id_smime_aa,18L
+
+#define SN_id_smime_aa_ets_otherSigCert "id-smime-aa-ets-otherSigCert"
+#define NID_id_smime_aa_ets_otherSigCert 230
+#define OBJ_id_smime_aa_ets_otherSigCert OBJ_id_smime_aa,19L
+
+#define SN_id_smime_aa_ets_contentTimestamp "id-smime-aa-ets-contentTimestamp"
+#define NID_id_smime_aa_ets_contentTimestamp 231
+#define OBJ_id_smime_aa_ets_contentTimestamp OBJ_id_smime_aa,20L
+
+#define SN_id_smime_aa_ets_CertificateRefs "id-smime-aa-ets-CertificateRefs"
+#define NID_id_smime_aa_ets_CertificateRefs 232
+#define OBJ_id_smime_aa_ets_CertificateRefs OBJ_id_smime_aa,21L
+
+#define SN_id_smime_aa_ets_RevocationRefs "id-smime-aa-ets-RevocationRefs"
+#define NID_id_smime_aa_ets_RevocationRefs 233
+#define OBJ_id_smime_aa_ets_RevocationRefs OBJ_id_smime_aa,22L
+
+#define SN_id_smime_aa_ets_certValues "id-smime-aa-ets-certValues"
+#define NID_id_smime_aa_ets_certValues 234
+#define OBJ_id_smime_aa_ets_certValues OBJ_id_smime_aa,23L
+
+#define SN_id_smime_aa_ets_revocationValues "id-smime-aa-ets-revocationValues"
+#define NID_id_smime_aa_ets_revocationValues 235
+#define OBJ_id_smime_aa_ets_revocationValues OBJ_id_smime_aa,24L
+
+#define SN_id_smime_aa_ets_escTimeStamp "id-smime-aa-ets-escTimeStamp"
+#define NID_id_smime_aa_ets_escTimeStamp 236
+#define OBJ_id_smime_aa_ets_escTimeStamp OBJ_id_smime_aa,25L
+
+#define SN_id_smime_aa_ets_certCRLTimestamp "id-smime-aa-ets-certCRLTimestamp"
+#define NID_id_smime_aa_ets_certCRLTimestamp 237
+#define OBJ_id_smime_aa_ets_certCRLTimestamp OBJ_id_smime_aa,26L
+
+#define SN_id_smime_aa_ets_archiveTimeStamp "id-smime-aa-ets-archiveTimeStamp"
+#define NID_id_smime_aa_ets_archiveTimeStamp 238
+#define OBJ_id_smime_aa_ets_archiveTimeStamp OBJ_id_smime_aa,27L
+
+#define SN_id_smime_aa_signatureType "id-smime-aa-signatureType"
+#define NID_id_smime_aa_signatureType 239
+#define OBJ_id_smime_aa_signatureType OBJ_id_smime_aa,28L
+
+#define SN_id_smime_aa_dvcs_dvc "id-smime-aa-dvcs-dvc"
+#define NID_id_smime_aa_dvcs_dvc 240
+#define OBJ_id_smime_aa_dvcs_dvc OBJ_id_smime_aa,29L
+
+#define SN_id_smime_alg_ESDHwith3DES "id-smime-alg-ESDHwith3DES"
+#define NID_id_smime_alg_ESDHwith3DES 241
+#define OBJ_id_smime_alg_ESDHwith3DES OBJ_id_smime_alg,1L
+
+#define SN_id_smime_alg_ESDHwithRC2 "id-smime-alg-ESDHwithRC2"
+#define NID_id_smime_alg_ESDHwithRC2 242
+#define OBJ_id_smime_alg_ESDHwithRC2 OBJ_id_smime_alg,2L
+
+#define SN_id_smime_alg_3DESwrap "id-smime-alg-3DESwrap"
+#define NID_id_smime_alg_3DESwrap 243
+#define OBJ_id_smime_alg_3DESwrap OBJ_id_smime_alg,3L
+
+#define SN_id_smime_alg_RC2wrap "id-smime-alg-RC2wrap"
+#define NID_id_smime_alg_RC2wrap 244
+#define OBJ_id_smime_alg_RC2wrap OBJ_id_smime_alg,4L
+
+#define SN_id_smime_alg_ESDH "id-smime-alg-ESDH"
+#define NID_id_smime_alg_ESDH 245
+#define OBJ_id_smime_alg_ESDH OBJ_id_smime_alg,5L
+
+#define SN_id_smime_alg_CMS3DESwrap "id-smime-alg-CMS3DESwrap"
+#define NID_id_smime_alg_CMS3DESwrap 246
+#define OBJ_id_smime_alg_CMS3DESwrap OBJ_id_smime_alg,6L
+
+#define SN_id_smime_alg_CMSRC2wrap "id-smime-alg-CMSRC2wrap"
+#define NID_id_smime_alg_CMSRC2wrap 247
+#define OBJ_id_smime_alg_CMSRC2wrap OBJ_id_smime_alg,7L
+
+#define SN_id_alg_PWRI_KEK "id-alg-PWRI-KEK"
+#define NID_id_alg_PWRI_KEK 893
+#define OBJ_id_alg_PWRI_KEK OBJ_id_smime_alg,9L
+
+#define SN_id_smime_cd_ldap "id-smime-cd-ldap"
+#define NID_id_smime_cd_ldap 248
+#define OBJ_id_smime_cd_ldap OBJ_id_smime_cd,1L
+
+#define SN_id_smime_spq_ets_sqt_uri "id-smime-spq-ets-sqt-uri"
+#define NID_id_smime_spq_ets_sqt_uri 249
+#define OBJ_id_smime_spq_ets_sqt_uri OBJ_id_smime_spq,1L
+
+#define SN_id_smime_spq_ets_sqt_unotice "id-smime-spq-ets-sqt-unotice"
+#define NID_id_smime_spq_ets_sqt_unotice 250
+#define OBJ_id_smime_spq_ets_sqt_unotice OBJ_id_smime_spq,2L
+
+#define SN_id_smime_cti_ets_proofOfOrigin "id-smime-cti-ets-proofOfOrigin"
+#define NID_id_smime_cti_ets_proofOfOrigin 251
+#define OBJ_id_smime_cti_ets_proofOfOrigin OBJ_id_smime_cti,1L
+
+#define SN_id_smime_cti_ets_proofOfReceipt "id-smime-cti-ets-proofOfReceipt"
+#define NID_id_smime_cti_ets_proofOfReceipt 252
+#define OBJ_id_smime_cti_ets_proofOfReceipt OBJ_id_smime_cti,2L
+
+#define SN_id_smime_cti_ets_proofOfDelivery "id-smime-cti-ets-proofOfDelivery"
+#define NID_id_smime_cti_ets_proofOfDelivery 253
+#define OBJ_id_smime_cti_ets_proofOfDelivery OBJ_id_smime_cti,3L
+
+#define SN_id_smime_cti_ets_proofOfSender "id-smime-cti-ets-proofOfSender"
+#define NID_id_smime_cti_ets_proofOfSender 254
+#define OBJ_id_smime_cti_ets_proofOfSender OBJ_id_smime_cti,4L
+
+#define SN_id_smime_cti_ets_proofOfApproval "id-smime-cti-ets-proofOfApproval"
+#define NID_id_smime_cti_ets_proofOfApproval 255
+#define OBJ_id_smime_cti_ets_proofOfApproval OBJ_id_smime_cti,5L
+
+#define SN_id_smime_cti_ets_proofOfCreation "id-smime-cti-ets-proofOfCreation"
+#define NID_id_smime_cti_ets_proofOfCreation 256
+#define OBJ_id_smime_cti_ets_proofOfCreation OBJ_id_smime_cti,6L
+
+#define LN_friendlyName "friendlyName"
+#define NID_friendlyName 156
+#define OBJ_friendlyName OBJ_pkcs9,20L
+
+#define LN_localKeyID "localKeyID"
+#define NID_localKeyID 157
+#define OBJ_localKeyID OBJ_pkcs9,21L
+
+#define SN_ms_csp_name "CSPName"
+#define LN_ms_csp_name "Microsoft CSP Name"
+#define NID_ms_csp_name 417
+#define OBJ_ms_csp_name 1L,3L,6L,1L,4L,1L,311L,17L,1L
+
+#define SN_LocalKeySet "LocalKeySet"
+#define LN_LocalKeySet "Microsoft Local Key set"
+#define NID_LocalKeySet 856
+#define OBJ_LocalKeySet 1L,3L,6L,1L,4L,1L,311L,17L,2L
+
+#define OBJ_certTypes OBJ_pkcs9,22L
+
+#define LN_x509Certificate "x509Certificate"
+#define NID_x509Certificate 158
+#define OBJ_x509Certificate OBJ_certTypes,1L
+
+#define LN_sdsiCertificate "sdsiCertificate"
+#define NID_sdsiCertificate 159
+#define OBJ_sdsiCertificate OBJ_certTypes,2L
+
+#define OBJ_crlTypes OBJ_pkcs9,23L
+
+#define LN_x509Crl "x509Crl"
+#define NID_x509Crl 160
+#define OBJ_x509Crl OBJ_crlTypes,1L
+
+#define OBJ_pkcs12 OBJ_pkcs,12L
+
+#define OBJ_pkcs12_pbeids OBJ_pkcs12,1L
+
+#define SN_pbe_WithSHA1And128BitRC4 "PBE-SHA1-RC4-128"
+#define LN_pbe_WithSHA1And128BitRC4 "pbeWithSHA1And128BitRC4"
+#define NID_pbe_WithSHA1And128BitRC4 144
+#define OBJ_pbe_WithSHA1And128BitRC4 OBJ_pkcs12_pbeids,1L
+
+#define SN_pbe_WithSHA1And40BitRC4 "PBE-SHA1-RC4-40"
+#define LN_pbe_WithSHA1And40BitRC4 "pbeWithSHA1And40BitRC4"
+#define NID_pbe_WithSHA1And40BitRC4 145
+#define OBJ_pbe_WithSHA1And40BitRC4 OBJ_pkcs12_pbeids,2L
+
+#define SN_pbe_WithSHA1And3_Key_TripleDES_CBC "PBE-SHA1-3DES"
+#define LN_pbe_WithSHA1And3_Key_TripleDES_CBC "pbeWithSHA1And3-KeyTripleDES-CBC"
+#define NID_pbe_WithSHA1And3_Key_TripleDES_CBC 146
+#define OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC OBJ_pkcs12_pbeids,3L
+
+#define SN_pbe_WithSHA1And2_Key_TripleDES_CBC "PBE-SHA1-2DES"
+#define LN_pbe_WithSHA1And2_Key_TripleDES_CBC "pbeWithSHA1And2-KeyTripleDES-CBC"
+#define NID_pbe_WithSHA1And2_Key_TripleDES_CBC 147
+#define OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC OBJ_pkcs12_pbeids,4L
+
+#define SN_pbe_WithSHA1And128BitRC2_CBC "PBE-SHA1-RC2-128"
+#define LN_pbe_WithSHA1And128BitRC2_CBC "pbeWithSHA1And128BitRC2-CBC"
+#define NID_pbe_WithSHA1And128BitRC2_CBC 148
+#define OBJ_pbe_WithSHA1And128BitRC2_CBC OBJ_pkcs12_pbeids,5L
+
+#define SN_pbe_WithSHA1And40BitRC2_CBC "PBE-SHA1-RC2-40"
+#define LN_pbe_WithSHA1And40BitRC2_CBC "pbeWithSHA1And40BitRC2-CBC"
+#define NID_pbe_WithSHA1And40BitRC2_CBC 149
+#define OBJ_pbe_WithSHA1And40BitRC2_CBC OBJ_pkcs12_pbeids,6L
+
+#define OBJ_pkcs12_Version1 OBJ_pkcs12,10L
+
+#define OBJ_pkcs12_BagIds OBJ_pkcs12_Version1,1L
+
+#define LN_keyBag "keyBag"
+#define NID_keyBag 150
+#define OBJ_keyBag OBJ_pkcs12_BagIds,1L
+
+#define LN_pkcs8ShroudedKeyBag "pkcs8ShroudedKeyBag"
+#define NID_pkcs8ShroudedKeyBag 151
+#define OBJ_pkcs8ShroudedKeyBag OBJ_pkcs12_BagIds,2L
+
+#define LN_certBag "certBag"
+#define NID_certBag 152
+#define OBJ_certBag OBJ_pkcs12_BagIds,3L
+
+#define LN_crlBag "crlBag"
+#define NID_crlBag 153
+#define OBJ_crlBag OBJ_pkcs12_BagIds,4L
+
+#define LN_secretBag "secretBag"
+#define NID_secretBag 154
+#define OBJ_secretBag OBJ_pkcs12_BagIds,5L
+
+#define LN_safeContentsBag "safeContentsBag"
+#define NID_safeContentsBag 155
+#define OBJ_safeContentsBag OBJ_pkcs12_BagIds,6L
+
+#define SN_md2 "MD2"
+#define LN_md2 "md2"
+#define NID_md2 3
+#define OBJ_md2 OBJ_rsadsi,2L,2L
+
+#define SN_md4 "MD4"
+#define LN_md4 "md4"
+#define NID_md4 257
+#define OBJ_md4 OBJ_rsadsi,2L,4L
+
+#define SN_md5 "MD5"
+#define LN_md5 "md5"
+#define NID_md5 4
+#define OBJ_md5 OBJ_rsadsi,2L,5L
+
+#define SN_md5_sha1 "MD5-SHA1"
+#define LN_md5_sha1 "md5-sha1"
+#define NID_md5_sha1 114
+
+#define LN_hmacWithMD5 "hmacWithMD5"
+#define NID_hmacWithMD5 797
+#define OBJ_hmacWithMD5 OBJ_rsadsi,2L,6L
+
+#define LN_hmacWithSHA1 "hmacWithSHA1"
+#define NID_hmacWithSHA1 163
+#define OBJ_hmacWithSHA1 OBJ_rsadsi,2L,7L
+
+#define LN_hmacWithSHA224 "hmacWithSHA224"
+#define NID_hmacWithSHA224 798
+#define OBJ_hmacWithSHA224 OBJ_rsadsi,2L,8L
+
+#define LN_hmacWithSHA256 "hmacWithSHA256"
+#define NID_hmacWithSHA256 799
+#define OBJ_hmacWithSHA256 OBJ_rsadsi,2L,9L
+
+#define LN_hmacWithSHA384 "hmacWithSHA384"
+#define NID_hmacWithSHA384 800
+#define OBJ_hmacWithSHA384 OBJ_rsadsi,2L,10L
+
+#define LN_hmacWithSHA512 "hmacWithSHA512"
+#define NID_hmacWithSHA512 801
+#define OBJ_hmacWithSHA512 OBJ_rsadsi,2L,11L
+
+#define SN_rc2_cbc "RC2-CBC"
+#define LN_rc2_cbc "rc2-cbc"
+#define NID_rc2_cbc 37
+#define OBJ_rc2_cbc OBJ_rsadsi,3L,2L
+
+#define SN_rc2_ecb "RC2-ECB"
+#define LN_rc2_ecb "rc2-ecb"
+#define NID_rc2_ecb 38
+
+#define SN_rc2_cfb64 "RC2-CFB"
+#define LN_rc2_cfb64 "rc2-cfb"
+#define NID_rc2_cfb64 39
+
+#define SN_rc2_ofb64 "RC2-OFB"
+#define LN_rc2_ofb64 "rc2-ofb"
+#define NID_rc2_ofb64 40
+
+#define SN_rc2_40_cbc "RC2-40-CBC"
+#define LN_rc2_40_cbc "rc2-40-cbc"
+#define NID_rc2_40_cbc 98
+
+#define SN_rc2_64_cbc "RC2-64-CBC"
+#define LN_rc2_64_cbc "rc2-64-cbc"
+#define NID_rc2_64_cbc 166
+
+#define SN_rc4 "RC4"
+#define LN_rc4 "rc4"
+#define NID_rc4 5
+#define OBJ_rc4 OBJ_rsadsi,3L,4L
+
+#define SN_rc4_40 "RC4-40"
+#define LN_rc4_40 "rc4-40"
+#define NID_rc4_40 97
+
+#define SN_des_ede3_cbc "DES-EDE3-CBC"
+#define LN_des_ede3_cbc "des-ede3-cbc"
+#define NID_des_ede3_cbc 44
+#define OBJ_des_ede3_cbc OBJ_rsadsi,3L,7L
+
+#define SN_rc5_cbc "RC5-CBC"
+#define LN_rc5_cbc "rc5-cbc"
+#define NID_rc5_cbc 120
+#define OBJ_rc5_cbc OBJ_rsadsi,3L,8L
+
+#define SN_rc5_ecb "RC5-ECB"
+#define LN_rc5_ecb "rc5-ecb"
+#define NID_rc5_ecb 121
+
+#define SN_rc5_cfb64 "RC5-CFB"
+#define LN_rc5_cfb64 "rc5-cfb"
+#define NID_rc5_cfb64 122
+
+#define SN_rc5_ofb64 "RC5-OFB"
+#define LN_rc5_ofb64 "rc5-ofb"
+#define NID_rc5_ofb64 123
+
+#define SN_ms_ext_req "msExtReq"
+#define LN_ms_ext_req "Microsoft Extension Request"
+#define NID_ms_ext_req 171
+#define OBJ_ms_ext_req 1L,3L,6L,1L,4L,1L,311L,2L,1L,14L
+
+#define SN_ms_code_ind "msCodeInd"
+#define LN_ms_code_ind "Microsoft Individual Code Signing"
+#define NID_ms_code_ind 134
+#define OBJ_ms_code_ind 1L,3L,6L,1L,4L,1L,311L,2L,1L,21L
+
+#define SN_ms_code_com "msCodeCom"
+#define LN_ms_code_com "Microsoft Commercial Code Signing"
+#define NID_ms_code_com 135
+#define OBJ_ms_code_com 1L,3L,6L,1L,4L,1L,311L,2L,1L,22L
+
+#define SN_ms_ctl_sign "msCTLSign"
+#define LN_ms_ctl_sign "Microsoft Trust List Signing"
+#define NID_ms_ctl_sign 136
+#define OBJ_ms_ctl_sign 1L,3L,6L,1L,4L,1L,311L,10L,3L,1L
+
+#define SN_ms_sgc "msSGC"
+#define LN_ms_sgc "Microsoft Server Gated Crypto"
+#define NID_ms_sgc 137
+#define OBJ_ms_sgc 1L,3L,6L,1L,4L,1L,311L,10L,3L,3L
+
+#define SN_ms_efs "msEFS"
+#define LN_ms_efs "Microsoft Encrypted File System"
+#define NID_ms_efs 138
+#define OBJ_ms_efs 1L,3L,6L,1L,4L,1L,311L,10L,3L,4L
+
+#define SN_ms_smartcard_login "msSmartcardLogin"
+#define LN_ms_smartcard_login "Microsoft Smartcardlogin"
+#define NID_ms_smartcard_login 648
+#define OBJ_ms_smartcard_login 1L,3L,6L,1L,4L,1L,311L,20L,2L,2L
+
+#define SN_ms_upn "msUPN"
+#define LN_ms_upn "Microsoft Universal Principal Name"
+#define NID_ms_upn 649
+#define OBJ_ms_upn 1L,3L,6L,1L,4L,1L,311L,20L,2L,3L
+
+#define SN_idea_cbc "IDEA-CBC"
+#define LN_idea_cbc "idea-cbc"
+#define NID_idea_cbc 34
+#define OBJ_idea_cbc 1L,3L,6L,1L,4L,1L,188L,7L,1L,1L,2L
+
+#define SN_idea_ecb "IDEA-ECB"
+#define LN_idea_ecb "idea-ecb"
+#define NID_idea_ecb 36
+
+#define SN_idea_cfb64 "IDEA-CFB"
+#define LN_idea_cfb64 "idea-cfb"
+#define NID_idea_cfb64 35
+
+#define SN_idea_ofb64 "IDEA-OFB"
+#define LN_idea_ofb64 "idea-ofb"
+#define NID_idea_ofb64 46
+
+#define SN_bf_cbc "BF-CBC"
+#define LN_bf_cbc "bf-cbc"
+#define NID_bf_cbc 91
+#define OBJ_bf_cbc 1L,3L,6L,1L,4L,1L,3029L,1L,2L
+
+#define SN_bf_ecb "BF-ECB"
+#define LN_bf_ecb "bf-ecb"
+#define NID_bf_ecb 92
+
+#define SN_bf_cfb64 "BF-CFB"
+#define LN_bf_cfb64 "bf-cfb"
+#define NID_bf_cfb64 93
+
+#define SN_bf_ofb64 "BF-OFB"
+#define LN_bf_ofb64 "bf-ofb"
+#define NID_bf_ofb64 94
+
+#define SN_id_pkix "PKIX"
+#define NID_id_pkix 127
+#define OBJ_id_pkix 1L,3L,6L,1L,5L,5L,7L
+
+#define SN_id_pkix_mod "id-pkix-mod"
+#define NID_id_pkix_mod 258
+#define OBJ_id_pkix_mod OBJ_id_pkix,0L
+
+#define SN_id_pe "id-pe"
+#define NID_id_pe 175
+#define OBJ_id_pe OBJ_id_pkix,1L
+
+#define SN_id_qt "id-qt"
+#define NID_id_qt 259
+#define OBJ_id_qt OBJ_id_pkix,2L
+
+#define SN_id_kp "id-kp"
+#define NID_id_kp 128
+#define OBJ_id_kp OBJ_id_pkix,3L
+
+#define SN_id_it "id-it"
+#define NID_id_it 260
+#define OBJ_id_it OBJ_id_pkix,4L
+
+#define SN_id_pkip "id-pkip"
+#define NID_id_pkip 261
+#define OBJ_id_pkip OBJ_id_pkix,5L
+
+#define SN_id_alg "id-alg"
+#define NID_id_alg 262
+#define OBJ_id_alg OBJ_id_pkix,6L
+
+#define SN_id_cmc "id-cmc"
+#define NID_id_cmc 263
+#define OBJ_id_cmc OBJ_id_pkix,7L
+
+#define SN_id_on "id-on"
+#define NID_id_on 264
+#define OBJ_id_on OBJ_id_pkix,8L
+
+#define SN_id_pda "id-pda"
+#define NID_id_pda 265
+#define OBJ_id_pda OBJ_id_pkix,9L
+
+#define SN_id_aca "id-aca"
+#define NID_id_aca 266
+#define OBJ_id_aca OBJ_id_pkix,10L
+
+#define SN_id_qcs "id-qcs"
+#define NID_id_qcs 267
+#define OBJ_id_qcs OBJ_id_pkix,11L
+
+#define SN_id_cct "id-cct"
+#define NID_id_cct 268
+#define OBJ_id_cct OBJ_id_pkix,12L
+
+#define SN_id_ppl "id-ppl"
+#define NID_id_ppl 662
+#define OBJ_id_ppl OBJ_id_pkix,21L
+
+#define SN_id_ad "id-ad"
+#define NID_id_ad 176
+#define OBJ_id_ad OBJ_id_pkix,48L
+
+#define SN_id_pkix1_explicit_88 "id-pkix1-explicit-88"
+#define NID_id_pkix1_explicit_88 269
+#define OBJ_id_pkix1_explicit_88 OBJ_id_pkix_mod,1L
+
+#define SN_id_pkix1_implicit_88 "id-pkix1-implicit-88"
+#define NID_id_pkix1_implicit_88 270
+#define OBJ_id_pkix1_implicit_88 OBJ_id_pkix_mod,2L
+
+#define SN_id_pkix1_explicit_93 "id-pkix1-explicit-93"
+#define NID_id_pkix1_explicit_93 271
+#define OBJ_id_pkix1_explicit_93 OBJ_id_pkix_mod,3L
+
+#define SN_id_pkix1_implicit_93 "id-pkix1-implicit-93"
+#define NID_id_pkix1_implicit_93 272
+#define OBJ_id_pkix1_implicit_93 OBJ_id_pkix_mod,4L
+
+#define SN_id_mod_crmf "id-mod-crmf"
+#define NID_id_mod_crmf 273
+#define OBJ_id_mod_crmf OBJ_id_pkix_mod,5L
+
+#define SN_id_mod_cmc "id-mod-cmc"
+#define NID_id_mod_cmc 274
+#define OBJ_id_mod_cmc OBJ_id_pkix_mod,6L
+
+#define SN_id_mod_kea_profile_88 "id-mod-kea-profile-88"
+#define NID_id_mod_kea_profile_88 275
+#define OBJ_id_mod_kea_profile_88 OBJ_id_pkix_mod,7L
+
+#define SN_id_mod_kea_profile_93 "id-mod-kea-profile-93"
+#define NID_id_mod_kea_profile_93 276
+#define OBJ_id_mod_kea_profile_93 OBJ_id_pkix_mod,8L
+
+#define SN_id_mod_cmp "id-mod-cmp"
+#define NID_id_mod_cmp 277
+#define OBJ_id_mod_cmp OBJ_id_pkix_mod,9L
+
+#define SN_id_mod_qualified_cert_88 "id-mod-qualified-cert-88"
+#define NID_id_mod_qualified_cert_88 278
+#define OBJ_id_mod_qualified_cert_88 OBJ_id_pkix_mod,10L
+
+#define SN_id_mod_qualified_cert_93 "id-mod-qualified-cert-93"
+#define NID_id_mod_qualified_cert_93 279
+#define OBJ_id_mod_qualified_cert_93 OBJ_id_pkix_mod,11L
+
+#define SN_id_mod_attribute_cert "id-mod-attribute-cert"
+#define NID_id_mod_attribute_cert 280
+#define OBJ_id_mod_attribute_cert OBJ_id_pkix_mod,12L
+
+#define SN_id_mod_timestamp_protocol "id-mod-timestamp-protocol"
+#define NID_id_mod_timestamp_protocol 281
+#define OBJ_id_mod_timestamp_protocol OBJ_id_pkix_mod,13L
+
+#define SN_id_mod_ocsp "id-mod-ocsp"
+#define NID_id_mod_ocsp 282
+#define OBJ_id_mod_ocsp OBJ_id_pkix_mod,14L
+
+#define SN_id_mod_dvcs "id-mod-dvcs"
+#define NID_id_mod_dvcs 283
+#define OBJ_id_mod_dvcs OBJ_id_pkix_mod,15L
+
+#define SN_id_mod_cmp2000 "id-mod-cmp2000"
+#define NID_id_mod_cmp2000 284
+#define OBJ_id_mod_cmp2000 OBJ_id_pkix_mod,16L
+
+#define SN_info_access "authorityInfoAccess"
+#define LN_info_access "Authority Information Access"
+#define NID_info_access 177
+#define OBJ_info_access OBJ_id_pe,1L
+
+#define SN_biometricInfo "biometricInfo"
+#define LN_biometricInfo "Biometric Info"
+#define NID_biometricInfo 285
+#define OBJ_biometricInfo OBJ_id_pe,2L
+
+#define SN_qcStatements "qcStatements"
+#define NID_qcStatements 286
+#define OBJ_qcStatements OBJ_id_pe,3L
+
+#define SN_ac_auditEntity "ac-auditEntity"
+#define NID_ac_auditEntity 287
+#define OBJ_ac_auditEntity OBJ_id_pe,4L
+
+#define SN_ac_targeting "ac-targeting"
+#define NID_ac_targeting 288
+#define OBJ_ac_targeting OBJ_id_pe,5L
+
+#define SN_aaControls "aaControls"
+#define NID_aaControls 289
+#define OBJ_aaControls OBJ_id_pe,6L
+
+#define SN_sbgp_ipAddrBlock "sbgp-ipAddrBlock"
+#define NID_sbgp_ipAddrBlock 290
+#define OBJ_sbgp_ipAddrBlock OBJ_id_pe,7L
+
+#define SN_sbgp_autonomousSysNum "sbgp-autonomousSysNum"
+#define NID_sbgp_autonomousSysNum 291
+#define OBJ_sbgp_autonomousSysNum OBJ_id_pe,8L
+
+#define SN_sbgp_routerIdentifier "sbgp-routerIdentifier"
+#define NID_sbgp_routerIdentifier 292
+#define OBJ_sbgp_routerIdentifier OBJ_id_pe,9L
+
+#define SN_ac_proxying "ac-proxying"
+#define NID_ac_proxying 397
+#define OBJ_ac_proxying OBJ_id_pe,10L
+
+#define SN_sinfo_access "subjectInfoAccess"
+#define LN_sinfo_access "Subject Information Access"
+#define NID_sinfo_access 398
+#define OBJ_sinfo_access OBJ_id_pe,11L
+
+#define SN_proxyCertInfo "proxyCertInfo"
+#define LN_proxyCertInfo "Proxy Certificate Information"
+#define NID_proxyCertInfo 663
+#define OBJ_proxyCertInfo OBJ_id_pe,14L
+
+#define SN_id_qt_cps "id-qt-cps"
+#define LN_id_qt_cps "Policy Qualifier CPS"
+#define NID_id_qt_cps 164
+#define OBJ_id_qt_cps OBJ_id_qt,1L
+
+#define SN_id_qt_unotice "id-qt-unotice"
+#define LN_id_qt_unotice "Policy Qualifier User Notice"
+#define NID_id_qt_unotice 165
+#define OBJ_id_qt_unotice OBJ_id_qt,2L
+
+#define SN_textNotice "textNotice"
+#define NID_textNotice 293
+#define OBJ_textNotice OBJ_id_qt,3L
+
+#define SN_server_auth "serverAuth"
+#define LN_server_auth "TLS Web Server Authentication"
+#define NID_server_auth 129
+#define OBJ_server_auth OBJ_id_kp,1L
+
+#define SN_client_auth "clientAuth"
+#define LN_client_auth "TLS Web Client Authentication"
+#define NID_client_auth 130
+#define OBJ_client_auth OBJ_id_kp,2L
+
+#define SN_code_sign "codeSigning"
+#define LN_code_sign "Code Signing"
+#define NID_code_sign 131
+#define OBJ_code_sign OBJ_id_kp,3L
+
+#define SN_email_protect "emailProtection"
+#define LN_email_protect "E-mail Protection"
+#define NID_email_protect 132
+#define OBJ_email_protect OBJ_id_kp,4L
+
+#define SN_ipsecEndSystem "ipsecEndSystem"
+#define LN_ipsecEndSystem "IPSec End System"
+#define NID_ipsecEndSystem 294
+#define OBJ_ipsecEndSystem OBJ_id_kp,5L
+
+#define SN_ipsecTunnel "ipsecTunnel"
+#define LN_ipsecTunnel "IPSec Tunnel"
+#define NID_ipsecTunnel 295
+#define OBJ_ipsecTunnel OBJ_id_kp,6L
+
+#define SN_ipsecUser "ipsecUser"
+#define LN_ipsecUser "IPSec User"
+#define NID_ipsecUser 296
+#define OBJ_ipsecUser OBJ_id_kp,7L
+
+#define SN_time_stamp "timeStamping"
+#define LN_time_stamp "Time Stamping"
+#define NID_time_stamp 133
+#define OBJ_time_stamp OBJ_id_kp,8L
+
+#define SN_OCSP_sign "OCSPSigning"
+#define LN_OCSP_sign "OCSP Signing"
+#define NID_OCSP_sign 180
+#define OBJ_OCSP_sign OBJ_id_kp,9L
+
+#define SN_dvcs "DVCS"
+#define LN_dvcs "dvcs"
+#define NID_dvcs 297
+#define OBJ_dvcs OBJ_id_kp,10L
+
+#define SN_id_it_caProtEncCert "id-it-caProtEncCert"
+#define NID_id_it_caProtEncCert 298
+#define OBJ_id_it_caProtEncCert OBJ_id_it,1L
+
+#define SN_id_it_signKeyPairTypes "id-it-signKeyPairTypes"
+#define NID_id_it_signKeyPairTypes 299
+#define OBJ_id_it_signKeyPairTypes OBJ_id_it,2L
+
+#define SN_id_it_encKeyPairTypes "id-it-encKeyPairTypes"
+#define NID_id_it_encKeyPairTypes 300
+#define OBJ_id_it_encKeyPairTypes OBJ_id_it,3L
+
+#define SN_id_it_preferredSymmAlg "id-it-preferredSymmAlg"
+#define NID_id_it_preferredSymmAlg 301
+#define OBJ_id_it_preferredSymmAlg OBJ_id_it,4L
+
+#define SN_id_it_caKeyUpdateInfo "id-it-caKeyUpdateInfo"
+#define NID_id_it_caKeyUpdateInfo 302
+#define OBJ_id_it_caKeyUpdateInfo OBJ_id_it,5L
+
+#define SN_id_it_currentCRL "id-it-currentCRL"
+#define NID_id_it_currentCRL 303
+#define OBJ_id_it_currentCRL OBJ_id_it,6L
+
+#define SN_id_it_unsupportedOIDs "id-it-unsupportedOIDs"
+#define NID_id_it_unsupportedOIDs 304
+#define OBJ_id_it_unsupportedOIDs OBJ_id_it,7L
+
+#define SN_id_it_subscriptionRequest "id-it-subscriptionRequest"
+#define NID_id_it_subscriptionRequest 305
+#define OBJ_id_it_subscriptionRequest OBJ_id_it,8L
+
+#define SN_id_it_subscriptionResponse "id-it-subscriptionResponse"
+#define NID_id_it_subscriptionResponse 306
+#define OBJ_id_it_subscriptionResponse OBJ_id_it,9L
+
+#define SN_id_it_keyPairParamReq "id-it-keyPairParamReq"
+#define NID_id_it_keyPairParamReq 307
+#define OBJ_id_it_keyPairParamReq OBJ_id_it,10L
+
+#define SN_id_it_keyPairParamRep "id-it-keyPairParamRep"
+#define NID_id_it_keyPairParamRep 308
+#define OBJ_id_it_keyPairParamRep OBJ_id_it,11L
+
+#define SN_id_it_revPassphrase "id-it-revPassphrase"
+#define NID_id_it_revPassphrase 309
+#define OBJ_id_it_revPassphrase OBJ_id_it,12L
+
+#define SN_id_it_implicitConfirm "id-it-implicitConfirm"
+#define NID_id_it_implicitConfirm 310
+#define OBJ_id_it_implicitConfirm OBJ_id_it,13L
+
+#define SN_id_it_confirmWaitTime "id-it-confirmWaitTime"
+#define NID_id_it_confirmWaitTime 311
+#define OBJ_id_it_confirmWaitTime OBJ_id_it,14L
+
+#define SN_id_it_origPKIMessage "id-it-origPKIMessage"
+#define NID_id_it_origPKIMessage 312
+#define OBJ_id_it_origPKIMessage OBJ_id_it,15L
+
+#define SN_id_it_suppLangTags "id-it-suppLangTags"
+#define NID_id_it_suppLangTags 784
+#define OBJ_id_it_suppLangTags OBJ_id_it,16L
+
+#define SN_id_regCtrl "id-regCtrl"
+#define NID_id_regCtrl 313
+#define OBJ_id_regCtrl OBJ_id_pkip,1L
+
+#define SN_id_regInfo "id-regInfo"
+#define NID_id_regInfo 314
+#define OBJ_id_regInfo OBJ_id_pkip,2L
+
+#define SN_id_regCtrl_regToken "id-regCtrl-regToken"
+#define NID_id_regCtrl_regToken 315
+#define OBJ_id_regCtrl_regToken OBJ_id_regCtrl,1L
+
+#define SN_id_regCtrl_authenticator "id-regCtrl-authenticator"
+#define NID_id_regCtrl_authenticator 316
+#define OBJ_id_regCtrl_authenticator OBJ_id_regCtrl,2L
+
+#define SN_id_regCtrl_pkiPublicationInfo "id-regCtrl-pkiPublicationInfo"
+#define NID_id_regCtrl_pkiPublicationInfo 317
+#define OBJ_id_regCtrl_pkiPublicationInfo OBJ_id_regCtrl,3L
+
+#define SN_id_regCtrl_pkiArchiveOptions "id-regCtrl-pkiArchiveOptions"
+#define NID_id_regCtrl_pkiArchiveOptions 318
+#define OBJ_id_regCtrl_pkiArchiveOptions OBJ_id_regCtrl,4L
+
+#define SN_id_regCtrl_oldCertID "id-regCtrl-oldCertID"
+#define NID_id_regCtrl_oldCertID 319
+#define OBJ_id_regCtrl_oldCertID OBJ_id_regCtrl,5L
+
+#define SN_id_regCtrl_protocolEncrKey "id-regCtrl-protocolEncrKey"
+#define NID_id_regCtrl_protocolEncrKey 320
+#define OBJ_id_regCtrl_protocolEncrKey OBJ_id_regCtrl,6L
+
+#define SN_id_regInfo_utf8Pairs "id-regInfo-utf8Pairs"
+#define NID_id_regInfo_utf8Pairs 321
+#define OBJ_id_regInfo_utf8Pairs OBJ_id_regInfo,1L
+
+#define SN_id_regInfo_certReq "id-regInfo-certReq"
+#define NID_id_regInfo_certReq 322
+#define OBJ_id_regInfo_certReq OBJ_id_regInfo,2L
+
+#define SN_id_alg_des40 "id-alg-des40"
+#define NID_id_alg_des40 323
+#define OBJ_id_alg_des40 OBJ_id_alg,1L
+
+#define SN_id_alg_noSignature "id-alg-noSignature"
+#define NID_id_alg_noSignature 324
+#define OBJ_id_alg_noSignature OBJ_id_alg,2L
+
+#define SN_id_alg_dh_sig_hmac_sha1 "id-alg-dh-sig-hmac-sha1"
+#define NID_id_alg_dh_sig_hmac_sha1 325
+#define OBJ_id_alg_dh_sig_hmac_sha1 OBJ_id_alg,3L
+
+#define SN_id_alg_dh_pop "id-alg-dh-pop"
+#define NID_id_alg_dh_pop 326
+#define OBJ_id_alg_dh_pop OBJ_id_alg,4L
+
+#define SN_id_cmc_statusInfo "id-cmc-statusInfo"
+#define NID_id_cmc_statusInfo 327
+#define OBJ_id_cmc_statusInfo OBJ_id_cmc,1L
+
+#define SN_id_cmc_identification "id-cmc-identification"
+#define NID_id_cmc_identification 328
+#define OBJ_id_cmc_identification OBJ_id_cmc,2L
+
+#define SN_id_cmc_identityProof "id-cmc-identityProof"
+#define NID_id_cmc_identityProof 329
+#define OBJ_id_cmc_identityProof OBJ_id_cmc,3L
+
+#define SN_id_cmc_dataReturn "id-cmc-dataReturn"
+#define NID_id_cmc_dataReturn 330
+#define OBJ_id_cmc_dataReturn OBJ_id_cmc,4L
+
+#define SN_id_cmc_transactionId "id-cmc-transactionId"
+#define NID_id_cmc_transactionId 331
+#define OBJ_id_cmc_transactionId OBJ_id_cmc,5L
+
+#define SN_id_cmc_senderNonce "id-cmc-senderNonce"
+#define NID_id_cmc_senderNonce 332
+#define OBJ_id_cmc_senderNonce OBJ_id_cmc,6L
+
+#define SN_id_cmc_recipientNonce "id-cmc-recipientNonce"
+#define NID_id_cmc_recipientNonce 333
+#define OBJ_id_cmc_recipientNonce OBJ_id_cmc,7L
+
+#define SN_id_cmc_addExtensions "id-cmc-addExtensions"
+#define NID_id_cmc_addExtensions 334
+#define OBJ_id_cmc_addExtensions OBJ_id_cmc,8L
+
+#define SN_id_cmc_encryptedPOP "id-cmc-encryptedPOP"
+#define NID_id_cmc_encryptedPOP 335
+#define OBJ_id_cmc_encryptedPOP OBJ_id_cmc,9L
+
+#define SN_id_cmc_decryptedPOP "id-cmc-decryptedPOP"
+#define NID_id_cmc_decryptedPOP 336
+#define OBJ_id_cmc_decryptedPOP OBJ_id_cmc,10L
+
+#define SN_id_cmc_lraPOPWitness "id-cmc-lraPOPWitness"
+#define NID_id_cmc_lraPOPWitness 337
+#define OBJ_id_cmc_lraPOPWitness OBJ_id_cmc,11L
+
+#define SN_id_cmc_getCert "id-cmc-getCert"
+#define NID_id_cmc_getCert 338
+#define OBJ_id_cmc_getCert OBJ_id_cmc,15L
+
+#define SN_id_cmc_getCRL "id-cmc-getCRL"
+#define NID_id_cmc_getCRL 339
+#define OBJ_id_cmc_getCRL OBJ_id_cmc,16L
+
+#define SN_id_cmc_revokeRequest "id-cmc-revokeRequest"
+#define NID_id_cmc_revokeRequest 340
+#define OBJ_id_cmc_revokeRequest OBJ_id_cmc,17L
+
+#define SN_id_cmc_regInfo "id-cmc-regInfo"
+#define NID_id_cmc_regInfo 341
+#define OBJ_id_cmc_regInfo OBJ_id_cmc,18L
+
+#define SN_id_cmc_responseInfo "id-cmc-responseInfo"
+#define NID_id_cmc_responseInfo 342
+#define OBJ_id_cmc_responseInfo OBJ_id_cmc,19L
+
+#define SN_id_cmc_queryPending "id-cmc-queryPending"
+#define NID_id_cmc_queryPending 343
+#define OBJ_id_cmc_queryPending OBJ_id_cmc,21L
+
+#define SN_id_cmc_popLinkRandom "id-cmc-popLinkRandom"
+#define NID_id_cmc_popLinkRandom 344
+#define OBJ_id_cmc_popLinkRandom OBJ_id_cmc,22L
+
+#define SN_id_cmc_popLinkWitness "id-cmc-popLinkWitness"
+#define NID_id_cmc_popLinkWitness 345
+#define OBJ_id_cmc_popLinkWitness OBJ_id_cmc,23L
+
+#define SN_id_cmc_confirmCertAcceptance "id-cmc-confirmCertAcceptance"
+#define NID_id_cmc_confirmCertAcceptance 346
+#define OBJ_id_cmc_confirmCertAcceptance OBJ_id_cmc,24L
+
+#define SN_id_on_personalData "id-on-personalData"
+#define NID_id_on_personalData 347
+#define OBJ_id_on_personalData OBJ_id_on,1L
+
+#define SN_id_on_permanentIdentifier "id-on-permanentIdentifier"
+#define LN_id_on_permanentIdentifier "Permanent Identifier"
+#define NID_id_on_permanentIdentifier 858
+#define OBJ_id_on_permanentIdentifier OBJ_id_on,3L
+
+#define SN_id_pda_dateOfBirth "id-pda-dateOfBirth"
+#define NID_id_pda_dateOfBirth 348
+#define OBJ_id_pda_dateOfBirth OBJ_id_pda,1L
+
+#define SN_id_pda_placeOfBirth "id-pda-placeOfBirth"
+#define NID_id_pda_placeOfBirth 349
+#define OBJ_id_pda_placeOfBirth OBJ_id_pda,2L
+
+#define SN_id_pda_gender "id-pda-gender"
+#define NID_id_pda_gender 351
+#define OBJ_id_pda_gender OBJ_id_pda,3L
+
+#define SN_id_pda_countryOfCitizenship "id-pda-countryOfCitizenship"
+#define NID_id_pda_countryOfCitizenship 352
+#define OBJ_id_pda_countryOfCitizenship OBJ_id_pda,4L
+
+#define SN_id_pda_countryOfResidence "id-pda-countryOfResidence"
+#define NID_id_pda_countryOfResidence 353
+#define OBJ_id_pda_countryOfResidence OBJ_id_pda,5L
+
+#define SN_id_aca_authenticationInfo "id-aca-authenticationInfo"
+#define NID_id_aca_authenticationInfo 354
+#define OBJ_id_aca_authenticationInfo OBJ_id_aca,1L
+
+#define SN_id_aca_accessIdentity "id-aca-accessIdentity"
+#define NID_id_aca_accessIdentity 355
+#define OBJ_id_aca_accessIdentity OBJ_id_aca,2L
+
+#define SN_id_aca_chargingIdentity "id-aca-chargingIdentity"
+#define NID_id_aca_chargingIdentity 356
+#define OBJ_id_aca_chargingIdentity OBJ_id_aca,3L
+
+#define SN_id_aca_group "id-aca-group"
+#define NID_id_aca_group 357
+#define OBJ_id_aca_group OBJ_id_aca,4L
+
+#define SN_id_aca_role "id-aca-role"
+#define NID_id_aca_role 358
+#define OBJ_id_aca_role OBJ_id_aca,5L
+
+#define SN_id_aca_encAttrs "id-aca-encAttrs"
+#define NID_id_aca_encAttrs 399
+#define OBJ_id_aca_encAttrs OBJ_id_aca,6L
+
+#define SN_id_qcs_pkixQCSyntax_v1 "id-qcs-pkixQCSyntax-v1"
+#define NID_id_qcs_pkixQCSyntax_v1 359
+#define OBJ_id_qcs_pkixQCSyntax_v1 OBJ_id_qcs,1L
+
+#define SN_id_cct_crs "id-cct-crs"
+#define NID_id_cct_crs 360
+#define OBJ_id_cct_crs OBJ_id_cct,1L
+
+#define SN_id_cct_PKIData "id-cct-PKIData"
+#define NID_id_cct_PKIData 361
+#define OBJ_id_cct_PKIData OBJ_id_cct,2L
+
+#define SN_id_cct_PKIResponse "id-cct-PKIResponse"
+#define NID_id_cct_PKIResponse 362
+#define OBJ_id_cct_PKIResponse OBJ_id_cct,3L
+
+#define SN_id_ppl_anyLanguage "id-ppl-anyLanguage"
+#define LN_id_ppl_anyLanguage "Any language"
+#define NID_id_ppl_anyLanguage 664
+#define OBJ_id_ppl_anyLanguage OBJ_id_ppl,0L
+
+#define SN_id_ppl_inheritAll "id-ppl-inheritAll"
+#define LN_id_ppl_inheritAll "Inherit all"
+#define NID_id_ppl_inheritAll 665
+#define OBJ_id_ppl_inheritAll OBJ_id_ppl,1L
+
+#define SN_Independent "id-ppl-independent"
+#define LN_Independent "Independent"
+#define NID_Independent 667
+#define OBJ_Independent OBJ_id_ppl,2L
+
+#define SN_ad_OCSP "OCSP"
+#define LN_ad_OCSP "OCSP"
+#define NID_ad_OCSP 178
+#define OBJ_ad_OCSP OBJ_id_ad,1L
+
+#define SN_ad_ca_issuers "caIssuers"
+#define LN_ad_ca_issuers "CA Issuers"
+#define NID_ad_ca_issuers 179
+#define OBJ_ad_ca_issuers OBJ_id_ad,2L
+
+#define SN_ad_timeStamping "ad_timestamping"
+#define LN_ad_timeStamping "AD Time Stamping"
+#define NID_ad_timeStamping 363
+#define OBJ_ad_timeStamping OBJ_id_ad,3L
+
+#define SN_ad_dvcs "AD_DVCS"
+#define LN_ad_dvcs "ad dvcs"
+#define NID_ad_dvcs 364
+#define OBJ_ad_dvcs OBJ_id_ad,4L
+
+#define SN_caRepository "caRepository"
+#define LN_caRepository "CA Repository"
+#define NID_caRepository 785
+#define OBJ_caRepository OBJ_id_ad,5L
+
+#define OBJ_id_pkix_OCSP OBJ_ad_OCSP
+
+#define SN_id_pkix_OCSP_basic "basicOCSPResponse"
+#define LN_id_pkix_OCSP_basic "Basic OCSP Response"
+#define NID_id_pkix_OCSP_basic 365
+#define OBJ_id_pkix_OCSP_basic OBJ_id_pkix_OCSP,1L
+
+#define SN_id_pkix_OCSP_Nonce "Nonce"
+#define LN_id_pkix_OCSP_Nonce "OCSP Nonce"
+#define NID_id_pkix_OCSP_Nonce 366
+#define OBJ_id_pkix_OCSP_Nonce OBJ_id_pkix_OCSP,2L
+
+#define SN_id_pkix_OCSP_CrlID "CrlID"
+#define LN_id_pkix_OCSP_CrlID "OCSP CRL ID"
+#define NID_id_pkix_OCSP_CrlID 367
+#define OBJ_id_pkix_OCSP_CrlID OBJ_id_pkix_OCSP,3L
+
+#define SN_id_pkix_OCSP_acceptableResponses "acceptableResponses"
+#define LN_id_pkix_OCSP_acceptableResponses "Acceptable OCSP Responses"
+#define NID_id_pkix_OCSP_acceptableResponses 368
+#define OBJ_id_pkix_OCSP_acceptableResponses OBJ_id_pkix_OCSP,4L
+
+#define SN_id_pkix_OCSP_noCheck "noCheck"
+#define LN_id_pkix_OCSP_noCheck "OCSP No Check"
+#define NID_id_pkix_OCSP_noCheck 369
+#define OBJ_id_pkix_OCSP_noCheck OBJ_id_pkix_OCSP,5L
+
+#define SN_id_pkix_OCSP_archiveCutoff "archiveCutoff"
+#define LN_id_pkix_OCSP_archiveCutoff "OCSP Archive Cutoff"
+#define NID_id_pkix_OCSP_archiveCutoff 370
+#define OBJ_id_pkix_OCSP_archiveCutoff OBJ_id_pkix_OCSP,6L
+
+#define SN_id_pkix_OCSP_serviceLocator "serviceLocator"
+#define LN_id_pkix_OCSP_serviceLocator "OCSP Service Locator"
+#define NID_id_pkix_OCSP_serviceLocator 371
+#define OBJ_id_pkix_OCSP_serviceLocator OBJ_id_pkix_OCSP,7L
+
+#define SN_id_pkix_OCSP_extendedStatus "extendedStatus"
+#define LN_id_pkix_OCSP_extendedStatus "Extended OCSP Status"
+#define NID_id_pkix_OCSP_extendedStatus 372
+#define OBJ_id_pkix_OCSP_extendedStatus OBJ_id_pkix_OCSP,8L
+
+#define SN_id_pkix_OCSP_valid "valid"
+#define NID_id_pkix_OCSP_valid 373
+#define OBJ_id_pkix_OCSP_valid OBJ_id_pkix_OCSP,9L
+
+#define SN_id_pkix_OCSP_path "path"
+#define NID_id_pkix_OCSP_path 374
+#define OBJ_id_pkix_OCSP_path OBJ_id_pkix_OCSP,10L
+
+#define SN_id_pkix_OCSP_trustRoot "trustRoot"
+#define LN_id_pkix_OCSP_trustRoot "Trust Root"
+#define NID_id_pkix_OCSP_trustRoot 375
+#define OBJ_id_pkix_OCSP_trustRoot OBJ_id_pkix_OCSP,11L
+
+#define SN_algorithm "algorithm"
+#define LN_algorithm "algorithm"
+#define NID_algorithm 376
+#define OBJ_algorithm 1L,3L,14L,3L,2L
+
+#define SN_md5WithRSA "RSA-NP-MD5"
+#define LN_md5WithRSA "md5WithRSA"
+#define NID_md5WithRSA 104
+#define OBJ_md5WithRSA OBJ_algorithm,3L
+
+#define SN_des_ecb "DES-ECB"
+#define LN_des_ecb "des-ecb"
+#define NID_des_ecb 29
+#define OBJ_des_ecb OBJ_algorithm,6L
+
+#define SN_des_cbc "DES-CBC"
+#define LN_des_cbc "des-cbc"
+#define NID_des_cbc 31
+#define OBJ_des_cbc OBJ_algorithm,7L
+
+#define SN_des_ofb64 "DES-OFB"
+#define LN_des_ofb64 "des-ofb"
+#define NID_des_ofb64 45
+#define OBJ_des_ofb64 OBJ_algorithm,8L
+
+#define SN_des_cfb64 "DES-CFB"
+#define LN_des_cfb64 "des-cfb"
+#define NID_des_cfb64 30
+#define OBJ_des_cfb64 OBJ_algorithm,9L
+
+#define SN_rsaSignature "rsaSignature"
+#define NID_rsaSignature 377
+#define OBJ_rsaSignature OBJ_algorithm,11L
+
+#define SN_dsa_2 "DSA-old"
+#define LN_dsa_2 "dsaEncryption-old"
+#define NID_dsa_2 67
+#define OBJ_dsa_2 OBJ_algorithm,12L
+
+#define SN_dsaWithSHA "DSA-SHA"
+#define LN_dsaWithSHA "dsaWithSHA"
+#define NID_dsaWithSHA 66
+#define OBJ_dsaWithSHA OBJ_algorithm,13L
+
+#define SN_shaWithRSAEncryption "RSA-SHA"
+#define LN_shaWithRSAEncryption "shaWithRSAEncryption"
+#define NID_shaWithRSAEncryption 42
+#define OBJ_shaWithRSAEncryption OBJ_algorithm,15L
+
+#define SN_des_ede_ecb "DES-EDE"
+#define LN_des_ede_ecb "des-ede"
+#define NID_des_ede_ecb 32
+#define OBJ_des_ede_ecb OBJ_algorithm,17L
+
+#define SN_des_ede3_ecb "DES-EDE3"
+#define LN_des_ede3_ecb "des-ede3"
+#define NID_des_ede3_ecb 33
+
+#define SN_des_ede_cbc "DES-EDE-CBC"
+#define LN_des_ede_cbc "des-ede-cbc"
+#define NID_des_ede_cbc 43
+
+#define SN_des_ede_cfb64 "DES-EDE-CFB"
+#define LN_des_ede_cfb64 "des-ede-cfb"
+#define NID_des_ede_cfb64 60
+
+#define SN_des_ede3_cfb64 "DES-EDE3-CFB"
+#define LN_des_ede3_cfb64 "des-ede3-cfb"
+#define NID_des_ede3_cfb64 61
+
+#define SN_des_ede_ofb64 "DES-EDE-OFB"
+#define LN_des_ede_ofb64 "des-ede-ofb"
+#define NID_des_ede_ofb64 62
+
+#define SN_des_ede3_ofb64 "DES-EDE3-OFB"
+#define LN_des_ede3_ofb64 "des-ede3-ofb"
+#define NID_des_ede3_ofb64 63
+
+#define SN_desx_cbc "DESX-CBC"
+#define LN_desx_cbc "desx-cbc"
+#define NID_desx_cbc 80
+
+#define SN_sha "SHA"
+#define LN_sha "sha"
+#define NID_sha 41
+#define OBJ_sha OBJ_algorithm,18L
+
+#define SN_sha1 "SHA1"
+#define LN_sha1 "sha1"
+#define NID_sha1 64
+#define OBJ_sha1 OBJ_algorithm,26L
+
+#define SN_dsaWithSHA1_2 "DSA-SHA1-old"
+#define LN_dsaWithSHA1_2 "dsaWithSHA1-old"
+#define NID_dsaWithSHA1_2 70
+#define OBJ_dsaWithSHA1_2 OBJ_algorithm,27L
+
+#define SN_sha1WithRSA "RSA-SHA1-2"
+#define LN_sha1WithRSA "sha1WithRSA"
+#define NID_sha1WithRSA 115
+#define OBJ_sha1WithRSA OBJ_algorithm,29L
+
+#define SN_ripemd160 "RIPEMD160"
+#define LN_ripemd160 "ripemd160"
+#define NID_ripemd160 117
+#define OBJ_ripemd160 1L,3L,36L,3L,2L,1L
+
+#define SN_ripemd160WithRSA "RSA-RIPEMD160"
+#define LN_ripemd160WithRSA "ripemd160WithRSA"
+#define NID_ripemd160WithRSA 119
+#define OBJ_ripemd160WithRSA 1L,3L,36L,3L,3L,1L,2L
+
+#define SN_sxnet "SXNetID"
+#define LN_sxnet "Strong Extranet ID"
+#define NID_sxnet 143
+#define OBJ_sxnet 1L,3L,101L,1L,4L,1L
+
+#define SN_X500 "X500"
+#define LN_X500 "directory services (X.500)"
+#define NID_X500 11
+#define OBJ_X500 2L,5L
+
+#define SN_X509 "X509"
+#define NID_X509 12
+#define OBJ_X509 OBJ_X500,4L
+
+#define SN_commonName "CN"
+#define LN_commonName "commonName"
+#define NID_commonName 13
+#define OBJ_commonName OBJ_X509,3L
+
+#define SN_surname "SN"
+#define LN_surname "surname"
+#define NID_surname 100
+#define OBJ_surname OBJ_X509,4L
+
+#define LN_serialNumber "serialNumber"
+#define NID_serialNumber 105
+#define OBJ_serialNumber OBJ_X509,5L
+
+#define SN_countryName "C"
+#define LN_countryName "countryName"
+#define NID_countryName 14
+#define OBJ_countryName OBJ_X509,6L
+
+#define SN_localityName "L"
+#define LN_localityName "localityName"
+#define NID_localityName 15
+#define OBJ_localityName OBJ_X509,7L
+
+#define SN_stateOrProvinceName "ST"
+#define LN_stateOrProvinceName "stateOrProvinceName"
+#define NID_stateOrProvinceName 16
+#define OBJ_stateOrProvinceName OBJ_X509,8L
+
+#define SN_streetAddress "street"
+#define LN_streetAddress "streetAddress"
+#define NID_streetAddress 660
+#define OBJ_streetAddress OBJ_X509,9L
+
+#define SN_organizationName "O"
+#define LN_organizationName "organizationName"
+#define NID_organizationName 17
+#define OBJ_organizationName OBJ_X509,10L
+
+#define SN_organizationalUnitName "OU"
+#define LN_organizationalUnitName "organizationalUnitName"
+#define NID_organizationalUnitName 18
+#define OBJ_organizationalUnitName OBJ_X509,11L
+
+#define SN_title "title"
+#define LN_title "title"
+#define NID_title 106
+#define OBJ_title OBJ_X509,12L
+
+#define LN_description "description"
+#define NID_description 107
+#define OBJ_description OBJ_X509,13L
+
+#define LN_searchGuide "searchGuide"
+#define NID_searchGuide 859
+#define OBJ_searchGuide OBJ_X509,14L
+
+#define LN_businessCategory "businessCategory"
+#define NID_businessCategory 860
+#define OBJ_businessCategory OBJ_X509,15L
+
+#define LN_postalAddress "postalAddress"
+#define NID_postalAddress 861
+#define OBJ_postalAddress OBJ_X509,16L
+
+#define LN_postalCode "postalCode"
+#define NID_postalCode 661
+#define OBJ_postalCode OBJ_X509,17L
+
+#define LN_postOfficeBox "postOfficeBox"
+#define NID_postOfficeBox 862
+#define OBJ_postOfficeBox OBJ_X509,18L
+
+#define LN_physicalDeliveryOfficeName "physicalDeliveryOfficeName"
+#define NID_physicalDeliveryOfficeName 863
+#define OBJ_physicalDeliveryOfficeName OBJ_X509,19L
+
+#define LN_telephoneNumber "telephoneNumber"
+#define NID_telephoneNumber 864
+#define OBJ_telephoneNumber OBJ_X509,20L
+
+#define LN_telexNumber "telexNumber"
+#define NID_telexNumber 865
+#define OBJ_telexNumber OBJ_X509,21L
+
+#define LN_teletexTerminalIdentifier "teletexTerminalIdentifier"
+#define NID_teletexTerminalIdentifier 866
+#define OBJ_teletexTerminalIdentifier OBJ_X509,22L
+
+#define LN_facsimileTelephoneNumber "facsimileTelephoneNumber"
+#define NID_facsimileTelephoneNumber 867
+#define OBJ_facsimileTelephoneNumber OBJ_X509,23L
+
+#define LN_x121Address "x121Address"
+#define NID_x121Address 868
+#define OBJ_x121Address OBJ_X509,24L
+
+#define LN_internationaliSDNNumber "internationaliSDNNumber"
+#define NID_internationaliSDNNumber 869
+#define OBJ_internationaliSDNNumber OBJ_X509,25L
+
+#define LN_registeredAddress "registeredAddress"
+#define NID_registeredAddress 870
+#define OBJ_registeredAddress OBJ_X509,26L
+
+#define LN_destinationIndicator "destinationIndicator"
+#define NID_destinationIndicator 871
+#define OBJ_destinationIndicator OBJ_X509,27L
+
+#define LN_preferredDeliveryMethod "preferredDeliveryMethod"
+#define NID_preferredDeliveryMethod 872
+#define OBJ_preferredDeliveryMethod OBJ_X509,28L
+
+#define LN_presentationAddress "presentationAddress"
+#define NID_presentationAddress 873
+#define OBJ_presentationAddress OBJ_X509,29L
+
+#define LN_supportedApplicationContext "supportedApplicationContext"
+#define NID_supportedApplicationContext 874
+#define OBJ_supportedApplicationContext OBJ_X509,30L
+
+#define SN_member "member"
+#define NID_member 875
+#define OBJ_member OBJ_X509,31L
+
+#define SN_owner "owner"
+#define NID_owner 876
+#define OBJ_owner OBJ_X509,32L
+
+#define LN_roleOccupant "roleOccupant"
+#define NID_roleOccupant 877
+#define OBJ_roleOccupant OBJ_X509,33L
+
+#define SN_seeAlso "seeAlso"
+#define NID_seeAlso 878
+#define OBJ_seeAlso OBJ_X509,34L
+
+#define LN_userPassword "userPassword"
+#define NID_userPassword 879
+#define OBJ_userPassword OBJ_X509,35L
+
+#define LN_userCertificate "userCertificate"
+#define NID_userCertificate 880
+#define OBJ_userCertificate OBJ_X509,36L
+
+#define LN_cACertificate "cACertificate"
+#define NID_cACertificate 881
+#define OBJ_cACertificate OBJ_X509,37L
+
+#define LN_authorityRevocationList "authorityRevocationList"
+#define NID_authorityRevocationList 882
+#define OBJ_authorityRevocationList OBJ_X509,38L
+
+#define LN_certificateRevocationList "certificateRevocationList"
+#define NID_certificateRevocationList 883
+#define OBJ_certificateRevocationList OBJ_X509,39L
+
+#define LN_crossCertificatePair "crossCertificatePair"
+#define NID_crossCertificatePair 884
+#define OBJ_crossCertificatePair OBJ_X509,40L
+
+#define SN_name "name"
+#define LN_name "name"
+#define NID_name 173
+#define OBJ_name OBJ_X509,41L
+
+#define SN_givenName "GN"
+#define LN_givenName "givenName"
+#define NID_givenName 99
+#define OBJ_givenName OBJ_X509,42L
+
+#define SN_initials "initials"
+#define LN_initials "initials"
+#define NID_initials 101
+#define OBJ_initials OBJ_X509,43L
+
+#define LN_generationQualifier "generationQualifier"
+#define NID_generationQualifier 509
+#define OBJ_generationQualifier OBJ_X509,44L
+
+#define LN_x500UniqueIdentifier "x500UniqueIdentifier"
+#define NID_x500UniqueIdentifier 503
+#define OBJ_x500UniqueIdentifier OBJ_X509,45L
+
+#define SN_dnQualifier "dnQualifier"
+#define LN_dnQualifier "dnQualifier"
+#define NID_dnQualifier 174
+#define OBJ_dnQualifier OBJ_X509,46L
+
+#define LN_enhancedSearchGuide "enhancedSearchGuide"
+#define NID_enhancedSearchGuide 885
+#define OBJ_enhancedSearchGuide OBJ_X509,47L
+
+#define LN_protocolInformation "protocolInformation"
+#define NID_protocolInformation 886
+#define OBJ_protocolInformation OBJ_X509,48L
+
+#define LN_distinguishedName "distinguishedName"
+#define NID_distinguishedName 887
+#define OBJ_distinguishedName OBJ_X509,49L
+
+#define LN_uniqueMember "uniqueMember"
+#define NID_uniqueMember 888
+#define OBJ_uniqueMember OBJ_X509,50L
+
+#define LN_houseIdentifier "houseIdentifier"
+#define NID_houseIdentifier 889
+#define OBJ_houseIdentifier OBJ_X509,51L
+
+#define LN_supportedAlgorithms "supportedAlgorithms"
+#define NID_supportedAlgorithms 890
+#define OBJ_supportedAlgorithms OBJ_X509,52L
+
+#define LN_deltaRevocationList "deltaRevocationList"
+#define NID_deltaRevocationList 891
+#define OBJ_deltaRevocationList OBJ_X509,53L
+
+#define SN_dmdName "dmdName"
+#define NID_dmdName 892
+#define OBJ_dmdName OBJ_X509,54L
+
+#define LN_pseudonym "pseudonym"
+#define NID_pseudonym 510
+#define OBJ_pseudonym OBJ_X509,65L
+
+#define SN_role "role"
+#define LN_role "role"
+#define NID_role 400
+#define OBJ_role OBJ_X509,72L
+
+#define SN_X500algorithms "X500algorithms"
+#define LN_X500algorithms "directory services - algorithms"
+#define NID_X500algorithms 378
+#define OBJ_X500algorithms OBJ_X500,8L
+
+#define SN_rsa "RSA"
+#define LN_rsa "rsa"
+#define NID_rsa 19
+#define OBJ_rsa OBJ_X500algorithms,1L,1L
+
+#define SN_mdc2WithRSA "RSA-MDC2"
+#define LN_mdc2WithRSA "mdc2WithRSA"
+#define NID_mdc2WithRSA 96
+#define OBJ_mdc2WithRSA OBJ_X500algorithms,3L,100L
+
+#define SN_mdc2 "MDC2"
+#define LN_mdc2 "mdc2"
+#define NID_mdc2 95
+#define OBJ_mdc2 OBJ_X500algorithms,3L,101L
+
+#define SN_id_ce "id-ce"
+#define NID_id_ce 81
+#define OBJ_id_ce OBJ_X500,29L
+
+#define SN_subject_directory_attributes "subjectDirectoryAttributes"
+#define LN_subject_directory_attributes "X509v3 Subject Directory Attributes"
+#define NID_subject_directory_attributes 769
+#define OBJ_subject_directory_attributes OBJ_id_ce,9L
+
+#define SN_subject_key_identifier "subjectKeyIdentifier"
+#define LN_subject_key_identifier "X509v3 Subject Key Identifier"
+#define NID_subject_key_identifier 82
+#define OBJ_subject_key_identifier OBJ_id_ce,14L
+
+#define SN_key_usage "keyUsage"
+#define LN_key_usage "X509v3 Key Usage"
+#define NID_key_usage 83
+#define OBJ_key_usage OBJ_id_ce,15L
+
+#define SN_private_key_usage_period "privateKeyUsagePeriod"
+#define LN_private_key_usage_period "X509v3 Private Key Usage Period"
+#define NID_private_key_usage_period 84
+#define OBJ_private_key_usage_period OBJ_id_ce,16L
+
+#define SN_subject_alt_name "subjectAltName"
+#define LN_subject_alt_name "X509v3 Subject Alternative Name"
+#define NID_subject_alt_name 85
+#define OBJ_subject_alt_name OBJ_id_ce,17L
+
+#define SN_issuer_alt_name "issuerAltName"
+#define LN_issuer_alt_name "X509v3 Issuer Alternative Name"
+#define NID_issuer_alt_name 86
+#define OBJ_issuer_alt_name OBJ_id_ce,18L
+
+#define SN_basic_constraints "basicConstraints"
+#define LN_basic_constraints "X509v3 Basic Constraints"
+#define NID_basic_constraints 87
+#define OBJ_basic_constraints OBJ_id_ce,19L
+
+#define SN_crl_number "crlNumber"
+#define LN_crl_number "X509v3 CRL Number"
+#define NID_crl_number 88
+#define OBJ_crl_number OBJ_id_ce,20L
+
+#define SN_crl_reason "CRLReason"
+#define LN_crl_reason "X509v3 CRL Reason Code"
+#define NID_crl_reason 141
+#define OBJ_crl_reason OBJ_id_ce,21L
+
+#define SN_invalidity_date "invalidityDate"
+#define LN_invalidity_date "Invalidity Date"
+#define NID_invalidity_date 142
+#define OBJ_invalidity_date OBJ_id_ce,24L
+
+#define SN_delta_crl "deltaCRL"
+#define LN_delta_crl "X509v3 Delta CRL Indicator"
+#define NID_delta_crl 140
+#define OBJ_delta_crl OBJ_id_ce,27L
+
+#define SN_issuing_distribution_point "issuingDistributionPoint"
+#define LN_issuing_distribution_point "X509v3 Issuing Distribution Point"
+#define NID_issuing_distribution_point 770
+#define OBJ_issuing_distribution_point OBJ_id_ce,28L
+
+#define SN_certificate_issuer "certificateIssuer"
+#define LN_certificate_issuer "X509v3 Certificate Issuer"
+#define NID_certificate_issuer 771
+#define OBJ_certificate_issuer OBJ_id_ce,29L
+
+#define SN_name_constraints "nameConstraints"
+#define LN_name_constraints "X509v3 Name Constraints"
+#define NID_name_constraints 666
+#define OBJ_name_constraints OBJ_id_ce,30L
+
+#define SN_crl_distribution_points "crlDistributionPoints"
+#define LN_crl_distribution_points "X509v3 CRL Distribution Points"
+#define NID_crl_distribution_points 103
+#define OBJ_crl_distribution_points OBJ_id_ce,31L
+
+#define SN_certificate_policies "certificatePolicies"
+#define LN_certificate_policies "X509v3 Certificate Policies"
+#define NID_certificate_policies 89
+#define OBJ_certificate_policies OBJ_id_ce,32L
+
+#define SN_any_policy "anyPolicy"
+#define LN_any_policy "X509v3 Any Policy"
+#define NID_any_policy 746
+#define OBJ_any_policy OBJ_certificate_policies,0L
+
+#define SN_policy_mappings "policyMappings"
+#define LN_policy_mappings "X509v3 Policy Mappings"
+#define NID_policy_mappings 747
+#define OBJ_policy_mappings OBJ_id_ce,33L
+
+#define SN_authority_key_identifier "authorityKeyIdentifier"
+#define LN_authority_key_identifier "X509v3 Authority Key Identifier"
+#define NID_authority_key_identifier 90
+#define OBJ_authority_key_identifier OBJ_id_ce,35L
+
+#define SN_policy_constraints "policyConstraints"
+#define LN_policy_constraints "X509v3 Policy Constraints"
+#define NID_policy_constraints 401
+#define OBJ_policy_constraints OBJ_id_ce,36L
+
+#define SN_ext_key_usage "extendedKeyUsage"
+#define LN_ext_key_usage "X509v3 Extended Key Usage"
+#define NID_ext_key_usage 126
+#define OBJ_ext_key_usage OBJ_id_ce,37L
+
+#define SN_freshest_crl "freshestCRL"
+#define LN_freshest_crl "X509v3 Freshest CRL"
+#define NID_freshest_crl 857
+#define OBJ_freshest_crl OBJ_id_ce,46L
+
+#define SN_inhibit_any_policy "inhibitAnyPolicy"
+#define LN_inhibit_any_policy "X509v3 Inhibit Any Policy"
+#define NID_inhibit_any_policy 748
+#define OBJ_inhibit_any_policy OBJ_id_ce,54L
+
+#define SN_target_information "targetInformation"
+#define LN_target_information "X509v3 AC Targeting"
+#define NID_target_information 402
+#define OBJ_target_information OBJ_id_ce,55L
+
+#define SN_no_rev_avail "noRevAvail"
+#define LN_no_rev_avail "X509v3 No Revocation Available"
+#define NID_no_rev_avail 403
+#define OBJ_no_rev_avail OBJ_id_ce,56L
+
+#define SN_anyExtendedKeyUsage "anyExtendedKeyUsage"
+#define LN_anyExtendedKeyUsage "Any Extended Key Usage"
+#define NID_anyExtendedKeyUsage 910
+#define OBJ_anyExtendedKeyUsage OBJ_ext_key_usage,0L
+
+#define SN_netscape "Netscape"
+#define LN_netscape "Netscape Communications Corp."
+#define NID_netscape 57
+#define OBJ_netscape 2L,16L,840L,1L,113730L
+
+#define SN_netscape_cert_extension "nsCertExt"
+#define LN_netscape_cert_extension "Netscape Certificate Extension"
+#define NID_netscape_cert_extension 58
+#define OBJ_netscape_cert_extension OBJ_netscape,1L
+
+#define SN_netscape_data_type "nsDataType"
+#define LN_netscape_data_type "Netscape Data Type"
+#define NID_netscape_data_type 59
+#define OBJ_netscape_data_type OBJ_netscape,2L
+
+#define SN_netscape_cert_type "nsCertType"
+#define LN_netscape_cert_type "Netscape Cert Type"
+#define NID_netscape_cert_type 71
+#define OBJ_netscape_cert_type OBJ_netscape_cert_extension,1L
+
+#define SN_netscape_base_url "nsBaseUrl"
+#define LN_netscape_base_url "Netscape Base Url"
+#define NID_netscape_base_url 72
+#define OBJ_netscape_base_url OBJ_netscape_cert_extension,2L
+
+#define SN_netscape_revocation_url "nsRevocationUrl"
+#define LN_netscape_revocation_url "Netscape Revocation Url"
+#define NID_netscape_revocation_url 73
+#define OBJ_netscape_revocation_url OBJ_netscape_cert_extension,3L
+
+#define SN_netscape_ca_revocation_url "nsCaRevocationUrl"
+#define LN_netscape_ca_revocation_url "Netscape CA Revocation Url"
+#define NID_netscape_ca_revocation_url 74
+#define OBJ_netscape_ca_revocation_url OBJ_netscape_cert_extension,4L
+
+#define SN_netscape_renewal_url "nsRenewalUrl"
+#define LN_netscape_renewal_url "Netscape Renewal Url"
+#define NID_netscape_renewal_url 75
+#define OBJ_netscape_renewal_url OBJ_netscape_cert_extension,7L
+
+#define SN_netscape_ca_policy_url "nsCaPolicyUrl"
+#define LN_netscape_ca_policy_url "Netscape CA Policy Url"
+#define NID_netscape_ca_policy_url 76
+#define OBJ_netscape_ca_policy_url OBJ_netscape_cert_extension,8L
+
+#define SN_netscape_ssl_server_name "nsSslServerName"
+#define LN_netscape_ssl_server_name "Netscape SSL Server Name"
+#define NID_netscape_ssl_server_name 77
+#define OBJ_netscape_ssl_server_name OBJ_netscape_cert_extension,12L
+
+#define SN_netscape_comment "nsComment"
+#define LN_netscape_comment "Netscape Comment"
+#define NID_netscape_comment 78
+#define OBJ_netscape_comment OBJ_netscape_cert_extension,13L
+
+#define SN_netscape_cert_sequence "nsCertSequence"
+#define LN_netscape_cert_sequence "Netscape Certificate Sequence"
+#define NID_netscape_cert_sequence 79
+#define OBJ_netscape_cert_sequence OBJ_netscape_data_type,5L
+
+#define SN_ns_sgc "nsSGC"
+#define LN_ns_sgc "Netscape Server Gated Crypto"
+#define NID_ns_sgc 139
+#define OBJ_ns_sgc OBJ_netscape,4L,1L
+
+#define SN_org "ORG"
+#define LN_org "org"
+#define NID_org 379
+#define OBJ_org OBJ_iso,3L
+
+#define SN_dod "DOD"
+#define LN_dod "dod"
+#define NID_dod 380
+#define OBJ_dod OBJ_org,6L
+
+#define SN_iana "IANA"
+#define LN_iana "iana"
+#define NID_iana 381
+#define OBJ_iana OBJ_dod,1L
+
+#define OBJ_internet OBJ_iana
+
+#define SN_Directory "directory"
+#define LN_Directory "Directory"
+#define NID_Directory 382
+#define OBJ_Directory OBJ_internet,1L
+
+#define SN_Management "mgmt"
+#define LN_Management "Management"
+#define NID_Management 383
+#define OBJ_Management OBJ_internet,2L
+
+#define SN_Experimental "experimental"
+#define LN_Experimental "Experimental"
+#define NID_Experimental 384
+#define OBJ_Experimental OBJ_internet,3L
+
+#define SN_Private "private"
+#define LN_Private "Private"
+#define NID_Private 385
+#define OBJ_Private OBJ_internet,4L
+
+#define SN_Security "security"
+#define LN_Security "Security"
+#define NID_Security 386
+#define OBJ_Security OBJ_internet,5L
+
+#define SN_SNMPv2 "snmpv2"
+#define LN_SNMPv2 "SNMPv2"
+#define NID_SNMPv2 387
+#define OBJ_SNMPv2 OBJ_internet,6L
+
+#define LN_Mail "Mail"
+#define NID_Mail 388
+#define OBJ_Mail OBJ_internet,7L
+
+#define SN_Enterprises "enterprises"
+#define LN_Enterprises "Enterprises"
+#define NID_Enterprises 389
+#define OBJ_Enterprises OBJ_Private,1L
+
+#define SN_dcObject "dcobject"
+#define LN_dcObject "dcObject"
+#define NID_dcObject 390
+#define OBJ_dcObject OBJ_Enterprises,1466L,344L
+
+#define SN_mime_mhs "mime-mhs"
+#define LN_mime_mhs "MIME MHS"
+#define NID_mime_mhs 504
+#define OBJ_mime_mhs OBJ_Mail,1L
+
+#define SN_mime_mhs_headings "mime-mhs-headings"
+#define LN_mime_mhs_headings "mime-mhs-headings"
+#define NID_mime_mhs_headings 505
+#define OBJ_mime_mhs_headings OBJ_mime_mhs,1L
+
+#define SN_mime_mhs_bodies "mime-mhs-bodies"
+#define LN_mime_mhs_bodies "mime-mhs-bodies"
+#define NID_mime_mhs_bodies 506
+#define OBJ_mime_mhs_bodies OBJ_mime_mhs,2L
+
+#define SN_id_hex_partial_message "id-hex-partial-message"
+#define LN_id_hex_partial_message "id-hex-partial-message"
+#define NID_id_hex_partial_message 507
+#define OBJ_id_hex_partial_message OBJ_mime_mhs_headings,1L
+
+#define SN_id_hex_multipart_message "id-hex-multipart-message"
+#define LN_id_hex_multipart_message "id-hex-multipart-message"
+#define NID_id_hex_multipart_message 508
+#define OBJ_id_hex_multipart_message OBJ_mime_mhs_headings,2L
+
+#define SN_zlib_compression "ZLIB"
+#define LN_zlib_compression "zlib compression"
+#define NID_zlib_compression 125
+#define OBJ_zlib_compression OBJ_id_smime_alg,8L
+
+#define OBJ_csor 2L,16L,840L,1L,101L,3L
+
+#define OBJ_nistAlgorithms OBJ_csor,4L
+
+#define OBJ_aes OBJ_nistAlgorithms,1L
+
+#define SN_aes_128_ecb "AES-128-ECB"
+#define LN_aes_128_ecb "aes-128-ecb"
+#define NID_aes_128_ecb 418
+#define OBJ_aes_128_ecb OBJ_aes,1L
+
+#define SN_aes_128_cbc "AES-128-CBC"
+#define LN_aes_128_cbc "aes-128-cbc"
+#define NID_aes_128_cbc 419
+#define OBJ_aes_128_cbc OBJ_aes,2L
+
+#define SN_aes_128_ofb128 "AES-128-OFB"
+#define LN_aes_128_ofb128 "aes-128-ofb"
+#define NID_aes_128_ofb128 420
+#define OBJ_aes_128_ofb128 OBJ_aes,3L
+
+#define SN_aes_128_cfb128 "AES-128-CFB"
+#define LN_aes_128_cfb128 "aes-128-cfb"
+#define NID_aes_128_cfb128 421
+#define OBJ_aes_128_cfb128 OBJ_aes,4L
+
+#define SN_id_aes128_wrap "id-aes128-wrap"
+#define NID_id_aes128_wrap 788
+#define OBJ_id_aes128_wrap OBJ_aes,5L
+
+#define SN_aes_128_gcm "id-aes128-GCM"
+#define LN_aes_128_gcm "aes-128-gcm"
+#define NID_aes_128_gcm 895
+#define OBJ_aes_128_gcm OBJ_aes,6L
+
+#define SN_aes_128_ccm "id-aes128-CCM"
+#define LN_aes_128_ccm "aes-128-ccm"
+#define NID_aes_128_ccm 896
+#define OBJ_aes_128_ccm OBJ_aes,7L
+
+#define SN_id_aes128_wrap_pad "id-aes128-wrap-pad"
+#define NID_id_aes128_wrap_pad 897
+#define OBJ_id_aes128_wrap_pad OBJ_aes,8L
+
+#define SN_aes_192_ecb "AES-192-ECB"
+#define LN_aes_192_ecb "aes-192-ecb"
+#define NID_aes_192_ecb 422
+#define OBJ_aes_192_ecb OBJ_aes,21L
+
+#define SN_aes_192_cbc "AES-192-CBC"
+#define LN_aes_192_cbc "aes-192-cbc"
+#define NID_aes_192_cbc 423
+#define OBJ_aes_192_cbc OBJ_aes,22L
+
+#define SN_aes_192_ofb128 "AES-192-OFB"
+#define LN_aes_192_ofb128 "aes-192-ofb"
+#define NID_aes_192_ofb128 424
+#define OBJ_aes_192_ofb128 OBJ_aes,23L
+
+#define SN_aes_192_cfb128 "AES-192-CFB"
+#define LN_aes_192_cfb128 "aes-192-cfb"
+#define NID_aes_192_cfb128 425
+#define OBJ_aes_192_cfb128 OBJ_aes,24L
+
+#define SN_id_aes192_wrap "id-aes192-wrap"
+#define NID_id_aes192_wrap 789
+#define OBJ_id_aes192_wrap OBJ_aes,25L
+
+#define SN_aes_192_gcm "id-aes192-GCM"
+#define LN_aes_192_gcm "aes-192-gcm"
+#define NID_aes_192_gcm 898
+#define OBJ_aes_192_gcm OBJ_aes,26L
+
+#define SN_aes_192_ccm "id-aes192-CCM"
+#define LN_aes_192_ccm "aes-192-ccm"
+#define NID_aes_192_ccm 899
+#define OBJ_aes_192_ccm OBJ_aes,27L
+
+#define SN_id_aes192_wrap_pad "id-aes192-wrap-pad"
+#define NID_id_aes192_wrap_pad 900
+#define OBJ_id_aes192_wrap_pad OBJ_aes,28L
+
+#define SN_aes_256_ecb "AES-256-ECB"
+#define LN_aes_256_ecb "aes-256-ecb"
+#define NID_aes_256_ecb 426
+#define OBJ_aes_256_ecb OBJ_aes,41L
+
+#define SN_aes_256_cbc "AES-256-CBC"
+#define LN_aes_256_cbc "aes-256-cbc"
+#define NID_aes_256_cbc 427
+#define OBJ_aes_256_cbc OBJ_aes,42L
+
+#define SN_aes_256_ofb128 "AES-256-OFB"
+#define LN_aes_256_ofb128 "aes-256-ofb"
+#define NID_aes_256_ofb128 428
+#define OBJ_aes_256_ofb128 OBJ_aes,43L
+
+#define SN_aes_256_cfb128 "AES-256-CFB"
+#define LN_aes_256_cfb128 "aes-256-cfb"
+#define NID_aes_256_cfb128 429
+#define OBJ_aes_256_cfb128 OBJ_aes,44L
+
+#define SN_id_aes256_wrap "id-aes256-wrap"
+#define NID_id_aes256_wrap 790
+#define OBJ_id_aes256_wrap OBJ_aes,45L
+
+#define SN_aes_256_gcm "id-aes256-GCM"
+#define LN_aes_256_gcm "aes-256-gcm"
+#define NID_aes_256_gcm 901
+#define OBJ_aes_256_gcm OBJ_aes,46L
+
+#define SN_aes_256_ccm "id-aes256-CCM"
+#define LN_aes_256_ccm "aes-256-ccm"
+#define NID_aes_256_ccm 902
+#define OBJ_aes_256_ccm OBJ_aes,47L
+
+#define SN_id_aes256_wrap_pad "id-aes256-wrap-pad"
+#define NID_id_aes256_wrap_pad 903
+#define OBJ_id_aes256_wrap_pad OBJ_aes,48L
+
+#define SN_aes_128_cfb1 "AES-128-CFB1"
+#define LN_aes_128_cfb1 "aes-128-cfb1"
+#define NID_aes_128_cfb1 650
+
+#define SN_aes_192_cfb1 "AES-192-CFB1"
+#define LN_aes_192_cfb1 "aes-192-cfb1"
+#define NID_aes_192_cfb1 651
+
+#define SN_aes_256_cfb1 "AES-256-CFB1"
+#define LN_aes_256_cfb1 "aes-256-cfb1"
+#define NID_aes_256_cfb1 652
+
+#define SN_aes_128_cfb8 "AES-128-CFB8"
+#define LN_aes_128_cfb8 "aes-128-cfb8"
+#define NID_aes_128_cfb8 653
+
+#define SN_aes_192_cfb8 "AES-192-CFB8"
+#define LN_aes_192_cfb8 "aes-192-cfb8"
+#define NID_aes_192_cfb8 654
+
+#define SN_aes_256_cfb8 "AES-256-CFB8"
+#define LN_aes_256_cfb8 "aes-256-cfb8"
+#define NID_aes_256_cfb8 655
+
+#define SN_aes_128_ctr "AES-128-CTR"
+#define LN_aes_128_ctr "aes-128-ctr"
+#define NID_aes_128_ctr 904
+
+#define SN_aes_192_ctr "AES-192-CTR"
+#define LN_aes_192_ctr "aes-192-ctr"
+#define NID_aes_192_ctr 905
+
+#define SN_aes_256_ctr "AES-256-CTR"
+#define LN_aes_256_ctr "aes-256-ctr"
+#define NID_aes_256_ctr 906
+
+#define SN_aes_128_xts "AES-128-XTS"
+#define LN_aes_128_xts "aes-128-xts"
+#define NID_aes_128_xts 913
+
+#define SN_aes_256_xts "AES-256-XTS"
+#define LN_aes_256_xts "aes-256-xts"
+#define NID_aes_256_xts 914
+
+#define SN_des_cfb1 "DES-CFB1"
+#define LN_des_cfb1 "des-cfb1"
+#define NID_des_cfb1 656
+
+#define SN_des_cfb8 "DES-CFB8"
+#define LN_des_cfb8 "des-cfb8"
+#define NID_des_cfb8 657
+
+#define SN_des_ede3_cfb1 "DES-EDE3-CFB1"
+#define LN_des_ede3_cfb1 "des-ede3-cfb1"
+#define NID_des_ede3_cfb1 658
+
+#define SN_des_ede3_cfb8 "DES-EDE3-CFB8"
+#define LN_des_ede3_cfb8 "des-ede3-cfb8"
+#define NID_des_ede3_cfb8 659
+
+#define OBJ_nist_hashalgs OBJ_nistAlgorithms,2L
+
+#define SN_sha256 "SHA256"
+#define LN_sha256 "sha256"
+#define NID_sha256 672
+#define OBJ_sha256 OBJ_nist_hashalgs,1L
+
+#define SN_sha384 "SHA384"
+#define LN_sha384 "sha384"
+#define NID_sha384 673
+#define OBJ_sha384 OBJ_nist_hashalgs,2L
+
+#define SN_sha512 "SHA512"
+#define LN_sha512 "sha512"
+#define NID_sha512 674
+#define OBJ_sha512 OBJ_nist_hashalgs,3L
+
+#define SN_sha224 "SHA224"
+#define LN_sha224 "sha224"
+#define NID_sha224 675
+#define OBJ_sha224 OBJ_nist_hashalgs,4L
+
+#define OBJ_dsa_with_sha2 OBJ_nistAlgorithms,3L
+
+#define SN_dsa_with_SHA224 "dsa_with_SHA224"
+#define NID_dsa_with_SHA224 802
+#define OBJ_dsa_with_SHA224 OBJ_dsa_with_sha2,1L
+
+#define SN_dsa_with_SHA256 "dsa_with_SHA256"
+#define NID_dsa_with_SHA256 803
+#define OBJ_dsa_with_SHA256 OBJ_dsa_with_sha2,2L
+
+#define SN_hold_instruction_code "holdInstructionCode"
+#define LN_hold_instruction_code "Hold Instruction Code"
+#define NID_hold_instruction_code 430
+#define OBJ_hold_instruction_code OBJ_id_ce,23L
+
+#define OBJ_holdInstruction OBJ_X9_57,2L
+
+#define SN_hold_instruction_none "holdInstructionNone"
+#define LN_hold_instruction_none "Hold Instruction None"
+#define NID_hold_instruction_none 431
+#define OBJ_hold_instruction_none OBJ_holdInstruction,1L
+
+#define SN_hold_instruction_call_issuer "holdInstructionCallIssuer"
+#define LN_hold_instruction_call_issuer "Hold Instruction Call Issuer"
+#define NID_hold_instruction_call_issuer 432
+#define OBJ_hold_instruction_call_issuer OBJ_holdInstruction,2L
+
+#define SN_hold_instruction_reject "holdInstructionReject"
+#define LN_hold_instruction_reject "Hold Instruction Reject"
+#define NID_hold_instruction_reject 433
+#define OBJ_hold_instruction_reject OBJ_holdInstruction,3L
+
+#define SN_data "data"
+#define NID_data 434
+#define OBJ_data OBJ_itu_t,9L
+
+#define SN_pss "pss"
+#define NID_pss 435
+#define OBJ_pss OBJ_data,2342L
+
+#define SN_ucl "ucl"
+#define NID_ucl 436
+#define OBJ_ucl OBJ_pss,19200300L
+
+#define SN_pilot "pilot"
+#define NID_pilot 437
+#define OBJ_pilot OBJ_ucl,100L
+
+#define LN_pilotAttributeType "pilotAttributeType"
+#define NID_pilotAttributeType 438
+#define OBJ_pilotAttributeType OBJ_pilot,1L
+
+#define LN_pilotAttributeSyntax "pilotAttributeSyntax"
+#define NID_pilotAttributeSyntax 439
+#define OBJ_pilotAttributeSyntax OBJ_pilot,3L
+
+#define LN_pilotObjectClass "pilotObjectClass"
+#define NID_pilotObjectClass 440
+#define OBJ_pilotObjectClass OBJ_pilot,4L
+
+#define LN_pilotGroups "pilotGroups"
+#define NID_pilotGroups 441
+#define OBJ_pilotGroups OBJ_pilot,10L
+
+#define LN_iA5StringSyntax "iA5StringSyntax"
+#define NID_iA5StringSyntax 442
+#define OBJ_iA5StringSyntax OBJ_pilotAttributeSyntax,4L
+
+#define LN_caseIgnoreIA5StringSyntax "caseIgnoreIA5StringSyntax"
+#define NID_caseIgnoreIA5StringSyntax 443
+#define OBJ_caseIgnoreIA5StringSyntax OBJ_pilotAttributeSyntax,5L
+
+#define LN_pilotObject "pilotObject"
+#define NID_pilotObject 444
+#define OBJ_pilotObject OBJ_pilotObjectClass,3L
+
+#define LN_pilotPerson "pilotPerson"
+#define NID_pilotPerson 445
+#define OBJ_pilotPerson OBJ_pilotObjectClass,4L
+
+#define SN_account "account"
+#define NID_account 446
+#define OBJ_account OBJ_pilotObjectClass,5L
+
+#define SN_document "document"
+#define NID_document 447
+#define OBJ_document OBJ_pilotObjectClass,6L
+
+#define SN_room "room"
+#define NID_room 448
+#define OBJ_room OBJ_pilotObjectClass,7L
+
+#define LN_documentSeries "documentSeries"
+#define NID_documentSeries 449
+#define OBJ_documentSeries OBJ_pilotObjectClass,9L
+
+#define SN_Domain "domain"
+#define LN_Domain "Domain"
+#define NID_Domain 392
+#define OBJ_Domain OBJ_pilotObjectClass,13L
+
+#define LN_rFC822localPart "rFC822localPart"
+#define NID_rFC822localPart 450
+#define OBJ_rFC822localPart OBJ_pilotObjectClass,14L
+
+#define LN_dNSDomain "dNSDomain"
+#define NID_dNSDomain 451
+#define OBJ_dNSDomain OBJ_pilotObjectClass,15L
+
+#define LN_domainRelatedObject "domainRelatedObject"
+#define NID_domainRelatedObject 452
+#define OBJ_domainRelatedObject OBJ_pilotObjectClass,17L
+
+#define LN_friendlyCountry "friendlyCountry"
+#define NID_friendlyCountry 453
+#define OBJ_friendlyCountry OBJ_pilotObjectClass,18L
+
+#define LN_simpleSecurityObject "simpleSecurityObject"
+#define NID_simpleSecurityObject 454
+#define OBJ_simpleSecurityObject OBJ_pilotObjectClass,19L
+
+#define LN_pilotOrganization "pilotOrganization"
+#define NID_pilotOrganization 455
+#define OBJ_pilotOrganization OBJ_pilotObjectClass,20L
+
+#define LN_pilotDSA "pilotDSA"
+#define NID_pilotDSA 456
+#define OBJ_pilotDSA OBJ_pilotObjectClass,21L
+
+#define LN_qualityLabelledData "qualityLabelledData"
+#define NID_qualityLabelledData 457
+#define OBJ_qualityLabelledData OBJ_pilotObjectClass,22L
+
+#define SN_userId "UID"
+#define LN_userId "userId"
+#define NID_userId 458
+#define OBJ_userId OBJ_pilotAttributeType,1L
+
+#define LN_textEncodedORAddress "textEncodedORAddress"
+#define NID_textEncodedORAddress 459
+#define OBJ_textEncodedORAddress OBJ_pilotAttributeType,2L
+
+#define SN_rfc822Mailbox "mail"
+#define LN_rfc822Mailbox "rfc822Mailbox"
+#define NID_rfc822Mailbox 460
+#define OBJ_rfc822Mailbox OBJ_pilotAttributeType,3L
+
+#define SN_info "info"
+#define NID_info 461
+#define OBJ_info OBJ_pilotAttributeType,4L
+
+#define LN_favouriteDrink "favouriteDrink"
+#define NID_favouriteDrink 462
+#define OBJ_favouriteDrink OBJ_pilotAttributeType,5L
+
+#define LN_roomNumber "roomNumber"
+#define NID_roomNumber 463
+#define OBJ_roomNumber OBJ_pilotAttributeType,6L
+
+#define SN_photo "photo"
+#define NID_photo 464
+#define OBJ_photo OBJ_pilotAttributeType,7L
+
+#define LN_userClass "userClass"
+#define NID_userClass 465
+#define OBJ_userClass OBJ_pilotAttributeType,8L
+
+#define SN_host "host"
+#define NID_host 466
+#define OBJ_host OBJ_pilotAttributeType,9L
+
+#define SN_manager "manager"
+#define NID_manager 467
+#define OBJ_manager OBJ_pilotAttributeType,10L
+
+#define LN_documentIdentifier "documentIdentifier"
+#define NID_documentIdentifier 468
+#define OBJ_documentIdentifier OBJ_pilotAttributeType,11L
+
+#define LN_documentTitle "documentTitle"
+#define NID_documentTitle 469
+#define OBJ_documentTitle OBJ_pilotAttributeType,12L
+
+#define LN_documentVersion "documentVersion"
+#define NID_documentVersion 470
+#define OBJ_documentVersion OBJ_pilotAttributeType,13L
+
+#define LN_documentAuthor "documentAuthor"
+#define NID_documentAuthor 471
+#define OBJ_documentAuthor OBJ_pilotAttributeType,14L
+
+#define LN_documentLocation "documentLocation"
+#define NID_documentLocation 472
+#define OBJ_documentLocation OBJ_pilotAttributeType,15L
+
+#define LN_homeTelephoneNumber "homeTelephoneNumber"
+#define NID_homeTelephoneNumber 473
+#define OBJ_homeTelephoneNumber OBJ_pilotAttributeType,20L
+
+#define SN_secretary "secretary"
+#define NID_secretary 474
+#define OBJ_secretary OBJ_pilotAttributeType,21L
+
+#define LN_otherMailbox "otherMailbox"
+#define NID_otherMailbox 475
+#define OBJ_otherMailbox OBJ_pilotAttributeType,22L
+
+#define LN_lastModifiedTime "lastModifiedTime"
+#define NID_lastModifiedTime 476
+#define OBJ_lastModifiedTime OBJ_pilotAttributeType,23L
+
+#define LN_lastModifiedBy "lastModifiedBy"
+#define NID_lastModifiedBy 477
+#define OBJ_lastModifiedBy OBJ_pilotAttributeType,24L
+
+#define SN_domainComponent "DC"
+#define LN_domainComponent "domainComponent"
+#define NID_domainComponent 391
+#define OBJ_domainComponent OBJ_pilotAttributeType,25L
+
+#define LN_aRecord "aRecord"
+#define NID_aRecord 478
+#define OBJ_aRecord OBJ_pilotAttributeType,26L
+
+#define LN_pilotAttributeType27 "pilotAttributeType27"
+#define NID_pilotAttributeType27 479
+#define OBJ_pilotAttributeType27 OBJ_pilotAttributeType,27L
+
+#define LN_mXRecord "mXRecord"
+#define NID_mXRecord 480
+#define OBJ_mXRecord OBJ_pilotAttributeType,28L
+
+#define LN_nSRecord "nSRecord"
+#define NID_nSRecord 481
+#define OBJ_nSRecord OBJ_pilotAttributeType,29L
+
+#define LN_sOARecord "sOARecord"
+#define NID_sOARecord 482
+#define OBJ_sOARecord OBJ_pilotAttributeType,30L
+
+#define LN_cNAMERecord "cNAMERecord"
+#define NID_cNAMERecord 483
+#define OBJ_cNAMERecord OBJ_pilotAttributeType,31L
+
+#define LN_associatedDomain "associatedDomain"
+#define NID_associatedDomain 484
+#define OBJ_associatedDomain OBJ_pilotAttributeType,37L
+
+#define LN_associatedName "associatedName"
+#define NID_associatedName 485
+#define OBJ_associatedName OBJ_pilotAttributeType,38L
+
+#define LN_homePostalAddress "homePostalAddress"
+#define NID_homePostalAddress 486
+#define OBJ_homePostalAddress OBJ_pilotAttributeType,39L
+
+#define LN_personalTitle "personalTitle"
+#define NID_personalTitle 487
+#define OBJ_personalTitle OBJ_pilotAttributeType,40L
+
+#define LN_mobileTelephoneNumber "mobileTelephoneNumber"
+#define NID_mobileTelephoneNumber 488
+#define OBJ_mobileTelephoneNumber OBJ_pilotAttributeType,41L
+
+#define LN_pagerTelephoneNumber "pagerTelephoneNumber"
+#define NID_pagerTelephoneNumber 489
+#define OBJ_pagerTelephoneNumber OBJ_pilotAttributeType,42L
+
+#define LN_friendlyCountryName "friendlyCountryName"
+#define NID_friendlyCountryName 490
+#define OBJ_friendlyCountryName OBJ_pilotAttributeType,43L
+
+#define LN_organizationalStatus "organizationalStatus"
+#define NID_organizationalStatus 491
+#define OBJ_organizationalStatus OBJ_pilotAttributeType,45L
+
+#define LN_janetMailbox "janetMailbox"
+#define NID_janetMailbox 492
+#define OBJ_janetMailbox OBJ_pilotAttributeType,46L
+
+#define LN_mailPreferenceOption "mailPreferenceOption"
+#define NID_mailPreferenceOption 493
+#define OBJ_mailPreferenceOption OBJ_pilotAttributeType,47L
+
+#define LN_buildingName "buildingName"
+#define NID_buildingName 494
+#define OBJ_buildingName OBJ_pilotAttributeType,48L
+
+#define LN_dSAQuality "dSAQuality"
+#define NID_dSAQuality 495
+#define OBJ_dSAQuality OBJ_pilotAttributeType,49L
+
+#define LN_singleLevelQuality "singleLevelQuality"
+#define NID_singleLevelQuality 496
+#define OBJ_singleLevelQuality OBJ_pilotAttributeType,50L
+
+#define LN_subtreeMinimumQuality "subtreeMinimumQuality"
+#define NID_subtreeMinimumQuality 497
+#define OBJ_subtreeMinimumQuality OBJ_pilotAttributeType,51L
+
+#define LN_subtreeMaximumQuality "subtreeMaximumQuality"
+#define NID_subtreeMaximumQuality 498
+#define OBJ_subtreeMaximumQuality OBJ_pilotAttributeType,52L
+
+#define LN_personalSignature "personalSignature"
+#define NID_personalSignature 499
+#define OBJ_personalSignature OBJ_pilotAttributeType,53L
+
+#define LN_dITRedirect "dITRedirect"
+#define NID_dITRedirect 500
+#define OBJ_dITRedirect OBJ_pilotAttributeType,54L
+
+#define SN_audio "audio"
+#define NID_audio 501
+#define OBJ_audio OBJ_pilotAttributeType,55L
+
+#define LN_documentPublisher "documentPublisher"
+#define NID_documentPublisher 502
+#define OBJ_documentPublisher OBJ_pilotAttributeType,56L
+
+#define SN_id_set "id-set"
+#define LN_id_set "Secure Electronic Transactions"
+#define NID_id_set 512
+#define OBJ_id_set OBJ_international_organizations,42L
+
+#define SN_set_ctype "set-ctype"
+#define LN_set_ctype "content types"
+#define NID_set_ctype 513
+#define OBJ_set_ctype OBJ_id_set,0L
+
+#define SN_set_msgExt "set-msgExt"
+#define LN_set_msgExt "message extensions"
+#define NID_set_msgExt 514
+#define OBJ_set_msgExt OBJ_id_set,1L
+
+#define SN_set_attr "set-attr"
+#define NID_set_attr 515
+#define OBJ_set_attr OBJ_id_set,3L
+
+#define SN_set_policy "set-policy"
+#define NID_set_policy 516
+#define OBJ_set_policy OBJ_id_set,5L
+
+#define SN_set_certExt "set-certExt"
+#define LN_set_certExt "certificate extensions"
+#define NID_set_certExt 517
+#define OBJ_set_certExt OBJ_id_set,7L
+
+#define SN_set_brand "set-brand"
+#define NID_set_brand 518
+#define OBJ_set_brand OBJ_id_set,8L
+
+#define SN_setct_PANData "setct-PANData"
+#define NID_setct_PANData 519
+#define OBJ_setct_PANData OBJ_set_ctype,0L
+
+#define SN_setct_PANToken "setct-PANToken"
+#define NID_setct_PANToken 520
+#define OBJ_setct_PANToken OBJ_set_ctype,1L
+
+#define SN_setct_PANOnly "setct-PANOnly"
+#define NID_setct_PANOnly 521
+#define OBJ_setct_PANOnly OBJ_set_ctype,2L
+
+#define SN_setct_OIData "setct-OIData"
+#define NID_setct_OIData 522
+#define OBJ_setct_OIData OBJ_set_ctype,3L
+
+#define SN_setct_PI "setct-PI"
+#define NID_setct_PI 523
+#define OBJ_setct_PI OBJ_set_ctype,4L
+
+#define SN_setct_PIData "setct-PIData"
+#define NID_setct_PIData 524
+#define OBJ_setct_PIData OBJ_set_ctype,5L
+
+#define SN_setct_PIDataUnsigned "setct-PIDataUnsigned"
+#define NID_setct_PIDataUnsigned 525
+#define OBJ_setct_PIDataUnsigned OBJ_set_ctype,6L
+
+#define SN_setct_HODInput "setct-HODInput"
+#define NID_setct_HODInput 526
+#define OBJ_setct_HODInput OBJ_set_ctype,7L
+
+#define SN_setct_AuthResBaggage "setct-AuthResBaggage"
+#define NID_setct_AuthResBaggage 527
+#define OBJ_setct_AuthResBaggage OBJ_set_ctype,8L
+
+#define SN_setct_AuthRevReqBaggage "setct-AuthRevReqBaggage"
+#define NID_setct_AuthRevReqBaggage 528
+#define OBJ_setct_AuthRevReqBaggage OBJ_set_ctype,9L
+
+#define SN_setct_AuthRevResBaggage "setct-AuthRevResBaggage"
+#define NID_setct_AuthRevResBaggage 529
+#define OBJ_setct_AuthRevResBaggage OBJ_set_ctype,10L
+
+#define SN_setct_CapTokenSeq "setct-CapTokenSeq"
+#define NID_setct_CapTokenSeq 530
+#define OBJ_setct_CapTokenSeq OBJ_set_ctype,11L
+
+#define SN_setct_PInitResData "setct-PInitResData"
+#define NID_setct_PInitResData 531
+#define OBJ_setct_PInitResData OBJ_set_ctype,12L
+
+#define SN_setct_PI_TBS "setct-PI-TBS"
+#define NID_setct_PI_TBS 532
+#define OBJ_setct_PI_TBS OBJ_set_ctype,13L
+
+#define SN_setct_PResData "setct-PResData"
+#define NID_setct_PResData 533
+#define OBJ_setct_PResData OBJ_set_ctype,14L
+
+#define SN_setct_AuthReqTBS "setct-AuthReqTBS"
+#define NID_setct_AuthReqTBS 534
+#define OBJ_setct_AuthReqTBS OBJ_set_ctype,16L
+
+#define SN_setct_AuthResTBS "setct-AuthResTBS"
+#define NID_setct_AuthResTBS 535
+#define OBJ_setct_AuthResTBS OBJ_set_ctype,17L
+
+#define SN_setct_AuthResTBSX "setct-AuthResTBSX"
+#define NID_setct_AuthResTBSX 536
+#define OBJ_setct_AuthResTBSX OBJ_set_ctype,18L
+
+#define SN_setct_AuthTokenTBS "setct-AuthTokenTBS"
+#define NID_setct_AuthTokenTBS 537
+#define OBJ_setct_AuthTokenTBS OBJ_set_ctype,19L
+
+#define SN_setct_CapTokenData "setct-CapTokenData"
+#define NID_setct_CapTokenData 538
+#define OBJ_setct_CapTokenData OBJ_set_ctype,20L
+
+#define SN_setct_CapTokenTBS "setct-CapTokenTBS"
+#define NID_setct_CapTokenTBS 539
+#define OBJ_setct_CapTokenTBS OBJ_set_ctype,21L
+
+#define SN_setct_AcqCardCodeMsg "setct-AcqCardCodeMsg"
+#define NID_setct_AcqCardCodeMsg 540
+#define OBJ_setct_AcqCardCodeMsg OBJ_set_ctype,22L
+
+#define SN_setct_AuthRevReqTBS "setct-AuthRevReqTBS"
+#define NID_setct_AuthRevReqTBS 541
+#define OBJ_setct_AuthRevReqTBS OBJ_set_ctype,23L
+
+#define SN_setct_AuthRevResData "setct-AuthRevResData"
+#define NID_setct_AuthRevResData 542
+#define OBJ_setct_AuthRevResData OBJ_set_ctype,24L
+
+#define SN_setct_AuthRevResTBS "setct-AuthRevResTBS"
+#define NID_setct_AuthRevResTBS 543
+#define OBJ_setct_AuthRevResTBS OBJ_set_ctype,25L
+
+#define SN_setct_CapReqTBS "setct-CapReqTBS"
+#define NID_setct_CapReqTBS 544
+#define OBJ_setct_CapReqTBS OBJ_set_ctype,26L
+
+#define SN_setct_CapReqTBSX "setct-CapReqTBSX"
+#define NID_setct_CapReqTBSX 545
+#define OBJ_setct_CapReqTBSX OBJ_set_ctype,27L
+
+#define SN_setct_CapResData "setct-CapResData"
+#define NID_setct_CapResData 546
+#define OBJ_setct_CapResData OBJ_set_ctype,28L
+
+#define SN_setct_CapRevReqTBS "setct-CapRevReqTBS"
+#define NID_setct_CapRevReqTBS 547
+#define OBJ_setct_CapRevReqTBS OBJ_set_ctype,29L
+
+#define SN_setct_CapRevReqTBSX "setct-CapRevReqTBSX"
+#define NID_setct_CapRevReqTBSX 548
+#define OBJ_setct_CapRevReqTBSX OBJ_set_ctype,30L
+
+#define SN_setct_CapRevResData "setct-CapRevResData"
+#define NID_setct_CapRevResData 549
+#define OBJ_setct_CapRevResData OBJ_set_ctype,31L
+
+#define SN_setct_CredReqTBS "setct-CredReqTBS"
+#define NID_setct_CredReqTBS 550
+#define OBJ_setct_CredReqTBS OBJ_set_ctype,32L
+
+#define SN_setct_CredReqTBSX "setct-CredReqTBSX"
+#define NID_setct_CredReqTBSX 551
+#define OBJ_setct_CredReqTBSX OBJ_set_ctype,33L
+
+#define SN_setct_CredResData "setct-CredResData"
+#define NID_setct_CredResData 552
+#define OBJ_setct_CredResData OBJ_set_ctype,34L
+
+#define SN_setct_CredRevReqTBS "setct-CredRevReqTBS"
+#define NID_setct_CredRevReqTBS 553
+#define OBJ_setct_CredRevReqTBS OBJ_set_ctype,35L
+
+#define SN_setct_CredRevReqTBSX "setct-CredRevReqTBSX"
+#define NID_setct_CredRevReqTBSX 554
+#define OBJ_setct_CredRevReqTBSX OBJ_set_ctype,36L
+
+#define SN_setct_CredRevResData "setct-CredRevResData"
+#define NID_setct_CredRevResData 555
+#define OBJ_setct_CredRevResData OBJ_set_ctype,37L
+
+#define SN_setct_PCertReqData "setct-PCertReqData"
+#define NID_setct_PCertReqData 556
+#define OBJ_setct_PCertReqData OBJ_set_ctype,38L
+
+#define SN_setct_PCertResTBS "setct-PCertResTBS"
+#define NID_setct_PCertResTBS 557
+#define OBJ_setct_PCertResTBS OBJ_set_ctype,39L
+
+#define SN_setct_BatchAdminReqData "setct-BatchAdminReqData"
+#define NID_setct_BatchAdminReqData 558
+#define OBJ_setct_BatchAdminReqData OBJ_set_ctype,40L
+
+#define SN_setct_BatchAdminResData "setct-BatchAdminResData"
+#define NID_setct_BatchAdminResData 559
+#define OBJ_setct_BatchAdminResData OBJ_set_ctype,41L
+
+#define SN_setct_CardCInitResTBS "setct-CardCInitResTBS"
+#define NID_setct_CardCInitResTBS 560
+#define OBJ_setct_CardCInitResTBS OBJ_set_ctype,42L
+
+#define SN_setct_MeAqCInitResTBS "setct-MeAqCInitResTBS"
+#define NID_setct_MeAqCInitResTBS 561
+#define OBJ_setct_MeAqCInitResTBS OBJ_set_ctype,43L
+
+#define SN_setct_RegFormResTBS "setct-RegFormResTBS"
+#define NID_setct_RegFormResTBS 562
+#define OBJ_setct_RegFormResTBS OBJ_set_ctype,44L
+
+#define SN_setct_CertReqData "setct-CertReqData"
+#define NID_setct_CertReqData 563
+#define OBJ_setct_CertReqData OBJ_set_ctype,45L
+
+#define SN_setct_CertReqTBS "setct-CertReqTBS"
+#define NID_setct_CertReqTBS 564
+#define OBJ_setct_CertReqTBS OBJ_set_ctype,46L
+
+#define SN_setct_CertResData "setct-CertResData"
+#define NID_setct_CertResData 565
+#define OBJ_setct_CertResData OBJ_set_ctype,47L
+
+#define SN_setct_CertInqReqTBS "setct-CertInqReqTBS"
+#define NID_setct_CertInqReqTBS 566
+#define OBJ_setct_CertInqReqTBS OBJ_set_ctype,48L
+
+#define SN_setct_ErrorTBS "setct-ErrorTBS"
+#define NID_setct_ErrorTBS 567
+#define OBJ_setct_ErrorTBS OBJ_set_ctype,49L
+
+#define SN_setct_PIDualSignedTBE "setct-PIDualSignedTBE"
+#define NID_setct_PIDualSignedTBE 568
+#define OBJ_setct_PIDualSignedTBE OBJ_set_ctype,50L
+
+#define SN_setct_PIUnsignedTBE "setct-PIUnsignedTBE"
+#define NID_setct_PIUnsignedTBE 569
+#define OBJ_setct_PIUnsignedTBE OBJ_set_ctype,51L
+
+#define SN_setct_AuthReqTBE "setct-AuthReqTBE"
+#define NID_setct_AuthReqTBE 570
+#define OBJ_setct_AuthReqTBE OBJ_set_ctype,52L
+
+#define SN_setct_AuthResTBE "setct-AuthResTBE"
+#define NID_setct_AuthResTBE 571
+#define OBJ_setct_AuthResTBE OBJ_set_ctype,53L
+
+#define SN_setct_AuthResTBEX "setct-AuthResTBEX"
+#define NID_setct_AuthResTBEX 572
+#define OBJ_setct_AuthResTBEX OBJ_set_ctype,54L
+
+#define SN_setct_AuthTokenTBE "setct-AuthTokenTBE"
+#define NID_setct_AuthTokenTBE 573
+#define OBJ_setct_AuthTokenTBE OBJ_set_ctype,55L
+
+#define SN_setct_CapTokenTBE "setct-CapTokenTBE"
+#define NID_setct_CapTokenTBE 574
+#define OBJ_setct_CapTokenTBE OBJ_set_ctype,56L
+
+#define SN_setct_CapTokenTBEX "setct-CapTokenTBEX"
+#define NID_setct_CapTokenTBEX 575
+#define OBJ_setct_CapTokenTBEX OBJ_set_ctype,57L
+
+#define SN_setct_AcqCardCodeMsgTBE "setct-AcqCardCodeMsgTBE"
+#define NID_setct_AcqCardCodeMsgTBE 576
+#define OBJ_setct_AcqCardCodeMsgTBE OBJ_set_ctype,58L
+
+#define SN_setct_AuthRevReqTBE "setct-AuthRevReqTBE"
+#define NID_setct_AuthRevReqTBE 577
+#define OBJ_setct_AuthRevReqTBE OBJ_set_ctype,59L
+
+#define SN_setct_AuthRevResTBE "setct-AuthRevResTBE"
+#define NID_setct_AuthRevResTBE 578
+#define OBJ_setct_AuthRevResTBE OBJ_set_ctype,60L
+
+#define SN_setct_AuthRevResTBEB "setct-AuthRevResTBEB"
+#define NID_setct_AuthRevResTBEB 579
+#define OBJ_setct_AuthRevResTBEB OBJ_set_ctype,61L
+
+#define SN_setct_CapReqTBE "setct-CapReqTBE"
+#define NID_setct_CapReqTBE 580
+#define OBJ_setct_CapReqTBE OBJ_set_ctype,62L
+
+#define SN_setct_CapReqTBEX "setct-CapReqTBEX"
+#define NID_setct_CapReqTBEX 581
+#define OBJ_setct_CapReqTBEX OBJ_set_ctype,63L
+
+#define SN_setct_CapResTBE "setct-CapResTBE"
+#define NID_setct_CapResTBE 582
+#define OBJ_setct_CapResTBE OBJ_set_ctype,64L
+
+#define SN_setct_CapRevReqTBE "setct-CapRevReqTBE"
+#define NID_setct_CapRevReqTBE 583
+#define OBJ_setct_CapRevReqTBE OBJ_set_ctype,65L
+
+#define SN_setct_CapRevReqTBEX "setct-CapRevReqTBEX"
+#define NID_setct_CapRevReqTBEX 584
+#define OBJ_setct_CapRevReqTBEX OBJ_set_ctype,66L
+
+#define SN_setct_CapRevResTBE "setct-CapRevResTBE"
+#define NID_setct_CapRevResTBE 585
+#define OBJ_setct_CapRevResTBE OBJ_set_ctype,67L
+
+#define SN_setct_CredReqTBE "setct-CredReqTBE"
+#define NID_setct_CredReqTBE 586
+#define OBJ_setct_CredReqTBE OBJ_set_ctype,68L
+
+#define SN_setct_CredReqTBEX "setct-CredReqTBEX"
+#define NID_setct_CredReqTBEX 587
+#define OBJ_setct_CredReqTBEX OBJ_set_ctype,69L
+
+#define SN_setct_CredResTBE "setct-CredResTBE"
+#define NID_setct_CredResTBE 588
+#define OBJ_setct_CredResTBE OBJ_set_ctype,70L
+
+#define SN_setct_CredRevReqTBE "setct-CredRevReqTBE"
+#define NID_setct_CredRevReqTBE 589
+#define OBJ_setct_CredRevReqTBE OBJ_set_ctype,71L
+
+#define SN_setct_CredRevReqTBEX "setct-CredRevReqTBEX"
+#define NID_setct_CredRevReqTBEX 590
+#define OBJ_setct_CredRevReqTBEX OBJ_set_ctype,72L
+
+#define SN_setct_CredRevResTBE "setct-CredRevResTBE"
+#define NID_setct_CredRevResTBE 591
+#define OBJ_setct_CredRevResTBE OBJ_set_ctype,73L
+
+#define SN_setct_BatchAdminReqTBE "setct-BatchAdminReqTBE"
+#define NID_setct_BatchAdminReqTBE 592
+#define OBJ_setct_BatchAdminReqTBE OBJ_set_ctype,74L
+
+#define SN_setct_BatchAdminResTBE "setct-BatchAdminResTBE"
+#define NID_setct_BatchAdminResTBE 593
+#define OBJ_setct_BatchAdminResTBE OBJ_set_ctype,75L
+
+#define SN_setct_RegFormReqTBE "setct-RegFormReqTBE"
+#define NID_setct_RegFormReqTBE 594
+#define OBJ_setct_RegFormReqTBE OBJ_set_ctype,76L
+
+#define SN_setct_CertReqTBE "setct-CertReqTBE"
+#define NID_setct_CertReqTBE 595
+#define OBJ_setct_CertReqTBE OBJ_set_ctype,77L
+
+#define SN_setct_CertReqTBEX "setct-CertReqTBEX"
+#define NID_setct_CertReqTBEX 596
+#define OBJ_setct_CertReqTBEX OBJ_set_ctype,78L
+
+#define SN_setct_CertResTBE "setct-CertResTBE"
+#define NID_setct_CertResTBE 597
+#define OBJ_setct_CertResTBE OBJ_set_ctype,79L
+
+#define SN_setct_CRLNotificationTBS "setct-CRLNotificationTBS"
+#define NID_setct_CRLNotificationTBS 598
+#define OBJ_setct_CRLNotificationTBS OBJ_set_ctype,80L
+
+#define SN_setct_CRLNotificationResTBS "setct-CRLNotificationResTBS"
+#define NID_setct_CRLNotificationResTBS 599
+#define OBJ_setct_CRLNotificationResTBS OBJ_set_ctype,81L
+
+#define SN_setct_BCIDistributionTBS "setct-BCIDistributionTBS"
+#define NID_setct_BCIDistributionTBS 600
+#define OBJ_setct_BCIDistributionTBS OBJ_set_ctype,82L
+
+#define SN_setext_genCrypt "setext-genCrypt"
+#define LN_setext_genCrypt "generic cryptogram"
+#define NID_setext_genCrypt 601
+#define OBJ_setext_genCrypt OBJ_set_msgExt,1L
+
+#define SN_setext_miAuth "setext-miAuth"
+#define LN_setext_miAuth "merchant initiated auth"
+#define NID_setext_miAuth 602
+#define OBJ_setext_miAuth OBJ_set_msgExt,3L
+
+#define SN_setext_pinSecure "setext-pinSecure"
+#define NID_setext_pinSecure 603
+#define OBJ_setext_pinSecure OBJ_set_msgExt,4L
+
+#define SN_setext_pinAny "setext-pinAny"
+#define NID_setext_pinAny 604
+#define OBJ_setext_pinAny OBJ_set_msgExt,5L
+
+#define SN_setext_track2 "setext-track2"
+#define NID_setext_track2 605
+#define OBJ_setext_track2 OBJ_set_msgExt,7L
+
+#define SN_setext_cv "setext-cv"
+#define LN_setext_cv "additional verification"
+#define NID_setext_cv 606
+#define OBJ_setext_cv OBJ_set_msgExt,8L
+
+#define SN_set_policy_root "set-policy-root"
+#define NID_set_policy_root 607
+#define OBJ_set_policy_root OBJ_set_policy,0L
+
+#define SN_setCext_hashedRoot "setCext-hashedRoot"
+#define NID_setCext_hashedRoot 608
+#define OBJ_setCext_hashedRoot OBJ_set_certExt,0L
+
+#define SN_setCext_certType "setCext-certType"
+#define NID_setCext_certType 609
+#define OBJ_setCext_certType OBJ_set_certExt,1L
+
+#define SN_setCext_merchData "setCext-merchData"
+#define NID_setCext_merchData 610
+#define OBJ_setCext_merchData OBJ_set_certExt,2L
+
+#define SN_setCext_cCertRequired "setCext-cCertRequired"
+#define NID_setCext_cCertRequired 611
+#define OBJ_setCext_cCertRequired OBJ_set_certExt,3L
+
+#define SN_setCext_tunneling "setCext-tunneling"
+#define NID_setCext_tunneling 612
+#define OBJ_setCext_tunneling OBJ_set_certExt,4L
+
+#define SN_setCext_setExt "setCext-setExt"
+#define NID_setCext_setExt 613
+#define OBJ_setCext_setExt OBJ_set_certExt,5L
+
+#define SN_setCext_setQualf "setCext-setQualf"
+#define NID_setCext_setQualf 614
+#define OBJ_setCext_setQualf OBJ_set_certExt,6L
+
+#define SN_setCext_PGWYcapabilities "setCext-PGWYcapabilities"
+#define NID_setCext_PGWYcapabilities 615
+#define OBJ_setCext_PGWYcapabilities OBJ_set_certExt,7L
+
+#define SN_setCext_TokenIdentifier "setCext-TokenIdentifier"
+#define NID_setCext_TokenIdentifier 616
+#define OBJ_setCext_TokenIdentifier OBJ_set_certExt,8L
+
+#define SN_setCext_Track2Data "setCext-Track2Data"
+#define NID_setCext_Track2Data 617
+#define OBJ_setCext_Track2Data OBJ_set_certExt,9L
+
+#define SN_setCext_TokenType "setCext-TokenType"
+#define NID_setCext_TokenType 618
+#define OBJ_setCext_TokenType OBJ_set_certExt,10L
+
+#define SN_setCext_IssuerCapabilities "setCext-IssuerCapabilities"
+#define NID_setCext_IssuerCapabilities 619
+#define OBJ_setCext_IssuerCapabilities OBJ_set_certExt,11L
+
+#define SN_setAttr_Cert "setAttr-Cert"
+#define NID_setAttr_Cert 620
+#define OBJ_setAttr_Cert OBJ_set_attr,0L
+
+#define SN_setAttr_PGWYcap "setAttr-PGWYcap"
+#define LN_setAttr_PGWYcap "payment gateway capabilities"
+#define NID_setAttr_PGWYcap 621
+#define OBJ_setAttr_PGWYcap OBJ_set_attr,1L
+
+#define SN_setAttr_TokenType "setAttr-TokenType"
+#define NID_setAttr_TokenType 622
+#define OBJ_setAttr_TokenType OBJ_set_attr,2L
+
+#define SN_setAttr_IssCap "setAttr-IssCap"
+#define LN_setAttr_IssCap "issuer capabilities"
+#define NID_setAttr_IssCap 623
+#define OBJ_setAttr_IssCap OBJ_set_attr,3L
+
+#define SN_set_rootKeyThumb "set-rootKeyThumb"
+#define NID_set_rootKeyThumb 624
+#define OBJ_set_rootKeyThumb OBJ_setAttr_Cert,0L
+
+#define SN_set_addPolicy "set-addPolicy"
+#define NID_set_addPolicy 625
+#define OBJ_set_addPolicy OBJ_setAttr_Cert,1L
+
+#define SN_setAttr_Token_EMV "setAttr-Token-EMV"
+#define NID_setAttr_Token_EMV 626
+#define OBJ_setAttr_Token_EMV OBJ_setAttr_TokenType,1L
+
+#define SN_setAttr_Token_B0Prime "setAttr-Token-B0Prime"
+#define NID_setAttr_Token_B0Prime 627
+#define OBJ_setAttr_Token_B0Prime OBJ_setAttr_TokenType,2L
+
+#define SN_setAttr_IssCap_CVM "setAttr-IssCap-CVM"
+#define NID_setAttr_IssCap_CVM 628
+#define OBJ_setAttr_IssCap_CVM OBJ_setAttr_IssCap,3L
+
+#define SN_setAttr_IssCap_T2 "setAttr-IssCap-T2"
+#define NID_setAttr_IssCap_T2 629
+#define OBJ_setAttr_IssCap_T2 OBJ_setAttr_IssCap,4L
+
+#define SN_setAttr_IssCap_Sig "setAttr-IssCap-Sig"
+#define NID_setAttr_IssCap_Sig 630
+#define OBJ_setAttr_IssCap_Sig OBJ_setAttr_IssCap,5L
+
+#define SN_setAttr_GenCryptgrm "setAttr-GenCryptgrm"
+#define LN_setAttr_GenCryptgrm "generate cryptogram"
+#define NID_setAttr_GenCryptgrm 631
+#define OBJ_setAttr_GenCryptgrm OBJ_setAttr_IssCap_CVM,1L
+
+#define SN_setAttr_T2Enc "setAttr-T2Enc"
+#define LN_setAttr_T2Enc "encrypted track 2"
+#define NID_setAttr_T2Enc 632
+#define OBJ_setAttr_T2Enc OBJ_setAttr_IssCap_T2,1L
+
+#define SN_setAttr_T2cleartxt "setAttr-T2cleartxt"
+#define LN_setAttr_T2cleartxt "cleartext track 2"
+#define NID_setAttr_T2cleartxt 633
+#define OBJ_setAttr_T2cleartxt OBJ_setAttr_IssCap_T2,2L
+
+#define SN_setAttr_TokICCsig "setAttr-TokICCsig"
+#define LN_setAttr_TokICCsig "ICC or token signature"
+#define NID_setAttr_TokICCsig 634
+#define OBJ_setAttr_TokICCsig OBJ_setAttr_IssCap_Sig,1L
+
+#define SN_setAttr_SecDevSig "setAttr-SecDevSig"
+#define LN_setAttr_SecDevSig "secure device signature"
+#define NID_setAttr_SecDevSig 635
+#define OBJ_setAttr_SecDevSig OBJ_setAttr_IssCap_Sig,2L
+
+#define SN_set_brand_IATA_ATA "set-brand-IATA-ATA"
+#define NID_set_brand_IATA_ATA 636
+#define OBJ_set_brand_IATA_ATA OBJ_set_brand,1L
+
+#define SN_set_brand_Diners "set-brand-Diners"
+#define NID_set_brand_Diners 637
+#define OBJ_set_brand_Diners OBJ_set_brand,30L
+
+#define SN_set_brand_AmericanExpress "set-brand-AmericanExpress"
+#define NID_set_brand_AmericanExpress 638
+#define OBJ_set_brand_AmericanExpress OBJ_set_brand,34L
+
+#define SN_set_brand_JCB "set-brand-JCB"
+#define NID_set_brand_JCB 639
+#define OBJ_set_brand_JCB OBJ_set_brand,35L
+
+#define SN_set_brand_Visa "set-brand-Visa"
+#define NID_set_brand_Visa 640
+#define OBJ_set_brand_Visa OBJ_set_brand,4L
+
+#define SN_set_brand_MasterCard "set-brand-MasterCard"
+#define NID_set_brand_MasterCard 641
+#define OBJ_set_brand_MasterCard OBJ_set_brand,5L
+
+#define SN_set_brand_Novus "set-brand-Novus"
+#define NID_set_brand_Novus 642
+#define OBJ_set_brand_Novus OBJ_set_brand,6011L
+
+#define SN_des_cdmf "DES-CDMF"
+#define LN_des_cdmf "des-cdmf"
+#define NID_des_cdmf 643
+#define OBJ_des_cdmf OBJ_rsadsi,3L,10L
+
+#define SN_rsaOAEPEncryptionSET "rsaOAEPEncryptionSET"
+#define NID_rsaOAEPEncryptionSET 644
+#define OBJ_rsaOAEPEncryptionSET OBJ_rsadsi,1L,1L,6L
+
+#define SN_ipsec3 "Oakley-EC2N-3"
+#define LN_ipsec3 "ipsec3"
+#define NID_ipsec3 749
+
+#define SN_ipsec4 "Oakley-EC2N-4"
+#define LN_ipsec4 "ipsec4"
+#define NID_ipsec4 750
+
+#define SN_whirlpool "whirlpool"
+#define NID_whirlpool 804
+#define OBJ_whirlpool OBJ_iso,0L,10118L,3L,0L,55L
+
+#define SN_cryptopro "cryptopro"
+#define NID_cryptopro 805
+#define OBJ_cryptopro OBJ_member_body,643L,2L,2L
+
+#define SN_cryptocom "cryptocom"
+#define NID_cryptocom 806
+#define OBJ_cryptocom OBJ_member_body,643L,2L,9L
+
+#define SN_id_GostR3411_94_with_GostR3410_2001 "id-GostR3411-94-with-GostR3410-2001"
+#define LN_id_GostR3411_94_with_GostR3410_2001 "GOST R 34.11-94 with GOST R 34.10-2001"
+#define NID_id_GostR3411_94_with_GostR3410_2001 807
+#define OBJ_id_GostR3411_94_with_GostR3410_2001 OBJ_cryptopro,3L
+
+#define SN_id_GostR3411_94_with_GostR3410_94 "id-GostR3411-94-with-GostR3410-94"
+#define LN_id_GostR3411_94_with_GostR3410_94 "GOST R 34.11-94 with GOST R 34.10-94"
+#define NID_id_GostR3411_94_with_GostR3410_94 808
+#define OBJ_id_GostR3411_94_with_GostR3410_94 OBJ_cryptopro,4L
+
+#define SN_id_GostR3411_94 "md_gost94"
+#define LN_id_GostR3411_94 "GOST R 34.11-94"
+#define NID_id_GostR3411_94 809
+#define OBJ_id_GostR3411_94 OBJ_cryptopro,9L
+
+#define SN_id_HMACGostR3411_94 "id-HMACGostR3411-94"
+#define LN_id_HMACGostR3411_94 "HMAC GOST 34.11-94"
+#define NID_id_HMACGostR3411_94 810
+#define OBJ_id_HMACGostR3411_94 OBJ_cryptopro,10L
+
+#define SN_id_GostR3410_2001 "gost2001"
+#define LN_id_GostR3410_2001 "GOST R 34.10-2001"
+#define NID_id_GostR3410_2001 811
+#define OBJ_id_GostR3410_2001 OBJ_cryptopro,19L
+
+#define SN_id_GostR3410_94 "gost94"
+#define LN_id_GostR3410_94 "GOST R 34.10-94"
+#define NID_id_GostR3410_94 812
+#define OBJ_id_GostR3410_94 OBJ_cryptopro,20L
+
+#define SN_id_Gost28147_89 "gost89"
+#define LN_id_Gost28147_89 "GOST 28147-89"
+#define NID_id_Gost28147_89 813
+#define OBJ_id_Gost28147_89 OBJ_cryptopro,21L
+
+#define SN_gost89_cnt "gost89-cnt"
+#define NID_gost89_cnt 814
+
+#define SN_id_Gost28147_89_MAC "gost-mac"
+#define LN_id_Gost28147_89_MAC "GOST 28147-89 MAC"
+#define NID_id_Gost28147_89_MAC 815
+#define OBJ_id_Gost28147_89_MAC OBJ_cryptopro,22L
+
+#define SN_id_GostR3411_94_prf "prf-gostr3411-94"
+#define LN_id_GostR3411_94_prf "GOST R 34.11-94 PRF"
+#define NID_id_GostR3411_94_prf 816
+#define OBJ_id_GostR3411_94_prf OBJ_cryptopro,23L
+
+#define SN_id_GostR3410_2001DH "id-GostR3410-2001DH"
+#define LN_id_GostR3410_2001DH "GOST R 34.10-2001 DH"
+#define NID_id_GostR3410_2001DH 817
+#define OBJ_id_GostR3410_2001DH OBJ_cryptopro,98L
+
+#define SN_id_GostR3410_94DH "id-GostR3410-94DH"
+#define LN_id_GostR3410_94DH "GOST R 34.10-94 DH"
+#define NID_id_GostR3410_94DH 818
+#define OBJ_id_GostR3410_94DH OBJ_cryptopro,99L
+
+#define SN_id_Gost28147_89_CryptoPro_KeyMeshing "id-Gost28147-89-CryptoPro-KeyMeshing"
+#define NID_id_Gost28147_89_CryptoPro_KeyMeshing 819
+#define OBJ_id_Gost28147_89_CryptoPro_KeyMeshing OBJ_cryptopro,14L,1L
+
+#define SN_id_Gost28147_89_None_KeyMeshing "id-Gost28147-89-None-KeyMeshing"
+#define NID_id_Gost28147_89_None_KeyMeshing 820
+#define OBJ_id_Gost28147_89_None_KeyMeshing OBJ_cryptopro,14L,0L
+
+#define SN_id_GostR3411_94_TestParamSet "id-GostR3411-94-TestParamSet"
+#define NID_id_GostR3411_94_TestParamSet 821
+#define OBJ_id_GostR3411_94_TestParamSet OBJ_cryptopro,30L,0L
+
+#define SN_id_GostR3411_94_CryptoProParamSet "id-GostR3411-94-CryptoProParamSet"
+#define NID_id_GostR3411_94_CryptoProParamSet 822
+#define OBJ_id_GostR3411_94_CryptoProParamSet OBJ_cryptopro,30L,1L
+
+#define SN_id_Gost28147_89_TestParamSet "id-Gost28147-89-TestParamSet"
+#define NID_id_Gost28147_89_TestParamSet 823
+#define OBJ_id_Gost28147_89_TestParamSet OBJ_cryptopro,31L,0L
+
+#define SN_id_Gost28147_89_CryptoPro_A_ParamSet "id-Gost28147-89-CryptoPro-A-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_A_ParamSet 824
+#define OBJ_id_Gost28147_89_CryptoPro_A_ParamSet OBJ_cryptopro,31L,1L
+
+#define SN_id_Gost28147_89_CryptoPro_B_ParamSet "id-Gost28147-89-CryptoPro-B-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_B_ParamSet 825
+#define OBJ_id_Gost28147_89_CryptoPro_B_ParamSet OBJ_cryptopro,31L,2L
+
+#define SN_id_Gost28147_89_CryptoPro_C_ParamSet "id-Gost28147-89-CryptoPro-C-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_C_ParamSet 826
+#define OBJ_id_Gost28147_89_CryptoPro_C_ParamSet OBJ_cryptopro,31L,3L
+
+#define SN_id_Gost28147_89_CryptoPro_D_ParamSet "id-Gost28147-89-CryptoPro-D-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_D_ParamSet 827
+#define OBJ_id_Gost28147_89_CryptoPro_D_ParamSet OBJ_cryptopro,31L,4L
+
+#define SN_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet 828
+#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet OBJ_cryptopro,31L,5L
+
+#define SN_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet 829
+#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet OBJ_cryptopro,31L,6L
+
+#define SN_id_Gost28147_89_CryptoPro_RIC_1_ParamSet "id-Gost28147-89-CryptoPro-RIC-1-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet 830
+#define OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet OBJ_cryptopro,31L,7L
+
+#define SN_id_GostR3410_94_TestParamSet "id-GostR3410-94-TestParamSet"
+#define NID_id_GostR3410_94_TestParamSet 831
+#define OBJ_id_GostR3410_94_TestParamSet OBJ_cryptopro,32L,0L
+
+#define SN_id_GostR3410_94_CryptoPro_A_ParamSet "id-GostR3410-94-CryptoPro-A-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_A_ParamSet 832
+#define OBJ_id_GostR3410_94_CryptoPro_A_ParamSet OBJ_cryptopro,32L,2L
+
+#define SN_id_GostR3410_94_CryptoPro_B_ParamSet "id-GostR3410-94-CryptoPro-B-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_B_ParamSet 833
+#define OBJ_id_GostR3410_94_CryptoPro_B_ParamSet OBJ_cryptopro,32L,3L
+
+#define SN_id_GostR3410_94_CryptoPro_C_ParamSet "id-GostR3410-94-CryptoPro-C-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_C_ParamSet 834
+#define OBJ_id_GostR3410_94_CryptoPro_C_ParamSet OBJ_cryptopro,32L,4L
+
+#define SN_id_GostR3410_94_CryptoPro_D_ParamSet "id-GostR3410-94-CryptoPro-D-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_D_ParamSet 835
+#define OBJ_id_GostR3410_94_CryptoPro_D_ParamSet OBJ_cryptopro,32L,5L
+
+#define SN_id_GostR3410_94_CryptoPro_XchA_ParamSet "id-GostR3410-94-CryptoPro-XchA-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_XchA_ParamSet 836
+#define OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet OBJ_cryptopro,33L,1L
+
+#define SN_id_GostR3410_94_CryptoPro_XchB_ParamSet "id-GostR3410-94-CryptoPro-XchB-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_XchB_ParamSet 837
+#define OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet OBJ_cryptopro,33L,2L
+
+#define SN_id_GostR3410_94_CryptoPro_XchC_ParamSet "id-GostR3410-94-CryptoPro-XchC-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_XchC_ParamSet 838
+#define OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet OBJ_cryptopro,33L,3L
+
+#define SN_id_GostR3410_2001_TestParamSet "id-GostR3410-2001-TestParamSet"
+#define NID_id_GostR3410_2001_TestParamSet 839
+#define OBJ_id_GostR3410_2001_TestParamSet OBJ_cryptopro,35L,0L
+
+#define SN_id_GostR3410_2001_CryptoPro_A_ParamSet "id-GostR3410-2001-CryptoPro-A-ParamSet"
+#define NID_id_GostR3410_2001_CryptoPro_A_ParamSet 840
+#define OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet OBJ_cryptopro,35L,1L
+
+#define SN_id_GostR3410_2001_CryptoPro_B_ParamSet "id-GostR3410-2001-CryptoPro-B-ParamSet"
+#define NID_id_GostR3410_2001_CryptoPro_B_ParamSet 841
+#define OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet OBJ_cryptopro,35L,2L
+
+#define SN_id_GostR3410_2001_CryptoPro_C_ParamSet "id-GostR3410-2001-CryptoPro-C-ParamSet"
+#define NID_id_GostR3410_2001_CryptoPro_C_ParamSet 842
+#define OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet OBJ_cryptopro,35L,3L
+
+#define SN_id_GostR3410_2001_CryptoPro_XchA_ParamSet "id-GostR3410-2001-CryptoPro-XchA-ParamSet"
+#define NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet 843
+#define OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet OBJ_cryptopro,36L,0L
+
+#define SN_id_GostR3410_2001_CryptoPro_XchB_ParamSet "id-GostR3410-2001-CryptoPro-XchB-ParamSet"
+#define NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet 844
+#define OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet OBJ_cryptopro,36L,1L
+
+#define SN_id_GostR3410_94_a "id-GostR3410-94-a"
+#define NID_id_GostR3410_94_a 845
+#define OBJ_id_GostR3410_94_a OBJ_id_GostR3410_94,1L
+
+#define SN_id_GostR3410_94_aBis "id-GostR3410-94-aBis"
+#define NID_id_GostR3410_94_aBis 846
+#define OBJ_id_GostR3410_94_aBis OBJ_id_GostR3410_94,2L
+
+#define SN_id_GostR3410_94_b "id-GostR3410-94-b"
+#define NID_id_GostR3410_94_b 847
+#define OBJ_id_GostR3410_94_b OBJ_id_GostR3410_94,3L
+
+#define SN_id_GostR3410_94_bBis "id-GostR3410-94-bBis"
+#define NID_id_GostR3410_94_bBis 848
+#define OBJ_id_GostR3410_94_bBis OBJ_id_GostR3410_94,4L
+
+#define SN_id_Gost28147_89_cc "id-Gost28147-89-cc"
+#define LN_id_Gost28147_89_cc "GOST 28147-89 Cryptocom ParamSet"
+#define NID_id_Gost28147_89_cc 849
+#define OBJ_id_Gost28147_89_cc OBJ_cryptocom,1L,6L,1L
+
+#define SN_id_GostR3410_94_cc "gost94cc"
+#define LN_id_GostR3410_94_cc "GOST 34.10-94 Cryptocom"
+#define NID_id_GostR3410_94_cc 850
+#define OBJ_id_GostR3410_94_cc OBJ_cryptocom,1L,5L,3L
+
+#define SN_id_GostR3410_2001_cc "gost2001cc"
+#define LN_id_GostR3410_2001_cc "GOST 34.10-2001 Cryptocom"
+#define NID_id_GostR3410_2001_cc 851
+#define OBJ_id_GostR3410_2001_cc OBJ_cryptocom,1L,5L,4L
+
+#define SN_id_GostR3411_94_with_GostR3410_94_cc "id-GostR3411-94-with-GostR3410-94-cc"
+#define LN_id_GostR3411_94_with_GostR3410_94_cc "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom"
+#define NID_id_GostR3411_94_with_GostR3410_94_cc 852
+#define OBJ_id_GostR3411_94_with_GostR3410_94_cc OBJ_cryptocom,1L,3L,3L
+
+#define SN_id_GostR3411_94_with_GostR3410_2001_cc "id-GostR3411-94-with-GostR3410-2001-cc"
+#define LN_id_GostR3411_94_with_GostR3410_2001_cc "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom"
+#define NID_id_GostR3411_94_with_GostR3410_2001_cc 853
+#define OBJ_id_GostR3411_94_with_GostR3410_2001_cc OBJ_cryptocom,1L,3L,4L
+
+#define SN_id_GostR3410_2001_ParamSet_cc "id-GostR3410-2001-ParamSet-cc"
+#define LN_id_GostR3410_2001_ParamSet_cc "GOST R 3410-2001 Parameter Set Cryptocom"
+#define NID_id_GostR3410_2001_ParamSet_cc 854
+#define OBJ_id_GostR3410_2001_ParamSet_cc OBJ_cryptocom,1L,8L,1L
+
+#define SN_camellia_128_cbc "CAMELLIA-128-CBC"
+#define LN_camellia_128_cbc "camellia-128-cbc"
+#define NID_camellia_128_cbc 751
+#define OBJ_camellia_128_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,2L
+
+#define SN_camellia_192_cbc "CAMELLIA-192-CBC"
+#define LN_camellia_192_cbc "camellia-192-cbc"
+#define NID_camellia_192_cbc 752
+#define OBJ_camellia_192_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,3L
+
+#define SN_camellia_256_cbc "CAMELLIA-256-CBC"
+#define LN_camellia_256_cbc "camellia-256-cbc"
+#define NID_camellia_256_cbc 753
+#define OBJ_camellia_256_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,4L
+
+#define SN_id_camellia128_wrap "id-camellia128-wrap"
+#define NID_id_camellia128_wrap 907
+#define OBJ_id_camellia128_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,2L
+
+#define SN_id_camellia192_wrap "id-camellia192-wrap"
+#define NID_id_camellia192_wrap 908
+#define OBJ_id_camellia192_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,3L
+
+#define SN_id_camellia256_wrap "id-camellia256-wrap"
+#define NID_id_camellia256_wrap 909
+#define OBJ_id_camellia256_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,4L
+
+#define OBJ_ntt_ds 0L,3L,4401L,5L
+
+#define OBJ_camellia OBJ_ntt_ds,3L,1L,9L
+
+#define SN_camellia_128_ecb "CAMELLIA-128-ECB"
+#define LN_camellia_128_ecb "camellia-128-ecb"
+#define NID_camellia_128_ecb 754
+#define OBJ_camellia_128_ecb OBJ_camellia,1L
+
+#define SN_camellia_128_ofb128 "CAMELLIA-128-OFB"
+#define LN_camellia_128_ofb128 "camellia-128-ofb"
+#define NID_camellia_128_ofb128 766
+#define OBJ_camellia_128_ofb128 OBJ_camellia,3L
+
+#define SN_camellia_128_cfb128 "CAMELLIA-128-CFB"
+#define LN_camellia_128_cfb128 "camellia-128-cfb"
+#define NID_camellia_128_cfb128 757
+#define OBJ_camellia_128_cfb128 OBJ_camellia,4L
+
+#define SN_camellia_192_ecb "CAMELLIA-192-ECB"
+#define LN_camellia_192_ecb "camellia-192-ecb"
+#define NID_camellia_192_ecb 755
+#define OBJ_camellia_192_ecb OBJ_camellia,21L
+
+#define SN_camellia_192_ofb128 "CAMELLIA-192-OFB"
+#define LN_camellia_192_ofb128 "camellia-192-ofb"
+#define NID_camellia_192_ofb128 767
+#define OBJ_camellia_192_ofb128 OBJ_camellia,23L
+
+#define SN_camellia_192_cfb128 "CAMELLIA-192-CFB"
+#define LN_camellia_192_cfb128 "camellia-192-cfb"
+#define NID_camellia_192_cfb128 758
+#define OBJ_camellia_192_cfb128 OBJ_camellia,24L
+
+#define SN_camellia_256_ecb "CAMELLIA-256-ECB"
+#define LN_camellia_256_ecb "camellia-256-ecb"
+#define NID_camellia_256_ecb 756
+#define OBJ_camellia_256_ecb OBJ_camellia,41L
+
+#define SN_camellia_256_ofb128 "CAMELLIA-256-OFB"
+#define LN_camellia_256_ofb128 "camellia-256-ofb"
+#define NID_camellia_256_ofb128 768
+#define OBJ_camellia_256_ofb128 OBJ_camellia,43L
+
+#define SN_camellia_256_cfb128 "CAMELLIA-256-CFB"
+#define LN_camellia_256_cfb128 "camellia-256-cfb"
+#define NID_camellia_256_cfb128 759
+#define OBJ_camellia_256_cfb128 OBJ_camellia,44L
+
+#define SN_camellia_128_cfb1 "CAMELLIA-128-CFB1"
+#define LN_camellia_128_cfb1 "camellia-128-cfb1"
+#define NID_camellia_128_cfb1 760
+
+#define SN_camellia_192_cfb1 "CAMELLIA-192-CFB1"
+#define LN_camellia_192_cfb1 "camellia-192-cfb1"
+#define NID_camellia_192_cfb1 761
+
+#define SN_camellia_256_cfb1 "CAMELLIA-256-CFB1"
+#define LN_camellia_256_cfb1 "camellia-256-cfb1"
+#define NID_camellia_256_cfb1 762
+
+#define SN_camellia_128_cfb8 "CAMELLIA-128-CFB8"
+#define LN_camellia_128_cfb8 "camellia-128-cfb8"
+#define NID_camellia_128_cfb8 763
+
+#define SN_camellia_192_cfb8 "CAMELLIA-192-CFB8"
+#define LN_camellia_192_cfb8 "camellia-192-cfb8"
+#define NID_camellia_192_cfb8 764
+
+#define SN_camellia_256_cfb8 "CAMELLIA-256-CFB8"
+#define LN_camellia_256_cfb8 "camellia-256-cfb8"
+#define NID_camellia_256_cfb8 765
+
+#define SN_kisa "KISA"
+#define LN_kisa "kisa"
+#define NID_kisa 773
+#define OBJ_kisa OBJ_member_body,410L,200004L
+
+#define SN_seed_ecb "SEED-ECB"
+#define LN_seed_ecb "seed-ecb"
+#define NID_seed_ecb 776
+#define OBJ_seed_ecb OBJ_kisa,1L,3L
+
+#define SN_seed_cbc "SEED-CBC"
+#define LN_seed_cbc "seed-cbc"
+#define NID_seed_cbc 777
+#define OBJ_seed_cbc OBJ_kisa,1L,4L
+
+#define SN_seed_cfb128 "SEED-CFB"
+#define LN_seed_cfb128 "seed-cfb"
+#define NID_seed_cfb128 779
+#define OBJ_seed_cfb128 OBJ_kisa,1L,5L
+
+#define SN_seed_ofb128 "SEED-OFB"
+#define LN_seed_ofb128 "seed-ofb"
+#define NID_seed_ofb128 778
+#define OBJ_seed_ofb128 OBJ_kisa,1L,6L
+
+#define SN_hmac "HMAC"
+#define LN_hmac "hmac"
+#define NID_hmac 855
+
+#define SN_cmac "CMAC"
+#define LN_cmac "cmac"
+#define NID_cmac 894
+
+#define SN_rc4_hmac_md5 "RC4-HMAC-MD5"
+#define LN_rc4_hmac_md5 "rc4-hmac-md5"
+#define NID_rc4_hmac_md5 915
+
+#define SN_aes_128_cbc_hmac_sha1 "AES-128-CBC-HMAC-SHA1"
+#define LN_aes_128_cbc_hmac_sha1 "aes-128-cbc-hmac-sha1"
+#define NID_aes_128_cbc_hmac_sha1 916
+
+#define SN_aes_192_cbc_hmac_sha1 "AES-192-CBC-HMAC-SHA1"
+#define LN_aes_192_cbc_hmac_sha1 "aes-192-cbc-hmac-sha1"
+#define NID_aes_192_cbc_hmac_sha1 917
+
+#define SN_aes_256_cbc_hmac_sha1 "AES-256-CBC-HMAC-SHA1"
+#define LN_aes_256_cbc_hmac_sha1 "aes-256-cbc-hmac-sha1"
+#define NID_aes_256_cbc_hmac_sha1 918
+
+#define SN_dhpublicnumber "dhpublicnumber"
+#define LN_dhpublicnumber "X9.42 DH"
+#define NID_dhpublicnumber 920
+#define OBJ_dhpublicnumber OBJ_ISO_US,10046L,2L,1L
+
+#define SN_brainpoolP160r1 "brainpoolP160r1"
+#define NID_brainpoolP160r1 921
+#define OBJ_brainpoolP160r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,1L
+
+#define SN_brainpoolP160t1 "brainpoolP160t1"
+#define NID_brainpoolP160t1 922
+#define OBJ_brainpoolP160t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,2L
+
+#define SN_brainpoolP192r1 "brainpoolP192r1"
+#define NID_brainpoolP192r1 923
+#define OBJ_brainpoolP192r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,3L
+
+#define SN_brainpoolP192t1 "brainpoolP192t1"
+#define NID_brainpoolP192t1 924
+#define OBJ_brainpoolP192t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,4L
+
+#define SN_brainpoolP224r1 "brainpoolP224r1"
+#define NID_brainpoolP224r1 925
+#define OBJ_brainpoolP224r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,5L
+
+#define SN_brainpoolP224t1 "brainpoolP224t1"
+#define NID_brainpoolP224t1 926
+#define OBJ_brainpoolP224t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,6L
+
+#define SN_brainpoolP256r1 "brainpoolP256r1"
+#define NID_brainpoolP256r1 927
+#define OBJ_brainpoolP256r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,7L
+
+#define SN_brainpoolP256t1 "brainpoolP256t1"
+#define NID_brainpoolP256t1 928
+#define OBJ_brainpoolP256t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,8L
+
+#define SN_brainpoolP320r1 "brainpoolP320r1"
+#define NID_brainpoolP320r1 929
+#define OBJ_brainpoolP320r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,9L
+
+#define SN_brainpoolP320t1 "brainpoolP320t1"
+#define NID_brainpoolP320t1 930
+#define OBJ_brainpoolP320t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,10L
+
+#define SN_brainpoolP384r1 "brainpoolP384r1"
+#define NID_brainpoolP384r1 931
+#define OBJ_brainpoolP384r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,11L
+
+#define SN_brainpoolP384t1 "brainpoolP384t1"
+#define NID_brainpoolP384t1 932
+#define OBJ_brainpoolP384t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,12L
+
+#define SN_brainpoolP512r1 "brainpoolP512r1"
+#define NID_brainpoolP512r1 933
+#define OBJ_brainpoolP512r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,13L
+
+#define SN_brainpoolP512t1 "brainpoolP512t1"
+#define NID_brainpoolP512t1 934
+#define OBJ_brainpoolP512t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,14L
+
+#define OBJ_x9_63_scheme 1L,3L,133L,16L,840L,63L,0L
+
+#define OBJ_secg_scheme OBJ_certicom_arc,1L
+
+#define SN_dhSinglePass_stdDH_sha1kdf_scheme "dhSinglePass-stdDH-sha1kdf-scheme"
+#define NID_dhSinglePass_stdDH_sha1kdf_scheme 936
+#define OBJ_dhSinglePass_stdDH_sha1kdf_scheme OBJ_x9_63_scheme,2L
+
+#define SN_dhSinglePass_stdDH_sha224kdf_scheme "dhSinglePass-stdDH-sha224kdf-scheme"
+#define NID_dhSinglePass_stdDH_sha224kdf_scheme 937
+#define OBJ_dhSinglePass_stdDH_sha224kdf_scheme OBJ_secg_scheme,11L,0L
+
+#define SN_dhSinglePass_stdDH_sha256kdf_scheme "dhSinglePass-stdDH-sha256kdf-scheme"
+#define NID_dhSinglePass_stdDH_sha256kdf_scheme 938
+#define OBJ_dhSinglePass_stdDH_sha256kdf_scheme OBJ_secg_scheme,11L,1L
+
+#define SN_dhSinglePass_stdDH_sha384kdf_scheme "dhSinglePass-stdDH-sha384kdf-scheme"
+#define NID_dhSinglePass_stdDH_sha384kdf_scheme 939
+#define OBJ_dhSinglePass_stdDH_sha384kdf_scheme OBJ_secg_scheme,11L,2L
+
+#define SN_dhSinglePass_stdDH_sha512kdf_scheme "dhSinglePass-stdDH-sha512kdf-scheme"
+#define NID_dhSinglePass_stdDH_sha512kdf_scheme 940
+#define OBJ_dhSinglePass_stdDH_sha512kdf_scheme OBJ_secg_scheme,11L,3L
+
+#define SN_dhSinglePass_cofactorDH_sha1kdf_scheme "dhSinglePass-cofactorDH-sha1kdf-scheme"
+#define NID_dhSinglePass_cofactorDH_sha1kdf_scheme 941
+#define OBJ_dhSinglePass_cofactorDH_sha1kdf_scheme OBJ_x9_63_scheme,3L
+
+#define SN_dhSinglePass_cofactorDH_sha224kdf_scheme "dhSinglePass-cofactorDH-sha224kdf-scheme"
+#define NID_dhSinglePass_cofactorDH_sha224kdf_scheme 942
+#define OBJ_dhSinglePass_cofactorDH_sha224kdf_scheme OBJ_secg_scheme,14L,0L
+
+#define SN_dhSinglePass_cofactorDH_sha256kdf_scheme "dhSinglePass-cofactorDH-sha256kdf-scheme"
+#define NID_dhSinglePass_cofactorDH_sha256kdf_scheme 943
+#define OBJ_dhSinglePass_cofactorDH_sha256kdf_scheme OBJ_secg_scheme,14L,1L
+
+#define SN_dhSinglePass_cofactorDH_sha384kdf_scheme "dhSinglePass-cofactorDH-sha384kdf-scheme"
+#define NID_dhSinglePass_cofactorDH_sha384kdf_scheme 944
+#define OBJ_dhSinglePass_cofactorDH_sha384kdf_scheme OBJ_secg_scheme,14L,2L
+
+#define SN_dhSinglePass_cofactorDH_sha512kdf_scheme "dhSinglePass-cofactorDH-sha512kdf-scheme"
+#define NID_dhSinglePass_cofactorDH_sha512kdf_scheme 945
+#define OBJ_dhSinglePass_cofactorDH_sha512kdf_scheme OBJ_secg_scheme,14L,3L
+
+#define SN_dh_std_kdf "dh-std-kdf"
+#define NID_dh_std_kdf 946
+
+#define SN_dh_cofactor_kdf "dh-cofactor-kdf"
+#define NID_dh_cofactor_kdf 947
+
+#define SN_X25519 "X25519"
+#define NID_X25519 948
+
+
+#endif /* OPENSSL_HEADER_NID_H */
diff --git a/src/include/openssl/obj.h b/src/include/openssl/obj.h
index 32a48948..7e24820c 100644
--- a/src/include/openssl/obj.h
+++ b/src/include/openssl/obj.h
@@ -60,7 +60,7 @@
#include <openssl/base.h>
#include <openssl/bytestring.h>
-#include <openssl/obj_mac.h>
+#include <openssl/nid.h>
#if defined(__cplusplus)
extern "C" {
@@ -189,6 +189,32 @@ OPENSSL_EXPORT int OBJ_find_sigid_by_algs(int *out_sign_nid, int digest_nid,
int pkey_nid);
+/* Deprecated functions. */
+
+typedef struct obj_name_st {
+ int type;
+ const char *name;
+} OBJ_NAME;
+
+#define OBJ_NAME_TYPE_MD_METH 1
+#define OBJ_NAME_TYPE_CIPHER_METH 2
+
+/* OBJ_NAME_do_all_sorted calls |callback| zero or more times, each time with
+ * the name of a different primitive. If |type| is |OBJ_NAME_TYPE_MD_METH| then
+ * the primitives will be hash functions, alternatively if |type| is
+ * |OBJ_NAME_TYPE_CIPHER_METH| then the primitives will be ciphers or cipher
+ * modes.
+ *
+ * This function is ill-specified and should never be used. */
+OPENSSL_EXPORT void OBJ_NAME_do_all_sorted(
+ int type, void (*callback)(const OBJ_NAME *, void *arg), void *arg);
+
+/* OBJ_NAME_do_all calls |OBJ_NAME_do_all_sorted|. */
+OPENSSL_EXPORT void OBJ_NAME_do_all(int type, void (*callback)(const OBJ_NAME *,
+ void *arg),
+ void *arg);
+
+
#if defined(__cplusplus)
} /* extern C */
#endif
diff --git a/src/include/openssl/obj_mac.h b/src/include/openssl/obj_mac.h
index b636adcf..e7ccadc1 100644
--- a/src/include/openssl/obj_mac.h
+++ b/src/include/openssl/obj_mac.h
@@ -1,4144 +1,18 @@
-/* THIS FILE IS GENERATED FROM objects.txt by objects.pl via the
- * following command:
- * perl objects.pl objects.txt obj_mac.num ../../include/openssl/obj_mac.h */
-
-/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
+/* Copyright (c) 2016, 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.]
- */
-
-#define SN_undef "UNDEF"
-#define LN_undef "undefined"
-#define NID_undef 0
-#define OBJ_undef 0L
-
-#define SN_itu_t "ITU-T"
-#define LN_itu_t "itu-t"
-#define NID_itu_t 645
-#define OBJ_itu_t 0L
-
-#define NID_ccitt 404
-#define OBJ_ccitt OBJ_itu_t
-
-#define SN_iso "ISO"
-#define LN_iso "iso"
-#define NID_iso 181
-#define OBJ_iso 1L
-
-#define SN_joint_iso_itu_t "JOINT-ISO-ITU-T"
-#define LN_joint_iso_itu_t "joint-iso-itu-t"
-#define NID_joint_iso_itu_t 646
-#define OBJ_joint_iso_itu_t 2L
-
-#define NID_joint_iso_ccitt 393
-#define OBJ_joint_iso_ccitt OBJ_joint_iso_itu_t
-
-#define SN_member_body "member-body"
-#define LN_member_body "ISO Member Body"
-#define NID_member_body 182
-#define OBJ_member_body OBJ_iso,2L
-
-#define SN_identified_organization "identified-organization"
-#define NID_identified_organization 676
-#define OBJ_identified_organization OBJ_iso,3L
-
-#define SN_hmac_md5 "HMAC-MD5"
-#define LN_hmac_md5 "hmac-md5"
-#define NID_hmac_md5 780
-#define OBJ_hmac_md5 OBJ_identified_organization,6L,1L,5L,5L,8L,1L,1L
-
-#define SN_hmac_sha1 "HMAC-SHA1"
-#define LN_hmac_sha1 "hmac-sha1"
-#define NID_hmac_sha1 781
-#define OBJ_hmac_sha1 OBJ_identified_organization,6L,1L,5L,5L,8L,1L,2L
-
-#define SN_certicom_arc "certicom-arc"
-#define NID_certicom_arc 677
-#define OBJ_certicom_arc OBJ_identified_organization,132L
-
-#define SN_international_organizations "international-organizations"
-#define LN_international_organizations "International Organizations"
-#define NID_international_organizations 647
-#define OBJ_international_organizations OBJ_joint_iso_itu_t,23L
-
-#define SN_wap "wap"
-#define NID_wap 678
-#define OBJ_wap OBJ_international_organizations,43L
-
-#define SN_wap_wsg "wap-wsg"
-#define NID_wap_wsg 679
-#define OBJ_wap_wsg OBJ_wap,1L
-
-#define SN_selected_attribute_types "selected-attribute-types"
-#define LN_selected_attribute_types "Selected Attribute Types"
-#define NID_selected_attribute_types 394
-#define OBJ_selected_attribute_types OBJ_joint_iso_itu_t,5L,1L,5L
-
-#define SN_clearance "clearance"
-#define NID_clearance 395
-#define OBJ_clearance OBJ_selected_attribute_types,55L
-
-#define SN_ISO_US "ISO-US"
-#define LN_ISO_US "ISO US Member Body"
-#define NID_ISO_US 183
-#define OBJ_ISO_US OBJ_member_body,840L
-
-#define SN_X9_57 "X9-57"
-#define LN_X9_57 "X9.57"
-#define NID_X9_57 184
-#define OBJ_X9_57 OBJ_ISO_US,10040L
-
-#define SN_X9cm "X9cm"
-#define LN_X9cm "X9.57 CM ?"
-#define NID_X9cm 185
-#define OBJ_X9cm OBJ_X9_57,4L
-
-#define SN_dsa "DSA"
-#define LN_dsa "dsaEncryption"
-#define NID_dsa 116
-#define OBJ_dsa OBJ_X9cm,1L
-
-#define SN_dsaWithSHA1 "DSA-SHA1"
-#define LN_dsaWithSHA1 "dsaWithSHA1"
-#define NID_dsaWithSHA1 113
-#define OBJ_dsaWithSHA1 OBJ_X9cm,3L
-
-#define SN_ansi_X9_62 "ansi-X9-62"
-#define LN_ansi_X9_62 "ANSI X9.62"
-#define NID_ansi_X9_62 405
-#define OBJ_ansi_X9_62 OBJ_ISO_US,10045L
-
-#define OBJ_X9_62_id_fieldType OBJ_ansi_X9_62,1L
-
-#define SN_X9_62_prime_field "prime-field"
-#define NID_X9_62_prime_field 406
-#define OBJ_X9_62_prime_field OBJ_X9_62_id_fieldType,1L
-
-#define SN_X9_62_characteristic_two_field "characteristic-two-field"
-#define NID_X9_62_characteristic_two_field 407
-#define OBJ_X9_62_characteristic_two_field OBJ_X9_62_id_fieldType,2L
-
-#define SN_X9_62_id_characteristic_two_basis "id-characteristic-two-basis"
-#define NID_X9_62_id_characteristic_two_basis 680
-#define OBJ_X9_62_id_characteristic_two_basis OBJ_X9_62_characteristic_two_field,3L
-
-#define SN_X9_62_onBasis "onBasis"
-#define NID_X9_62_onBasis 681
-#define OBJ_X9_62_onBasis OBJ_X9_62_id_characteristic_two_basis,1L
-
-#define SN_X9_62_tpBasis "tpBasis"
-#define NID_X9_62_tpBasis 682
-#define OBJ_X9_62_tpBasis OBJ_X9_62_id_characteristic_two_basis,2L
-
-#define SN_X9_62_ppBasis "ppBasis"
-#define NID_X9_62_ppBasis 683
-#define OBJ_X9_62_ppBasis OBJ_X9_62_id_characteristic_two_basis,3L
-
-#define OBJ_X9_62_id_publicKeyType OBJ_ansi_X9_62,2L
-
-#define SN_X9_62_id_ecPublicKey "id-ecPublicKey"
-#define NID_X9_62_id_ecPublicKey 408
-#define OBJ_X9_62_id_ecPublicKey OBJ_X9_62_id_publicKeyType,1L
-
-#define OBJ_X9_62_ellipticCurve OBJ_ansi_X9_62,3L
-
-#define OBJ_X9_62_c_TwoCurve OBJ_X9_62_ellipticCurve,0L
-
-#define SN_X9_62_c2pnb163v1 "c2pnb163v1"
-#define NID_X9_62_c2pnb163v1 684
-#define OBJ_X9_62_c2pnb163v1 OBJ_X9_62_c_TwoCurve,1L
-
-#define SN_X9_62_c2pnb163v2 "c2pnb163v2"
-#define NID_X9_62_c2pnb163v2 685
-#define OBJ_X9_62_c2pnb163v2 OBJ_X9_62_c_TwoCurve,2L
-
-#define SN_X9_62_c2pnb163v3 "c2pnb163v3"
-#define NID_X9_62_c2pnb163v3 686
-#define OBJ_X9_62_c2pnb163v3 OBJ_X9_62_c_TwoCurve,3L
-
-#define SN_X9_62_c2pnb176v1 "c2pnb176v1"
-#define NID_X9_62_c2pnb176v1 687
-#define OBJ_X9_62_c2pnb176v1 OBJ_X9_62_c_TwoCurve,4L
-
-#define SN_X9_62_c2tnb191v1 "c2tnb191v1"
-#define NID_X9_62_c2tnb191v1 688
-#define OBJ_X9_62_c2tnb191v1 OBJ_X9_62_c_TwoCurve,5L
-
-#define SN_X9_62_c2tnb191v2 "c2tnb191v2"
-#define NID_X9_62_c2tnb191v2 689
-#define OBJ_X9_62_c2tnb191v2 OBJ_X9_62_c_TwoCurve,6L
-
-#define SN_X9_62_c2tnb191v3 "c2tnb191v3"
-#define NID_X9_62_c2tnb191v3 690
-#define OBJ_X9_62_c2tnb191v3 OBJ_X9_62_c_TwoCurve,7L
-
-#define SN_X9_62_c2onb191v4 "c2onb191v4"
-#define NID_X9_62_c2onb191v4 691
-#define OBJ_X9_62_c2onb191v4 OBJ_X9_62_c_TwoCurve,8L
-
-#define SN_X9_62_c2onb191v5 "c2onb191v5"
-#define NID_X9_62_c2onb191v5 692
-#define OBJ_X9_62_c2onb191v5 OBJ_X9_62_c_TwoCurve,9L
-
-#define SN_X9_62_c2pnb208w1 "c2pnb208w1"
-#define NID_X9_62_c2pnb208w1 693
-#define OBJ_X9_62_c2pnb208w1 OBJ_X9_62_c_TwoCurve,10L
-
-#define SN_X9_62_c2tnb239v1 "c2tnb239v1"
-#define NID_X9_62_c2tnb239v1 694
-#define OBJ_X9_62_c2tnb239v1 OBJ_X9_62_c_TwoCurve,11L
-
-#define SN_X9_62_c2tnb239v2 "c2tnb239v2"
-#define NID_X9_62_c2tnb239v2 695
-#define OBJ_X9_62_c2tnb239v2 OBJ_X9_62_c_TwoCurve,12L
-
-#define SN_X9_62_c2tnb239v3 "c2tnb239v3"
-#define NID_X9_62_c2tnb239v3 696
-#define OBJ_X9_62_c2tnb239v3 OBJ_X9_62_c_TwoCurve,13L
-
-#define SN_X9_62_c2onb239v4 "c2onb239v4"
-#define NID_X9_62_c2onb239v4 697
-#define OBJ_X9_62_c2onb239v4 OBJ_X9_62_c_TwoCurve,14L
-
-#define SN_X9_62_c2onb239v5 "c2onb239v5"
-#define NID_X9_62_c2onb239v5 698
-#define OBJ_X9_62_c2onb239v5 OBJ_X9_62_c_TwoCurve,15L
-
-#define SN_X9_62_c2pnb272w1 "c2pnb272w1"
-#define NID_X9_62_c2pnb272w1 699
-#define OBJ_X9_62_c2pnb272w1 OBJ_X9_62_c_TwoCurve,16L
-
-#define SN_X9_62_c2pnb304w1 "c2pnb304w1"
-#define NID_X9_62_c2pnb304w1 700
-#define OBJ_X9_62_c2pnb304w1 OBJ_X9_62_c_TwoCurve,17L
-
-#define SN_X9_62_c2tnb359v1 "c2tnb359v1"
-#define NID_X9_62_c2tnb359v1 701
-#define OBJ_X9_62_c2tnb359v1 OBJ_X9_62_c_TwoCurve,18L
-
-#define SN_X9_62_c2pnb368w1 "c2pnb368w1"
-#define NID_X9_62_c2pnb368w1 702
-#define OBJ_X9_62_c2pnb368w1 OBJ_X9_62_c_TwoCurve,19L
-
-#define SN_X9_62_c2tnb431r1 "c2tnb431r1"
-#define NID_X9_62_c2tnb431r1 703
-#define OBJ_X9_62_c2tnb431r1 OBJ_X9_62_c_TwoCurve,20L
-
-#define OBJ_X9_62_primeCurve OBJ_X9_62_ellipticCurve,1L
-
-#define SN_X9_62_prime192v1 "prime192v1"
-#define NID_X9_62_prime192v1 409
-#define OBJ_X9_62_prime192v1 OBJ_X9_62_primeCurve,1L
-
-#define SN_X9_62_prime192v2 "prime192v2"
-#define NID_X9_62_prime192v2 410
-#define OBJ_X9_62_prime192v2 OBJ_X9_62_primeCurve,2L
-
-#define SN_X9_62_prime192v3 "prime192v3"
-#define NID_X9_62_prime192v3 411
-#define OBJ_X9_62_prime192v3 OBJ_X9_62_primeCurve,3L
-
-#define SN_X9_62_prime239v1 "prime239v1"
-#define NID_X9_62_prime239v1 412
-#define OBJ_X9_62_prime239v1 OBJ_X9_62_primeCurve,4L
-
-#define SN_X9_62_prime239v2 "prime239v2"
-#define NID_X9_62_prime239v2 413
-#define OBJ_X9_62_prime239v2 OBJ_X9_62_primeCurve,5L
-
-#define SN_X9_62_prime239v3 "prime239v3"
-#define NID_X9_62_prime239v3 414
-#define OBJ_X9_62_prime239v3 OBJ_X9_62_primeCurve,6L
-
-#define SN_X9_62_prime256v1 "prime256v1"
-#define NID_X9_62_prime256v1 415
-#define OBJ_X9_62_prime256v1 OBJ_X9_62_primeCurve,7L
-
-#define OBJ_X9_62_id_ecSigType OBJ_ansi_X9_62,4L
-
-#define SN_ecdsa_with_SHA1 "ecdsa-with-SHA1"
-#define NID_ecdsa_with_SHA1 416
-#define OBJ_ecdsa_with_SHA1 OBJ_X9_62_id_ecSigType,1L
-
-#define SN_ecdsa_with_Recommended "ecdsa-with-Recommended"
-#define NID_ecdsa_with_Recommended 791
-#define OBJ_ecdsa_with_Recommended OBJ_X9_62_id_ecSigType,2L
-
-#define SN_ecdsa_with_Specified "ecdsa-with-Specified"
-#define NID_ecdsa_with_Specified 792
-#define OBJ_ecdsa_with_Specified OBJ_X9_62_id_ecSigType,3L
-
-#define SN_ecdsa_with_SHA224 "ecdsa-with-SHA224"
-#define NID_ecdsa_with_SHA224 793
-#define OBJ_ecdsa_with_SHA224 OBJ_ecdsa_with_Specified,1L
-
-#define SN_ecdsa_with_SHA256 "ecdsa-with-SHA256"
-#define NID_ecdsa_with_SHA256 794
-#define OBJ_ecdsa_with_SHA256 OBJ_ecdsa_with_Specified,2L
-
-#define SN_ecdsa_with_SHA384 "ecdsa-with-SHA384"
-#define NID_ecdsa_with_SHA384 795
-#define OBJ_ecdsa_with_SHA384 OBJ_ecdsa_with_Specified,3L
-
-#define SN_ecdsa_with_SHA512 "ecdsa-with-SHA512"
-#define NID_ecdsa_with_SHA512 796
-#define OBJ_ecdsa_with_SHA512 OBJ_ecdsa_with_Specified,4L
-
-#define OBJ_secg_ellipticCurve OBJ_certicom_arc,0L
-
-#define SN_secp112r1 "secp112r1"
-#define NID_secp112r1 704
-#define OBJ_secp112r1 OBJ_secg_ellipticCurve,6L
-
-#define SN_secp112r2 "secp112r2"
-#define NID_secp112r2 705
-#define OBJ_secp112r2 OBJ_secg_ellipticCurve,7L
-
-#define SN_secp128r1 "secp128r1"
-#define NID_secp128r1 706
-#define OBJ_secp128r1 OBJ_secg_ellipticCurve,28L
-
-#define SN_secp128r2 "secp128r2"
-#define NID_secp128r2 707
-#define OBJ_secp128r2 OBJ_secg_ellipticCurve,29L
-
-#define SN_secp160k1 "secp160k1"
-#define NID_secp160k1 708
-#define OBJ_secp160k1 OBJ_secg_ellipticCurve,9L
-
-#define SN_secp160r1 "secp160r1"
-#define NID_secp160r1 709
-#define OBJ_secp160r1 OBJ_secg_ellipticCurve,8L
-
-#define SN_secp160r2 "secp160r2"
-#define NID_secp160r2 710
-#define OBJ_secp160r2 OBJ_secg_ellipticCurve,30L
-
-#define SN_secp192k1 "secp192k1"
-#define NID_secp192k1 711
-#define OBJ_secp192k1 OBJ_secg_ellipticCurve,31L
-
-#define SN_secp224k1 "secp224k1"
-#define NID_secp224k1 712
-#define OBJ_secp224k1 OBJ_secg_ellipticCurve,32L
-
-#define SN_secp224r1 "secp224r1"
-#define NID_secp224r1 713
-#define OBJ_secp224r1 OBJ_secg_ellipticCurve,33L
-
-#define SN_secp256k1 "secp256k1"
-#define NID_secp256k1 714
-#define OBJ_secp256k1 OBJ_secg_ellipticCurve,10L
-
-#define SN_secp384r1 "secp384r1"
-#define NID_secp384r1 715
-#define OBJ_secp384r1 OBJ_secg_ellipticCurve,34L
-
-#define SN_secp521r1 "secp521r1"
-#define NID_secp521r1 716
-#define OBJ_secp521r1 OBJ_secg_ellipticCurve,35L
-
-#define SN_sect113r1 "sect113r1"
-#define NID_sect113r1 717
-#define OBJ_sect113r1 OBJ_secg_ellipticCurve,4L
-
-#define SN_sect113r2 "sect113r2"
-#define NID_sect113r2 718
-#define OBJ_sect113r2 OBJ_secg_ellipticCurve,5L
-
-#define SN_sect131r1 "sect131r1"
-#define NID_sect131r1 719
-#define OBJ_sect131r1 OBJ_secg_ellipticCurve,22L
-
-#define SN_sect131r2 "sect131r2"
-#define NID_sect131r2 720
-#define OBJ_sect131r2 OBJ_secg_ellipticCurve,23L
-
-#define SN_sect163k1 "sect163k1"
-#define NID_sect163k1 721
-#define OBJ_sect163k1 OBJ_secg_ellipticCurve,1L
-
-#define SN_sect163r1 "sect163r1"
-#define NID_sect163r1 722
-#define OBJ_sect163r1 OBJ_secg_ellipticCurve,2L
-
-#define SN_sect163r2 "sect163r2"
-#define NID_sect163r2 723
-#define OBJ_sect163r2 OBJ_secg_ellipticCurve,15L
-
-#define SN_sect193r1 "sect193r1"
-#define NID_sect193r1 724
-#define OBJ_sect193r1 OBJ_secg_ellipticCurve,24L
-
-#define SN_sect193r2 "sect193r2"
-#define NID_sect193r2 725
-#define OBJ_sect193r2 OBJ_secg_ellipticCurve,25L
-
-#define SN_sect233k1 "sect233k1"
-#define NID_sect233k1 726
-#define OBJ_sect233k1 OBJ_secg_ellipticCurve,26L
-
-#define SN_sect233r1 "sect233r1"
-#define NID_sect233r1 727
-#define OBJ_sect233r1 OBJ_secg_ellipticCurve,27L
-
-#define SN_sect239k1 "sect239k1"
-#define NID_sect239k1 728
-#define OBJ_sect239k1 OBJ_secg_ellipticCurve,3L
-
-#define SN_sect283k1 "sect283k1"
-#define NID_sect283k1 729
-#define OBJ_sect283k1 OBJ_secg_ellipticCurve,16L
-
-#define SN_sect283r1 "sect283r1"
-#define NID_sect283r1 730
-#define OBJ_sect283r1 OBJ_secg_ellipticCurve,17L
-
-#define SN_sect409k1 "sect409k1"
-#define NID_sect409k1 731
-#define OBJ_sect409k1 OBJ_secg_ellipticCurve,36L
-
-#define SN_sect409r1 "sect409r1"
-#define NID_sect409r1 732
-#define OBJ_sect409r1 OBJ_secg_ellipticCurve,37L
-
-#define SN_sect571k1 "sect571k1"
-#define NID_sect571k1 733
-#define OBJ_sect571k1 OBJ_secg_ellipticCurve,38L
-
-#define SN_sect571r1 "sect571r1"
-#define NID_sect571r1 734
-#define OBJ_sect571r1 OBJ_secg_ellipticCurve,39L
-
-#define OBJ_wap_wsg_idm_ecid OBJ_wap_wsg,4L
-
-#define SN_wap_wsg_idm_ecid_wtls1 "wap-wsg-idm-ecid-wtls1"
-#define NID_wap_wsg_idm_ecid_wtls1 735
-#define OBJ_wap_wsg_idm_ecid_wtls1 OBJ_wap_wsg_idm_ecid,1L
-
-#define SN_wap_wsg_idm_ecid_wtls3 "wap-wsg-idm-ecid-wtls3"
-#define NID_wap_wsg_idm_ecid_wtls3 736
-#define OBJ_wap_wsg_idm_ecid_wtls3 OBJ_wap_wsg_idm_ecid,3L
-
-#define SN_wap_wsg_idm_ecid_wtls4 "wap-wsg-idm-ecid-wtls4"
-#define NID_wap_wsg_idm_ecid_wtls4 737
-#define OBJ_wap_wsg_idm_ecid_wtls4 OBJ_wap_wsg_idm_ecid,4L
-
-#define SN_wap_wsg_idm_ecid_wtls5 "wap-wsg-idm-ecid-wtls5"
-#define NID_wap_wsg_idm_ecid_wtls5 738
-#define OBJ_wap_wsg_idm_ecid_wtls5 OBJ_wap_wsg_idm_ecid,5L
-
-#define SN_wap_wsg_idm_ecid_wtls6 "wap-wsg-idm-ecid-wtls6"
-#define NID_wap_wsg_idm_ecid_wtls6 739
-#define OBJ_wap_wsg_idm_ecid_wtls6 OBJ_wap_wsg_idm_ecid,6L
-
-#define SN_wap_wsg_idm_ecid_wtls7 "wap-wsg-idm-ecid-wtls7"
-#define NID_wap_wsg_idm_ecid_wtls7 740
-#define OBJ_wap_wsg_idm_ecid_wtls7 OBJ_wap_wsg_idm_ecid,7L
-
-#define SN_wap_wsg_idm_ecid_wtls8 "wap-wsg-idm-ecid-wtls8"
-#define NID_wap_wsg_idm_ecid_wtls8 741
-#define OBJ_wap_wsg_idm_ecid_wtls8 OBJ_wap_wsg_idm_ecid,8L
-
-#define SN_wap_wsg_idm_ecid_wtls9 "wap-wsg-idm-ecid-wtls9"
-#define NID_wap_wsg_idm_ecid_wtls9 742
-#define OBJ_wap_wsg_idm_ecid_wtls9 OBJ_wap_wsg_idm_ecid,9L
-
-#define SN_wap_wsg_idm_ecid_wtls10 "wap-wsg-idm-ecid-wtls10"
-#define NID_wap_wsg_idm_ecid_wtls10 743
-#define OBJ_wap_wsg_idm_ecid_wtls10 OBJ_wap_wsg_idm_ecid,10L
-
-#define SN_wap_wsg_idm_ecid_wtls11 "wap-wsg-idm-ecid-wtls11"
-#define NID_wap_wsg_idm_ecid_wtls11 744
-#define OBJ_wap_wsg_idm_ecid_wtls11 OBJ_wap_wsg_idm_ecid,11L
-
-#define SN_wap_wsg_idm_ecid_wtls12 "wap-wsg-idm-ecid-wtls12"
-#define NID_wap_wsg_idm_ecid_wtls12 745
-#define OBJ_wap_wsg_idm_ecid_wtls12 OBJ_wap_wsg_idm_ecid,12L
-
-#define SN_cast5_cbc "CAST5-CBC"
-#define LN_cast5_cbc "cast5-cbc"
-#define NID_cast5_cbc 108
-#define OBJ_cast5_cbc OBJ_ISO_US,113533L,7L,66L,10L
-
-#define SN_cast5_ecb "CAST5-ECB"
-#define LN_cast5_ecb "cast5-ecb"
-#define NID_cast5_ecb 109
-
-#define SN_cast5_cfb64 "CAST5-CFB"
-#define LN_cast5_cfb64 "cast5-cfb"
-#define NID_cast5_cfb64 110
-
-#define SN_cast5_ofb64 "CAST5-OFB"
-#define LN_cast5_ofb64 "cast5-ofb"
-#define NID_cast5_ofb64 111
-
-#define LN_pbeWithMD5AndCast5_CBC "pbeWithMD5AndCast5CBC"
-#define NID_pbeWithMD5AndCast5_CBC 112
-#define OBJ_pbeWithMD5AndCast5_CBC OBJ_ISO_US,113533L,7L,66L,12L
-
-#define SN_id_PasswordBasedMAC "id-PasswordBasedMAC"
-#define LN_id_PasswordBasedMAC "password based MAC"
-#define NID_id_PasswordBasedMAC 782
-#define OBJ_id_PasswordBasedMAC OBJ_ISO_US,113533L,7L,66L,13L
-
-#define SN_id_DHBasedMac "id-DHBasedMac"
-#define LN_id_DHBasedMac "Diffie-Hellman based MAC"
-#define NID_id_DHBasedMac 783
-#define OBJ_id_DHBasedMac OBJ_ISO_US,113533L,7L,66L,30L
-
-#define SN_rsadsi "rsadsi"
-#define LN_rsadsi "RSA Data Security, Inc."
-#define NID_rsadsi 1
-#define OBJ_rsadsi OBJ_ISO_US,113549L
-
-#define SN_pkcs "pkcs"
-#define LN_pkcs "RSA Data Security, Inc. PKCS"
-#define NID_pkcs 2
-#define OBJ_pkcs OBJ_rsadsi,1L
-
-#define SN_pkcs1 "pkcs1"
-#define NID_pkcs1 186
-#define OBJ_pkcs1 OBJ_pkcs,1L
-
-#define LN_rsaEncryption "rsaEncryption"
-#define NID_rsaEncryption 6
-#define OBJ_rsaEncryption OBJ_pkcs1,1L
-
-#define SN_md2WithRSAEncryption "RSA-MD2"
-#define LN_md2WithRSAEncryption "md2WithRSAEncryption"
-#define NID_md2WithRSAEncryption 7
-#define OBJ_md2WithRSAEncryption OBJ_pkcs1,2L
-
-#define SN_md4WithRSAEncryption "RSA-MD4"
-#define LN_md4WithRSAEncryption "md4WithRSAEncryption"
-#define NID_md4WithRSAEncryption 396
-#define OBJ_md4WithRSAEncryption OBJ_pkcs1,3L
-
-#define SN_md5WithRSAEncryption "RSA-MD5"
-#define LN_md5WithRSAEncryption "md5WithRSAEncryption"
-#define NID_md5WithRSAEncryption 8
-#define OBJ_md5WithRSAEncryption OBJ_pkcs1,4L
-
-#define SN_sha1WithRSAEncryption "RSA-SHA1"
-#define LN_sha1WithRSAEncryption "sha1WithRSAEncryption"
-#define NID_sha1WithRSAEncryption 65
-#define OBJ_sha1WithRSAEncryption OBJ_pkcs1,5L
-
-#define SN_rsaesOaep "RSAES-OAEP"
-#define LN_rsaesOaep "rsaesOaep"
-#define NID_rsaesOaep 919
-#define OBJ_rsaesOaep OBJ_pkcs1,7L
-
-#define SN_mgf1 "MGF1"
-#define LN_mgf1 "mgf1"
-#define NID_mgf1 911
-#define OBJ_mgf1 OBJ_pkcs1,8L
-
-#define SN_pSpecified "PSPECIFIED"
-#define LN_pSpecified "pSpecified"
-#define NID_pSpecified 935
-#define OBJ_pSpecified OBJ_pkcs1,9L
-
-#define SN_rsassaPss "RSASSA-PSS"
-#define LN_rsassaPss "rsassaPss"
-#define NID_rsassaPss 912
-#define OBJ_rsassaPss OBJ_pkcs1,10L
-
-#define SN_sha256WithRSAEncryption "RSA-SHA256"
-#define LN_sha256WithRSAEncryption "sha256WithRSAEncryption"
-#define NID_sha256WithRSAEncryption 668
-#define OBJ_sha256WithRSAEncryption OBJ_pkcs1,11L
-
-#define SN_sha384WithRSAEncryption "RSA-SHA384"
-#define LN_sha384WithRSAEncryption "sha384WithRSAEncryption"
-#define NID_sha384WithRSAEncryption 669
-#define OBJ_sha384WithRSAEncryption OBJ_pkcs1,12L
-
-#define SN_sha512WithRSAEncryption "RSA-SHA512"
-#define LN_sha512WithRSAEncryption "sha512WithRSAEncryption"
-#define NID_sha512WithRSAEncryption 670
-#define OBJ_sha512WithRSAEncryption OBJ_pkcs1,13L
-
-#define SN_sha224WithRSAEncryption "RSA-SHA224"
-#define LN_sha224WithRSAEncryption "sha224WithRSAEncryption"
-#define NID_sha224WithRSAEncryption 671
-#define OBJ_sha224WithRSAEncryption OBJ_pkcs1,14L
-
-#define SN_pkcs3 "pkcs3"
-#define NID_pkcs3 27
-#define OBJ_pkcs3 OBJ_pkcs,3L
-
-#define LN_dhKeyAgreement "dhKeyAgreement"
-#define NID_dhKeyAgreement 28
-#define OBJ_dhKeyAgreement OBJ_pkcs3,1L
-
-#define SN_pkcs5 "pkcs5"
-#define NID_pkcs5 187
-#define OBJ_pkcs5 OBJ_pkcs,5L
-
-#define SN_pbeWithMD2AndDES_CBC "PBE-MD2-DES"
-#define LN_pbeWithMD2AndDES_CBC "pbeWithMD2AndDES-CBC"
-#define NID_pbeWithMD2AndDES_CBC 9
-#define OBJ_pbeWithMD2AndDES_CBC OBJ_pkcs5,1L
-
-#define SN_pbeWithMD5AndDES_CBC "PBE-MD5-DES"
-#define LN_pbeWithMD5AndDES_CBC "pbeWithMD5AndDES-CBC"
-#define NID_pbeWithMD5AndDES_CBC 10
-#define OBJ_pbeWithMD5AndDES_CBC OBJ_pkcs5,3L
-
-#define SN_pbeWithMD2AndRC2_CBC "PBE-MD2-RC2-64"
-#define LN_pbeWithMD2AndRC2_CBC "pbeWithMD2AndRC2-CBC"
-#define NID_pbeWithMD2AndRC2_CBC 168
-#define OBJ_pbeWithMD2AndRC2_CBC OBJ_pkcs5,4L
-
-#define SN_pbeWithMD5AndRC2_CBC "PBE-MD5-RC2-64"
-#define LN_pbeWithMD5AndRC2_CBC "pbeWithMD5AndRC2-CBC"
-#define NID_pbeWithMD5AndRC2_CBC 169
-#define OBJ_pbeWithMD5AndRC2_CBC OBJ_pkcs5,6L
-
-#define SN_pbeWithSHA1AndDES_CBC "PBE-SHA1-DES"
-#define LN_pbeWithSHA1AndDES_CBC "pbeWithSHA1AndDES-CBC"
-#define NID_pbeWithSHA1AndDES_CBC 170
-#define OBJ_pbeWithSHA1AndDES_CBC OBJ_pkcs5,10L
-
-#define SN_pbeWithSHA1AndRC2_CBC "PBE-SHA1-RC2-64"
-#define LN_pbeWithSHA1AndRC2_CBC "pbeWithSHA1AndRC2-CBC"
-#define NID_pbeWithSHA1AndRC2_CBC 68
-#define OBJ_pbeWithSHA1AndRC2_CBC OBJ_pkcs5,11L
-
-#define LN_id_pbkdf2 "PBKDF2"
-#define NID_id_pbkdf2 69
-#define OBJ_id_pbkdf2 OBJ_pkcs5,12L
-
-#define LN_pbes2 "PBES2"
-#define NID_pbes2 161
-#define OBJ_pbes2 OBJ_pkcs5,13L
-
-#define LN_pbmac1 "PBMAC1"
-#define NID_pbmac1 162
-#define OBJ_pbmac1 OBJ_pkcs5,14L
-
-#define SN_pkcs7 "pkcs7"
-#define NID_pkcs7 20
-#define OBJ_pkcs7 OBJ_pkcs,7L
-
-#define LN_pkcs7_data "pkcs7-data"
-#define NID_pkcs7_data 21
-#define OBJ_pkcs7_data OBJ_pkcs7,1L
-
-#define LN_pkcs7_signed "pkcs7-signedData"
-#define NID_pkcs7_signed 22
-#define OBJ_pkcs7_signed OBJ_pkcs7,2L
-
-#define LN_pkcs7_enveloped "pkcs7-envelopedData"
-#define NID_pkcs7_enveloped 23
-#define OBJ_pkcs7_enveloped OBJ_pkcs7,3L
-
-#define LN_pkcs7_signedAndEnveloped "pkcs7-signedAndEnvelopedData"
-#define NID_pkcs7_signedAndEnveloped 24
-#define OBJ_pkcs7_signedAndEnveloped OBJ_pkcs7,4L
-
-#define LN_pkcs7_digest "pkcs7-digestData"
-#define NID_pkcs7_digest 25
-#define OBJ_pkcs7_digest OBJ_pkcs7,5L
-
-#define LN_pkcs7_encrypted "pkcs7-encryptedData"
-#define NID_pkcs7_encrypted 26
-#define OBJ_pkcs7_encrypted OBJ_pkcs7,6L
-
-#define SN_pkcs9 "pkcs9"
-#define NID_pkcs9 47
-#define OBJ_pkcs9 OBJ_pkcs,9L
-
-#define LN_pkcs9_emailAddress "emailAddress"
-#define NID_pkcs9_emailAddress 48
-#define OBJ_pkcs9_emailAddress OBJ_pkcs9,1L
-
-#define LN_pkcs9_unstructuredName "unstructuredName"
-#define NID_pkcs9_unstructuredName 49
-#define OBJ_pkcs9_unstructuredName OBJ_pkcs9,2L
-
-#define LN_pkcs9_contentType "contentType"
-#define NID_pkcs9_contentType 50
-#define OBJ_pkcs9_contentType OBJ_pkcs9,3L
-
-#define LN_pkcs9_messageDigest "messageDigest"
-#define NID_pkcs9_messageDigest 51
-#define OBJ_pkcs9_messageDigest OBJ_pkcs9,4L
-
-#define LN_pkcs9_signingTime "signingTime"
-#define NID_pkcs9_signingTime 52
-#define OBJ_pkcs9_signingTime OBJ_pkcs9,5L
-
-#define LN_pkcs9_countersignature "countersignature"
-#define NID_pkcs9_countersignature 53
-#define OBJ_pkcs9_countersignature OBJ_pkcs9,6L
-
-#define LN_pkcs9_challengePassword "challengePassword"
-#define NID_pkcs9_challengePassword 54
-#define OBJ_pkcs9_challengePassword OBJ_pkcs9,7L
-
-#define LN_pkcs9_unstructuredAddress "unstructuredAddress"
-#define NID_pkcs9_unstructuredAddress 55
-#define OBJ_pkcs9_unstructuredAddress OBJ_pkcs9,8L
-
-#define LN_pkcs9_extCertAttributes "extendedCertificateAttributes"
-#define NID_pkcs9_extCertAttributes 56
-#define OBJ_pkcs9_extCertAttributes OBJ_pkcs9,9L
-
-#define SN_ext_req "extReq"
-#define LN_ext_req "Extension Request"
-#define NID_ext_req 172
-#define OBJ_ext_req OBJ_pkcs9,14L
-
-#define SN_SMIMECapabilities "SMIME-CAPS"
-#define LN_SMIMECapabilities "S/MIME Capabilities"
-#define NID_SMIMECapabilities 167
-#define OBJ_SMIMECapabilities OBJ_pkcs9,15L
-
-#define SN_SMIME "SMIME"
-#define LN_SMIME "S/MIME"
-#define NID_SMIME 188
-#define OBJ_SMIME OBJ_pkcs9,16L
-
-#define SN_id_smime_mod "id-smime-mod"
-#define NID_id_smime_mod 189
-#define OBJ_id_smime_mod OBJ_SMIME,0L
-
-#define SN_id_smime_ct "id-smime-ct"
-#define NID_id_smime_ct 190
-#define OBJ_id_smime_ct OBJ_SMIME,1L
-
-#define SN_id_smime_aa "id-smime-aa"
-#define NID_id_smime_aa 191
-#define OBJ_id_smime_aa OBJ_SMIME,2L
-
-#define SN_id_smime_alg "id-smime-alg"
-#define NID_id_smime_alg 192
-#define OBJ_id_smime_alg OBJ_SMIME,3L
-
-#define SN_id_smime_cd "id-smime-cd"
-#define NID_id_smime_cd 193
-#define OBJ_id_smime_cd OBJ_SMIME,4L
-
-#define SN_id_smime_spq "id-smime-spq"
-#define NID_id_smime_spq 194
-#define OBJ_id_smime_spq OBJ_SMIME,5L
-
-#define SN_id_smime_cti "id-smime-cti"
-#define NID_id_smime_cti 195
-#define OBJ_id_smime_cti OBJ_SMIME,6L
-
-#define SN_id_smime_mod_cms "id-smime-mod-cms"
-#define NID_id_smime_mod_cms 196
-#define OBJ_id_smime_mod_cms OBJ_id_smime_mod,1L
-
-#define SN_id_smime_mod_ess "id-smime-mod-ess"
-#define NID_id_smime_mod_ess 197
-#define OBJ_id_smime_mod_ess OBJ_id_smime_mod,2L
-
-#define SN_id_smime_mod_oid "id-smime-mod-oid"
-#define NID_id_smime_mod_oid 198
-#define OBJ_id_smime_mod_oid OBJ_id_smime_mod,3L
-
-#define SN_id_smime_mod_msg_v3 "id-smime-mod-msg-v3"
-#define NID_id_smime_mod_msg_v3 199
-#define OBJ_id_smime_mod_msg_v3 OBJ_id_smime_mod,4L
-
-#define SN_id_smime_mod_ets_eSignature_88 "id-smime-mod-ets-eSignature-88"
-#define NID_id_smime_mod_ets_eSignature_88 200
-#define OBJ_id_smime_mod_ets_eSignature_88 OBJ_id_smime_mod,5L
-
-#define SN_id_smime_mod_ets_eSignature_97 "id-smime-mod-ets-eSignature-97"
-#define NID_id_smime_mod_ets_eSignature_97 201
-#define OBJ_id_smime_mod_ets_eSignature_97 OBJ_id_smime_mod,6L
-
-#define SN_id_smime_mod_ets_eSigPolicy_88 "id-smime-mod-ets-eSigPolicy-88"
-#define NID_id_smime_mod_ets_eSigPolicy_88 202
-#define OBJ_id_smime_mod_ets_eSigPolicy_88 OBJ_id_smime_mod,7L
-
-#define SN_id_smime_mod_ets_eSigPolicy_97 "id-smime-mod-ets-eSigPolicy-97"
-#define NID_id_smime_mod_ets_eSigPolicy_97 203
-#define OBJ_id_smime_mod_ets_eSigPolicy_97 OBJ_id_smime_mod,8L
-
-#define SN_id_smime_ct_receipt "id-smime-ct-receipt"
-#define NID_id_smime_ct_receipt 204
-#define OBJ_id_smime_ct_receipt OBJ_id_smime_ct,1L
-
-#define SN_id_smime_ct_authData "id-smime-ct-authData"
-#define NID_id_smime_ct_authData 205
-#define OBJ_id_smime_ct_authData OBJ_id_smime_ct,2L
-
-#define SN_id_smime_ct_publishCert "id-smime-ct-publishCert"
-#define NID_id_smime_ct_publishCert 206
-#define OBJ_id_smime_ct_publishCert OBJ_id_smime_ct,3L
-
-#define SN_id_smime_ct_TSTInfo "id-smime-ct-TSTInfo"
-#define NID_id_smime_ct_TSTInfo 207
-#define OBJ_id_smime_ct_TSTInfo OBJ_id_smime_ct,4L
-
-#define SN_id_smime_ct_TDTInfo "id-smime-ct-TDTInfo"
-#define NID_id_smime_ct_TDTInfo 208
-#define OBJ_id_smime_ct_TDTInfo OBJ_id_smime_ct,5L
-
-#define SN_id_smime_ct_contentInfo "id-smime-ct-contentInfo"
-#define NID_id_smime_ct_contentInfo 209
-#define OBJ_id_smime_ct_contentInfo OBJ_id_smime_ct,6L
-
-#define SN_id_smime_ct_DVCSRequestData "id-smime-ct-DVCSRequestData"
-#define NID_id_smime_ct_DVCSRequestData 210
-#define OBJ_id_smime_ct_DVCSRequestData OBJ_id_smime_ct,7L
-
-#define SN_id_smime_ct_DVCSResponseData "id-smime-ct-DVCSResponseData"
-#define NID_id_smime_ct_DVCSResponseData 211
-#define OBJ_id_smime_ct_DVCSResponseData OBJ_id_smime_ct,8L
-
-#define SN_id_smime_ct_compressedData "id-smime-ct-compressedData"
-#define NID_id_smime_ct_compressedData 786
-#define OBJ_id_smime_ct_compressedData OBJ_id_smime_ct,9L
-
-#define SN_id_ct_asciiTextWithCRLF "id-ct-asciiTextWithCRLF"
-#define NID_id_ct_asciiTextWithCRLF 787
-#define OBJ_id_ct_asciiTextWithCRLF OBJ_id_smime_ct,27L
-
-#define SN_id_smime_aa_receiptRequest "id-smime-aa-receiptRequest"
-#define NID_id_smime_aa_receiptRequest 212
-#define OBJ_id_smime_aa_receiptRequest OBJ_id_smime_aa,1L
-
-#define SN_id_smime_aa_securityLabel "id-smime-aa-securityLabel"
-#define NID_id_smime_aa_securityLabel 213
-#define OBJ_id_smime_aa_securityLabel OBJ_id_smime_aa,2L
-
-#define SN_id_smime_aa_mlExpandHistory "id-smime-aa-mlExpandHistory"
-#define NID_id_smime_aa_mlExpandHistory 214
-#define OBJ_id_smime_aa_mlExpandHistory OBJ_id_smime_aa,3L
-
-#define SN_id_smime_aa_contentHint "id-smime-aa-contentHint"
-#define NID_id_smime_aa_contentHint 215
-#define OBJ_id_smime_aa_contentHint OBJ_id_smime_aa,4L
-
-#define SN_id_smime_aa_msgSigDigest "id-smime-aa-msgSigDigest"
-#define NID_id_smime_aa_msgSigDigest 216
-#define OBJ_id_smime_aa_msgSigDigest OBJ_id_smime_aa,5L
-
-#define SN_id_smime_aa_encapContentType "id-smime-aa-encapContentType"
-#define NID_id_smime_aa_encapContentType 217
-#define OBJ_id_smime_aa_encapContentType OBJ_id_smime_aa,6L
-
-#define SN_id_smime_aa_contentIdentifier "id-smime-aa-contentIdentifier"
-#define NID_id_smime_aa_contentIdentifier 218
-#define OBJ_id_smime_aa_contentIdentifier OBJ_id_smime_aa,7L
-
-#define SN_id_smime_aa_macValue "id-smime-aa-macValue"
-#define NID_id_smime_aa_macValue 219
-#define OBJ_id_smime_aa_macValue OBJ_id_smime_aa,8L
-
-#define SN_id_smime_aa_equivalentLabels "id-smime-aa-equivalentLabels"
-#define NID_id_smime_aa_equivalentLabels 220
-#define OBJ_id_smime_aa_equivalentLabels OBJ_id_smime_aa,9L
-
-#define SN_id_smime_aa_contentReference "id-smime-aa-contentReference"
-#define NID_id_smime_aa_contentReference 221
-#define OBJ_id_smime_aa_contentReference OBJ_id_smime_aa,10L
-
-#define SN_id_smime_aa_encrypKeyPref "id-smime-aa-encrypKeyPref"
-#define NID_id_smime_aa_encrypKeyPref 222
-#define OBJ_id_smime_aa_encrypKeyPref OBJ_id_smime_aa,11L
-
-#define SN_id_smime_aa_signingCertificate "id-smime-aa-signingCertificate"
-#define NID_id_smime_aa_signingCertificate 223
-#define OBJ_id_smime_aa_signingCertificate OBJ_id_smime_aa,12L
-
-#define SN_id_smime_aa_smimeEncryptCerts "id-smime-aa-smimeEncryptCerts"
-#define NID_id_smime_aa_smimeEncryptCerts 224
-#define OBJ_id_smime_aa_smimeEncryptCerts OBJ_id_smime_aa,13L
-
-#define SN_id_smime_aa_timeStampToken "id-smime-aa-timeStampToken"
-#define NID_id_smime_aa_timeStampToken 225
-#define OBJ_id_smime_aa_timeStampToken OBJ_id_smime_aa,14L
-
-#define SN_id_smime_aa_ets_sigPolicyId "id-smime-aa-ets-sigPolicyId"
-#define NID_id_smime_aa_ets_sigPolicyId 226
-#define OBJ_id_smime_aa_ets_sigPolicyId OBJ_id_smime_aa,15L
-
-#define SN_id_smime_aa_ets_commitmentType "id-smime-aa-ets-commitmentType"
-#define NID_id_smime_aa_ets_commitmentType 227
-#define OBJ_id_smime_aa_ets_commitmentType OBJ_id_smime_aa,16L
-
-#define SN_id_smime_aa_ets_signerLocation "id-smime-aa-ets-signerLocation"
-#define NID_id_smime_aa_ets_signerLocation 228
-#define OBJ_id_smime_aa_ets_signerLocation OBJ_id_smime_aa,17L
-
-#define SN_id_smime_aa_ets_signerAttr "id-smime-aa-ets-signerAttr"
-#define NID_id_smime_aa_ets_signerAttr 229
-#define OBJ_id_smime_aa_ets_signerAttr OBJ_id_smime_aa,18L
-
-#define SN_id_smime_aa_ets_otherSigCert "id-smime-aa-ets-otherSigCert"
-#define NID_id_smime_aa_ets_otherSigCert 230
-#define OBJ_id_smime_aa_ets_otherSigCert OBJ_id_smime_aa,19L
-
-#define SN_id_smime_aa_ets_contentTimestamp "id-smime-aa-ets-contentTimestamp"
-#define NID_id_smime_aa_ets_contentTimestamp 231
-#define OBJ_id_smime_aa_ets_contentTimestamp OBJ_id_smime_aa,20L
-
-#define SN_id_smime_aa_ets_CertificateRefs "id-smime-aa-ets-CertificateRefs"
-#define NID_id_smime_aa_ets_CertificateRefs 232
-#define OBJ_id_smime_aa_ets_CertificateRefs OBJ_id_smime_aa,21L
-
-#define SN_id_smime_aa_ets_RevocationRefs "id-smime-aa-ets-RevocationRefs"
-#define NID_id_smime_aa_ets_RevocationRefs 233
-#define OBJ_id_smime_aa_ets_RevocationRefs OBJ_id_smime_aa,22L
-
-#define SN_id_smime_aa_ets_certValues "id-smime-aa-ets-certValues"
-#define NID_id_smime_aa_ets_certValues 234
-#define OBJ_id_smime_aa_ets_certValues OBJ_id_smime_aa,23L
-
-#define SN_id_smime_aa_ets_revocationValues "id-smime-aa-ets-revocationValues"
-#define NID_id_smime_aa_ets_revocationValues 235
-#define OBJ_id_smime_aa_ets_revocationValues OBJ_id_smime_aa,24L
-
-#define SN_id_smime_aa_ets_escTimeStamp "id-smime-aa-ets-escTimeStamp"
-#define NID_id_smime_aa_ets_escTimeStamp 236
-#define OBJ_id_smime_aa_ets_escTimeStamp OBJ_id_smime_aa,25L
-
-#define SN_id_smime_aa_ets_certCRLTimestamp "id-smime-aa-ets-certCRLTimestamp"
-#define NID_id_smime_aa_ets_certCRLTimestamp 237
-#define OBJ_id_smime_aa_ets_certCRLTimestamp OBJ_id_smime_aa,26L
-
-#define SN_id_smime_aa_ets_archiveTimeStamp "id-smime-aa-ets-archiveTimeStamp"
-#define NID_id_smime_aa_ets_archiveTimeStamp 238
-#define OBJ_id_smime_aa_ets_archiveTimeStamp OBJ_id_smime_aa,27L
-
-#define SN_id_smime_aa_signatureType "id-smime-aa-signatureType"
-#define NID_id_smime_aa_signatureType 239
-#define OBJ_id_smime_aa_signatureType OBJ_id_smime_aa,28L
-
-#define SN_id_smime_aa_dvcs_dvc "id-smime-aa-dvcs-dvc"
-#define NID_id_smime_aa_dvcs_dvc 240
-#define OBJ_id_smime_aa_dvcs_dvc OBJ_id_smime_aa,29L
-
-#define SN_id_smime_alg_ESDHwith3DES "id-smime-alg-ESDHwith3DES"
-#define NID_id_smime_alg_ESDHwith3DES 241
-#define OBJ_id_smime_alg_ESDHwith3DES OBJ_id_smime_alg,1L
-
-#define SN_id_smime_alg_ESDHwithRC2 "id-smime-alg-ESDHwithRC2"
-#define NID_id_smime_alg_ESDHwithRC2 242
-#define OBJ_id_smime_alg_ESDHwithRC2 OBJ_id_smime_alg,2L
-
-#define SN_id_smime_alg_3DESwrap "id-smime-alg-3DESwrap"
-#define NID_id_smime_alg_3DESwrap 243
-#define OBJ_id_smime_alg_3DESwrap OBJ_id_smime_alg,3L
-
-#define SN_id_smime_alg_RC2wrap "id-smime-alg-RC2wrap"
-#define NID_id_smime_alg_RC2wrap 244
-#define OBJ_id_smime_alg_RC2wrap OBJ_id_smime_alg,4L
-
-#define SN_id_smime_alg_ESDH "id-smime-alg-ESDH"
-#define NID_id_smime_alg_ESDH 245
-#define OBJ_id_smime_alg_ESDH OBJ_id_smime_alg,5L
-
-#define SN_id_smime_alg_CMS3DESwrap "id-smime-alg-CMS3DESwrap"
-#define NID_id_smime_alg_CMS3DESwrap 246
-#define OBJ_id_smime_alg_CMS3DESwrap OBJ_id_smime_alg,6L
-
-#define SN_id_smime_alg_CMSRC2wrap "id-smime-alg-CMSRC2wrap"
-#define NID_id_smime_alg_CMSRC2wrap 247
-#define OBJ_id_smime_alg_CMSRC2wrap OBJ_id_smime_alg,7L
-
-#define SN_id_alg_PWRI_KEK "id-alg-PWRI-KEK"
-#define NID_id_alg_PWRI_KEK 893
-#define OBJ_id_alg_PWRI_KEK OBJ_id_smime_alg,9L
-
-#define SN_id_smime_cd_ldap "id-smime-cd-ldap"
-#define NID_id_smime_cd_ldap 248
-#define OBJ_id_smime_cd_ldap OBJ_id_smime_cd,1L
-
-#define SN_id_smime_spq_ets_sqt_uri "id-smime-spq-ets-sqt-uri"
-#define NID_id_smime_spq_ets_sqt_uri 249
-#define OBJ_id_smime_spq_ets_sqt_uri OBJ_id_smime_spq,1L
-
-#define SN_id_smime_spq_ets_sqt_unotice "id-smime-spq-ets-sqt-unotice"
-#define NID_id_smime_spq_ets_sqt_unotice 250
-#define OBJ_id_smime_spq_ets_sqt_unotice OBJ_id_smime_spq,2L
-
-#define SN_id_smime_cti_ets_proofOfOrigin "id-smime-cti-ets-proofOfOrigin"
-#define NID_id_smime_cti_ets_proofOfOrigin 251
-#define OBJ_id_smime_cti_ets_proofOfOrigin OBJ_id_smime_cti,1L
-
-#define SN_id_smime_cti_ets_proofOfReceipt "id-smime-cti-ets-proofOfReceipt"
-#define NID_id_smime_cti_ets_proofOfReceipt 252
-#define OBJ_id_smime_cti_ets_proofOfReceipt OBJ_id_smime_cti,2L
-
-#define SN_id_smime_cti_ets_proofOfDelivery "id-smime-cti-ets-proofOfDelivery"
-#define NID_id_smime_cti_ets_proofOfDelivery 253
-#define OBJ_id_smime_cti_ets_proofOfDelivery OBJ_id_smime_cti,3L
-
-#define SN_id_smime_cti_ets_proofOfSender "id-smime-cti-ets-proofOfSender"
-#define NID_id_smime_cti_ets_proofOfSender 254
-#define OBJ_id_smime_cti_ets_proofOfSender OBJ_id_smime_cti,4L
-
-#define SN_id_smime_cti_ets_proofOfApproval "id-smime-cti-ets-proofOfApproval"
-#define NID_id_smime_cti_ets_proofOfApproval 255
-#define OBJ_id_smime_cti_ets_proofOfApproval OBJ_id_smime_cti,5L
-
-#define SN_id_smime_cti_ets_proofOfCreation "id-smime-cti-ets-proofOfCreation"
-#define NID_id_smime_cti_ets_proofOfCreation 256
-#define OBJ_id_smime_cti_ets_proofOfCreation OBJ_id_smime_cti,6L
-
-#define LN_friendlyName "friendlyName"
-#define NID_friendlyName 156
-#define OBJ_friendlyName OBJ_pkcs9,20L
-
-#define LN_localKeyID "localKeyID"
-#define NID_localKeyID 157
-#define OBJ_localKeyID OBJ_pkcs9,21L
-
-#define SN_ms_csp_name "CSPName"
-#define LN_ms_csp_name "Microsoft CSP Name"
-#define NID_ms_csp_name 417
-#define OBJ_ms_csp_name 1L,3L,6L,1L,4L,1L,311L,17L,1L
-
-#define SN_LocalKeySet "LocalKeySet"
-#define LN_LocalKeySet "Microsoft Local Key set"
-#define NID_LocalKeySet 856
-#define OBJ_LocalKeySet 1L,3L,6L,1L,4L,1L,311L,17L,2L
-
-#define OBJ_certTypes OBJ_pkcs9,22L
-
-#define LN_x509Certificate "x509Certificate"
-#define NID_x509Certificate 158
-#define OBJ_x509Certificate OBJ_certTypes,1L
-
-#define LN_sdsiCertificate "sdsiCertificate"
-#define NID_sdsiCertificate 159
-#define OBJ_sdsiCertificate OBJ_certTypes,2L
-
-#define OBJ_crlTypes OBJ_pkcs9,23L
-
-#define LN_x509Crl "x509Crl"
-#define NID_x509Crl 160
-#define OBJ_x509Crl OBJ_crlTypes,1L
-
-#define OBJ_pkcs12 OBJ_pkcs,12L
-
-#define OBJ_pkcs12_pbeids OBJ_pkcs12,1L
-
-#define SN_pbe_WithSHA1And128BitRC4 "PBE-SHA1-RC4-128"
-#define LN_pbe_WithSHA1And128BitRC4 "pbeWithSHA1And128BitRC4"
-#define NID_pbe_WithSHA1And128BitRC4 144
-#define OBJ_pbe_WithSHA1And128BitRC4 OBJ_pkcs12_pbeids,1L
-
-#define SN_pbe_WithSHA1And40BitRC4 "PBE-SHA1-RC4-40"
-#define LN_pbe_WithSHA1And40BitRC4 "pbeWithSHA1And40BitRC4"
-#define NID_pbe_WithSHA1And40BitRC4 145
-#define OBJ_pbe_WithSHA1And40BitRC4 OBJ_pkcs12_pbeids,2L
-
-#define SN_pbe_WithSHA1And3_Key_TripleDES_CBC "PBE-SHA1-3DES"
-#define LN_pbe_WithSHA1And3_Key_TripleDES_CBC "pbeWithSHA1And3-KeyTripleDES-CBC"
-#define NID_pbe_WithSHA1And3_Key_TripleDES_CBC 146
-#define OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC OBJ_pkcs12_pbeids,3L
-
-#define SN_pbe_WithSHA1And2_Key_TripleDES_CBC "PBE-SHA1-2DES"
-#define LN_pbe_WithSHA1And2_Key_TripleDES_CBC "pbeWithSHA1And2-KeyTripleDES-CBC"
-#define NID_pbe_WithSHA1And2_Key_TripleDES_CBC 147
-#define OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC OBJ_pkcs12_pbeids,4L
-
-#define SN_pbe_WithSHA1And128BitRC2_CBC "PBE-SHA1-RC2-128"
-#define LN_pbe_WithSHA1And128BitRC2_CBC "pbeWithSHA1And128BitRC2-CBC"
-#define NID_pbe_WithSHA1And128BitRC2_CBC 148
-#define OBJ_pbe_WithSHA1And128BitRC2_CBC OBJ_pkcs12_pbeids,5L
-
-#define SN_pbe_WithSHA1And40BitRC2_CBC "PBE-SHA1-RC2-40"
-#define LN_pbe_WithSHA1And40BitRC2_CBC "pbeWithSHA1And40BitRC2-CBC"
-#define NID_pbe_WithSHA1And40BitRC2_CBC 149
-#define OBJ_pbe_WithSHA1And40BitRC2_CBC OBJ_pkcs12_pbeids,6L
-
-#define OBJ_pkcs12_Version1 OBJ_pkcs12,10L
-
-#define OBJ_pkcs12_BagIds OBJ_pkcs12_Version1,1L
-
-#define LN_keyBag "keyBag"
-#define NID_keyBag 150
-#define OBJ_keyBag OBJ_pkcs12_BagIds,1L
-
-#define LN_pkcs8ShroudedKeyBag "pkcs8ShroudedKeyBag"
-#define NID_pkcs8ShroudedKeyBag 151
-#define OBJ_pkcs8ShroudedKeyBag OBJ_pkcs12_BagIds,2L
-
-#define LN_certBag "certBag"
-#define NID_certBag 152
-#define OBJ_certBag OBJ_pkcs12_BagIds,3L
-
-#define LN_crlBag "crlBag"
-#define NID_crlBag 153
-#define OBJ_crlBag OBJ_pkcs12_BagIds,4L
-
-#define LN_secretBag "secretBag"
-#define NID_secretBag 154
-#define OBJ_secretBag OBJ_pkcs12_BagIds,5L
-
-#define LN_safeContentsBag "safeContentsBag"
-#define NID_safeContentsBag 155
-#define OBJ_safeContentsBag OBJ_pkcs12_BagIds,6L
-
-#define SN_md2 "MD2"
-#define LN_md2 "md2"
-#define NID_md2 3
-#define OBJ_md2 OBJ_rsadsi,2L,2L
-
-#define SN_md4 "MD4"
-#define LN_md4 "md4"
-#define NID_md4 257
-#define OBJ_md4 OBJ_rsadsi,2L,4L
-
-#define SN_md5 "MD5"
-#define LN_md5 "md5"
-#define NID_md5 4
-#define OBJ_md5 OBJ_rsadsi,2L,5L
-
-#define SN_md5_sha1 "MD5-SHA1"
-#define LN_md5_sha1 "md5-sha1"
-#define NID_md5_sha1 114
-
-#define LN_hmacWithMD5 "hmacWithMD5"
-#define NID_hmacWithMD5 797
-#define OBJ_hmacWithMD5 OBJ_rsadsi,2L,6L
-
-#define LN_hmacWithSHA1 "hmacWithSHA1"
-#define NID_hmacWithSHA1 163
-#define OBJ_hmacWithSHA1 OBJ_rsadsi,2L,7L
-
-#define LN_hmacWithSHA224 "hmacWithSHA224"
-#define NID_hmacWithSHA224 798
-#define OBJ_hmacWithSHA224 OBJ_rsadsi,2L,8L
-
-#define LN_hmacWithSHA256 "hmacWithSHA256"
-#define NID_hmacWithSHA256 799
-#define OBJ_hmacWithSHA256 OBJ_rsadsi,2L,9L
-
-#define LN_hmacWithSHA384 "hmacWithSHA384"
-#define NID_hmacWithSHA384 800
-#define OBJ_hmacWithSHA384 OBJ_rsadsi,2L,10L
-
-#define LN_hmacWithSHA512 "hmacWithSHA512"
-#define NID_hmacWithSHA512 801
-#define OBJ_hmacWithSHA512 OBJ_rsadsi,2L,11L
-
-#define SN_rc2_cbc "RC2-CBC"
-#define LN_rc2_cbc "rc2-cbc"
-#define NID_rc2_cbc 37
-#define OBJ_rc2_cbc OBJ_rsadsi,3L,2L
-
-#define SN_rc2_ecb "RC2-ECB"
-#define LN_rc2_ecb "rc2-ecb"
-#define NID_rc2_ecb 38
-
-#define SN_rc2_cfb64 "RC2-CFB"
-#define LN_rc2_cfb64 "rc2-cfb"
-#define NID_rc2_cfb64 39
-
-#define SN_rc2_ofb64 "RC2-OFB"
-#define LN_rc2_ofb64 "rc2-ofb"
-#define NID_rc2_ofb64 40
-
-#define SN_rc2_40_cbc "RC2-40-CBC"
-#define LN_rc2_40_cbc "rc2-40-cbc"
-#define NID_rc2_40_cbc 98
-
-#define SN_rc2_64_cbc "RC2-64-CBC"
-#define LN_rc2_64_cbc "rc2-64-cbc"
-#define NID_rc2_64_cbc 166
-
-#define SN_rc4 "RC4"
-#define LN_rc4 "rc4"
-#define NID_rc4 5
-#define OBJ_rc4 OBJ_rsadsi,3L,4L
-
-#define SN_rc4_40 "RC4-40"
-#define LN_rc4_40 "rc4-40"
-#define NID_rc4_40 97
-
-#define SN_des_ede3_cbc "DES-EDE3-CBC"
-#define LN_des_ede3_cbc "des-ede3-cbc"
-#define NID_des_ede3_cbc 44
-#define OBJ_des_ede3_cbc OBJ_rsadsi,3L,7L
-
-#define SN_rc5_cbc "RC5-CBC"
-#define LN_rc5_cbc "rc5-cbc"
-#define NID_rc5_cbc 120
-#define OBJ_rc5_cbc OBJ_rsadsi,3L,8L
-
-#define SN_rc5_ecb "RC5-ECB"
-#define LN_rc5_ecb "rc5-ecb"
-#define NID_rc5_ecb 121
-
-#define SN_rc5_cfb64 "RC5-CFB"
-#define LN_rc5_cfb64 "rc5-cfb"
-#define NID_rc5_cfb64 122
-
-#define SN_rc5_ofb64 "RC5-OFB"
-#define LN_rc5_ofb64 "rc5-ofb"
-#define NID_rc5_ofb64 123
-
-#define SN_ms_ext_req "msExtReq"
-#define LN_ms_ext_req "Microsoft Extension Request"
-#define NID_ms_ext_req 171
-#define OBJ_ms_ext_req 1L,3L,6L,1L,4L,1L,311L,2L,1L,14L
-
-#define SN_ms_code_ind "msCodeInd"
-#define LN_ms_code_ind "Microsoft Individual Code Signing"
-#define NID_ms_code_ind 134
-#define OBJ_ms_code_ind 1L,3L,6L,1L,4L,1L,311L,2L,1L,21L
-
-#define SN_ms_code_com "msCodeCom"
-#define LN_ms_code_com "Microsoft Commercial Code Signing"
-#define NID_ms_code_com 135
-#define OBJ_ms_code_com 1L,3L,6L,1L,4L,1L,311L,2L,1L,22L
-
-#define SN_ms_ctl_sign "msCTLSign"
-#define LN_ms_ctl_sign "Microsoft Trust List Signing"
-#define NID_ms_ctl_sign 136
-#define OBJ_ms_ctl_sign 1L,3L,6L,1L,4L,1L,311L,10L,3L,1L
-
-#define SN_ms_sgc "msSGC"
-#define LN_ms_sgc "Microsoft Server Gated Crypto"
-#define NID_ms_sgc 137
-#define OBJ_ms_sgc 1L,3L,6L,1L,4L,1L,311L,10L,3L,3L
-
-#define SN_ms_efs "msEFS"
-#define LN_ms_efs "Microsoft Encrypted File System"
-#define NID_ms_efs 138
-#define OBJ_ms_efs 1L,3L,6L,1L,4L,1L,311L,10L,3L,4L
-
-#define SN_ms_smartcard_login "msSmartcardLogin"
-#define LN_ms_smartcard_login "Microsoft Smartcardlogin"
-#define NID_ms_smartcard_login 648
-#define OBJ_ms_smartcard_login 1L,3L,6L,1L,4L,1L,311L,20L,2L,2L
-
-#define SN_ms_upn "msUPN"
-#define LN_ms_upn "Microsoft Universal Principal Name"
-#define NID_ms_upn 649
-#define OBJ_ms_upn 1L,3L,6L,1L,4L,1L,311L,20L,2L,3L
-
-#define SN_idea_cbc "IDEA-CBC"
-#define LN_idea_cbc "idea-cbc"
-#define NID_idea_cbc 34
-#define OBJ_idea_cbc 1L,3L,6L,1L,4L,1L,188L,7L,1L,1L,2L
-
-#define SN_idea_ecb "IDEA-ECB"
-#define LN_idea_ecb "idea-ecb"
-#define NID_idea_ecb 36
-
-#define SN_idea_cfb64 "IDEA-CFB"
-#define LN_idea_cfb64 "idea-cfb"
-#define NID_idea_cfb64 35
-
-#define SN_idea_ofb64 "IDEA-OFB"
-#define LN_idea_ofb64 "idea-ofb"
-#define NID_idea_ofb64 46
-
-#define SN_bf_cbc "BF-CBC"
-#define LN_bf_cbc "bf-cbc"
-#define NID_bf_cbc 91
-#define OBJ_bf_cbc 1L,3L,6L,1L,4L,1L,3029L,1L,2L
-
-#define SN_bf_ecb "BF-ECB"
-#define LN_bf_ecb "bf-ecb"
-#define NID_bf_ecb 92
-
-#define SN_bf_cfb64 "BF-CFB"
-#define LN_bf_cfb64 "bf-cfb"
-#define NID_bf_cfb64 93
-
-#define SN_bf_ofb64 "BF-OFB"
-#define LN_bf_ofb64 "bf-ofb"
-#define NID_bf_ofb64 94
-
-#define SN_id_pkix "PKIX"
-#define NID_id_pkix 127
-#define OBJ_id_pkix 1L,3L,6L,1L,5L,5L,7L
-
-#define SN_id_pkix_mod "id-pkix-mod"
-#define NID_id_pkix_mod 258
-#define OBJ_id_pkix_mod OBJ_id_pkix,0L
-
-#define SN_id_pe "id-pe"
-#define NID_id_pe 175
-#define OBJ_id_pe OBJ_id_pkix,1L
-
-#define SN_id_qt "id-qt"
-#define NID_id_qt 259
-#define OBJ_id_qt OBJ_id_pkix,2L
-
-#define SN_id_kp "id-kp"
-#define NID_id_kp 128
-#define OBJ_id_kp OBJ_id_pkix,3L
-
-#define SN_id_it "id-it"
-#define NID_id_it 260
-#define OBJ_id_it OBJ_id_pkix,4L
-
-#define SN_id_pkip "id-pkip"
-#define NID_id_pkip 261
-#define OBJ_id_pkip OBJ_id_pkix,5L
-
-#define SN_id_alg "id-alg"
-#define NID_id_alg 262
-#define OBJ_id_alg OBJ_id_pkix,6L
-
-#define SN_id_cmc "id-cmc"
-#define NID_id_cmc 263
-#define OBJ_id_cmc OBJ_id_pkix,7L
-
-#define SN_id_on "id-on"
-#define NID_id_on 264
-#define OBJ_id_on OBJ_id_pkix,8L
-
-#define SN_id_pda "id-pda"
-#define NID_id_pda 265
-#define OBJ_id_pda OBJ_id_pkix,9L
-
-#define SN_id_aca "id-aca"
-#define NID_id_aca 266
-#define OBJ_id_aca OBJ_id_pkix,10L
-
-#define SN_id_qcs "id-qcs"
-#define NID_id_qcs 267
-#define OBJ_id_qcs OBJ_id_pkix,11L
-
-#define SN_id_cct "id-cct"
-#define NID_id_cct 268
-#define OBJ_id_cct OBJ_id_pkix,12L
-
-#define SN_id_ppl "id-ppl"
-#define NID_id_ppl 662
-#define OBJ_id_ppl OBJ_id_pkix,21L
-
-#define SN_id_ad "id-ad"
-#define NID_id_ad 176
-#define OBJ_id_ad OBJ_id_pkix,48L
-
-#define SN_id_pkix1_explicit_88 "id-pkix1-explicit-88"
-#define NID_id_pkix1_explicit_88 269
-#define OBJ_id_pkix1_explicit_88 OBJ_id_pkix_mod,1L
-
-#define SN_id_pkix1_implicit_88 "id-pkix1-implicit-88"
-#define NID_id_pkix1_implicit_88 270
-#define OBJ_id_pkix1_implicit_88 OBJ_id_pkix_mod,2L
-
-#define SN_id_pkix1_explicit_93 "id-pkix1-explicit-93"
-#define NID_id_pkix1_explicit_93 271
-#define OBJ_id_pkix1_explicit_93 OBJ_id_pkix_mod,3L
-
-#define SN_id_pkix1_implicit_93 "id-pkix1-implicit-93"
-#define NID_id_pkix1_implicit_93 272
-#define OBJ_id_pkix1_implicit_93 OBJ_id_pkix_mod,4L
-
-#define SN_id_mod_crmf "id-mod-crmf"
-#define NID_id_mod_crmf 273
-#define OBJ_id_mod_crmf OBJ_id_pkix_mod,5L
-
-#define SN_id_mod_cmc "id-mod-cmc"
-#define NID_id_mod_cmc 274
-#define OBJ_id_mod_cmc OBJ_id_pkix_mod,6L
-
-#define SN_id_mod_kea_profile_88 "id-mod-kea-profile-88"
-#define NID_id_mod_kea_profile_88 275
-#define OBJ_id_mod_kea_profile_88 OBJ_id_pkix_mod,7L
-
-#define SN_id_mod_kea_profile_93 "id-mod-kea-profile-93"
-#define NID_id_mod_kea_profile_93 276
-#define OBJ_id_mod_kea_profile_93 OBJ_id_pkix_mod,8L
-
-#define SN_id_mod_cmp "id-mod-cmp"
-#define NID_id_mod_cmp 277
-#define OBJ_id_mod_cmp OBJ_id_pkix_mod,9L
-
-#define SN_id_mod_qualified_cert_88 "id-mod-qualified-cert-88"
-#define NID_id_mod_qualified_cert_88 278
-#define OBJ_id_mod_qualified_cert_88 OBJ_id_pkix_mod,10L
-
-#define SN_id_mod_qualified_cert_93 "id-mod-qualified-cert-93"
-#define NID_id_mod_qualified_cert_93 279
-#define OBJ_id_mod_qualified_cert_93 OBJ_id_pkix_mod,11L
-
-#define SN_id_mod_attribute_cert "id-mod-attribute-cert"
-#define NID_id_mod_attribute_cert 280
-#define OBJ_id_mod_attribute_cert OBJ_id_pkix_mod,12L
-
-#define SN_id_mod_timestamp_protocol "id-mod-timestamp-protocol"
-#define NID_id_mod_timestamp_protocol 281
-#define OBJ_id_mod_timestamp_protocol OBJ_id_pkix_mod,13L
-
-#define SN_id_mod_ocsp "id-mod-ocsp"
-#define NID_id_mod_ocsp 282
-#define OBJ_id_mod_ocsp OBJ_id_pkix_mod,14L
-
-#define SN_id_mod_dvcs "id-mod-dvcs"
-#define NID_id_mod_dvcs 283
-#define OBJ_id_mod_dvcs OBJ_id_pkix_mod,15L
-
-#define SN_id_mod_cmp2000 "id-mod-cmp2000"
-#define NID_id_mod_cmp2000 284
-#define OBJ_id_mod_cmp2000 OBJ_id_pkix_mod,16L
-
-#define SN_info_access "authorityInfoAccess"
-#define LN_info_access "Authority Information Access"
-#define NID_info_access 177
-#define OBJ_info_access OBJ_id_pe,1L
-
-#define SN_biometricInfo "biometricInfo"
-#define LN_biometricInfo "Biometric Info"
-#define NID_biometricInfo 285
-#define OBJ_biometricInfo OBJ_id_pe,2L
-
-#define SN_qcStatements "qcStatements"
-#define NID_qcStatements 286
-#define OBJ_qcStatements OBJ_id_pe,3L
-
-#define SN_ac_auditEntity "ac-auditEntity"
-#define NID_ac_auditEntity 287
-#define OBJ_ac_auditEntity OBJ_id_pe,4L
-
-#define SN_ac_targeting "ac-targeting"
-#define NID_ac_targeting 288
-#define OBJ_ac_targeting OBJ_id_pe,5L
-
-#define SN_aaControls "aaControls"
-#define NID_aaControls 289
-#define OBJ_aaControls OBJ_id_pe,6L
-
-#define SN_sbgp_ipAddrBlock "sbgp-ipAddrBlock"
-#define NID_sbgp_ipAddrBlock 290
-#define OBJ_sbgp_ipAddrBlock OBJ_id_pe,7L
-
-#define SN_sbgp_autonomousSysNum "sbgp-autonomousSysNum"
-#define NID_sbgp_autonomousSysNum 291
-#define OBJ_sbgp_autonomousSysNum OBJ_id_pe,8L
-
-#define SN_sbgp_routerIdentifier "sbgp-routerIdentifier"
-#define NID_sbgp_routerIdentifier 292
-#define OBJ_sbgp_routerIdentifier OBJ_id_pe,9L
-
-#define SN_ac_proxying "ac-proxying"
-#define NID_ac_proxying 397
-#define OBJ_ac_proxying OBJ_id_pe,10L
-
-#define SN_sinfo_access "subjectInfoAccess"
-#define LN_sinfo_access "Subject Information Access"
-#define NID_sinfo_access 398
-#define OBJ_sinfo_access OBJ_id_pe,11L
-
-#define SN_proxyCertInfo "proxyCertInfo"
-#define LN_proxyCertInfo "Proxy Certificate Information"
-#define NID_proxyCertInfo 663
-#define OBJ_proxyCertInfo OBJ_id_pe,14L
-
-#define SN_id_qt_cps "id-qt-cps"
-#define LN_id_qt_cps "Policy Qualifier CPS"
-#define NID_id_qt_cps 164
-#define OBJ_id_qt_cps OBJ_id_qt,1L
-
-#define SN_id_qt_unotice "id-qt-unotice"
-#define LN_id_qt_unotice "Policy Qualifier User Notice"
-#define NID_id_qt_unotice 165
-#define OBJ_id_qt_unotice OBJ_id_qt,2L
-
-#define SN_textNotice "textNotice"
-#define NID_textNotice 293
-#define OBJ_textNotice OBJ_id_qt,3L
-
-#define SN_server_auth "serverAuth"
-#define LN_server_auth "TLS Web Server Authentication"
-#define NID_server_auth 129
-#define OBJ_server_auth OBJ_id_kp,1L
-
-#define SN_client_auth "clientAuth"
-#define LN_client_auth "TLS Web Client Authentication"
-#define NID_client_auth 130
-#define OBJ_client_auth OBJ_id_kp,2L
-
-#define SN_code_sign "codeSigning"
-#define LN_code_sign "Code Signing"
-#define NID_code_sign 131
-#define OBJ_code_sign OBJ_id_kp,3L
-
-#define SN_email_protect "emailProtection"
-#define LN_email_protect "E-mail Protection"
-#define NID_email_protect 132
-#define OBJ_email_protect OBJ_id_kp,4L
-
-#define SN_ipsecEndSystem "ipsecEndSystem"
-#define LN_ipsecEndSystem "IPSec End System"
-#define NID_ipsecEndSystem 294
-#define OBJ_ipsecEndSystem OBJ_id_kp,5L
-
-#define SN_ipsecTunnel "ipsecTunnel"
-#define LN_ipsecTunnel "IPSec Tunnel"
-#define NID_ipsecTunnel 295
-#define OBJ_ipsecTunnel OBJ_id_kp,6L
-
-#define SN_ipsecUser "ipsecUser"
-#define LN_ipsecUser "IPSec User"
-#define NID_ipsecUser 296
-#define OBJ_ipsecUser OBJ_id_kp,7L
-
-#define SN_time_stamp "timeStamping"
-#define LN_time_stamp "Time Stamping"
-#define NID_time_stamp 133
-#define OBJ_time_stamp OBJ_id_kp,8L
-
-#define SN_OCSP_sign "OCSPSigning"
-#define LN_OCSP_sign "OCSP Signing"
-#define NID_OCSP_sign 180
-#define OBJ_OCSP_sign OBJ_id_kp,9L
-
-#define SN_dvcs "DVCS"
-#define LN_dvcs "dvcs"
-#define NID_dvcs 297
-#define OBJ_dvcs OBJ_id_kp,10L
-
-#define SN_id_it_caProtEncCert "id-it-caProtEncCert"
-#define NID_id_it_caProtEncCert 298
-#define OBJ_id_it_caProtEncCert OBJ_id_it,1L
-
-#define SN_id_it_signKeyPairTypes "id-it-signKeyPairTypes"
-#define NID_id_it_signKeyPairTypes 299
-#define OBJ_id_it_signKeyPairTypes OBJ_id_it,2L
-
-#define SN_id_it_encKeyPairTypes "id-it-encKeyPairTypes"
-#define NID_id_it_encKeyPairTypes 300
-#define OBJ_id_it_encKeyPairTypes OBJ_id_it,3L
-
-#define SN_id_it_preferredSymmAlg "id-it-preferredSymmAlg"
-#define NID_id_it_preferredSymmAlg 301
-#define OBJ_id_it_preferredSymmAlg OBJ_id_it,4L
-
-#define SN_id_it_caKeyUpdateInfo "id-it-caKeyUpdateInfo"
-#define NID_id_it_caKeyUpdateInfo 302
-#define OBJ_id_it_caKeyUpdateInfo OBJ_id_it,5L
-
-#define SN_id_it_currentCRL "id-it-currentCRL"
-#define NID_id_it_currentCRL 303
-#define OBJ_id_it_currentCRL OBJ_id_it,6L
-
-#define SN_id_it_unsupportedOIDs "id-it-unsupportedOIDs"
-#define NID_id_it_unsupportedOIDs 304
-#define OBJ_id_it_unsupportedOIDs OBJ_id_it,7L
-
-#define SN_id_it_subscriptionRequest "id-it-subscriptionRequest"
-#define NID_id_it_subscriptionRequest 305
-#define OBJ_id_it_subscriptionRequest OBJ_id_it,8L
-
-#define SN_id_it_subscriptionResponse "id-it-subscriptionResponse"
-#define NID_id_it_subscriptionResponse 306
-#define OBJ_id_it_subscriptionResponse OBJ_id_it,9L
-
-#define SN_id_it_keyPairParamReq "id-it-keyPairParamReq"
-#define NID_id_it_keyPairParamReq 307
-#define OBJ_id_it_keyPairParamReq OBJ_id_it,10L
-
-#define SN_id_it_keyPairParamRep "id-it-keyPairParamRep"
-#define NID_id_it_keyPairParamRep 308
-#define OBJ_id_it_keyPairParamRep OBJ_id_it,11L
-
-#define SN_id_it_revPassphrase "id-it-revPassphrase"
-#define NID_id_it_revPassphrase 309
-#define OBJ_id_it_revPassphrase OBJ_id_it,12L
-
-#define SN_id_it_implicitConfirm "id-it-implicitConfirm"
-#define NID_id_it_implicitConfirm 310
-#define OBJ_id_it_implicitConfirm OBJ_id_it,13L
-
-#define SN_id_it_confirmWaitTime "id-it-confirmWaitTime"
-#define NID_id_it_confirmWaitTime 311
-#define OBJ_id_it_confirmWaitTime OBJ_id_it,14L
-
-#define SN_id_it_origPKIMessage "id-it-origPKIMessage"
-#define NID_id_it_origPKIMessage 312
-#define OBJ_id_it_origPKIMessage OBJ_id_it,15L
-
-#define SN_id_it_suppLangTags "id-it-suppLangTags"
-#define NID_id_it_suppLangTags 784
-#define OBJ_id_it_suppLangTags OBJ_id_it,16L
-
-#define SN_id_regCtrl "id-regCtrl"
-#define NID_id_regCtrl 313
-#define OBJ_id_regCtrl OBJ_id_pkip,1L
-
-#define SN_id_regInfo "id-regInfo"
-#define NID_id_regInfo 314
-#define OBJ_id_regInfo OBJ_id_pkip,2L
-
-#define SN_id_regCtrl_regToken "id-regCtrl-regToken"
-#define NID_id_regCtrl_regToken 315
-#define OBJ_id_regCtrl_regToken OBJ_id_regCtrl,1L
-
-#define SN_id_regCtrl_authenticator "id-regCtrl-authenticator"
-#define NID_id_regCtrl_authenticator 316
-#define OBJ_id_regCtrl_authenticator OBJ_id_regCtrl,2L
-
-#define SN_id_regCtrl_pkiPublicationInfo "id-regCtrl-pkiPublicationInfo"
-#define NID_id_regCtrl_pkiPublicationInfo 317
-#define OBJ_id_regCtrl_pkiPublicationInfo OBJ_id_regCtrl,3L
-
-#define SN_id_regCtrl_pkiArchiveOptions "id-regCtrl-pkiArchiveOptions"
-#define NID_id_regCtrl_pkiArchiveOptions 318
-#define OBJ_id_regCtrl_pkiArchiveOptions OBJ_id_regCtrl,4L
-
-#define SN_id_regCtrl_oldCertID "id-regCtrl-oldCertID"
-#define NID_id_regCtrl_oldCertID 319
-#define OBJ_id_regCtrl_oldCertID OBJ_id_regCtrl,5L
-
-#define SN_id_regCtrl_protocolEncrKey "id-regCtrl-protocolEncrKey"
-#define NID_id_regCtrl_protocolEncrKey 320
-#define OBJ_id_regCtrl_protocolEncrKey OBJ_id_regCtrl,6L
-
-#define SN_id_regInfo_utf8Pairs "id-regInfo-utf8Pairs"
-#define NID_id_regInfo_utf8Pairs 321
-#define OBJ_id_regInfo_utf8Pairs OBJ_id_regInfo,1L
-
-#define SN_id_regInfo_certReq "id-regInfo-certReq"
-#define NID_id_regInfo_certReq 322
-#define OBJ_id_regInfo_certReq OBJ_id_regInfo,2L
-
-#define SN_id_alg_des40 "id-alg-des40"
-#define NID_id_alg_des40 323
-#define OBJ_id_alg_des40 OBJ_id_alg,1L
-
-#define SN_id_alg_noSignature "id-alg-noSignature"
-#define NID_id_alg_noSignature 324
-#define OBJ_id_alg_noSignature OBJ_id_alg,2L
-
-#define SN_id_alg_dh_sig_hmac_sha1 "id-alg-dh-sig-hmac-sha1"
-#define NID_id_alg_dh_sig_hmac_sha1 325
-#define OBJ_id_alg_dh_sig_hmac_sha1 OBJ_id_alg,3L
-
-#define SN_id_alg_dh_pop "id-alg-dh-pop"
-#define NID_id_alg_dh_pop 326
-#define OBJ_id_alg_dh_pop OBJ_id_alg,4L
-
-#define SN_id_cmc_statusInfo "id-cmc-statusInfo"
-#define NID_id_cmc_statusInfo 327
-#define OBJ_id_cmc_statusInfo OBJ_id_cmc,1L
-
-#define SN_id_cmc_identification "id-cmc-identification"
-#define NID_id_cmc_identification 328
-#define OBJ_id_cmc_identification OBJ_id_cmc,2L
-
-#define SN_id_cmc_identityProof "id-cmc-identityProof"
-#define NID_id_cmc_identityProof 329
-#define OBJ_id_cmc_identityProof OBJ_id_cmc,3L
-
-#define SN_id_cmc_dataReturn "id-cmc-dataReturn"
-#define NID_id_cmc_dataReturn 330
-#define OBJ_id_cmc_dataReturn OBJ_id_cmc,4L
-
-#define SN_id_cmc_transactionId "id-cmc-transactionId"
-#define NID_id_cmc_transactionId 331
-#define OBJ_id_cmc_transactionId OBJ_id_cmc,5L
-
-#define SN_id_cmc_senderNonce "id-cmc-senderNonce"
-#define NID_id_cmc_senderNonce 332
-#define OBJ_id_cmc_senderNonce OBJ_id_cmc,6L
-
-#define SN_id_cmc_recipientNonce "id-cmc-recipientNonce"
-#define NID_id_cmc_recipientNonce 333
-#define OBJ_id_cmc_recipientNonce OBJ_id_cmc,7L
-
-#define SN_id_cmc_addExtensions "id-cmc-addExtensions"
-#define NID_id_cmc_addExtensions 334
-#define OBJ_id_cmc_addExtensions OBJ_id_cmc,8L
-
-#define SN_id_cmc_encryptedPOP "id-cmc-encryptedPOP"
-#define NID_id_cmc_encryptedPOP 335
-#define OBJ_id_cmc_encryptedPOP OBJ_id_cmc,9L
-
-#define SN_id_cmc_decryptedPOP "id-cmc-decryptedPOP"
-#define NID_id_cmc_decryptedPOP 336
-#define OBJ_id_cmc_decryptedPOP OBJ_id_cmc,10L
-
-#define SN_id_cmc_lraPOPWitness "id-cmc-lraPOPWitness"
-#define NID_id_cmc_lraPOPWitness 337
-#define OBJ_id_cmc_lraPOPWitness OBJ_id_cmc,11L
-
-#define SN_id_cmc_getCert "id-cmc-getCert"
-#define NID_id_cmc_getCert 338
-#define OBJ_id_cmc_getCert OBJ_id_cmc,15L
-
-#define SN_id_cmc_getCRL "id-cmc-getCRL"
-#define NID_id_cmc_getCRL 339
-#define OBJ_id_cmc_getCRL OBJ_id_cmc,16L
-
-#define SN_id_cmc_revokeRequest "id-cmc-revokeRequest"
-#define NID_id_cmc_revokeRequest 340
-#define OBJ_id_cmc_revokeRequest OBJ_id_cmc,17L
-
-#define SN_id_cmc_regInfo "id-cmc-regInfo"
-#define NID_id_cmc_regInfo 341
-#define OBJ_id_cmc_regInfo OBJ_id_cmc,18L
-
-#define SN_id_cmc_responseInfo "id-cmc-responseInfo"
-#define NID_id_cmc_responseInfo 342
-#define OBJ_id_cmc_responseInfo OBJ_id_cmc,19L
-
-#define SN_id_cmc_queryPending "id-cmc-queryPending"
-#define NID_id_cmc_queryPending 343
-#define OBJ_id_cmc_queryPending OBJ_id_cmc,21L
-
-#define SN_id_cmc_popLinkRandom "id-cmc-popLinkRandom"
-#define NID_id_cmc_popLinkRandom 344
-#define OBJ_id_cmc_popLinkRandom OBJ_id_cmc,22L
-
-#define SN_id_cmc_popLinkWitness "id-cmc-popLinkWitness"
-#define NID_id_cmc_popLinkWitness 345
-#define OBJ_id_cmc_popLinkWitness OBJ_id_cmc,23L
-
-#define SN_id_cmc_confirmCertAcceptance "id-cmc-confirmCertAcceptance"
-#define NID_id_cmc_confirmCertAcceptance 346
-#define OBJ_id_cmc_confirmCertAcceptance OBJ_id_cmc,24L
-
-#define SN_id_on_personalData "id-on-personalData"
-#define NID_id_on_personalData 347
-#define OBJ_id_on_personalData OBJ_id_on,1L
-
-#define SN_id_on_permanentIdentifier "id-on-permanentIdentifier"
-#define LN_id_on_permanentIdentifier "Permanent Identifier"
-#define NID_id_on_permanentIdentifier 858
-#define OBJ_id_on_permanentIdentifier OBJ_id_on,3L
-
-#define SN_id_pda_dateOfBirth "id-pda-dateOfBirth"
-#define NID_id_pda_dateOfBirth 348
-#define OBJ_id_pda_dateOfBirth OBJ_id_pda,1L
-
-#define SN_id_pda_placeOfBirth "id-pda-placeOfBirth"
-#define NID_id_pda_placeOfBirth 349
-#define OBJ_id_pda_placeOfBirth OBJ_id_pda,2L
-
-#define SN_id_pda_gender "id-pda-gender"
-#define NID_id_pda_gender 351
-#define OBJ_id_pda_gender OBJ_id_pda,3L
-
-#define SN_id_pda_countryOfCitizenship "id-pda-countryOfCitizenship"
-#define NID_id_pda_countryOfCitizenship 352
-#define OBJ_id_pda_countryOfCitizenship OBJ_id_pda,4L
-
-#define SN_id_pda_countryOfResidence "id-pda-countryOfResidence"
-#define NID_id_pda_countryOfResidence 353
-#define OBJ_id_pda_countryOfResidence OBJ_id_pda,5L
-
-#define SN_id_aca_authenticationInfo "id-aca-authenticationInfo"
-#define NID_id_aca_authenticationInfo 354
-#define OBJ_id_aca_authenticationInfo OBJ_id_aca,1L
-
-#define SN_id_aca_accessIdentity "id-aca-accessIdentity"
-#define NID_id_aca_accessIdentity 355
-#define OBJ_id_aca_accessIdentity OBJ_id_aca,2L
-
-#define SN_id_aca_chargingIdentity "id-aca-chargingIdentity"
-#define NID_id_aca_chargingIdentity 356
-#define OBJ_id_aca_chargingIdentity OBJ_id_aca,3L
-
-#define SN_id_aca_group "id-aca-group"
-#define NID_id_aca_group 357
-#define OBJ_id_aca_group OBJ_id_aca,4L
-
-#define SN_id_aca_role "id-aca-role"
-#define NID_id_aca_role 358
-#define OBJ_id_aca_role OBJ_id_aca,5L
-
-#define SN_id_aca_encAttrs "id-aca-encAttrs"
-#define NID_id_aca_encAttrs 399
-#define OBJ_id_aca_encAttrs OBJ_id_aca,6L
-
-#define SN_id_qcs_pkixQCSyntax_v1 "id-qcs-pkixQCSyntax-v1"
-#define NID_id_qcs_pkixQCSyntax_v1 359
-#define OBJ_id_qcs_pkixQCSyntax_v1 OBJ_id_qcs,1L
-
-#define SN_id_cct_crs "id-cct-crs"
-#define NID_id_cct_crs 360
-#define OBJ_id_cct_crs OBJ_id_cct,1L
-
-#define SN_id_cct_PKIData "id-cct-PKIData"
-#define NID_id_cct_PKIData 361
-#define OBJ_id_cct_PKIData OBJ_id_cct,2L
-
-#define SN_id_cct_PKIResponse "id-cct-PKIResponse"
-#define NID_id_cct_PKIResponse 362
-#define OBJ_id_cct_PKIResponse OBJ_id_cct,3L
-
-#define SN_id_ppl_anyLanguage "id-ppl-anyLanguage"
-#define LN_id_ppl_anyLanguage "Any language"
-#define NID_id_ppl_anyLanguage 664
-#define OBJ_id_ppl_anyLanguage OBJ_id_ppl,0L
-
-#define SN_id_ppl_inheritAll "id-ppl-inheritAll"
-#define LN_id_ppl_inheritAll "Inherit all"
-#define NID_id_ppl_inheritAll 665
-#define OBJ_id_ppl_inheritAll OBJ_id_ppl,1L
-
-#define SN_Independent "id-ppl-independent"
-#define LN_Independent "Independent"
-#define NID_Independent 667
-#define OBJ_Independent OBJ_id_ppl,2L
-
-#define SN_ad_OCSP "OCSP"
-#define LN_ad_OCSP "OCSP"
-#define NID_ad_OCSP 178
-#define OBJ_ad_OCSP OBJ_id_ad,1L
-
-#define SN_ad_ca_issuers "caIssuers"
-#define LN_ad_ca_issuers "CA Issuers"
-#define NID_ad_ca_issuers 179
-#define OBJ_ad_ca_issuers OBJ_id_ad,2L
-
-#define SN_ad_timeStamping "ad_timestamping"
-#define LN_ad_timeStamping "AD Time Stamping"
-#define NID_ad_timeStamping 363
-#define OBJ_ad_timeStamping OBJ_id_ad,3L
-
-#define SN_ad_dvcs "AD_DVCS"
-#define LN_ad_dvcs "ad dvcs"
-#define NID_ad_dvcs 364
-#define OBJ_ad_dvcs OBJ_id_ad,4L
-
-#define SN_caRepository "caRepository"
-#define LN_caRepository "CA Repository"
-#define NID_caRepository 785
-#define OBJ_caRepository OBJ_id_ad,5L
-
-#define OBJ_id_pkix_OCSP OBJ_ad_OCSP
-
-#define SN_id_pkix_OCSP_basic "basicOCSPResponse"
-#define LN_id_pkix_OCSP_basic "Basic OCSP Response"
-#define NID_id_pkix_OCSP_basic 365
-#define OBJ_id_pkix_OCSP_basic OBJ_id_pkix_OCSP,1L
-
-#define SN_id_pkix_OCSP_Nonce "Nonce"
-#define LN_id_pkix_OCSP_Nonce "OCSP Nonce"
-#define NID_id_pkix_OCSP_Nonce 366
-#define OBJ_id_pkix_OCSP_Nonce OBJ_id_pkix_OCSP,2L
-
-#define SN_id_pkix_OCSP_CrlID "CrlID"
-#define LN_id_pkix_OCSP_CrlID "OCSP CRL ID"
-#define NID_id_pkix_OCSP_CrlID 367
-#define OBJ_id_pkix_OCSP_CrlID OBJ_id_pkix_OCSP,3L
-
-#define SN_id_pkix_OCSP_acceptableResponses "acceptableResponses"
-#define LN_id_pkix_OCSP_acceptableResponses "Acceptable OCSP Responses"
-#define NID_id_pkix_OCSP_acceptableResponses 368
-#define OBJ_id_pkix_OCSP_acceptableResponses OBJ_id_pkix_OCSP,4L
-
-#define SN_id_pkix_OCSP_noCheck "noCheck"
-#define LN_id_pkix_OCSP_noCheck "OCSP No Check"
-#define NID_id_pkix_OCSP_noCheck 369
-#define OBJ_id_pkix_OCSP_noCheck OBJ_id_pkix_OCSP,5L
-
-#define SN_id_pkix_OCSP_archiveCutoff "archiveCutoff"
-#define LN_id_pkix_OCSP_archiveCutoff "OCSP Archive Cutoff"
-#define NID_id_pkix_OCSP_archiveCutoff 370
-#define OBJ_id_pkix_OCSP_archiveCutoff OBJ_id_pkix_OCSP,6L
-
-#define SN_id_pkix_OCSP_serviceLocator "serviceLocator"
-#define LN_id_pkix_OCSP_serviceLocator "OCSP Service Locator"
-#define NID_id_pkix_OCSP_serviceLocator 371
-#define OBJ_id_pkix_OCSP_serviceLocator OBJ_id_pkix_OCSP,7L
-
-#define SN_id_pkix_OCSP_extendedStatus "extendedStatus"
-#define LN_id_pkix_OCSP_extendedStatus "Extended OCSP Status"
-#define NID_id_pkix_OCSP_extendedStatus 372
-#define OBJ_id_pkix_OCSP_extendedStatus OBJ_id_pkix_OCSP,8L
-
-#define SN_id_pkix_OCSP_valid "valid"
-#define NID_id_pkix_OCSP_valid 373
-#define OBJ_id_pkix_OCSP_valid OBJ_id_pkix_OCSP,9L
-
-#define SN_id_pkix_OCSP_path "path"
-#define NID_id_pkix_OCSP_path 374
-#define OBJ_id_pkix_OCSP_path OBJ_id_pkix_OCSP,10L
-
-#define SN_id_pkix_OCSP_trustRoot "trustRoot"
-#define LN_id_pkix_OCSP_trustRoot "Trust Root"
-#define NID_id_pkix_OCSP_trustRoot 375
-#define OBJ_id_pkix_OCSP_trustRoot OBJ_id_pkix_OCSP,11L
-
-#define SN_algorithm "algorithm"
-#define LN_algorithm "algorithm"
-#define NID_algorithm 376
-#define OBJ_algorithm 1L,3L,14L,3L,2L
-
-#define SN_md5WithRSA "RSA-NP-MD5"
-#define LN_md5WithRSA "md5WithRSA"
-#define NID_md5WithRSA 104
-#define OBJ_md5WithRSA OBJ_algorithm,3L
-
-#define SN_des_ecb "DES-ECB"
-#define LN_des_ecb "des-ecb"
-#define NID_des_ecb 29
-#define OBJ_des_ecb OBJ_algorithm,6L
-
-#define SN_des_cbc "DES-CBC"
-#define LN_des_cbc "des-cbc"
-#define NID_des_cbc 31
-#define OBJ_des_cbc OBJ_algorithm,7L
-
-#define SN_des_ofb64 "DES-OFB"
-#define LN_des_ofb64 "des-ofb"
-#define NID_des_ofb64 45
-#define OBJ_des_ofb64 OBJ_algorithm,8L
-
-#define SN_des_cfb64 "DES-CFB"
-#define LN_des_cfb64 "des-cfb"
-#define NID_des_cfb64 30
-#define OBJ_des_cfb64 OBJ_algorithm,9L
-
-#define SN_rsaSignature "rsaSignature"
-#define NID_rsaSignature 377
-#define OBJ_rsaSignature OBJ_algorithm,11L
-
-#define SN_dsa_2 "DSA-old"
-#define LN_dsa_2 "dsaEncryption-old"
-#define NID_dsa_2 67
-#define OBJ_dsa_2 OBJ_algorithm,12L
-
-#define SN_dsaWithSHA "DSA-SHA"
-#define LN_dsaWithSHA "dsaWithSHA"
-#define NID_dsaWithSHA 66
-#define OBJ_dsaWithSHA OBJ_algorithm,13L
-
-#define SN_shaWithRSAEncryption "RSA-SHA"
-#define LN_shaWithRSAEncryption "shaWithRSAEncryption"
-#define NID_shaWithRSAEncryption 42
-#define OBJ_shaWithRSAEncryption OBJ_algorithm,15L
-
-#define SN_des_ede_ecb "DES-EDE"
-#define LN_des_ede_ecb "des-ede"
-#define NID_des_ede_ecb 32
-#define OBJ_des_ede_ecb OBJ_algorithm,17L
-
-#define SN_des_ede3_ecb "DES-EDE3"
-#define LN_des_ede3_ecb "des-ede3"
-#define NID_des_ede3_ecb 33
-
-#define SN_des_ede_cbc "DES-EDE-CBC"
-#define LN_des_ede_cbc "des-ede-cbc"
-#define NID_des_ede_cbc 43
-
-#define SN_des_ede_cfb64 "DES-EDE-CFB"
-#define LN_des_ede_cfb64 "des-ede-cfb"
-#define NID_des_ede_cfb64 60
-
-#define SN_des_ede3_cfb64 "DES-EDE3-CFB"
-#define LN_des_ede3_cfb64 "des-ede3-cfb"
-#define NID_des_ede3_cfb64 61
-
-#define SN_des_ede_ofb64 "DES-EDE-OFB"
-#define LN_des_ede_ofb64 "des-ede-ofb"
-#define NID_des_ede_ofb64 62
-
-#define SN_des_ede3_ofb64 "DES-EDE3-OFB"
-#define LN_des_ede3_ofb64 "des-ede3-ofb"
-#define NID_des_ede3_ofb64 63
-
-#define SN_desx_cbc "DESX-CBC"
-#define LN_desx_cbc "desx-cbc"
-#define NID_desx_cbc 80
-
-#define SN_sha "SHA"
-#define LN_sha "sha"
-#define NID_sha 41
-#define OBJ_sha OBJ_algorithm,18L
-
-#define SN_sha1 "SHA1"
-#define LN_sha1 "sha1"
-#define NID_sha1 64
-#define OBJ_sha1 OBJ_algorithm,26L
-
-#define SN_dsaWithSHA1_2 "DSA-SHA1-old"
-#define LN_dsaWithSHA1_2 "dsaWithSHA1-old"
-#define NID_dsaWithSHA1_2 70
-#define OBJ_dsaWithSHA1_2 OBJ_algorithm,27L
-
-#define SN_sha1WithRSA "RSA-SHA1-2"
-#define LN_sha1WithRSA "sha1WithRSA"
-#define NID_sha1WithRSA 115
-#define OBJ_sha1WithRSA OBJ_algorithm,29L
-
-#define SN_ripemd160 "RIPEMD160"
-#define LN_ripemd160 "ripemd160"
-#define NID_ripemd160 117
-#define OBJ_ripemd160 1L,3L,36L,3L,2L,1L
-
-#define SN_ripemd160WithRSA "RSA-RIPEMD160"
-#define LN_ripemd160WithRSA "ripemd160WithRSA"
-#define NID_ripemd160WithRSA 119
-#define OBJ_ripemd160WithRSA 1L,3L,36L,3L,3L,1L,2L
-
-#define SN_sxnet "SXNetID"
-#define LN_sxnet "Strong Extranet ID"
-#define NID_sxnet 143
-#define OBJ_sxnet 1L,3L,101L,1L,4L,1L
-
-#define SN_X500 "X500"
-#define LN_X500 "directory services (X.500)"
-#define NID_X500 11
-#define OBJ_X500 2L,5L
-
-#define SN_X509 "X509"
-#define NID_X509 12
-#define OBJ_X509 OBJ_X500,4L
-
-#define SN_commonName "CN"
-#define LN_commonName "commonName"
-#define NID_commonName 13
-#define OBJ_commonName OBJ_X509,3L
-
-#define SN_surname "SN"
-#define LN_surname "surname"
-#define NID_surname 100
-#define OBJ_surname OBJ_X509,4L
-
-#define LN_serialNumber "serialNumber"
-#define NID_serialNumber 105
-#define OBJ_serialNumber OBJ_X509,5L
-
-#define SN_countryName "C"
-#define LN_countryName "countryName"
-#define NID_countryName 14
-#define OBJ_countryName OBJ_X509,6L
-
-#define SN_localityName "L"
-#define LN_localityName "localityName"
-#define NID_localityName 15
-#define OBJ_localityName OBJ_X509,7L
-
-#define SN_stateOrProvinceName "ST"
-#define LN_stateOrProvinceName "stateOrProvinceName"
-#define NID_stateOrProvinceName 16
-#define OBJ_stateOrProvinceName OBJ_X509,8L
-
-#define SN_streetAddress "street"
-#define LN_streetAddress "streetAddress"
-#define NID_streetAddress 660
-#define OBJ_streetAddress OBJ_X509,9L
-
-#define SN_organizationName "O"
-#define LN_organizationName "organizationName"
-#define NID_organizationName 17
-#define OBJ_organizationName OBJ_X509,10L
-
-#define SN_organizationalUnitName "OU"
-#define LN_organizationalUnitName "organizationalUnitName"
-#define NID_organizationalUnitName 18
-#define OBJ_organizationalUnitName OBJ_X509,11L
-
-#define SN_title "title"
-#define LN_title "title"
-#define NID_title 106
-#define OBJ_title OBJ_X509,12L
-
-#define LN_description "description"
-#define NID_description 107
-#define OBJ_description OBJ_X509,13L
-
-#define LN_searchGuide "searchGuide"
-#define NID_searchGuide 859
-#define OBJ_searchGuide OBJ_X509,14L
-
-#define LN_businessCategory "businessCategory"
-#define NID_businessCategory 860
-#define OBJ_businessCategory OBJ_X509,15L
-
-#define LN_postalAddress "postalAddress"
-#define NID_postalAddress 861
-#define OBJ_postalAddress OBJ_X509,16L
-
-#define LN_postalCode "postalCode"
-#define NID_postalCode 661
-#define OBJ_postalCode OBJ_X509,17L
-
-#define LN_postOfficeBox "postOfficeBox"
-#define NID_postOfficeBox 862
-#define OBJ_postOfficeBox OBJ_X509,18L
-
-#define LN_physicalDeliveryOfficeName "physicalDeliveryOfficeName"
-#define NID_physicalDeliveryOfficeName 863
-#define OBJ_physicalDeliveryOfficeName OBJ_X509,19L
-
-#define LN_telephoneNumber "telephoneNumber"
-#define NID_telephoneNumber 864
-#define OBJ_telephoneNumber OBJ_X509,20L
-
-#define LN_telexNumber "telexNumber"
-#define NID_telexNumber 865
-#define OBJ_telexNumber OBJ_X509,21L
-
-#define LN_teletexTerminalIdentifier "teletexTerminalIdentifier"
-#define NID_teletexTerminalIdentifier 866
-#define OBJ_teletexTerminalIdentifier OBJ_X509,22L
-
-#define LN_facsimileTelephoneNumber "facsimileTelephoneNumber"
-#define NID_facsimileTelephoneNumber 867
-#define OBJ_facsimileTelephoneNumber OBJ_X509,23L
-
-#define LN_x121Address "x121Address"
-#define NID_x121Address 868
-#define OBJ_x121Address OBJ_X509,24L
-
-#define LN_internationaliSDNNumber "internationaliSDNNumber"
-#define NID_internationaliSDNNumber 869
-#define OBJ_internationaliSDNNumber OBJ_X509,25L
-
-#define LN_registeredAddress "registeredAddress"
-#define NID_registeredAddress 870
-#define OBJ_registeredAddress OBJ_X509,26L
-
-#define LN_destinationIndicator "destinationIndicator"
-#define NID_destinationIndicator 871
-#define OBJ_destinationIndicator OBJ_X509,27L
-
-#define LN_preferredDeliveryMethod "preferredDeliveryMethod"
-#define NID_preferredDeliveryMethod 872
-#define OBJ_preferredDeliveryMethod OBJ_X509,28L
-
-#define LN_presentationAddress "presentationAddress"
-#define NID_presentationAddress 873
-#define OBJ_presentationAddress OBJ_X509,29L
-
-#define LN_supportedApplicationContext "supportedApplicationContext"
-#define NID_supportedApplicationContext 874
-#define OBJ_supportedApplicationContext OBJ_X509,30L
-
-#define SN_member "member"
-#define NID_member 875
-#define OBJ_member OBJ_X509,31L
-
-#define SN_owner "owner"
-#define NID_owner 876
-#define OBJ_owner OBJ_X509,32L
-
-#define LN_roleOccupant "roleOccupant"
-#define NID_roleOccupant 877
-#define OBJ_roleOccupant OBJ_X509,33L
-
-#define SN_seeAlso "seeAlso"
-#define NID_seeAlso 878
-#define OBJ_seeAlso OBJ_X509,34L
-
-#define LN_userPassword "userPassword"
-#define NID_userPassword 879
-#define OBJ_userPassword OBJ_X509,35L
-
-#define LN_userCertificate "userCertificate"
-#define NID_userCertificate 880
-#define OBJ_userCertificate OBJ_X509,36L
-
-#define LN_cACertificate "cACertificate"
-#define NID_cACertificate 881
-#define OBJ_cACertificate OBJ_X509,37L
-
-#define LN_authorityRevocationList "authorityRevocationList"
-#define NID_authorityRevocationList 882
-#define OBJ_authorityRevocationList OBJ_X509,38L
-
-#define LN_certificateRevocationList "certificateRevocationList"
-#define NID_certificateRevocationList 883
-#define OBJ_certificateRevocationList OBJ_X509,39L
-
-#define LN_crossCertificatePair "crossCertificatePair"
-#define NID_crossCertificatePair 884
-#define OBJ_crossCertificatePair OBJ_X509,40L
-
-#define SN_name "name"
-#define LN_name "name"
-#define NID_name 173
-#define OBJ_name OBJ_X509,41L
-
-#define SN_givenName "GN"
-#define LN_givenName "givenName"
-#define NID_givenName 99
-#define OBJ_givenName OBJ_X509,42L
-
-#define SN_initials "initials"
-#define LN_initials "initials"
-#define NID_initials 101
-#define OBJ_initials OBJ_X509,43L
-
-#define LN_generationQualifier "generationQualifier"
-#define NID_generationQualifier 509
-#define OBJ_generationQualifier OBJ_X509,44L
-
-#define LN_x500UniqueIdentifier "x500UniqueIdentifier"
-#define NID_x500UniqueIdentifier 503
-#define OBJ_x500UniqueIdentifier OBJ_X509,45L
-
-#define SN_dnQualifier "dnQualifier"
-#define LN_dnQualifier "dnQualifier"
-#define NID_dnQualifier 174
-#define OBJ_dnQualifier OBJ_X509,46L
-
-#define LN_enhancedSearchGuide "enhancedSearchGuide"
-#define NID_enhancedSearchGuide 885
-#define OBJ_enhancedSearchGuide OBJ_X509,47L
-
-#define LN_protocolInformation "protocolInformation"
-#define NID_protocolInformation 886
-#define OBJ_protocolInformation OBJ_X509,48L
-
-#define LN_distinguishedName "distinguishedName"
-#define NID_distinguishedName 887
-#define OBJ_distinguishedName OBJ_X509,49L
-
-#define LN_uniqueMember "uniqueMember"
-#define NID_uniqueMember 888
-#define OBJ_uniqueMember OBJ_X509,50L
-
-#define LN_houseIdentifier "houseIdentifier"
-#define NID_houseIdentifier 889
-#define OBJ_houseIdentifier OBJ_X509,51L
-
-#define LN_supportedAlgorithms "supportedAlgorithms"
-#define NID_supportedAlgorithms 890
-#define OBJ_supportedAlgorithms OBJ_X509,52L
-
-#define LN_deltaRevocationList "deltaRevocationList"
-#define NID_deltaRevocationList 891
-#define OBJ_deltaRevocationList OBJ_X509,53L
-
-#define SN_dmdName "dmdName"
-#define NID_dmdName 892
-#define OBJ_dmdName OBJ_X509,54L
-
-#define LN_pseudonym "pseudonym"
-#define NID_pseudonym 510
-#define OBJ_pseudonym OBJ_X509,65L
-
-#define SN_role "role"
-#define LN_role "role"
-#define NID_role 400
-#define OBJ_role OBJ_X509,72L
-
-#define SN_X500algorithms "X500algorithms"
-#define LN_X500algorithms "directory services - algorithms"
-#define NID_X500algorithms 378
-#define OBJ_X500algorithms OBJ_X500,8L
-
-#define SN_rsa "RSA"
-#define LN_rsa "rsa"
-#define NID_rsa 19
-#define OBJ_rsa OBJ_X500algorithms,1L,1L
-
-#define SN_mdc2WithRSA "RSA-MDC2"
-#define LN_mdc2WithRSA "mdc2WithRSA"
-#define NID_mdc2WithRSA 96
-#define OBJ_mdc2WithRSA OBJ_X500algorithms,3L,100L
-
-#define SN_mdc2 "MDC2"
-#define LN_mdc2 "mdc2"
-#define NID_mdc2 95
-#define OBJ_mdc2 OBJ_X500algorithms,3L,101L
-
-#define SN_id_ce "id-ce"
-#define NID_id_ce 81
-#define OBJ_id_ce OBJ_X500,29L
-
-#define SN_subject_directory_attributes "subjectDirectoryAttributes"
-#define LN_subject_directory_attributes "X509v3 Subject Directory Attributes"
-#define NID_subject_directory_attributes 769
-#define OBJ_subject_directory_attributes OBJ_id_ce,9L
-
-#define SN_subject_key_identifier "subjectKeyIdentifier"
-#define LN_subject_key_identifier "X509v3 Subject Key Identifier"
-#define NID_subject_key_identifier 82
-#define OBJ_subject_key_identifier OBJ_id_ce,14L
-
-#define SN_key_usage "keyUsage"
-#define LN_key_usage "X509v3 Key Usage"
-#define NID_key_usage 83
-#define OBJ_key_usage OBJ_id_ce,15L
-
-#define SN_private_key_usage_period "privateKeyUsagePeriod"
-#define LN_private_key_usage_period "X509v3 Private Key Usage Period"
-#define NID_private_key_usage_period 84
-#define OBJ_private_key_usage_period OBJ_id_ce,16L
-
-#define SN_subject_alt_name "subjectAltName"
-#define LN_subject_alt_name "X509v3 Subject Alternative Name"
-#define NID_subject_alt_name 85
-#define OBJ_subject_alt_name OBJ_id_ce,17L
-
-#define SN_issuer_alt_name "issuerAltName"
-#define LN_issuer_alt_name "X509v3 Issuer Alternative Name"
-#define NID_issuer_alt_name 86
-#define OBJ_issuer_alt_name OBJ_id_ce,18L
-
-#define SN_basic_constraints "basicConstraints"
-#define LN_basic_constraints "X509v3 Basic Constraints"
-#define NID_basic_constraints 87
-#define OBJ_basic_constraints OBJ_id_ce,19L
-
-#define SN_crl_number "crlNumber"
-#define LN_crl_number "X509v3 CRL Number"
-#define NID_crl_number 88
-#define OBJ_crl_number OBJ_id_ce,20L
-
-#define SN_crl_reason "CRLReason"
-#define LN_crl_reason "X509v3 CRL Reason Code"
-#define NID_crl_reason 141
-#define OBJ_crl_reason OBJ_id_ce,21L
-
-#define SN_invalidity_date "invalidityDate"
-#define LN_invalidity_date "Invalidity Date"
-#define NID_invalidity_date 142
-#define OBJ_invalidity_date OBJ_id_ce,24L
-
-#define SN_delta_crl "deltaCRL"
-#define LN_delta_crl "X509v3 Delta CRL Indicator"
-#define NID_delta_crl 140
-#define OBJ_delta_crl OBJ_id_ce,27L
-
-#define SN_issuing_distribution_point "issuingDistributionPoint"
-#define LN_issuing_distribution_point "X509v3 Issuing Distribution Point"
-#define NID_issuing_distribution_point 770
-#define OBJ_issuing_distribution_point OBJ_id_ce,28L
-
-#define SN_certificate_issuer "certificateIssuer"
-#define LN_certificate_issuer "X509v3 Certificate Issuer"
-#define NID_certificate_issuer 771
-#define OBJ_certificate_issuer OBJ_id_ce,29L
-
-#define SN_name_constraints "nameConstraints"
-#define LN_name_constraints "X509v3 Name Constraints"
-#define NID_name_constraints 666
-#define OBJ_name_constraints OBJ_id_ce,30L
-
-#define SN_crl_distribution_points "crlDistributionPoints"
-#define LN_crl_distribution_points "X509v3 CRL Distribution Points"
-#define NID_crl_distribution_points 103
-#define OBJ_crl_distribution_points OBJ_id_ce,31L
-
-#define SN_certificate_policies "certificatePolicies"
-#define LN_certificate_policies "X509v3 Certificate Policies"
-#define NID_certificate_policies 89
-#define OBJ_certificate_policies OBJ_id_ce,32L
-
-#define SN_any_policy "anyPolicy"
-#define LN_any_policy "X509v3 Any Policy"
-#define NID_any_policy 746
-#define OBJ_any_policy OBJ_certificate_policies,0L
-
-#define SN_policy_mappings "policyMappings"
-#define LN_policy_mappings "X509v3 Policy Mappings"
-#define NID_policy_mappings 747
-#define OBJ_policy_mappings OBJ_id_ce,33L
-
-#define SN_authority_key_identifier "authorityKeyIdentifier"
-#define LN_authority_key_identifier "X509v3 Authority Key Identifier"
-#define NID_authority_key_identifier 90
-#define OBJ_authority_key_identifier OBJ_id_ce,35L
-
-#define SN_policy_constraints "policyConstraints"
-#define LN_policy_constraints "X509v3 Policy Constraints"
-#define NID_policy_constraints 401
-#define OBJ_policy_constraints OBJ_id_ce,36L
-
-#define SN_ext_key_usage "extendedKeyUsage"
-#define LN_ext_key_usage "X509v3 Extended Key Usage"
-#define NID_ext_key_usage 126
-#define OBJ_ext_key_usage OBJ_id_ce,37L
-
-#define SN_freshest_crl "freshestCRL"
-#define LN_freshest_crl "X509v3 Freshest CRL"
-#define NID_freshest_crl 857
-#define OBJ_freshest_crl OBJ_id_ce,46L
-
-#define SN_inhibit_any_policy "inhibitAnyPolicy"
-#define LN_inhibit_any_policy "X509v3 Inhibit Any Policy"
-#define NID_inhibit_any_policy 748
-#define OBJ_inhibit_any_policy OBJ_id_ce,54L
-
-#define SN_target_information "targetInformation"
-#define LN_target_information "X509v3 AC Targeting"
-#define NID_target_information 402
-#define OBJ_target_information OBJ_id_ce,55L
-
-#define SN_no_rev_avail "noRevAvail"
-#define LN_no_rev_avail "X509v3 No Revocation Available"
-#define NID_no_rev_avail 403
-#define OBJ_no_rev_avail OBJ_id_ce,56L
-
-#define SN_anyExtendedKeyUsage "anyExtendedKeyUsage"
-#define LN_anyExtendedKeyUsage "Any Extended Key Usage"
-#define NID_anyExtendedKeyUsage 910
-#define OBJ_anyExtendedKeyUsage OBJ_ext_key_usage,0L
-
-#define SN_netscape "Netscape"
-#define LN_netscape "Netscape Communications Corp."
-#define NID_netscape 57
-#define OBJ_netscape 2L,16L,840L,1L,113730L
-
-#define SN_netscape_cert_extension "nsCertExt"
-#define LN_netscape_cert_extension "Netscape Certificate Extension"
-#define NID_netscape_cert_extension 58
-#define OBJ_netscape_cert_extension OBJ_netscape,1L
-
-#define SN_netscape_data_type "nsDataType"
-#define LN_netscape_data_type "Netscape Data Type"
-#define NID_netscape_data_type 59
-#define OBJ_netscape_data_type OBJ_netscape,2L
-
-#define SN_netscape_cert_type "nsCertType"
-#define LN_netscape_cert_type "Netscape Cert Type"
-#define NID_netscape_cert_type 71
-#define OBJ_netscape_cert_type OBJ_netscape_cert_extension,1L
-
-#define SN_netscape_base_url "nsBaseUrl"
-#define LN_netscape_base_url "Netscape Base Url"
-#define NID_netscape_base_url 72
-#define OBJ_netscape_base_url OBJ_netscape_cert_extension,2L
-
-#define SN_netscape_revocation_url "nsRevocationUrl"
-#define LN_netscape_revocation_url "Netscape Revocation Url"
-#define NID_netscape_revocation_url 73
-#define OBJ_netscape_revocation_url OBJ_netscape_cert_extension,3L
-
-#define SN_netscape_ca_revocation_url "nsCaRevocationUrl"
-#define LN_netscape_ca_revocation_url "Netscape CA Revocation Url"
-#define NID_netscape_ca_revocation_url 74
-#define OBJ_netscape_ca_revocation_url OBJ_netscape_cert_extension,4L
-
-#define SN_netscape_renewal_url "nsRenewalUrl"
-#define LN_netscape_renewal_url "Netscape Renewal Url"
-#define NID_netscape_renewal_url 75
-#define OBJ_netscape_renewal_url OBJ_netscape_cert_extension,7L
-
-#define SN_netscape_ca_policy_url "nsCaPolicyUrl"
-#define LN_netscape_ca_policy_url "Netscape CA Policy Url"
-#define NID_netscape_ca_policy_url 76
-#define OBJ_netscape_ca_policy_url OBJ_netscape_cert_extension,8L
-
-#define SN_netscape_ssl_server_name "nsSslServerName"
-#define LN_netscape_ssl_server_name "Netscape SSL Server Name"
-#define NID_netscape_ssl_server_name 77
-#define OBJ_netscape_ssl_server_name OBJ_netscape_cert_extension,12L
-
-#define SN_netscape_comment "nsComment"
-#define LN_netscape_comment "Netscape Comment"
-#define NID_netscape_comment 78
-#define OBJ_netscape_comment OBJ_netscape_cert_extension,13L
-
-#define SN_netscape_cert_sequence "nsCertSequence"
-#define LN_netscape_cert_sequence "Netscape Certificate Sequence"
-#define NID_netscape_cert_sequence 79
-#define OBJ_netscape_cert_sequence OBJ_netscape_data_type,5L
-
-#define SN_ns_sgc "nsSGC"
-#define LN_ns_sgc "Netscape Server Gated Crypto"
-#define NID_ns_sgc 139
-#define OBJ_ns_sgc OBJ_netscape,4L,1L
-
-#define SN_org "ORG"
-#define LN_org "org"
-#define NID_org 379
-#define OBJ_org OBJ_iso,3L
-
-#define SN_dod "DOD"
-#define LN_dod "dod"
-#define NID_dod 380
-#define OBJ_dod OBJ_org,6L
-
-#define SN_iana "IANA"
-#define LN_iana "iana"
-#define NID_iana 381
-#define OBJ_iana OBJ_dod,1L
-
-#define OBJ_internet OBJ_iana
-
-#define SN_Directory "directory"
-#define LN_Directory "Directory"
-#define NID_Directory 382
-#define OBJ_Directory OBJ_internet,1L
-
-#define SN_Management "mgmt"
-#define LN_Management "Management"
-#define NID_Management 383
-#define OBJ_Management OBJ_internet,2L
-
-#define SN_Experimental "experimental"
-#define LN_Experimental "Experimental"
-#define NID_Experimental 384
-#define OBJ_Experimental OBJ_internet,3L
-
-#define SN_Private "private"
-#define LN_Private "Private"
-#define NID_Private 385
-#define OBJ_Private OBJ_internet,4L
-
-#define SN_Security "security"
-#define LN_Security "Security"
-#define NID_Security 386
-#define OBJ_Security OBJ_internet,5L
-
-#define SN_SNMPv2 "snmpv2"
-#define LN_SNMPv2 "SNMPv2"
-#define NID_SNMPv2 387
-#define OBJ_SNMPv2 OBJ_internet,6L
-
-#define LN_Mail "Mail"
-#define NID_Mail 388
-#define OBJ_Mail OBJ_internet,7L
-
-#define SN_Enterprises "enterprises"
-#define LN_Enterprises "Enterprises"
-#define NID_Enterprises 389
-#define OBJ_Enterprises OBJ_Private,1L
-
-#define SN_dcObject "dcobject"
-#define LN_dcObject "dcObject"
-#define NID_dcObject 390
-#define OBJ_dcObject OBJ_Enterprises,1466L,344L
-
-#define SN_mime_mhs "mime-mhs"
-#define LN_mime_mhs "MIME MHS"
-#define NID_mime_mhs 504
-#define OBJ_mime_mhs OBJ_Mail,1L
-
-#define SN_mime_mhs_headings "mime-mhs-headings"
-#define LN_mime_mhs_headings "mime-mhs-headings"
-#define NID_mime_mhs_headings 505
-#define OBJ_mime_mhs_headings OBJ_mime_mhs,1L
-
-#define SN_mime_mhs_bodies "mime-mhs-bodies"
-#define LN_mime_mhs_bodies "mime-mhs-bodies"
-#define NID_mime_mhs_bodies 506
-#define OBJ_mime_mhs_bodies OBJ_mime_mhs,2L
-
-#define SN_id_hex_partial_message "id-hex-partial-message"
-#define LN_id_hex_partial_message "id-hex-partial-message"
-#define NID_id_hex_partial_message 507
-#define OBJ_id_hex_partial_message OBJ_mime_mhs_headings,1L
-
-#define SN_id_hex_multipart_message "id-hex-multipart-message"
-#define LN_id_hex_multipart_message "id-hex-multipart-message"
-#define NID_id_hex_multipart_message 508
-#define OBJ_id_hex_multipart_message OBJ_mime_mhs_headings,2L
-
-#define SN_zlib_compression "ZLIB"
-#define LN_zlib_compression "zlib compression"
-#define NID_zlib_compression 125
-#define OBJ_zlib_compression OBJ_id_smime_alg,8L
-
-#define OBJ_csor 2L,16L,840L,1L,101L,3L
-
-#define OBJ_nistAlgorithms OBJ_csor,4L
-
-#define OBJ_aes OBJ_nistAlgorithms,1L
-
-#define SN_aes_128_ecb "AES-128-ECB"
-#define LN_aes_128_ecb "aes-128-ecb"
-#define NID_aes_128_ecb 418
-#define OBJ_aes_128_ecb OBJ_aes,1L
-
-#define SN_aes_128_cbc "AES-128-CBC"
-#define LN_aes_128_cbc "aes-128-cbc"
-#define NID_aes_128_cbc 419
-#define OBJ_aes_128_cbc OBJ_aes,2L
-
-#define SN_aes_128_ofb128 "AES-128-OFB"
-#define LN_aes_128_ofb128 "aes-128-ofb"
-#define NID_aes_128_ofb128 420
-#define OBJ_aes_128_ofb128 OBJ_aes,3L
-
-#define SN_aes_128_cfb128 "AES-128-CFB"
-#define LN_aes_128_cfb128 "aes-128-cfb"
-#define NID_aes_128_cfb128 421
-#define OBJ_aes_128_cfb128 OBJ_aes,4L
-
-#define SN_id_aes128_wrap "id-aes128-wrap"
-#define NID_id_aes128_wrap 788
-#define OBJ_id_aes128_wrap OBJ_aes,5L
-
-#define SN_aes_128_gcm "id-aes128-GCM"
-#define LN_aes_128_gcm "aes-128-gcm"
-#define NID_aes_128_gcm 895
-#define OBJ_aes_128_gcm OBJ_aes,6L
-
-#define SN_aes_128_ccm "id-aes128-CCM"
-#define LN_aes_128_ccm "aes-128-ccm"
-#define NID_aes_128_ccm 896
-#define OBJ_aes_128_ccm OBJ_aes,7L
-
-#define SN_id_aes128_wrap_pad "id-aes128-wrap-pad"
-#define NID_id_aes128_wrap_pad 897
-#define OBJ_id_aes128_wrap_pad OBJ_aes,8L
-
-#define SN_aes_192_ecb "AES-192-ECB"
-#define LN_aes_192_ecb "aes-192-ecb"
-#define NID_aes_192_ecb 422
-#define OBJ_aes_192_ecb OBJ_aes,21L
-
-#define SN_aes_192_cbc "AES-192-CBC"
-#define LN_aes_192_cbc "aes-192-cbc"
-#define NID_aes_192_cbc 423
-#define OBJ_aes_192_cbc OBJ_aes,22L
-
-#define SN_aes_192_ofb128 "AES-192-OFB"
-#define LN_aes_192_ofb128 "aes-192-ofb"
-#define NID_aes_192_ofb128 424
-#define OBJ_aes_192_ofb128 OBJ_aes,23L
-
-#define SN_aes_192_cfb128 "AES-192-CFB"
-#define LN_aes_192_cfb128 "aes-192-cfb"
-#define NID_aes_192_cfb128 425
-#define OBJ_aes_192_cfb128 OBJ_aes,24L
-
-#define SN_id_aes192_wrap "id-aes192-wrap"
-#define NID_id_aes192_wrap 789
-#define OBJ_id_aes192_wrap OBJ_aes,25L
-
-#define SN_aes_192_gcm "id-aes192-GCM"
-#define LN_aes_192_gcm "aes-192-gcm"
-#define NID_aes_192_gcm 898
-#define OBJ_aes_192_gcm OBJ_aes,26L
-
-#define SN_aes_192_ccm "id-aes192-CCM"
-#define LN_aes_192_ccm "aes-192-ccm"
-#define NID_aes_192_ccm 899
-#define OBJ_aes_192_ccm OBJ_aes,27L
-
-#define SN_id_aes192_wrap_pad "id-aes192-wrap-pad"
-#define NID_id_aes192_wrap_pad 900
-#define OBJ_id_aes192_wrap_pad OBJ_aes,28L
-
-#define SN_aes_256_ecb "AES-256-ECB"
-#define LN_aes_256_ecb "aes-256-ecb"
-#define NID_aes_256_ecb 426
-#define OBJ_aes_256_ecb OBJ_aes,41L
-
-#define SN_aes_256_cbc "AES-256-CBC"
-#define LN_aes_256_cbc "aes-256-cbc"
-#define NID_aes_256_cbc 427
-#define OBJ_aes_256_cbc OBJ_aes,42L
-
-#define SN_aes_256_ofb128 "AES-256-OFB"
-#define LN_aes_256_ofb128 "aes-256-ofb"
-#define NID_aes_256_ofb128 428
-#define OBJ_aes_256_ofb128 OBJ_aes,43L
-
-#define SN_aes_256_cfb128 "AES-256-CFB"
-#define LN_aes_256_cfb128 "aes-256-cfb"
-#define NID_aes_256_cfb128 429
-#define OBJ_aes_256_cfb128 OBJ_aes,44L
-
-#define SN_id_aes256_wrap "id-aes256-wrap"
-#define NID_id_aes256_wrap 790
-#define OBJ_id_aes256_wrap OBJ_aes,45L
-
-#define SN_aes_256_gcm "id-aes256-GCM"
-#define LN_aes_256_gcm "aes-256-gcm"
-#define NID_aes_256_gcm 901
-#define OBJ_aes_256_gcm OBJ_aes,46L
-
-#define SN_aes_256_ccm "id-aes256-CCM"
-#define LN_aes_256_ccm "aes-256-ccm"
-#define NID_aes_256_ccm 902
-#define OBJ_aes_256_ccm OBJ_aes,47L
-
-#define SN_id_aes256_wrap_pad "id-aes256-wrap-pad"
-#define NID_id_aes256_wrap_pad 903
-#define OBJ_id_aes256_wrap_pad OBJ_aes,48L
-
-#define SN_aes_128_cfb1 "AES-128-CFB1"
-#define LN_aes_128_cfb1 "aes-128-cfb1"
-#define NID_aes_128_cfb1 650
-
-#define SN_aes_192_cfb1 "AES-192-CFB1"
-#define LN_aes_192_cfb1 "aes-192-cfb1"
-#define NID_aes_192_cfb1 651
-
-#define SN_aes_256_cfb1 "AES-256-CFB1"
-#define LN_aes_256_cfb1 "aes-256-cfb1"
-#define NID_aes_256_cfb1 652
-
-#define SN_aes_128_cfb8 "AES-128-CFB8"
-#define LN_aes_128_cfb8 "aes-128-cfb8"
-#define NID_aes_128_cfb8 653
-
-#define SN_aes_192_cfb8 "AES-192-CFB8"
-#define LN_aes_192_cfb8 "aes-192-cfb8"
-#define NID_aes_192_cfb8 654
-
-#define SN_aes_256_cfb8 "AES-256-CFB8"
-#define LN_aes_256_cfb8 "aes-256-cfb8"
-#define NID_aes_256_cfb8 655
-
-#define SN_aes_128_ctr "AES-128-CTR"
-#define LN_aes_128_ctr "aes-128-ctr"
-#define NID_aes_128_ctr 904
-
-#define SN_aes_192_ctr "AES-192-CTR"
-#define LN_aes_192_ctr "aes-192-ctr"
-#define NID_aes_192_ctr 905
-
-#define SN_aes_256_ctr "AES-256-CTR"
-#define LN_aes_256_ctr "aes-256-ctr"
-#define NID_aes_256_ctr 906
-
-#define SN_aes_128_xts "AES-128-XTS"
-#define LN_aes_128_xts "aes-128-xts"
-#define NID_aes_128_xts 913
-
-#define SN_aes_256_xts "AES-256-XTS"
-#define LN_aes_256_xts "aes-256-xts"
-#define NID_aes_256_xts 914
-
-#define SN_des_cfb1 "DES-CFB1"
-#define LN_des_cfb1 "des-cfb1"
-#define NID_des_cfb1 656
-
-#define SN_des_cfb8 "DES-CFB8"
-#define LN_des_cfb8 "des-cfb8"
-#define NID_des_cfb8 657
-
-#define SN_des_ede3_cfb1 "DES-EDE3-CFB1"
-#define LN_des_ede3_cfb1 "des-ede3-cfb1"
-#define NID_des_ede3_cfb1 658
-
-#define SN_des_ede3_cfb8 "DES-EDE3-CFB8"
-#define LN_des_ede3_cfb8 "des-ede3-cfb8"
-#define NID_des_ede3_cfb8 659
-
-#define OBJ_nist_hashalgs OBJ_nistAlgorithms,2L
-
-#define SN_sha256 "SHA256"
-#define LN_sha256 "sha256"
-#define NID_sha256 672
-#define OBJ_sha256 OBJ_nist_hashalgs,1L
-
-#define SN_sha384 "SHA384"
-#define LN_sha384 "sha384"
-#define NID_sha384 673
-#define OBJ_sha384 OBJ_nist_hashalgs,2L
-
-#define SN_sha512 "SHA512"
-#define LN_sha512 "sha512"
-#define NID_sha512 674
-#define OBJ_sha512 OBJ_nist_hashalgs,3L
-
-#define SN_sha224 "SHA224"
-#define LN_sha224 "sha224"
-#define NID_sha224 675
-#define OBJ_sha224 OBJ_nist_hashalgs,4L
-
-#define OBJ_dsa_with_sha2 OBJ_nistAlgorithms,3L
-
-#define SN_dsa_with_SHA224 "dsa_with_SHA224"
-#define NID_dsa_with_SHA224 802
-#define OBJ_dsa_with_SHA224 OBJ_dsa_with_sha2,1L
-
-#define SN_dsa_with_SHA256 "dsa_with_SHA256"
-#define NID_dsa_with_SHA256 803
-#define OBJ_dsa_with_SHA256 OBJ_dsa_with_sha2,2L
-
-#define SN_hold_instruction_code "holdInstructionCode"
-#define LN_hold_instruction_code "Hold Instruction Code"
-#define NID_hold_instruction_code 430
-#define OBJ_hold_instruction_code OBJ_id_ce,23L
-
-#define OBJ_holdInstruction OBJ_X9_57,2L
-
-#define SN_hold_instruction_none "holdInstructionNone"
-#define LN_hold_instruction_none "Hold Instruction None"
-#define NID_hold_instruction_none 431
-#define OBJ_hold_instruction_none OBJ_holdInstruction,1L
-
-#define SN_hold_instruction_call_issuer "holdInstructionCallIssuer"
-#define LN_hold_instruction_call_issuer "Hold Instruction Call Issuer"
-#define NID_hold_instruction_call_issuer 432
-#define OBJ_hold_instruction_call_issuer OBJ_holdInstruction,2L
-
-#define SN_hold_instruction_reject "holdInstructionReject"
-#define LN_hold_instruction_reject "Hold Instruction Reject"
-#define NID_hold_instruction_reject 433
-#define OBJ_hold_instruction_reject OBJ_holdInstruction,3L
-
-#define SN_data "data"
-#define NID_data 434
-#define OBJ_data OBJ_itu_t,9L
-
-#define SN_pss "pss"
-#define NID_pss 435
-#define OBJ_pss OBJ_data,2342L
-
-#define SN_ucl "ucl"
-#define NID_ucl 436
-#define OBJ_ucl OBJ_pss,19200300L
-
-#define SN_pilot "pilot"
-#define NID_pilot 437
-#define OBJ_pilot OBJ_ucl,100L
-
-#define LN_pilotAttributeType "pilotAttributeType"
-#define NID_pilotAttributeType 438
-#define OBJ_pilotAttributeType OBJ_pilot,1L
-
-#define LN_pilotAttributeSyntax "pilotAttributeSyntax"
-#define NID_pilotAttributeSyntax 439
-#define OBJ_pilotAttributeSyntax OBJ_pilot,3L
-
-#define LN_pilotObjectClass "pilotObjectClass"
-#define NID_pilotObjectClass 440
-#define OBJ_pilotObjectClass OBJ_pilot,4L
-
-#define LN_pilotGroups "pilotGroups"
-#define NID_pilotGroups 441
-#define OBJ_pilotGroups OBJ_pilot,10L
-
-#define LN_iA5StringSyntax "iA5StringSyntax"
-#define NID_iA5StringSyntax 442
-#define OBJ_iA5StringSyntax OBJ_pilotAttributeSyntax,4L
-
-#define LN_caseIgnoreIA5StringSyntax "caseIgnoreIA5StringSyntax"
-#define NID_caseIgnoreIA5StringSyntax 443
-#define OBJ_caseIgnoreIA5StringSyntax OBJ_pilotAttributeSyntax,5L
-
-#define LN_pilotObject "pilotObject"
-#define NID_pilotObject 444
-#define OBJ_pilotObject OBJ_pilotObjectClass,3L
-
-#define LN_pilotPerson "pilotPerson"
-#define NID_pilotPerson 445
-#define OBJ_pilotPerson OBJ_pilotObjectClass,4L
-
-#define SN_account "account"
-#define NID_account 446
-#define OBJ_account OBJ_pilotObjectClass,5L
-
-#define SN_document "document"
-#define NID_document 447
-#define OBJ_document OBJ_pilotObjectClass,6L
-
-#define SN_room "room"
-#define NID_room 448
-#define OBJ_room OBJ_pilotObjectClass,7L
-
-#define LN_documentSeries "documentSeries"
-#define NID_documentSeries 449
-#define OBJ_documentSeries OBJ_pilotObjectClass,9L
-
-#define SN_Domain "domain"
-#define LN_Domain "Domain"
-#define NID_Domain 392
-#define OBJ_Domain OBJ_pilotObjectClass,13L
-
-#define LN_rFC822localPart "rFC822localPart"
-#define NID_rFC822localPart 450
-#define OBJ_rFC822localPart OBJ_pilotObjectClass,14L
-
-#define LN_dNSDomain "dNSDomain"
-#define NID_dNSDomain 451
-#define OBJ_dNSDomain OBJ_pilotObjectClass,15L
-
-#define LN_domainRelatedObject "domainRelatedObject"
-#define NID_domainRelatedObject 452
-#define OBJ_domainRelatedObject OBJ_pilotObjectClass,17L
-
-#define LN_friendlyCountry "friendlyCountry"
-#define NID_friendlyCountry 453
-#define OBJ_friendlyCountry OBJ_pilotObjectClass,18L
-
-#define LN_simpleSecurityObject "simpleSecurityObject"
-#define NID_simpleSecurityObject 454
-#define OBJ_simpleSecurityObject OBJ_pilotObjectClass,19L
-
-#define LN_pilotOrganization "pilotOrganization"
-#define NID_pilotOrganization 455
-#define OBJ_pilotOrganization OBJ_pilotObjectClass,20L
-
-#define LN_pilotDSA "pilotDSA"
-#define NID_pilotDSA 456
-#define OBJ_pilotDSA OBJ_pilotObjectClass,21L
-
-#define LN_qualityLabelledData "qualityLabelledData"
-#define NID_qualityLabelledData 457
-#define OBJ_qualityLabelledData OBJ_pilotObjectClass,22L
-
-#define SN_userId "UID"
-#define LN_userId "userId"
-#define NID_userId 458
-#define OBJ_userId OBJ_pilotAttributeType,1L
-
-#define LN_textEncodedORAddress "textEncodedORAddress"
-#define NID_textEncodedORAddress 459
-#define OBJ_textEncodedORAddress OBJ_pilotAttributeType,2L
-
-#define SN_rfc822Mailbox "mail"
-#define LN_rfc822Mailbox "rfc822Mailbox"
-#define NID_rfc822Mailbox 460
-#define OBJ_rfc822Mailbox OBJ_pilotAttributeType,3L
-
-#define SN_info "info"
-#define NID_info 461
-#define OBJ_info OBJ_pilotAttributeType,4L
-
-#define LN_favouriteDrink "favouriteDrink"
-#define NID_favouriteDrink 462
-#define OBJ_favouriteDrink OBJ_pilotAttributeType,5L
-
-#define LN_roomNumber "roomNumber"
-#define NID_roomNumber 463
-#define OBJ_roomNumber OBJ_pilotAttributeType,6L
-
-#define SN_photo "photo"
-#define NID_photo 464
-#define OBJ_photo OBJ_pilotAttributeType,7L
-
-#define LN_userClass "userClass"
-#define NID_userClass 465
-#define OBJ_userClass OBJ_pilotAttributeType,8L
-
-#define SN_host "host"
-#define NID_host 466
-#define OBJ_host OBJ_pilotAttributeType,9L
-
-#define SN_manager "manager"
-#define NID_manager 467
-#define OBJ_manager OBJ_pilotAttributeType,10L
-
-#define LN_documentIdentifier "documentIdentifier"
-#define NID_documentIdentifier 468
-#define OBJ_documentIdentifier OBJ_pilotAttributeType,11L
-
-#define LN_documentTitle "documentTitle"
-#define NID_documentTitle 469
-#define OBJ_documentTitle OBJ_pilotAttributeType,12L
-
-#define LN_documentVersion "documentVersion"
-#define NID_documentVersion 470
-#define OBJ_documentVersion OBJ_pilotAttributeType,13L
-
-#define LN_documentAuthor "documentAuthor"
-#define NID_documentAuthor 471
-#define OBJ_documentAuthor OBJ_pilotAttributeType,14L
-
-#define LN_documentLocation "documentLocation"
-#define NID_documentLocation 472
-#define OBJ_documentLocation OBJ_pilotAttributeType,15L
-
-#define LN_homeTelephoneNumber "homeTelephoneNumber"
-#define NID_homeTelephoneNumber 473
-#define OBJ_homeTelephoneNumber OBJ_pilotAttributeType,20L
-
-#define SN_secretary "secretary"
-#define NID_secretary 474
-#define OBJ_secretary OBJ_pilotAttributeType,21L
-
-#define LN_otherMailbox "otherMailbox"
-#define NID_otherMailbox 475
-#define OBJ_otherMailbox OBJ_pilotAttributeType,22L
-
-#define LN_lastModifiedTime "lastModifiedTime"
-#define NID_lastModifiedTime 476
-#define OBJ_lastModifiedTime OBJ_pilotAttributeType,23L
-
-#define LN_lastModifiedBy "lastModifiedBy"
-#define NID_lastModifiedBy 477
-#define OBJ_lastModifiedBy OBJ_pilotAttributeType,24L
-
-#define SN_domainComponent "DC"
-#define LN_domainComponent "domainComponent"
-#define NID_domainComponent 391
-#define OBJ_domainComponent OBJ_pilotAttributeType,25L
-
-#define LN_aRecord "aRecord"
-#define NID_aRecord 478
-#define OBJ_aRecord OBJ_pilotAttributeType,26L
-
-#define LN_pilotAttributeType27 "pilotAttributeType27"
-#define NID_pilotAttributeType27 479
-#define OBJ_pilotAttributeType27 OBJ_pilotAttributeType,27L
-
-#define LN_mXRecord "mXRecord"
-#define NID_mXRecord 480
-#define OBJ_mXRecord OBJ_pilotAttributeType,28L
-
-#define LN_nSRecord "nSRecord"
-#define NID_nSRecord 481
-#define OBJ_nSRecord OBJ_pilotAttributeType,29L
-
-#define LN_sOARecord "sOARecord"
-#define NID_sOARecord 482
-#define OBJ_sOARecord OBJ_pilotAttributeType,30L
-
-#define LN_cNAMERecord "cNAMERecord"
-#define NID_cNAMERecord 483
-#define OBJ_cNAMERecord OBJ_pilotAttributeType,31L
-
-#define LN_associatedDomain "associatedDomain"
-#define NID_associatedDomain 484
-#define OBJ_associatedDomain OBJ_pilotAttributeType,37L
-
-#define LN_associatedName "associatedName"
-#define NID_associatedName 485
-#define OBJ_associatedName OBJ_pilotAttributeType,38L
-
-#define LN_homePostalAddress "homePostalAddress"
-#define NID_homePostalAddress 486
-#define OBJ_homePostalAddress OBJ_pilotAttributeType,39L
-
-#define LN_personalTitle "personalTitle"
-#define NID_personalTitle 487
-#define OBJ_personalTitle OBJ_pilotAttributeType,40L
-
-#define LN_mobileTelephoneNumber "mobileTelephoneNumber"
-#define NID_mobileTelephoneNumber 488
-#define OBJ_mobileTelephoneNumber OBJ_pilotAttributeType,41L
-
-#define LN_pagerTelephoneNumber "pagerTelephoneNumber"
-#define NID_pagerTelephoneNumber 489
-#define OBJ_pagerTelephoneNumber OBJ_pilotAttributeType,42L
-
-#define LN_friendlyCountryName "friendlyCountryName"
-#define NID_friendlyCountryName 490
-#define OBJ_friendlyCountryName OBJ_pilotAttributeType,43L
-
-#define LN_organizationalStatus "organizationalStatus"
-#define NID_organizationalStatus 491
-#define OBJ_organizationalStatus OBJ_pilotAttributeType,45L
-
-#define LN_janetMailbox "janetMailbox"
-#define NID_janetMailbox 492
-#define OBJ_janetMailbox OBJ_pilotAttributeType,46L
-
-#define LN_mailPreferenceOption "mailPreferenceOption"
-#define NID_mailPreferenceOption 493
-#define OBJ_mailPreferenceOption OBJ_pilotAttributeType,47L
-
-#define LN_buildingName "buildingName"
-#define NID_buildingName 494
-#define OBJ_buildingName OBJ_pilotAttributeType,48L
-
-#define LN_dSAQuality "dSAQuality"
-#define NID_dSAQuality 495
-#define OBJ_dSAQuality OBJ_pilotAttributeType,49L
-
-#define LN_singleLevelQuality "singleLevelQuality"
-#define NID_singleLevelQuality 496
-#define OBJ_singleLevelQuality OBJ_pilotAttributeType,50L
-
-#define LN_subtreeMinimumQuality "subtreeMinimumQuality"
-#define NID_subtreeMinimumQuality 497
-#define OBJ_subtreeMinimumQuality OBJ_pilotAttributeType,51L
-
-#define LN_subtreeMaximumQuality "subtreeMaximumQuality"
-#define NID_subtreeMaximumQuality 498
-#define OBJ_subtreeMaximumQuality OBJ_pilotAttributeType,52L
-
-#define LN_personalSignature "personalSignature"
-#define NID_personalSignature 499
-#define OBJ_personalSignature OBJ_pilotAttributeType,53L
-
-#define LN_dITRedirect "dITRedirect"
-#define NID_dITRedirect 500
-#define OBJ_dITRedirect OBJ_pilotAttributeType,54L
-
-#define SN_audio "audio"
-#define NID_audio 501
-#define OBJ_audio OBJ_pilotAttributeType,55L
-
-#define LN_documentPublisher "documentPublisher"
-#define NID_documentPublisher 502
-#define OBJ_documentPublisher OBJ_pilotAttributeType,56L
-
-#define SN_id_set "id-set"
-#define LN_id_set "Secure Electronic Transactions"
-#define NID_id_set 512
-#define OBJ_id_set OBJ_international_organizations,42L
-
-#define SN_set_ctype "set-ctype"
-#define LN_set_ctype "content types"
-#define NID_set_ctype 513
-#define OBJ_set_ctype OBJ_id_set,0L
-
-#define SN_set_msgExt "set-msgExt"
-#define LN_set_msgExt "message extensions"
-#define NID_set_msgExt 514
-#define OBJ_set_msgExt OBJ_id_set,1L
-
-#define SN_set_attr "set-attr"
-#define NID_set_attr 515
-#define OBJ_set_attr OBJ_id_set,3L
-
-#define SN_set_policy "set-policy"
-#define NID_set_policy 516
-#define OBJ_set_policy OBJ_id_set,5L
-
-#define SN_set_certExt "set-certExt"
-#define LN_set_certExt "certificate extensions"
-#define NID_set_certExt 517
-#define OBJ_set_certExt OBJ_id_set,7L
-
-#define SN_set_brand "set-brand"
-#define NID_set_brand 518
-#define OBJ_set_brand OBJ_id_set,8L
-
-#define SN_setct_PANData "setct-PANData"
-#define NID_setct_PANData 519
-#define OBJ_setct_PANData OBJ_set_ctype,0L
-
-#define SN_setct_PANToken "setct-PANToken"
-#define NID_setct_PANToken 520
-#define OBJ_setct_PANToken OBJ_set_ctype,1L
-
-#define SN_setct_PANOnly "setct-PANOnly"
-#define NID_setct_PANOnly 521
-#define OBJ_setct_PANOnly OBJ_set_ctype,2L
-
-#define SN_setct_OIData "setct-OIData"
-#define NID_setct_OIData 522
-#define OBJ_setct_OIData OBJ_set_ctype,3L
-
-#define SN_setct_PI "setct-PI"
-#define NID_setct_PI 523
-#define OBJ_setct_PI OBJ_set_ctype,4L
-
-#define SN_setct_PIData "setct-PIData"
-#define NID_setct_PIData 524
-#define OBJ_setct_PIData OBJ_set_ctype,5L
-
-#define SN_setct_PIDataUnsigned "setct-PIDataUnsigned"
-#define NID_setct_PIDataUnsigned 525
-#define OBJ_setct_PIDataUnsigned OBJ_set_ctype,6L
-
-#define SN_setct_HODInput "setct-HODInput"
-#define NID_setct_HODInput 526
-#define OBJ_setct_HODInput OBJ_set_ctype,7L
-
-#define SN_setct_AuthResBaggage "setct-AuthResBaggage"
-#define NID_setct_AuthResBaggage 527
-#define OBJ_setct_AuthResBaggage OBJ_set_ctype,8L
-
-#define SN_setct_AuthRevReqBaggage "setct-AuthRevReqBaggage"
-#define NID_setct_AuthRevReqBaggage 528
-#define OBJ_setct_AuthRevReqBaggage OBJ_set_ctype,9L
-
-#define SN_setct_AuthRevResBaggage "setct-AuthRevResBaggage"
-#define NID_setct_AuthRevResBaggage 529
-#define OBJ_setct_AuthRevResBaggage OBJ_set_ctype,10L
-
-#define SN_setct_CapTokenSeq "setct-CapTokenSeq"
-#define NID_setct_CapTokenSeq 530
-#define OBJ_setct_CapTokenSeq OBJ_set_ctype,11L
-
-#define SN_setct_PInitResData "setct-PInitResData"
-#define NID_setct_PInitResData 531
-#define OBJ_setct_PInitResData OBJ_set_ctype,12L
-
-#define SN_setct_PI_TBS "setct-PI-TBS"
-#define NID_setct_PI_TBS 532
-#define OBJ_setct_PI_TBS OBJ_set_ctype,13L
-
-#define SN_setct_PResData "setct-PResData"
-#define NID_setct_PResData 533
-#define OBJ_setct_PResData OBJ_set_ctype,14L
-
-#define SN_setct_AuthReqTBS "setct-AuthReqTBS"
-#define NID_setct_AuthReqTBS 534
-#define OBJ_setct_AuthReqTBS OBJ_set_ctype,16L
-
-#define SN_setct_AuthResTBS "setct-AuthResTBS"
-#define NID_setct_AuthResTBS 535
-#define OBJ_setct_AuthResTBS OBJ_set_ctype,17L
-
-#define SN_setct_AuthResTBSX "setct-AuthResTBSX"
-#define NID_setct_AuthResTBSX 536
-#define OBJ_setct_AuthResTBSX OBJ_set_ctype,18L
-
-#define SN_setct_AuthTokenTBS "setct-AuthTokenTBS"
-#define NID_setct_AuthTokenTBS 537
-#define OBJ_setct_AuthTokenTBS OBJ_set_ctype,19L
-
-#define SN_setct_CapTokenData "setct-CapTokenData"
-#define NID_setct_CapTokenData 538
-#define OBJ_setct_CapTokenData OBJ_set_ctype,20L
-
-#define SN_setct_CapTokenTBS "setct-CapTokenTBS"
-#define NID_setct_CapTokenTBS 539
-#define OBJ_setct_CapTokenTBS OBJ_set_ctype,21L
-
-#define SN_setct_AcqCardCodeMsg "setct-AcqCardCodeMsg"
-#define NID_setct_AcqCardCodeMsg 540
-#define OBJ_setct_AcqCardCodeMsg OBJ_set_ctype,22L
-
-#define SN_setct_AuthRevReqTBS "setct-AuthRevReqTBS"
-#define NID_setct_AuthRevReqTBS 541
-#define OBJ_setct_AuthRevReqTBS OBJ_set_ctype,23L
-
-#define SN_setct_AuthRevResData "setct-AuthRevResData"
-#define NID_setct_AuthRevResData 542
-#define OBJ_setct_AuthRevResData OBJ_set_ctype,24L
-
-#define SN_setct_AuthRevResTBS "setct-AuthRevResTBS"
-#define NID_setct_AuthRevResTBS 543
-#define OBJ_setct_AuthRevResTBS OBJ_set_ctype,25L
-
-#define SN_setct_CapReqTBS "setct-CapReqTBS"
-#define NID_setct_CapReqTBS 544
-#define OBJ_setct_CapReqTBS OBJ_set_ctype,26L
-
-#define SN_setct_CapReqTBSX "setct-CapReqTBSX"
-#define NID_setct_CapReqTBSX 545
-#define OBJ_setct_CapReqTBSX OBJ_set_ctype,27L
-
-#define SN_setct_CapResData "setct-CapResData"
-#define NID_setct_CapResData 546
-#define OBJ_setct_CapResData OBJ_set_ctype,28L
-
-#define SN_setct_CapRevReqTBS "setct-CapRevReqTBS"
-#define NID_setct_CapRevReqTBS 547
-#define OBJ_setct_CapRevReqTBS OBJ_set_ctype,29L
-
-#define SN_setct_CapRevReqTBSX "setct-CapRevReqTBSX"
-#define NID_setct_CapRevReqTBSX 548
-#define OBJ_setct_CapRevReqTBSX OBJ_set_ctype,30L
-
-#define SN_setct_CapRevResData "setct-CapRevResData"
-#define NID_setct_CapRevResData 549
-#define OBJ_setct_CapRevResData OBJ_set_ctype,31L
-
-#define SN_setct_CredReqTBS "setct-CredReqTBS"
-#define NID_setct_CredReqTBS 550
-#define OBJ_setct_CredReqTBS OBJ_set_ctype,32L
-
-#define SN_setct_CredReqTBSX "setct-CredReqTBSX"
-#define NID_setct_CredReqTBSX 551
-#define OBJ_setct_CredReqTBSX OBJ_set_ctype,33L
-
-#define SN_setct_CredResData "setct-CredResData"
-#define NID_setct_CredResData 552
-#define OBJ_setct_CredResData OBJ_set_ctype,34L
-
-#define SN_setct_CredRevReqTBS "setct-CredRevReqTBS"
-#define NID_setct_CredRevReqTBS 553
-#define OBJ_setct_CredRevReqTBS OBJ_set_ctype,35L
-
-#define SN_setct_CredRevReqTBSX "setct-CredRevReqTBSX"
-#define NID_setct_CredRevReqTBSX 554
-#define OBJ_setct_CredRevReqTBSX OBJ_set_ctype,36L
-
-#define SN_setct_CredRevResData "setct-CredRevResData"
-#define NID_setct_CredRevResData 555
-#define OBJ_setct_CredRevResData OBJ_set_ctype,37L
-
-#define SN_setct_PCertReqData "setct-PCertReqData"
-#define NID_setct_PCertReqData 556
-#define OBJ_setct_PCertReqData OBJ_set_ctype,38L
-
-#define SN_setct_PCertResTBS "setct-PCertResTBS"
-#define NID_setct_PCertResTBS 557
-#define OBJ_setct_PCertResTBS OBJ_set_ctype,39L
-
-#define SN_setct_BatchAdminReqData "setct-BatchAdminReqData"
-#define NID_setct_BatchAdminReqData 558
-#define OBJ_setct_BatchAdminReqData OBJ_set_ctype,40L
-
-#define SN_setct_BatchAdminResData "setct-BatchAdminResData"
-#define NID_setct_BatchAdminResData 559
-#define OBJ_setct_BatchAdminResData OBJ_set_ctype,41L
-
-#define SN_setct_CardCInitResTBS "setct-CardCInitResTBS"
-#define NID_setct_CardCInitResTBS 560
-#define OBJ_setct_CardCInitResTBS OBJ_set_ctype,42L
-
-#define SN_setct_MeAqCInitResTBS "setct-MeAqCInitResTBS"
-#define NID_setct_MeAqCInitResTBS 561
-#define OBJ_setct_MeAqCInitResTBS OBJ_set_ctype,43L
-
-#define SN_setct_RegFormResTBS "setct-RegFormResTBS"
-#define NID_setct_RegFormResTBS 562
-#define OBJ_setct_RegFormResTBS OBJ_set_ctype,44L
-
-#define SN_setct_CertReqData "setct-CertReqData"
-#define NID_setct_CertReqData 563
-#define OBJ_setct_CertReqData OBJ_set_ctype,45L
-
-#define SN_setct_CertReqTBS "setct-CertReqTBS"
-#define NID_setct_CertReqTBS 564
-#define OBJ_setct_CertReqTBS OBJ_set_ctype,46L
-
-#define SN_setct_CertResData "setct-CertResData"
-#define NID_setct_CertResData 565
-#define OBJ_setct_CertResData OBJ_set_ctype,47L
-
-#define SN_setct_CertInqReqTBS "setct-CertInqReqTBS"
-#define NID_setct_CertInqReqTBS 566
-#define OBJ_setct_CertInqReqTBS OBJ_set_ctype,48L
-
-#define SN_setct_ErrorTBS "setct-ErrorTBS"
-#define NID_setct_ErrorTBS 567
-#define OBJ_setct_ErrorTBS OBJ_set_ctype,49L
-
-#define SN_setct_PIDualSignedTBE "setct-PIDualSignedTBE"
-#define NID_setct_PIDualSignedTBE 568
-#define OBJ_setct_PIDualSignedTBE OBJ_set_ctype,50L
-
-#define SN_setct_PIUnsignedTBE "setct-PIUnsignedTBE"
-#define NID_setct_PIUnsignedTBE 569
-#define OBJ_setct_PIUnsignedTBE OBJ_set_ctype,51L
-
-#define SN_setct_AuthReqTBE "setct-AuthReqTBE"
-#define NID_setct_AuthReqTBE 570
-#define OBJ_setct_AuthReqTBE OBJ_set_ctype,52L
-
-#define SN_setct_AuthResTBE "setct-AuthResTBE"
-#define NID_setct_AuthResTBE 571
-#define OBJ_setct_AuthResTBE OBJ_set_ctype,53L
-
-#define SN_setct_AuthResTBEX "setct-AuthResTBEX"
-#define NID_setct_AuthResTBEX 572
-#define OBJ_setct_AuthResTBEX OBJ_set_ctype,54L
-
-#define SN_setct_AuthTokenTBE "setct-AuthTokenTBE"
-#define NID_setct_AuthTokenTBE 573
-#define OBJ_setct_AuthTokenTBE OBJ_set_ctype,55L
-
-#define SN_setct_CapTokenTBE "setct-CapTokenTBE"
-#define NID_setct_CapTokenTBE 574
-#define OBJ_setct_CapTokenTBE OBJ_set_ctype,56L
-
-#define SN_setct_CapTokenTBEX "setct-CapTokenTBEX"
-#define NID_setct_CapTokenTBEX 575
-#define OBJ_setct_CapTokenTBEX OBJ_set_ctype,57L
-
-#define SN_setct_AcqCardCodeMsgTBE "setct-AcqCardCodeMsgTBE"
-#define NID_setct_AcqCardCodeMsgTBE 576
-#define OBJ_setct_AcqCardCodeMsgTBE OBJ_set_ctype,58L
-
-#define SN_setct_AuthRevReqTBE "setct-AuthRevReqTBE"
-#define NID_setct_AuthRevReqTBE 577
-#define OBJ_setct_AuthRevReqTBE OBJ_set_ctype,59L
-
-#define SN_setct_AuthRevResTBE "setct-AuthRevResTBE"
-#define NID_setct_AuthRevResTBE 578
-#define OBJ_setct_AuthRevResTBE OBJ_set_ctype,60L
-
-#define SN_setct_AuthRevResTBEB "setct-AuthRevResTBEB"
-#define NID_setct_AuthRevResTBEB 579
-#define OBJ_setct_AuthRevResTBEB OBJ_set_ctype,61L
-
-#define SN_setct_CapReqTBE "setct-CapReqTBE"
-#define NID_setct_CapReqTBE 580
-#define OBJ_setct_CapReqTBE OBJ_set_ctype,62L
-
-#define SN_setct_CapReqTBEX "setct-CapReqTBEX"
-#define NID_setct_CapReqTBEX 581
-#define OBJ_setct_CapReqTBEX OBJ_set_ctype,63L
-
-#define SN_setct_CapResTBE "setct-CapResTBE"
-#define NID_setct_CapResTBE 582
-#define OBJ_setct_CapResTBE OBJ_set_ctype,64L
-
-#define SN_setct_CapRevReqTBE "setct-CapRevReqTBE"
-#define NID_setct_CapRevReqTBE 583
-#define OBJ_setct_CapRevReqTBE OBJ_set_ctype,65L
-
-#define SN_setct_CapRevReqTBEX "setct-CapRevReqTBEX"
-#define NID_setct_CapRevReqTBEX 584
-#define OBJ_setct_CapRevReqTBEX OBJ_set_ctype,66L
-
-#define SN_setct_CapRevResTBE "setct-CapRevResTBE"
-#define NID_setct_CapRevResTBE 585
-#define OBJ_setct_CapRevResTBE OBJ_set_ctype,67L
-
-#define SN_setct_CredReqTBE "setct-CredReqTBE"
-#define NID_setct_CredReqTBE 586
-#define OBJ_setct_CredReqTBE OBJ_set_ctype,68L
-
-#define SN_setct_CredReqTBEX "setct-CredReqTBEX"
-#define NID_setct_CredReqTBEX 587
-#define OBJ_setct_CredReqTBEX OBJ_set_ctype,69L
-
-#define SN_setct_CredResTBE "setct-CredResTBE"
-#define NID_setct_CredResTBE 588
-#define OBJ_setct_CredResTBE OBJ_set_ctype,70L
-
-#define SN_setct_CredRevReqTBE "setct-CredRevReqTBE"
-#define NID_setct_CredRevReqTBE 589
-#define OBJ_setct_CredRevReqTBE OBJ_set_ctype,71L
-
-#define SN_setct_CredRevReqTBEX "setct-CredRevReqTBEX"
-#define NID_setct_CredRevReqTBEX 590
-#define OBJ_setct_CredRevReqTBEX OBJ_set_ctype,72L
-
-#define SN_setct_CredRevResTBE "setct-CredRevResTBE"
-#define NID_setct_CredRevResTBE 591
-#define OBJ_setct_CredRevResTBE OBJ_set_ctype,73L
-
-#define SN_setct_BatchAdminReqTBE "setct-BatchAdminReqTBE"
-#define NID_setct_BatchAdminReqTBE 592
-#define OBJ_setct_BatchAdminReqTBE OBJ_set_ctype,74L
-
-#define SN_setct_BatchAdminResTBE "setct-BatchAdminResTBE"
-#define NID_setct_BatchAdminResTBE 593
-#define OBJ_setct_BatchAdminResTBE OBJ_set_ctype,75L
-
-#define SN_setct_RegFormReqTBE "setct-RegFormReqTBE"
-#define NID_setct_RegFormReqTBE 594
-#define OBJ_setct_RegFormReqTBE OBJ_set_ctype,76L
-
-#define SN_setct_CertReqTBE "setct-CertReqTBE"
-#define NID_setct_CertReqTBE 595
-#define OBJ_setct_CertReqTBE OBJ_set_ctype,77L
-
-#define SN_setct_CertReqTBEX "setct-CertReqTBEX"
-#define NID_setct_CertReqTBEX 596
-#define OBJ_setct_CertReqTBEX OBJ_set_ctype,78L
-
-#define SN_setct_CertResTBE "setct-CertResTBE"
-#define NID_setct_CertResTBE 597
-#define OBJ_setct_CertResTBE OBJ_set_ctype,79L
-
-#define SN_setct_CRLNotificationTBS "setct-CRLNotificationTBS"
-#define NID_setct_CRLNotificationTBS 598
-#define OBJ_setct_CRLNotificationTBS OBJ_set_ctype,80L
-
-#define SN_setct_CRLNotificationResTBS "setct-CRLNotificationResTBS"
-#define NID_setct_CRLNotificationResTBS 599
-#define OBJ_setct_CRLNotificationResTBS OBJ_set_ctype,81L
-
-#define SN_setct_BCIDistributionTBS "setct-BCIDistributionTBS"
-#define NID_setct_BCIDistributionTBS 600
-#define OBJ_setct_BCIDistributionTBS OBJ_set_ctype,82L
-
-#define SN_setext_genCrypt "setext-genCrypt"
-#define LN_setext_genCrypt "generic cryptogram"
-#define NID_setext_genCrypt 601
-#define OBJ_setext_genCrypt OBJ_set_msgExt,1L
-
-#define SN_setext_miAuth "setext-miAuth"
-#define LN_setext_miAuth "merchant initiated auth"
-#define NID_setext_miAuth 602
-#define OBJ_setext_miAuth OBJ_set_msgExt,3L
-
-#define SN_setext_pinSecure "setext-pinSecure"
-#define NID_setext_pinSecure 603
-#define OBJ_setext_pinSecure OBJ_set_msgExt,4L
-
-#define SN_setext_pinAny "setext-pinAny"
-#define NID_setext_pinAny 604
-#define OBJ_setext_pinAny OBJ_set_msgExt,5L
-
-#define SN_setext_track2 "setext-track2"
-#define NID_setext_track2 605
-#define OBJ_setext_track2 OBJ_set_msgExt,7L
-
-#define SN_setext_cv "setext-cv"
-#define LN_setext_cv "additional verification"
-#define NID_setext_cv 606
-#define OBJ_setext_cv OBJ_set_msgExt,8L
-
-#define SN_set_policy_root "set-policy-root"
-#define NID_set_policy_root 607
-#define OBJ_set_policy_root OBJ_set_policy,0L
-
-#define SN_setCext_hashedRoot "setCext-hashedRoot"
-#define NID_setCext_hashedRoot 608
-#define OBJ_setCext_hashedRoot OBJ_set_certExt,0L
-
-#define SN_setCext_certType "setCext-certType"
-#define NID_setCext_certType 609
-#define OBJ_setCext_certType OBJ_set_certExt,1L
-
-#define SN_setCext_merchData "setCext-merchData"
-#define NID_setCext_merchData 610
-#define OBJ_setCext_merchData OBJ_set_certExt,2L
-
-#define SN_setCext_cCertRequired "setCext-cCertRequired"
-#define NID_setCext_cCertRequired 611
-#define OBJ_setCext_cCertRequired OBJ_set_certExt,3L
-
-#define SN_setCext_tunneling "setCext-tunneling"
-#define NID_setCext_tunneling 612
-#define OBJ_setCext_tunneling OBJ_set_certExt,4L
-
-#define SN_setCext_setExt "setCext-setExt"
-#define NID_setCext_setExt 613
-#define OBJ_setCext_setExt OBJ_set_certExt,5L
-
-#define SN_setCext_setQualf "setCext-setQualf"
-#define NID_setCext_setQualf 614
-#define OBJ_setCext_setQualf OBJ_set_certExt,6L
-
-#define SN_setCext_PGWYcapabilities "setCext-PGWYcapabilities"
-#define NID_setCext_PGWYcapabilities 615
-#define OBJ_setCext_PGWYcapabilities OBJ_set_certExt,7L
-
-#define SN_setCext_TokenIdentifier "setCext-TokenIdentifier"
-#define NID_setCext_TokenIdentifier 616
-#define OBJ_setCext_TokenIdentifier OBJ_set_certExt,8L
-
-#define SN_setCext_Track2Data "setCext-Track2Data"
-#define NID_setCext_Track2Data 617
-#define OBJ_setCext_Track2Data OBJ_set_certExt,9L
-
-#define SN_setCext_TokenType "setCext-TokenType"
-#define NID_setCext_TokenType 618
-#define OBJ_setCext_TokenType OBJ_set_certExt,10L
-
-#define SN_setCext_IssuerCapabilities "setCext-IssuerCapabilities"
-#define NID_setCext_IssuerCapabilities 619
-#define OBJ_setCext_IssuerCapabilities OBJ_set_certExt,11L
-
-#define SN_setAttr_Cert "setAttr-Cert"
-#define NID_setAttr_Cert 620
-#define OBJ_setAttr_Cert OBJ_set_attr,0L
-
-#define SN_setAttr_PGWYcap "setAttr-PGWYcap"
-#define LN_setAttr_PGWYcap "payment gateway capabilities"
-#define NID_setAttr_PGWYcap 621
-#define OBJ_setAttr_PGWYcap OBJ_set_attr,1L
-
-#define SN_setAttr_TokenType "setAttr-TokenType"
-#define NID_setAttr_TokenType 622
-#define OBJ_setAttr_TokenType OBJ_set_attr,2L
-
-#define SN_setAttr_IssCap "setAttr-IssCap"
-#define LN_setAttr_IssCap "issuer capabilities"
-#define NID_setAttr_IssCap 623
-#define OBJ_setAttr_IssCap OBJ_set_attr,3L
-
-#define SN_set_rootKeyThumb "set-rootKeyThumb"
-#define NID_set_rootKeyThumb 624
-#define OBJ_set_rootKeyThumb OBJ_setAttr_Cert,0L
-
-#define SN_set_addPolicy "set-addPolicy"
-#define NID_set_addPolicy 625
-#define OBJ_set_addPolicy OBJ_setAttr_Cert,1L
-
-#define SN_setAttr_Token_EMV "setAttr-Token-EMV"
-#define NID_setAttr_Token_EMV 626
-#define OBJ_setAttr_Token_EMV OBJ_setAttr_TokenType,1L
-
-#define SN_setAttr_Token_B0Prime "setAttr-Token-B0Prime"
-#define NID_setAttr_Token_B0Prime 627
-#define OBJ_setAttr_Token_B0Prime OBJ_setAttr_TokenType,2L
-
-#define SN_setAttr_IssCap_CVM "setAttr-IssCap-CVM"
-#define NID_setAttr_IssCap_CVM 628
-#define OBJ_setAttr_IssCap_CVM OBJ_setAttr_IssCap,3L
-
-#define SN_setAttr_IssCap_T2 "setAttr-IssCap-T2"
-#define NID_setAttr_IssCap_T2 629
-#define OBJ_setAttr_IssCap_T2 OBJ_setAttr_IssCap,4L
-
-#define SN_setAttr_IssCap_Sig "setAttr-IssCap-Sig"
-#define NID_setAttr_IssCap_Sig 630
-#define OBJ_setAttr_IssCap_Sig OBJ_setAttr_IssCap,5L
-
-#define SN_setAttr_GenCryptgrm "setAttr-GenCryptgrm"
-#define LN_setAttr_GenCryptgrm "generate cryptogram"
-#define NID_setAttr_GenCryptgrm 631
-#define OBJ_setAttr_GenCryptgrm OBJ_setAttr_IssCap_CVM,1L
-
-#define SN_setAttr_T2Enc "setAttr-T2Enc"
-#define LN_setAttr_T2Enc "encrypted track 2"
-#define NID_setAttr_T2Enc 632
-#define OBJ_setAttr_T2Enc OBJ_setAttr_IssCap_T2,1L
-
-#define SN_setAttr_T2cleartxt "setAttr-T2cleartxt"
-#define LN_setAttr_T2cleartxt "cleartext track 2"
-#define NID_setAttr_T2cleartxt 633
-#define OBJ_setAttr_T2cleartxt OBJ_setAttr_IssCap_T2,2L
-
-#define SN_setAttr_TokICCsig "setAttr-TokICCsig"
-#define LN_setAttr_TokICCsig "ICC or token signature"
-#define NID_setAttr_TokICCsig 634
-#define OBJ_setAttr_TokICCsig OBJ_setAttr_IssCap_Sig,1L
-
-#define SN_setAttr_SecDevSig "setAttr-SecDevSig"
-#define LN_setAttr_SecDevSig "secure device signature"
-#define NID_setAttr_SecDevSig 635
-#define OBJ_setAttr_SecDevSig OBJ_setAttr_IssCap_Sig,2L
-
-#define SN_set_brand_IATA_ATA "set-brand-IATA-ATA"
-#define NID_set_brand_IATA_ATA 636
-#define OBJ_set_brand_IATA_ATA OBJ_set_brand,1L
-
-#define SN_set_brand_Diners "set-brand-Diners"
-#define NID_set_brand_Diners 637
-#define OBJ_set_brand_Diners OBJ_set_brand,30L
-
-#define SN_set_brand_AmericanExpress "set-brand-AmericanExpress"
-#define NID_set_brand_AmericanExpress 638
-#define OBJ_set_brand_AmericanExpress OBJ_set_brand,34L
-
-#define SN_set_brand_JCB "set-brand-JCB"
-#define NID_set_brand_JCB 639
-#define OBJ_set_brand_JCB OBJ_set_brand,35L
-
-#define SN_set_brand_Visa "set-brand-Visa"
-#define NID_set_brand_Visa 640
-#define OBJ_set_brand_Visa OBJ_set_brand,4L
-
-#define SN_set_brand_MasterCard "set-brand-MasterCard"
-#define NID_set_brand_MasterCard 641
-#define OBJ_set_brand_MasterCard OBJ_set_brand,5L
-
-#define SN_set_brand_Novus "set-brand-Novus"
-#define NID_set_brand_Novus 642
-#define OBJ_set_brand_Novus OBJ_set_brand,6011L
-
-#define SN_des_cdmf "DES-CDMF"
-#define LN_des_cdmf "des-cdmf"
-#define NID_des_cdmf 643
-#define OBJ_des_cdmf OBJ_rsadsi,3L,10L
-
-#define SN_rsaOAEPEncryptionSET "rsaOAEPEncryptionSET"
-#define NID_rsaOAEPEncryptionSET 644
-#define OBJ_rsaOAEPEncryptionSET OBJ_rsadsi,1L,1L,6L
-
-#define SN_ipsec3 "Oakley-EC2N-3"
-#define LN_ipsec3 "ipsec3"
-#define NID_ipsec3 749
-
-#define SN_ipsec4 "Oakley-EC2N-4"
-#define LN_ipsec4 "ipsec4"
-#define NID_ipsec4 750
-
-#define SN_whirlpool "whirlpool"
-#define NID_whirlpool 804
-#define OBJ_whirlpool OBJ_iso,0L,10118L,3L,0L,55L
-
-#define SN_cryptopro "cryptopro"
-#define NID_cryptopro 805
-#define OBJ_cryptopro OBJ_member_body,643L,2L,2L
-
-#define SN_cryptocom "cryptocom"
-#define NID_cryptocom 806
-#define OBJ_cryptocom OBJ_member_body,643L,2L,9L
-
-#define SN_id_GostR3411_94_with_GostR3410_2001 "id-GostR3411-94-with-GostR3410-2001"
-#define LN_id_GostR3411_94_with_GostR3410_2001 "GOST R 34.11-94 with GOST R 34.10-2001"
-#define NID_id_GostR3411_94_with_GostR3410_2001 807
-#define OBJ_id_GostR3411_94_with_GostR3410_2001 OBJ_cryptopro,3L
-
-#define SN_id_GostR3411_94_with_GostR3410_94 "id-GostR3411-94-with-GostR3410-94"
-#define LN_id_GostR3411_94_with_GostR3410_94 "GOST R 34.11-94 with GOST R 34.10-94"
-#define NID_id_GostR3411_94_with_GostR3410_94 808
-#define OBJ_id_GostR3411_94_with_GostR3410_94 OBJ_cryptopro,4L
-
-#define SN_id_GostR3411_94 "md_gost94"
-#define LN_id_GostR3411_94 "GOST R 34.11-94"
-#define NID_id_GostR3411_94 809
-#define OBJ_id_GostR3411_94 OBJ_cryptopro,9L
-
-#define SN_id_HMACGostR3411_94 "id-HMACGostR3411-94"
-#define LN_id_HMACGostR3411_94 "HMAC GOST 34.11-94"
-#define NID_id_HMACGostR3411_94 810
-#define OBJ_id_HMACGostR3411_94 OBJ_cryptopro,10L
-
-#define SN_id_GostR3410_2001 "gost2001"
-#define LN_id_GostR3410_2001 "GOST R 34.10-2001"
-#define NID_id_GostR3410_2001 811
-#define OBJ_id_GostR3410_2001 OBJ_cryptopro,19L
-
-#define SN_id_GostR3410_94 "gost94"
-#define LN_id_GostR3410_94 "GOST R 34.10-94"
-#define NID_id_GostR3410_94 812
-#define OBJ_id_GostR3410_94 OBJ_cryptopro,20L
-
-#define SN_id_Gost28147_89 "gost89"
-#define LN_id_Gost28147_89 "GOST 28147-89"
-#define NID_id_Gost28147_89 813
-#define OBJ_id_Gost28147_89 OBJ_cryptopro,21L
-
-#define SN_gost89_cnt "gost89-cnt"
-#define NID_gost89_cnt 814
-
-#define SN_id_Gost28147_89_MAC "gost-mac"
-#define LN_id_Gost28147_89_MAC "GOST 28147-89 MAC"
-#define NID_id_Gost28147_89_MAC 815
-#define OBJ_id_Gost28147_89_MAC OBJ_cryptopro,22L
-
-#define SN_id_GostR3411_94_prf "prf-gostr3411-94"
-#define LN_id_GostR3411_94_prf "GOST R 34.11-94 PRF"
-#define NID_id_GostR3411_94_prf 816
-#define OBJ_id_GostR3411_94_prf OBJ_cryptopro,23L
-
-#define SN_id_GostR3410_2001DH "id-GostR3410-2001DH"
-#define LN_id_GostR3410_2001DH "GOST R 34.10-2001 DH"
-#define NID_id_GostR3410_2001DH 817
-#define OBJ_id_GostR3410_2001DH OBJ_cryptopro,98L
-
-#define SN_id_GostR3410_94DH "id-GostR3410-94DH"
-#define LN_id_GostR3410_94DH "GOST R 34.10-94 DH"
-#define NID_id_GostR3410_94DH 818
-#define OBJ_id_GostR3410_94DH OBJ_cryptopro,99L
-
-#define SN_id_Gost28147_89_CryptoPro_KeyMeshing "id-Gost28147-89-CryptoPro-KeyMeshing"
-#define NID_id_Gost28147_89_CryptoPro_KeyMeshing 819
-#define OBJ_id_Gost28147_89_CryptoPro_KeyMeshing OBJ_cryptopro,14L,1L
-
-#define SN_id_Gost28147_89_None_KeyMeshing "id-Gost28147-89-None-KeyMeshing"
-#define NID_id_Gost28147_89_None_KeyMeshing 820
-#define OBJ_id_Gost28147_89_None_KeyMeshing OBJ_cryptopro,14L,0L
-
-#define SN_id_GostR3411_94_TestParamSet "id-GostR3411-94-TestParamSet"
-#define NID_id_GostR3411_94_TestParamSet 821
-#define OBJ_id_GostR3411_94_TestParamSet OBJ_cryptopro,30L,0L
-
-#define SN_id_GostR3411_94_CryptoProParamSet "id-GostR3411-94-CryptoProParamSet"
-#define NID_id_GostR3411_94_CryptoProParamSet 822
-#define OBJ_id_GostR3411_94_CryptoProParamSet OBJ_cryptopro,30L,1L
-
-#define SN_id_Gost28147_89_TestParamSet "id-Gost28147-89-TestParamSet"
-#define NID_id_Gost28147_89_TestParamSet 823
-#define OBJ_id_Gost28147_89_TestParamSet OBJ_cryptopro,31L,0L
-
-#define SN_id_Gost28147_89_CryptoPro_A_ParamSet "id-Gost28147-89-CryptoPro-A-ParamSet"
-#define NID_id_Gost28147_89_CryptoPro_A_ParamSet 824
-#define OBJ_id_Gost28147_89_CryptoPro_A_ParamSet OBJ_cryptopro,31L,1L
-
-#define SN_id_Gost28147_89_CryptoPro_B_ParamSet "id-Gost28147-89-CryptoPro-B-ParamSet"
-#define NID_id_Gost28147_89_CryptoPro_B_ParamSet 825
-#define OBJ_id_Gost28147_89_CryptoPro_B_ParamSet OBJ_cryptopro,31L,2L
-
-#define SN_id_Gost28147_89_CryptoPro_C_ParamSet "id-Gost28147-89-CryptoPro-C-ParamSet"
-#define NID_id_Gost28147_89_CryptoPro_C_ParamSet 826
-#define OBJ_id_Gost28147_89_CryptoPro_C_ParamSet OBJ_cryptopro,31L,3L
-
-#define SN_id_Gost28147_89_CryptoPro_D_ParamSet "id-Gost28147-89-CryptoPro-D-ParamSet"
-#define NID_id_Gost28147_89_CryptoPro_D_ParamSet 827
-#define OBJ_id_Gost28147_89_CryptoPro_D_ParamSet OBJ_cryptopro,31L,4L
-
-#define SN_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet"
-#define NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet 828
-#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet OBJ_cryptopro,31L,5L
-
-#define SN_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet"
-#define NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet 829
-#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet OBJ_cryptopro,31L,6L
-
-#define SN_id_Gost28147_89_CryptoPro_RIC_1_ParamSet "id-Gost28147-89-CryptoPro-RIC-1-ParamSet"
-#define NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet 830
-#define OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet OBJ_cryptopro,31L,7L
-
-#define SN_id_GostR3410_94_TestParamSet "id-GostR3410-94-TestParamSet"
-#define NID_id_GostR3410_94_TestParamSet 831
-#define OBJ_id_GostR3410_94_TestParamSet OBJ_cryptopro,32L,0L
-
-#define SN_id_GostR3410_94_CryptoPro_A_ParamSet "id-GostR3410-94-CryptoPro-A-ParamSet"
-#define NID_id_GostR3410_94_CryptoPro_A_ParamSet 832
-#define OBJ_id_GostR3410_94_CryptoPro_A_ParamSet OBJ_cryptopro,32L,2L
-
-#define SN_id_GostR3410_94_CryptoPro_B_ParamSet "id-GostR3410-94-CryptoPro-B-ParamSet"
-#define NID_id_GostR3410_94_CryptoPro_B_ParamSet 833
-#define OBJ_id_GostR3410_94_CryptoPro_B_ParamSet OBJ_cryptopro,32L,3L
-
-#define SN_id_GostR3410_94_CryptoPro_C_ParamSet "id-GostR3410-94-CryptoPro-C-ParamSet"
-#define NID_id_GostR3410_94_CryptoPro_C_ParamSet 834
-#define OBJ_id_GostR3410_94_CryptoPro_C_ParamSet OBJ_cryptopro,32L,4L
-
-#define SN_id_GostR3410_94_CryptoPro_D_ParamSet "id-GostR3410-94-CryptoPro-D-ParamSet"
-#define NID_id_GostR3410_94_CryptoPro_D_ParamSet 835
-#define OBJ_id_GostR3410_94_CryptoPro_D_ParamSet OBJ_cryptopro,32L,5L
-
-#define SN_id_GostR3410_94_CryptoPro_XchA_ParamSet "id-GostR3410-94-CryptoPro-XchA-ParamSet"
-#define NID_id_GostR3410_94_CryptoPro_XchA_ParamSet 836
-#define OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet OBJ_cryptopro,33L,1L
-
-#define SN_id_GostR3410_94_CryptoPro_XchB_ParamSet "id-GostR3410-94-CryptoPro-XchB-ParamSet"
-#define NID_id_GostR3410_94_CryptoPro_XchB_ParamSet 837
-#define OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet OBJ_cryptopro,33L,2L
-
-#define SN_id_GostR3410_94_CryptoPro_XchC_ParamSet "id-GostR3410-94-CryptoPro-XchC-ParamSet"
-#define NID_id_GostR3410_94_CryptoPro_XchC_ParamSet 838
-#define OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet OBJ_cryptopro,33L,3L
-
-#define SN_id_GostR3410_2001_TestParamSet "id-GostR3410-2001-TestParamSet"
-#define NID_id_GostR3410_2001_TestParamSet 839
-#define OBJ_id_GostR3410_2001_TestParamSet OBJ_cryptopro,35L,0L
-
-#define SN_id_GostR3410_2001_CryptoPro_A_ParamSet "id-GostR3410-2001-CryptoPro-A-ParamSet"
-#define NID_id_GostR3410_2001_CryptoPro_A_ParamSet 840
-#define OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet OBJ_cryptopro,35L,1L
-
-#define SN_id_GostR3410_2001_CryptoPro_B_ParamSet "id-GostR3410-2001-CryptoPro-B-ParamSet"
-#define NID_id_GostR3410_2001_CryptoPro_B_ParamSet 841
-#define OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet OBJ_cryptopro,35L,2L
-
-#define SN_id_GostR3410_2001_CryptoPro_C_ParamSet "id-GostR3410-2001-CryptoPro-C-ParamSet"
-#define NID_id_GostR3410_2001_CryptoPro_C_ParamSet 842
-#define OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet OBJ_cryptopro,35L,3L
-
-#define SN_id_GostR3410_2001_CryptoPro_XchA_ParamSet "id-GostR3410-2001-CryptoPro-XchA-ParamSet"
-#define NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet 843
-#define OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet OBJ_cryptopro,36L,0L
-
-#define SN_id_GostR3410_2001_CryptoPro_XchB_ParamSet "id-GostR3410-2001-CryptoPro-XchB-ParamSet"
-#define NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet 844
-#define OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet OBJ_cryptopro,36L,1L
-
-#define SN_id_GostR3410_94_a "id-GostR3410-94-a"
-#define NID_id_GostR3410_94_a 845
-#define OBJ_id_GostR3410_94_a OBJ_id_GostR3410_94,1L
-
-#define SN_id_GostR3410_94_aBis "id-GostR3410-94-aBis"
-#define NID_id_GostR3410_94_aBis 846
-#define OBJ_id_GostR3410_94_aBis OBJ_id_GostR3410_94,2L
-
-#define SN_id_GostR3410_94_b "id-GostR3410-94-b"
-#define NID_id_GostR3410_94_b 847
-#define OBJ_id_GostR3410_94_b OBJ_id_GostR3410_94,3L
-
-#define SN_id_GostR3410_94_bBis "id-GostR3410-94-bBis"
-#define NID_id_GostR3410_94_bBis 848
-#define OBJ_id_GostR3410_94_bBis OBJ_id_GostR3410_94,4L
-
-#define SN_id_Gost28147_89_cc "id-Gost28147-89-cc"
-#define LN_id_Gost28147_89_cc "GOST 28147-89 Cryptocom ParamSet"
-#define NID_id_Gost28147_89_cc 849
-#define OBJ_id_Gost28147_89_cc OBJ_cryptocom,1L,6L,1L
-
-#define SN_id_GostR3410_94_cc "gost94cc"
-#define LN_id_GostR3410_94_cc "GOST 34.10-94 Cryptocom"
-#define NID_id_GostR3410_94_cc 850
-#define OBJ_id_GostR3410_94_cc OBJ_cryptocom,1L,5L,3L
-
-#define SN_id_GostR3410_2001_cc "gost2001cc"
-#define LN_id_GostR3410_2001_cc "GOST 34.10-2001 Cryptocom"
-#define NID_id_GostR3410_2001_cc 851
-#define OBJ_id_GostR3410_2001_cc OBJ_cryptocom,1L,5L,4L
-
-#define SN_id_GostR3411_94_with_GostR3410_94_cc "id-GostR3411-94-with-GostR3410-94-cc"
-#define LN_id_GostR3411_94_with_GostR3410_94_cc "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom"
-#define NID_id_GostR3411_94_with_GostR3410_94_cc 852
-#define OBJ_id_GostR3411_94_with_GostR3410_94_cc OBJ_cryptocom,1L,3L,3L
-
-#define SN_id_GostR3411_94_with_GostR3410_2001_cc "id-GostR3411-94-with-GostR3410-2001-cc"
-#define LN_id_GostR3411_94_with_GostR3410_2001_cc "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom"
-#define NID_id_GostR3411_94_with_GostR3410_2001_cc 853
-#define OBJ_id_GostR3411_94_with_GostR3410_2001_cc OBJ_cryptocom,1L,3L,4L
-
-#define SN_id_GostR3410_2001_ParamSet_cc "id-GostR3410-2001-ParamSet-cc"
-#define LN_id_GostR3410_2001_ParamSet_cc "GOST R 3410-2001 Parameter Set Cryptocom"
-#define NID_id_GostR3410_2001_ParamSet_cc 854
-#define OBJ_id_GostR3410_2001_ParamSet_cc OBJ_cryptocom,1L,8L,1L
-
-#define SN_camellia_128_cbc "CAMELLIA-128-CBC"
-#define LN_camellia_128_cbc "camellia-128-cbc"
-#define NID_camellia_128_cbc 751
-#define OBJ_camellia_128_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,2L
-
-#define SN_camellia_192_cbc "CAMELLIA-192-CBC"
-#define LN_camellia_192_cbc "camellia-192-cbc"
-#define NID_camellia_192_cbc 752
-#define OBJ_camellia_192_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,3L
-
-#define SN_camellia_256_cbc "CAMELLIA-256-CBC"
-#define LN_camellia_256_cbc "camellia-256-cbc"
-#define NID_camellia_256_cbc 753
-#define OBJ_camellia_256_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,4L
-
-#define SN_id_camellia128_wrap "id-camellia128-wrap"
-#define NID_id_camellia128_wrap 907
-#define OBJ_id_camellia128_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,2L
-
-#define SN_id_camellia192_wrap "id-camellia192-wrap"
-#define NID_id_camellia192_wrap 908
-#define OBJ_id_camellia192_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,3L
-
-#define SN_id_camellia256_wrap "id-camellia256-wrap"
-#define NID_id_camellia256_wrap 909
-#define OBJ_id_camellia256_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,4L
-
-#define OBJ_ntt_ds 0L,3L,4401L,5L
-
-#define OBJ_camellia OBJ_ntt_ds,3L,1L,9L
-
-#define SN_camellia_128_ecb "CAMELLIA-128-ECB"
-#define LN_camellia_128_ecb "camellia-128-ecb"
-#define NID_camellia_128_ecb 754
-#define OBJ_camellia_128_ecb OBJ_camellia,1L
-
-#define SN_camellia_128_ofb128 "CAMELLIA-128-OFB"
-#define LN_camellia_128_ofb128 "camellia-128-ofb"
-#define NID_camellia_128_ofb128 766
-#define OBJ_camellia_128_ofb128 OBJ_camellia,3L
-
-#define SN_camellia_128_cfb128 "CAMELLIA-128-CFB"
-#define LN_camellia_128_cfb128 "camellia-128-cfb"
-#define NID_camellia_128_cfb128 757
-#define OBJ_camellia_128_cfb128 OBJ_camellia,4L
-
-#define SN_camellia_192_ecb "CAMELLIA-192-ECB"
-#define LN_camellia_192_ecb "camellia-192-ecb"
-#define NID_camellia_192_ecb 755
-#define OBJ_camellia_192_ecb OBJ_camellia,21L
-
-#define SN_camellia_192_ofb128 "CAMELLIA-192-OFB"
-#define LN_camellia_192_ofb128 "camellia-192-ofb"
-#define NID_camellia_192_ofb128 767
-#define OBJ_camellia_192_ofb128 OBJ_camellia,23L
-
-#define SN_camellia_192_cfb128 "CAMELLIA-192-CFB"
-#define LN_camellia_192_cfb128 "camellia-192-cfb"
-#define NID_camellia_192_cfb128 758
-#define OBJ_camellia_192_cfb128 OBJ_camellia,24L
-
-#define SN_camellia_256_ecb "CAMELLIA-256-ECB"
-#define LN_camellia_256_ecb "camellia-256-ecb"
-#define NID_camellia_256_ecb 756
-#define OBJ_camellia_256_ecb OBJ_camellia,41L
-
-#define SN_camellia_256_ofb128 "CAMELLIA-256-OFB"
-#define LN_camellia_256_ofb128 "camellia-256-ofb"
-#define NID_camellia_256_ofb128 768
-#define OBJ_camellia_256_ofb128 OBJ_camellia,43L
-
-#define SN_camellia_256_cfb128 "CAMELLIA-256-CFB"
-#define LN_camellia_256_cfb128 "camellia-256-cfb"
-#define NID_camellia_256_cfb128 759
-#define OBJ_camellia_256_cfb128 OBJ_camellia,44L
-
-#define SN_camellia_128_cfb1 "CAMELLIA-128-CFB1"
-#define LN_camellia_128_cfb1 "camellia-128-cfb1"
-#define NID_camellia_128_cfb1 760
-
-#define SN_camellia_192_cfb1 "CAMELLIA-192-CFB1"
-#define LN_camellia_192_cfb1 "camellia-192-cfb1"
-#define NID_camellia_192_cfb1 761
-
-#define SN_camellia_256_cfb1 "CAMELLIA-256-CFB1"
-#define LN_camellia_256_cfb1 "camellia-256-cfb1"
-#define NID_camellia_256_cfb1 762
-
-#define SN_camellia_128_cfb8 "CAMELLIA-128-CFB8"
-#define LN_camellia_128_cfb8 "camellia-128-cfb8"
-#define NID_camellia_128_cfb8 763
-
-#define SN_camellia_192_cfb8 "CAMELLIA-192-CFB8"
-#define LN_camellia_192_cfb8 "camellia-192-cfb8"
-#define NID_camellia_192_cfb8 764
-
-#define SN_camellia_256_cfb8 "CAMELLIA-256-CFB8"
-#define LN_camellia_256_cfb8 "camellia-256-cfb8"
-#define NID_camellia_256_cfb8 765
-
-#define SN_kisa "KISA"
-#define LN_kisa "kisa"
-#define NID_kisa 773
-#define OBJ_kisa OBJ_member_body,410L,200004L
-
-#define SN_seed_ecb "SEED-ECB"
-#define LN_seed_ecb "seed-ecb"
-#define NID_seed_ecb 776
-#define OBJ_seed_ecb OBJ_kisa,1L,3L
-
-#define SN_seed_cbc "SEED-CBC"
-#define LN_seed_cbc "seed-cbc"
-#define NID_seed_cbc 777
-#define OBJ_seed_cbc OBJ_kisa,1L,4L
-
-#define SN_seed_cfb128 "SEED-CFB"
-#define LN_seed_cfb128 "seed-cfb"
-#define NID_seed_cfb128 779
-#define OBJ_seed_cfb128 OBJ_kisa,1L,5L
-
-#define SN_seed_ofb128 "SEED-OFB"
-#define LN_seed_ofb128 "seed-ofb"
-#define NID_seed_ofb128 778
-#define OBJ_seed_ofb128 OBJ_kisa,1L,6L
-
-#define SN_hmac "HMAC"
-#define LN_hmac "hmac"
-#define NID_hmac 855
-
-#define SN_cmac "CMAC"
-#define LN_cmac "cmac"
-#define NID_cmac 894
-
-#define SN_rc4_hmac_md5 "RC4-HMAC-MD5"
-#define LN_rc4_hmac_md5 "rc4-hmac-md5"
-#define NID_rc4_hmac_md5 915
-
-#define SN_aes_128_cbc_hmac_sha1 "AES-128-CBC-HMAC-SHA1"
-#define LN_aes_128_cbc_hmac_sha1 "aes-128-cbc-hmac-sha1"
-#define NID_aes_128_cbc_hmac_sha1 916
-
-#define SN_aes_192_cbc_hmac_sha1 "AES-192-CBC-HMAC-SHA1"
-#define LN_aes_192_cbc_hmac_sha1 "aes-192-cbc-hmac-sha1"
-#define NID_aes_192_cbc_hmac_sha1 917
-
-#define SN_aes_256_cbc_hmac_sha1 "AES-256-CBC-HMAC-SHA1"
-#define LN_aes_256_cbc_hmac_sha1 "aes-256-cbc-hmac-sha1"
-#define NID_aes_256_cbc_hmac_sha1 918
-
-#define SN_dhpublicnumber "dhpublicnumber"
-#define LN_dhpublicnumber "X9.42 DH"
-#define NID_dhpublicnumber 920
-#define OBJ_dhpublicnumber OBJ_ISO_US,10046L,2L,1L
-
-#define SN_brainpoolP160r1 "brainpoolP160r1"
-#define NID_brainpoolP160r1 921
-#define OBJ_brainpoolP160r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,1L
-
-#define SN_brainpoolP160t1 "brainpoolP160t1"
-#define NID_brainpoolP160t1 922
-#define OBJ_brainpoolP160t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,2L
-
-#define SN_brainpoolP192r1 "brainpoolP192r1"
-#define NID_brainpoolP192r1 923
-#define OBJ_brainpoolP192r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,3L
-
-#define SN_brainpoolP192t1 "brainpoolP192t1"
-#define NID_brainpoolP192t1 924
-#define OBJ_brainpoolP192t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,4L
-
-#define SN_brainpoolP224r1 "brainpoolP224r1"
-#define NID_brainpoolP224r1 925
-#define OBJ_brainpoolP224r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,5L
-
-#define SN_brainpoolP224t1 "brainpoolP224t1"
-#define NID_brainpoolP224t1 926
-#define OBJ_brainpoolP224t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,6L
-
-#define SN_brainpoolP256r1 "brainpoolP256r1"
-#define NID_brainpoolP256r1 927
-#define OBJ_brainpoolP256r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,7L
-
-#define SN_brainpoolP256t1 "brainpoolP256t1"
-#define NID_brainpoolP256t1 928
-#define OBJ_brainpoolP256t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,8L
-
-#define SN_brainpoolP320r1 "brainpoolP320r1"
-#define NID_brainpoolP320r1 929
-#define OBJ_brainpoolP320r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,9L
-
-#define SN_brainpoolP320t1 "brainpoolP320t1"
-#define NID_brainpoolP320t1 930
-#define OBJ_brainpoolP320t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,10L
-
-#define SN_brainpoolP384r1 "brainpoolP384r1"
-#define NID_brainpoolP384r1 931
-#define OBJ_brainpoolP384r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,11L
-
-#define SN_brainpoolP384t1 "brainpoolP384t1"
-#define NID_brainpoolP384t1 932
-#define OBJ_brainpoolP384t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,12L
-
-#define SN_brainpoolP512r1 "brainpoolP512r1"
-#define NID_brainpoolP512r1 933
-#define OBJ_brainpoolP512r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,13L
-
-#define SN_brainpoolP512t1 "brainpoolP512t1"
-#define NID_brainpoolP512t1 934
-#define OBJ_brainpoolP512t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,14L
-
-#define OBJ_x9_63_scheme 1L,3L,133L,16L,840L,63L,0L
-
-#define OBJ_secg_scheme OBJ_certicom_arc,1L
-
-#define SN_dhSinglePass_stdDH_sha1kdf_scheme "dhSinglePass-stdDH-sha1kdf-scheme"
-#define NID_dhSinglePass_stdDH_sha1kdf_scheme 936
-#define OBJ_dhSinglePass_stdDH_sha1kdf_scheme OBJ_x9_63_scheme,2L
-
-#define SN_dhSinglePass_stdDH_sha224kdf_scheme "dhSinglePass-stdDH-sha224kdf-scheme"
-#define NID_dhSinglePass_stdDH_sha224kdf_scheme 937
-#define OBJ_dhSinglePass_stdDH_sha224kdf_scheme OBJ_secg_scheme,11L,0L
-
-#define SN_dhSinglePass_stdDH_sha256kdf_scheme "dhSinglePass-stdDH-sha256kdf-scheme"
-#define NID_dhSinglePass_stdDH_sha256kdf_scheme 938
-#define OBJ_dhSinglePass_stdDH_sha256kdf_scheme OBJ_secg_scheme,11L,1L
-
-#define SN_dhSinglePass_stdDH_sha384kdf_scheme "dhSinglePass-stdDH-sha384kdf-scheme"
-#define NID_dhSinglePass_stdDH_sha384kdf_scheme 939
-#define OBJ_dhSinglePass_stdDH_sha384kdf_scheme OBJ_secg_scheme,11L,2L
-
-#define SN_dhSinglePass_stdDH_sha512kdf_scheme "dhSinglePass-stdDH-sha512kdf-scheme"
-#define NID_dhSinglePass_stdDH_sha512kdf_scheme 940
-#define OBJ_dhSinglePass_stdDH_sha512kdf_scheme OBJ_secg_scheme,11L,3L
-
-#define SN_dhSinglePass_cofactorDH_sha1kdf_scheme "dhSinglePass-cofactorDH-sha1kdf-scheme"
-#define NID_dhSinglePass_cofactorDH_sha1kdf_scheme 941
-#define OBJ_dhSinglePass_cofactorDH_sha1kdf_scheme OBJ_x9_63_scheme,3L
-
-#define SN_dhSinglePass_cofactorDH_sha224kdf_scheme "dhSinglePass-cofactorDH-sha224kdf-scheme"
-#define NID_dhSinglePass_cofactorDH_sha224kdf_scheme 942
-#define OBJ_dhSinglePass_cofactorDH_sha224kdf_scheme OBJ_secg_scheme,14L,0L
-
-#define SN_dhSinglePass_cofactorDH_sha256kdf_scheme "dhSinglePass-cofactorDH-sha256kdf-scheme"
-#define NID_dhSinglePass_cofactorDH_sha256kdf_scheme 943
-#define OBJ_dhSinglePass_cofactorDH_sha256kdf_scheme OBJ_secg_scheme,14L,1L
-
-#define SN_dhSinglePass_cofactorDH_sha384kdf_scheme "dhSinglePass-cofactorDH-sha384kdf-scheme"
-#define NID_dhSinglePass_cofactorDH_sha384kdf_scheme 944
-#define OBJ_dhSinglePass_cofactorDH_sha384kdf_scheme OBJ_secg_scheme,14L,2L
-
-#define SN_dhSinglePass_cofactorDH_sha512kdf_scheme "dhSinglePass-cofactorDH-sha512kdf-scheme"
-#define NID_dhSinglePass_cofactorDH_sha512kdf_scheme 945
-#define OBJ_dhSinglePass_cofactorDH_sha512kdf_scheme OBJ_secg_scheme,14L,3L
-
-#define SN_dh_std_kdf "dh-std-kdf"
-#define NID_dh_std_kdf 946
-
-#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
-
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+/* This header is provided in order to make compiling against code that expects
+ OpenSSL easier. */
+
+#include "nid.h"
diff --git a/src/include/openssl/opensslfeatures.h b/src/include/openssl/opensslconf.h
index c3f97d5a..bf65fc3b 100644
--- a/src/include/openssl/opensslfeatures.h
+++ b/src/include/openssl/opensslconf.h
@@ -15,8 +15,8 @@
/* This header is provided in order to make compiling against code that expects
OpenSSL easier. */
-#ifndef OPENSSL_HEADER_OPENSSLFEATURES_H
-#define OPENSSL_HEADER_OPENSSLFEATURES_H
+#ifndef OPENSSL_HEADER_OPENSSLCONF_H
+#define OPENSSL_HEADER_OPENSSLCONF_H
#define OPENSSL_NO_BF
@@ -57,4 +57,4 @@
#define OPENSSL_NO_WHIRLPOOL
-#endif /* OPENSSL_HEADER_OPENSSLFEATURES_H */
+#endif /* OPENSSL_HEADER_OPENSSLCONF_H */
diff --git a/src/include/openssl/pem.h b/src/include/openssl/pem.h
index a6687a69..b899d9f7 100644
--- a/src/include/openssl/pem.h
+++ b/src/include/openssl/pem.h
@@ -120,6 +120,7 @@ extern "C" {
#define PEM_STRING_RSA_PUBLIC "RSA PUBLIC KEY"
#define PEM_STRING_DSA "DSA PRIVATE KEY"
#define PEM_STRING_DSA_PUBLIC "DSA PUBLIC KEY"
+#define PEM_STRING_EC "EC PRIVATE KEY"
#define PEM_STRING_PKCS7 "PKCS7"
#define PEM_STRING_PKCS7_SIGNED "PKCS #7 SIGNED DATA"
#define PEM_STRING_PKCS8 "ENCRYPTED PRIVATE KEY"
@@ -129,7 +130,6 @@ extern "C" {
#define PEM_STRING_DSAPARAMS "DSA PARAMETERS"
#define PEM_STRING_ECDSA_PUBLIC "ECDSA PUBLIC KEY"
#define PEM_STRING_ECPRIVATEKEY "EC PRIVATE KEY"
-#define PEM_STRING_PARAMETERS "PARAMETERS"
#define PEM_STRING_CMS "CMS"
/* Note that this structure is initialised by PEM_SealInit and cleaned up
@@ -477,10 +477,6 @@ OPENSSL_EXPORT EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_pass
OPENSSL_EXPORT int PEM_write_PKCS8PrivateKey(FILE *fp,EVP_PKEY *x,const EVP_CIPHER *enc, char *kstr,int klen, pem_password_cb *cd, void *u);
-OPENSSL_EXPORT EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x);
-OPENSSL_EXPORT int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x);
-
-
OPENSSL_EXPORT EVP_PKEY *b2i_PrivateKey(const unsigned char **in, long length);
OPENSSL_EXPORT EVP_PKEY *b2i_PublicKey(const unsigned char **in, long length);
OPENSSL_EXPORT EVP_PKEY *b2i_PrivateKey_bio(BIO *in);
diff --git a/src/include/openssl/pkcs8.h b/src/include/openssl/pkcs8.h
index 6b51f855..28cf6ac1 100644
--- a/src/include/openssl/pkcs8.h
+++ b/src/include/openssl/pkcs8.h
@@ -139,12 +139,16 @@ OPENSSL_EXPORT PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(X509_SIG *pkcs8,
OPENSSL_EXPORT void PKCS12_PBE_add(void);
/* d2i_PKCS12 is a dummy function that copies |*ber_bytes| into a
- * |PKCS12| structure. The |out_p12| argument must be NULL. On exit,
+ * |PKCS12| structure. The |out_p12| argument should be NULL(✝). On exit,
* |*ber_bytes| will be advanced by |ber_len|. It returns a fresh |PKCS12|
* structure or NULL on error.
*
* Note: unlike other d2i functions, |d2i_PKCS12| will always consume |ber_len|
- * bytes.*/
+ * bytes.
+ *
+ * (✝) If |out_p12| is not NULL and the function is successful, |*out_p12| will
+ * be freed if not NULL itself and the result will be written to |*out_p12|.
+ * New code should not depend on this. */
OPENSSL_EXPORT PKCS12 *d2i_PKCS12(PKCS12 **out_p12, const uint8_t **ber_bytes,
size_t ber_len);
diff --git a/src/include/openssl/rand.h b/src/include/openssl/rand.h
index 3a8e357c..322249c9 100644
--- a/src/include/openssl/rand.h
+++ b/src/include/openssl/rand.h
@@ -62,6 +62,12 @@ OPENSSL_EXPORT void RAND_set_urandom_fd(int fd);
OPENSSL_EXPORT void RAND_enable_fork_unsafe_buffering(int fd);
#endif
+#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
+/* RAND_reset_for_fuzzing resets the fuzzer-only deterministic RNG. This
+ * function is only defined in the fuzzer-only build configuration. */
+OPENSSL_EXPORT void RAND_reset_for_fuzzing(void);
+#endif
+
/* Deprecated functions */
@@ -75,6 +81,9 @@ OPENSSL_EXPORT void RAND_seed(const void *buf, int num);
/* RAND_load_file returns a nonnegative number. */
OPENSSL_EXPORT int RAND_load_file(const char *path, long num);
+/* RAND_file_name returns NULL. */
+OPENSSL_EXPORT const char *RAND_file_name(char *buf, size_t num);
+
/* RAND_add does nothing. */
OPENSSL_EXPORT void RAND_add(const void *buf, int num, double entropy);
diff --git a/src/include/openssl/rc4.h b/src/include/openssl/rc4.h
index 0619cac3..68af8782 100644
--- a/src/include/openssl/rc4.h
+++ b/src/include/openssl/rc4.h
@@ -83,6 +83,12 @@ OPENSSL_EXPORT void RC4(RC4_KEY *key, size_t len, const uint8_t *in,
uint8_t *out);
+/* Deprecated functions. */
+
+/* RC4_options returns the string "rc4(ptr,int)". */
+OPENSSL_EXPORT const char *RC4_options(void);
+
+
#if defined(__cplusplus)
} /* extern C */
#endif
diff --git a/src/crypto/asn1/t_pkey.c b/src/include/openssl/ripemd.h
index 6ac9b3d6..cf1e49e2 100644
--- a/src/crypto/asn1/t_pkey.c
+++ b/src/include/openssl/ripemd.h
@@ -54,59 +54,54 @@
* copied and put under another distribution licence
* [including the GNU Public Licence.] */
-#include <openssl/asn1.h>
+#ifndef OPENSSL_HEADER_RIPEMD_H
+#define OPENSSL_HEADER_RIPEMD_H
-#include <openssl/bio.h>
-#include <openssl/mem.h>
+#include <openssl/base.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
-int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num,
- unsigned char *buf, int off)
- {
- int n,i;
- const char *neg;
- if (num == NULL) return(1);
- neg = (BN_is_negative(num))?"-":"";
- if(!BIO_indent(bp,off,128))
- return 0;
- if (BN_is_zero(num))
- {
- if (BIO_printf(bp, "%s 0\n", number) <= 0)
- return 0;
- return 1;
- }
+# define RIPEMD160_CBLOCK 64
+# define RIPEMD160_LBLOCK (RIPEMD160_CBLOCK/4)
+# define RIPEMD160_DIGEST_LENGTH 20
- if (BN_num_bytes(num) <= sizeof(long))
- {
- if (BIO_printf(bp,"%s %s%lu (%s0x%lx)\n",number,neg,
- (unsigned long)num->d[0],neg,(unsigned long)num->d[0])
- <= 0) return(0);
- }
- else
- {
- buf[0]=0;
- if (BIO_printf(bp,"%s%s",number,
- (neg[0] == '-')?" (Negative)":"") <= 0)
- return(0);
- n=BN_bn2bin(num,&buf[1]);
-
- if (buf[1] & 0x80)
- n++;
- else buf++;
+struct RIPEMD160state_st {
+ uint32_t h[5];
+ uint32_t Nl, Nh;
+ uint8_t data[RIPEMD160_CBLOCK];
+ unsigned num;
+};
- for (i=0; i<n; i++)
- {
- if ((i%15) == 0)
- {
- if(BIO_puts(bp,"\n") <= 0
- || !BIO_indent(bp,off+4,128))
- return 0;
- }
- if (BIO_printf(bp,"%02x%s",buf[i],((i+1) == n)?"":":")
- <= 0) return(0);
- }
- if (BIO_write(bp,"\n",1) <= 0) return(0);
- }
- return(1);
- }
+/* RIPEMD160_Init initialises |ctx| and returns one. */
+OPENSSL_EXPORT int RIPEMD160_Init(RIPEMD160_CTX *ctx);
+
+/* RIPEMD160_Update adds |len| bytes from |data| to |ctx| and returns one. */
+OPENSSL_EXPORT int RIPEMD160_Update(RIPEMD160_CTX *ctx, const void *data,
+ size_t len);
+
+/* RIPEMD160_Final adds the final padding to |ctx| and writes the resulting
+ * digest to |md|, which must have at least |RIPEMD160_DIGEST_LENGTH| bytes of
+ * space. It returns one. */
+OPENSSL_EXPORT int RIPEMD160_Final(uint8_t *md, RIPEMD160_CTX *ctx);
+
+/* RIPEMD160 writes the digest of |len| bytes from |data| to |out| and returns
+ * |out|. There must be at least |RIPEMD160_DIGEST_LENGTH| bytes of space in
+ * |out|. */
+OPENSSL_EXPORT uint8_t *RIPEMD160(const uint8_t *data, size_t len,
+ uint8_t *out);
+
+/* RIPEMD160_Transform is a low-level function that performs a single,
+ * RIPEMD160 block transformation using the state from |ctx| and 64 bytes from
+ * |block|. */
+OPENSSL_EXPORT void RIPEMD160_Transform(RIPEMD160_CTX *ctx,
+ const uint8_t *block);
+
+
+#if defined(__cplusplus)
+} /* extern C */
+#endif
+
+#endif /* OPENSSL_HEADER_RIPEMD_H */
diff --git a/src/include/openssl/rsa.h b/src/include/openssl/rsa.h
index 304c5558..83fdf163 100644
--- a/src/include/openssl/rsa.h
+++ b/src/include/openssl/rsa.h
@@ -59,7 +59,6 @@
#include <openssl/base.h>
-#include <openssl/asn1.h>
#include <openssl/engine.h>
#include <openssl/ex_data.h>
#include <openssl/thread.h>
@@ -322,6 +321,17 @@ OPENSSL_EXPORT int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, uint8_t *EM,
const EVP_MD *mgf1Hash,
int sLen);
+/* RSA_padding_add_PKCS1_OAEP_mgf1 writes an OAEP padding of |from| to |to|
+ * with the given parameters and hash functions. If |md| is NULL then SHA-1 is
+ * used. If |mgf1md| is NULL then the value of |md| is used (which means SHA-1
+ * if that, in turn, is NULL).
+ *
+ * It returns one on success or zero on error. */
+OPENSSL_EXPORT 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);
+
/* 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,
@@ -400,20 +410,20 @@ OPENSSL_EXPORT void *RSA_get_ex_data(const RSA *r, int idx);
* API, like a platform key store. */
#define RSA_FLAG_OPAQUE 1
-/* RSA_FLAG_CACHE_PUBLIC causes a precomputed Montgomery context to be created,
- * on demand, for the public key operations. */
+/* Deprecated and ignored. */
#define RSA_FLAG_CACHE_PUBLIC 2
-/* RSA_FLAG_CACHE_PRIVATE causes a precomputed Montgomery context to be
- * created, on demand, for the private key operations. */
+/* Deprecated and ignored. */
#define RSA_FLAG_CACHE_PRIVATE 4
-/* RSA_FLAG_NO_BLINDING disables blinding of private operations. */
+/* RSA_FLAG_NO_BLINDING disables blinding of private operations, which is a
+ * dangerous thing to do. It is deprecated and may be ignored in the future.
+ *
+ * This flag must be used if a key without the public exponent |e| is used for
+ * private key operations; avoid using such keys whenever possible. */
#define RSA_FLAG_NO_BLINDING 8
-/* RSA_FLAG_EXT_PKEY means that private key operations will be handled by
- * |mod_exp| and that they do not depend on the private key components being
- * present: for example a key stored in external hardware. */
+/* RSA_FLAG_EXT_PKEY is deprecated and ignored. */
#define RSA_FLAG_EXT_PKEY 0x20
/* RSA_FLAG_SIGN_VER causes the |sign| and |verify| functions of |rsa_meth_st|
@@ -441,10 +451,10 @@ OPENSSL_EXPORT RSA *RSA_generate_key(int bits, unsigned long e, void *callback,
/* 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. */
+ * is in |*out|. Note that, even if |*out| is already non-NULL on entry, it
+ * will not be written to. Rather, a fresh |RSA| is allocated and the previous
+ * one is freed. 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
@@ -455,10 +465,10 @@ 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. */
+ * is in |*out|. Note that, even if |*out| is already non-NULL on entry, it
+ * will not be written to. Rather, a fresh |RSA| is allocated and the previous
+ * one is freed. 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
@@ -467,14 +477,26 @@ OPENSSL_EXPORT RSA *d2i_RSAPrivateKey(RSA **out, const uint8_t **inp, long len);
* 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;
+/* RSA_padding_add_PKCS1_PSS acts like |RSA_padding_add_PKCS1_PSS_mgf1| but the
+ * |mgf1Hash| parameter of the latter is implicitly set to |Hash|. */
+OPENSSL_EXPORT int RSA_padding_add_PKCS1_PSS(RSA *rsa, uint8_t *EM,
+ const uint8_t *mHash,
+ const EVP_MD *Hash, int sLen);
+
+/* RSA_verify_PKCS1_PSS acts like |RSA_verify_PKCS1_PSS_mgf1| but the
+ * |mgf1Hash| parameter of the latter is implicitly set to |Hash|. */
+OPENSSL_EXPORT int RSA_verify_PKCS1_PSS(RSA *rsa, const uint8_t *mHash,
+ const EVP_MD *Hash, const uint8_t *EM,
+ int sLen);
-DECLARE_ASN1_FUNCTIONS(RSA_PSS_PARAMS)
+/* RSA_padding_add_PKCS1_OAEP acts like |RSA_padding_add_PKCS1_OAEP_mgf1| but
+ * the |md| and |mgf1md| paramaters of the latter are implicitly set to NULL,
+ * which means SHA-1. */
+OPENSSL_EXPORT int RSA_padding_add_PKCS1_OAEP(uint8_t *to, unsigned to_len,
+ const uint8_t *from,
+ unsigned from_len,
+ const uint8_t *param,
+ unsigned param_len);
struct rsa_meth_st {
@@ -491,6 +513,7 @@ struct rsa_meth_st {
int (*sign)(int type, const uint8_t *m, unsigned int m_length,
uint8_t *sigret, unsigned int *siglen, const RSA *rsa);
+ /* Ignored. Set this to NULL. */
int (*verify)(int dtype, const uint8_t *m, unsigned int m_length,
const uint8_t *sigbuf, unsigned int siglen, const RSA *rsa);
@@ -503,6 +526,7 @@ struct rsa_meth_st {
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);
+ /* Ignored. Set this to NULL. */
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);
@@ -521,8 +545,10 @@ struct rsa_meth_st {
int (*private_transform)(RSA *rsa, uint8_t *out, const uint8_t *in,
size_t len);
- int (*mod_exp)(BIGNUM *r0, const BIGNUM *I, RSA *rsa,
- BN_CTX *ctx); /* Can be null */
+ /* mod_exp is deprecated and ignored. Set it to NULL. */
+ int (*mod_exp)(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
+
+ /* bn_mod_exp is deprecated and ignored. Set it to NULL. */
int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
const BIGNUM *m, BN_CTX *ctx,
const BN_MONT_CTX *mont);
@@ -587,51 +613,51 @@ struct rsa_st {
} /* extern C */
#endif
-#define RSA_R_BAD_E_VALUE 100
-#define RSA_R_BAD_FIXED_HEADER_DECRYPT 101
-#define RSA_R_BAD_PAD_BYTE_COUNT 102
-#define RSA_R_BAD_RSA_PARAMETERS 103
-#define RSA_R_BAD_SIGNATURE 104
-#define RSA_R_BLOCK_TYPE_IS_NOT_01 105
-#define RSA_R_BN_NOT_INITIALIZED 106
-#define RSA_R_CRT_PARAMS_ALREADY_GIVEN 107
-#define RSA_R_CRT_VALUES_INCORRECT 108
-#define RSA_R_DATA_LEN_NOT_EQUAL_TO_MOD_LEN 109
-#define RSA_R_DATA_TOO_LARGE 110
-#define RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 111
-#define RSA_R_DATA_TOO_LARGE_FOR_MODULUS 112
-#define RSA_R_DATA_TOO_SMALL 113
-#define RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE 114
-#define RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY 115
-#define RSA_R_D_E_NOT_CONGRUENT_TO_1 116
-#define RSA_R_EMPTY_PUBLIC_KEY 117
-#define RSA_R_FIRST_OCTET_INVALID 118
-#define RSA_R_INCONSISTENT_SET_OF_CRT_VALUES 119
-#define RSA_R_INTERNAL_ERROR 120
-#define RSA_R_INVALID_MESSAGE_LENGTH 121
-#define RSA_R_KEY_SIZE_TOO_SMALL 122
-#define RSA_R_LAST_OCTET_INVALID 123
-#define RSA_R_MODULUS_TOO_LARGE 124
-#define RSA_R_NO_PUBLIC_EXPONENT 125
-#define RSA_R_NULL_BEFORE_BLOCK_MISSING 126
-#define RSA_R_N_NOT_EQUAL_P_Q 127
-#define RSA_R_OAEP_DECODING_ERROR 128
-#define RSA_R_ONLY_ONE_OF_P_Q_GIVEN 129
-#define RSA_R_OUTPUT_BUFFER_TOO_SMALL 130
-#define RSA_R_PADDING_CHECK_FAILED 131
-#define RSA_R_PKCS_DECODING_ERROR 132
-#define RSA_R_SLEN_CHECK_FAILED 133
-#define RSA_R_SLEN_RECOVERY_FAILED 134
-#define RSA_R_TOO_LONG 135
-#define RSA_R_TOO_MANY_ITERATIONS 136
-#define RSA_R_UNKNOWN_ALGORITHM_TYPE 137
-#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
+#define RSA_R_BAD_ENCODING 100
+#define RSA_R_BAD_E_VALUE 101
+#define RSA_R_BAD_FIXED_HEADER_DECRYPT 102
+#define RSA_R_BAD_PAD_BYTE_COUNT 103
+#define RSA_R_BAD_RSA_PARAMETERS 104
+#define RSA_R_BAD_SIGNATURE 105
+#define RSA_R_BAD_VERSION 106
+#define RSA_R_BLOCK_TYPE_IS_NOT_01 107
+#define RSA_R_BN_NOT_INITIALIZED 108
+#define RSA_R_CANNOT_RECOVER_MULTI_PRIME_KEY 109
+#define RSA_R_CRT_PARAMS_ALREADY_GIVEN 110
+#define RSA_R_CRT_VALUES_INCORRECT 111
+#define RSA_R_DATA_LEN_NOT_EQUAL_TO_MOD_LEN 112
+#define RSA_R_DATA_TOO_LARGE 113
+#define RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 114
+#define RSA_R_DATA_TOO_LARGE_FOR_MODULUS 115
+#define RSA_R_DATA_TOO_SMALL 116
+#define RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE 117
+#define RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY 118
+#define RSA_R_D_E_NOT_CONGRUENT_TO_1 119
+#define RSA_R_EMPTY_PUBLIC_KEY 120
+#define RSA_R_ENCODE_ERROR 121
+#define RSA_R_FIRST_OCTET_INVALID 122
+#define RSA_R_INCONSISTENT_SET_OF_CRT_VALUES 123
+#define RSA_R_INTERNAL_ERROR 124
+#define RSA_R_INVALID_MESSAGE_LENGTH 125
+#define RSA_R_KEY_SIZE_TOO_SMALL 126
+#define RSA_R_LAST_OCTET_INVALID 127
+#define RSA_R_MODULUS_TOO_LARGE 128
+#define RSA_R_MUST_HAVE_AT_LEAST_TWO_PRIMES 129
+#define RSA_R_NO_PUBLIC_EXPONENT 130
+#define RSA_R_NULL_BEFORE_BLOCK_MISSING 131
+#define RSA_R_N_NOT_EQUAL_P_Q 132
+#define RSA_R_OAEP_DECODING_ERROR 133
+#define RSA_R_ONLY_ONE_OF_P_Q_GIVEN 134
+#define RSA_R_OUTPUT_BUFFER_TOO_SMALL 135
+#define RSA_R_PADDING_CHECK_FAILED 136
+#define RSA_R_PKCS_DECODING_ERROR 137
+#define RSA_R_SLEN_CHECK_FAILED 138
+#define RSA_R_SLEN_RECOVERY_FAILED 139
+#define RSA_R_TOO_LONG 140
+#define RSA_R_TOO_MANY_ITERATIONS 141
+#define RSA_R_UNKNOWN_ALGORITHM_TYPE 142
+#define RSA_R_UNKNOWN_PADDING_TYPE 143
+#define RSA_R_VALUE_MISSING 144
+#define RSA_R_WRONG_SIGNATURE_LENGTH 145
#endif /* OPENSSL_HEADER_RSA_H */
diff --git a/src/include/openssl/ssl.h b/src/include/openssl/ssl.h
index dcfee915..1d0b4867 100644
--- a/src/include/openssl/ssl.h
+++ b/src/include/openssl/ssl.h
@@ -251,25 +251,39 @@ OPENSSL_EXPORT int SSL_get_fd(const SSL *ssl);
/* 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. */
+ * descriptor then it returns -1.
+ *
+ * Note: On Windows, this may return either a file descriptor or a socket (cast
+ * to int), depending on whether |ssl| was configured with a file descriptor or
+ * socket |BIO|. */
OPENSSL_EXPORT int SSL_get_rfd(const SSL *ssl);
/* 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. */
+ * descriptor then it returns -1.
+ *
+ * Note: On Windows, this may return either a file descriptor or a socket (cast
+ * to int), depending on whether |ssl| was configured with a file descriptor or
+ * socket |BIO|. */
OPENSSL_EXPORT int SSL_get_wfd(const SSL *ssl);
/* 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|. */
+ * |fd|.
+ *
+ * On Windows, |fd| is cast to a |SOCKET| and used with Winsock APIs. */
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|. */
+ * zero on allocation error. The caller retains ownership of |fd|.
+ *
+ * On Windows, |fd| is cast to a |SOCKET| and used with Winsock APIs. */
OPENSSL_EXPORT int SSL_set_rfd(SSL *ssl, int fd);
/* 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|. */
+ * zero on allocation error. The caller retains ownership of |fd|.
+ *
+ * On Windows, |fd| is cast to a |SOCKET| and used with Winsock APIs. */
OPENSSL_EXPORT int SSL_set_wfd(SSL *ssl, int fd);
/* SSL_do_handshake continues the current handshake. If there is none or the
@@ -465,7 +479,8 @@ OPENSSL_EXPORT int SSL_get_error(const SSL *ssl, int ret_code);
* 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|. */
+ * See also |SSL_set_private_key_method| and
+ * |SSL_CTX_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
@@ -1003,6 +1018,11 @@ typedef struct ssl_private_key_method_st {
OPENSSL_EXPORT void SSL_set_private_key_method(
SSL *ssl, const SSL_PRIVATE_KEY_METHOD *key_method);
+/* SSL_CTX_set_private_key_method configures a custom private key on |ctx|.
+ * |key_method| must remain valid for the lifetime of |ctx|. */
+OPENSSL_EXPORT void SSL_CTX_set_private_key_method(
+ SSL_CTX *ctx, const SSL_PRIVATE_KEY_METHOD *key_method);
+
/* Cipher suites.
*
@@ -1029,6 +1049,9 @@ 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_has_SHA256_HMAC returns one if |cipher| uses HMAC-SHA256. */
+OPENSSL_EXPORT int SSL_CIPHER_has_SHA256_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);
@@ -1473,6 +1496,16 @@ OPENSSL_EXPORT uint32_t SSL_SESSION_get_key_exchange_info(
* TODO(davidben): This should return a const X509 *. */
OPENSSL_EXPORT X509 *SSL_SESSION_get0_peer(const SSL_SESSION *session);
+/* TODO(davidben): Remove this when wpa_supplicant in Android has synced with
+ * upstream. */
+#if !defined(BORINGSSL_SUPPRESS_ACCESSORS)
+/* SSL_SESSION_get_master_key writes up to |max_out| bytes of |session|'s master
+ * secret to |out| and returns the number of bytes written. If |max_out| is
+ * zero, it returns the size of the master secret. */
+OPENSSL_EXPORT size_t SSL_SESSION_get_master_key(const SSL_SESSION *session,
+ uint8_t *out, size_t max_out);
+#endif
+
/* 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. */
@@ -2062,6 +2095,28 @@ OPENSSL_EXPORT int SSL_enable_ocsp_stapling(SSL *ssl);
* handshake. */
OPENSSL_EXPORT void SSL_CTX_enable_ocsp_stapling(SSL_CTX *ctx);
+/* SSL_CTX_set0_verify_cert_store sets an |X509_STORE| that will be used
+ * exclusively for certificate verification and returns one. Ownership of
+ * |store| is transferred to the |SSL_CTX|. */
+OPENSSL_EXPORT int SSL_CTX_set0_verify_cert_store(SSL_CTX *ctx,
+ X509_STORE *store);
+
+/* SSL_CTX_set1_verify_cert_store sets an |X509_STORE| that will be used
+ * exclusively for certificate verification and returns one. An additional
+ * reference to |store| will be taken. */
+OPENSSL_EXPORT int SSL_CTX_set1_verify_cert_store(SSL_CTX *ctx,
+ X509_STORE *store);
+
+/* SSL_set0_verify_cert_store sets an |X509_STORE| that will be used
+ * exclusively for certificate verification and returns one. Ownership of
+ * |store| is transferred to the |SSL|. */
+OPENSSL_EXPORT int SSL_set0_verify_cert_store(SSL *ssl, X509_STORE *store);
+
+/* SSL_set1_verify_cert_store sets an |X509_STORE| that will be used
+ * exclusively for certificate verification and returns one. An additional
+ * reference to |store| will be taken. */
+OPENSSL_EXPORT int SSL_set1_verify_cert_store(SSL *ssl, X509_STORE *store);
+
/* Client certificate CA list.
*
@@ -2118,12 +2173,6 @@ OPENSSL_EXPORT STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *list);
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.
*
@@ -2359,8 +2408,8 @@ OPENSSL_EXPORT void (*SSL_CTX_get_channel_id_cb(SSL_CTX *ctx))(
*
* See RFC 5764. */
-/* An SRTP_PROTECTION_PROFILE is an SRTP profile for use with the use_srtp
- * extension. */
+/* srtp_protection_profile_st (aka |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;
@@ -2574,7 +2623,7 @@ OPENSSL_EXPORT int SSL_CTX_get_ex_new_index(long argl, void *argp,
CRYPTO_EX_free *free_func);
-/* Obscure functions. */
+/* Low-level record-layer state. */
/* 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|
@@ -2592,6 +2641,28 @@ 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_key_block_len returns the length of |ssl|'s key block. */
+OPENSSL_EXPORT size_t SSL_get_key_block_len(const SSL *ssl);
+
+/* SSL_generate_key_block generates |out_len| bytes of key material for |ssl|'s
+ * current connection state. */
+OPENSSL_EXPORT int SSL_generate_key_block(const SSL *ssl, uint8_t *out,
+ size_t out_len);
+
+/* SSL_get_read_sequence returns, in TLS, the expected sequence number of the
+ * next incoming record in the current epoch. In DTLS, it returns the maximum
+ * sequence number received in the current epoch and includes the epoch number
+ * in the two most significant bytes. */
+OPENSSL_EXPORT uint64_t SSL_get_read_sequence(const SSL *ssl);
+
+/* SSL_get_write_sequence returns the sequence number of the next outgoing
+ * record in the current epoch. In DTLS, it includes the epoch number in the
+ * two most significant bytes. */
+OPENSSL_EXPORT uint64_t SSL_get_write_sequence(const SSL *ssl);
+
+
+/* Obscure functions. */
+
/* 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. */
@@ -2696,15 +2767,17 @@ 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);
+ * will be split into multiple records. It returns one on success or zero on
+ * error. */
+OPENSSL_EXPORT int 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_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. It returns one on success or zero on
+ * error. */
+OPENSSL_EXPORT int 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
@@ -2860,6 +2933,34 @@ OPENSSL_EXPORT int SSL_get_shutdown(const SSL *ssl);
* |TLSEXT_hash_none|. */
OPENSSL_EXPORT uint8_t SSL_get_server_key_exchange_hash(const SSL *ssl);
+/* TODO(davidben): Remove this when wpa_supplicant in Android has synced with
+ * upstream. */
+#if !defined(BORINGSSL_SUPPRESS_ACCESSORS)
+/* SSL_get_client_random writes up to |max_out| bytes of the most recent
+ * handshake's client_random to |out| and returns the number of bytes written.
+ * If |max_out| is zero, it returns the size of the client_random. */
+OPENSSL_EXPORT size_t SSL_get_client_random(const SSL *ssl, uint8_t *out,
+ size_t max_out);
+
+/* SSL_get_server_random writes up to |max_out| bytes of the most recent
+ * handshake's server_random to |out| and returns the number of bytes written.
+ * If |max_out| is zero, it returns the size of the server_random. */
+OPENSSL_EXPORT size_t SSL_get_server_random(const SSL *ssl, uint8_t *out,
+ size_t max_out);
+#endif
+
+/* SSL_get_pending_cipher returns the cipher suite for the current handshake or
+ * NULL if one has not been negotiated yet or there is no pending handshake. */
+OPENSSL_EXPORT const SSL_CIPHER *SSL_get_pending_cipher(const SSL *ssl);
+
+/* SSL_CTX_set_retain_only_sha256_of_client_certs, on a server, sets whether
+ * only the SHA-256 hash of peer's certificate should be saved in memory and in
+ * the session. This can save memory, ticket size and session cache space. If
+ * enabled, |SSL_get_peer_certificate| will return NULL after the handshake
+ * completes. See the |peer_sha256| field of |SSL_SESSION| for the hash. */
+OPENSSL_EXPORT void SSL_CTX_set_retain_only_sha256_of_client_certs(SSL_CTX *ctx,
+ int enable);
+
/* Deprecated functions. */
@@ -3013,6 +3114,10 @@ OPENSSL_EXPORT int SSL_renegotiate(SSL *ssl);
/* SSL_set_state does nothing. */
OPENSSL_EXPORT void SSL_set_state(SSL *ssl, int state);
+/* SSL_get_shared_ciphers writes an empty string to |buf| and returns a
+ * pointer to |buf|, or NULL if |len| is less than or equal to zero. */
+OPENSSL_EXPORT char *SSL_get_shared_ciphers(const SSL *ssl, char *buf, int len);
+
/* SSL_MODE_HANDSHAKE_CUTTHROUGH is the same as SSL_MODE_ENABLE_FALSE_START. */
#define SSL_MODE_HANDSHAKE_CUTTHROUGH SSL_MODE_ENABLE_FALSE_START
@@ -3071,6 +3176,9 @@ 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);
+/* SSL_get_server_tmp_key returns zero. */
+OPENSSL_EXPORT int *SSL_get_server_tmp_key(SSL *ssl, EVP_PKEY **out_key);
+
#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) \
@@ -3303,6 +3411,13 @@ OPENSSL_EXPORT int SSL_CTX_set_tmp_ecdh(SSL_CTX *ctx, const EC_KEY *ec_key);
* |ec_key|'s curve. */
OPENSSL_EXPORT int SSL_set_tmp_ecdh(SSL *ssl, const EC_KEY *ec_key);
+/* 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. This function is only available from the libdecrepit
+ * library. */
+OPENSSL_EXPORT int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *out,
+ const char *dir);
+
/* Private structures.
*
@@ -3463,6 +3578,8 @@ struct ssl_cipher_preference_list_st {
uint8_t *in_group_flags;
};
+/* ssl_ctx_st (aka |SSL_CTX|) contains configuration common to several SSL
+ * connections. */
struct ssl_ctx_st {
const SSL_PROTOCOL_METHOD *method;
@@ -3627,7 +3744,7 @@ struct ssl_ctx_st {
/* retain_only_sha256_of_client_certs is true if we should compute the SHA256
- * hash of the peer's certifiate and then discard it to save memory and
+ * hash of the peer's certificate and then discard it to save memory and
* session space. Only effective on the server side. */
char retain_only_sha256_of_client_certs;
@@ -3706,6 +3823,11 @@ struct ssl_ctx_st {
* means that we'll accept Channel IDs from clients. For a client, means that
* we'll advertise support. */
unsigned tlsext_channel_id_enabled:1;
+
+ /* extra_certs is a dummy value included for compatibility.
+ * TODO(agl): remove once node.js no longer references this. */
+ STACK_OF(X509)* extra_certs;
+ int freelist_max_len;
};
struct ssl_st {
@@ -3724,10 +3846,6 @@ struct ssl_st {
* 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 */
@@ -3775,9 +3893,6 @@ struct ssl_st {
struct ssl_cipher_preference_list_st *cipher_list;
STACK_OF(SSL_CIPHER) *cipher_list_by_id;
- SSL_AEAD_CTX *aead_read_ctx;
- SSL_AEAD_CTX *aead_write_ctx;
-
/* session info */
/* client cert? */
@@ -3836,15 +3951,6 @@ struct ssl_st {
SSL_CTX *initial_ctx; /* initial ctx, used to store sessions */
- /* Next protocol negotiation. For the client, this is the protocol that we
- * sent in NextProtocol and is set when handling ServerHello extensions.
- *
- * For a server, this is the client's selected_protocol from NextProtocol and
- * is set when handling the NextProtocol message, before the Finished
- * message. */
- uint8_t *next_proto_negotiated;
- size_t next_proto_negotiated_len;
-
/* srtp_profiles is the list of configured SRTP protection profiles for
* DTLS-SRTP. */
STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles;
@@ -3870,10 +3976,6 @@ struct ssl_st {
EVP_CIPHER_CTX *enc_read_ctx;
EVP_MD_CTX *read_hash;
- /* in_handshake is non-zero when we are actually in SSL_accept() or
- * SSL_connect() */
- int in_handshake;
-
/* verify_mode is a bitmask of |SSL_VERIFY_*| values. */
uint8_t verify_mode;
@@ -3900,6 +4002,9 @@ struct ssl_st {
* means that we'll accept Channel IDs from clients. For a client, means that
* we'll advertise support. */
unsigned tlsext_channel_id_enabled:1;
+
+ /* TODO(agl): remove once node.js not longer references this. */
+ int tlsext_status_type;
};
typedef struct ssl3_record_st {
@@ -3964,8 +4069,10 @@ typedef struct ssl3_state_st {
* the handshake hash for TLS 1.1 and below. */
EVP_MD_CTX handshake_md5;
- int warn_alert;
- int fatal_alert;
+ /* clean_shutdown is one if the connection was cleanly shutdown with a
+ * close_notify and zero otherwise. */
+ char clean_shutdown;
+
/* we allow one fatal and one warning alert to be outstanding, send close
* alert via the warning alert */
int alert_dispatch;
@@ -3980,6 +4087,16 @@ typedef struct ssl3_state_st {
* received. */
uint8_t warning_alert_count;
+ /* aead_read_ctx is the current read cipher state. */
+ SSL_AEAD_CTX *aead_read_ctx;
+
+ /* aead_write_ctx is the current write cipher state. */
+ SSL_AEAD_CTX *aead_write_ctx;
+
+ /* enc_method is the method table corresponding to the current protocol
+ * version. */
+ const SSL3_ENC_METHOD *enc_method;
+
/* State pertaining to the pending handshake.
*
* TODO(davidben): State is current spread all over the place. Move
@@ -4045,13 +4162,12 @@ typedef struct ssl3_state_st {
uint8_t *certificate_types;
size_t num_certificate_types;
- int key_block_length;
uint8_t *key_block;
+ uint8_t key_block_length;
- const EVP_AEAD *new_aead;
uint8_t new_mac_secret_len;
+ uint8_t new_key_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. */
@@ -4114,6 +4230,15 @@ typedef struct ssl3_state_st {
/* Set if we saw the Next Protocol Negotiation extension from our peer. */
int next_proto_neg_seen;
+ /* Next protocol negotiation. For the client, this is the protocol that we
+ * sent in NextProtocol and is set when handling ServerHello extensions.
+ *
+ * For a server, this is the client's selected_protocol from NextProtocol and
+ * is set when handling the NextProtocol message, before the Finished
+ * message. */
+ uint8_t *next_proto_negotiated;
+ size_t next_proto_negotiated_len;
+
/* ALPN information
* (we are in the process of transitioning from NPN to ALPN.) */
@@ -4142,8 +4267,6 @@ typedef struct ssl3_state_st {
* wpa_supplicant will take a little time to sync with upstream. Outside of
* Android they'll have no definition. */
-#define SSL_F_SSL_SET_SESSION_TICKET_EXT doesnt_exist
-
OPENSSL_EXPORT int SSL_set_session_ticket_ext(SSL *s, void *ext_data,
int ext_len);
OPENSSL_EXPORT int SSL_set_session_secret_cb(SSL *s, void *cb, void *arg);
@@ -4151,6 +4274,14 @@ 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);
+/* Nodejs compatibility section (hidden).
+ *
+ * These defines exist for node.js, with the hope that we can eliminate the
+ * need for them over time. */
+#define SSLerr(function, reason) \
+ ERR_put_error(ERR_LIB_SSL, 0, reason, __FILE__, __LINE__)
+
+
/* Preprocessor compatibility section (hidden).
*
* Historically, a number of APIs were implemented in OpenSSL as macros and
@@ -4438,6 +4569,7 @@ OPENSSL_EXPORT int SSL_set_ssl_method(SSL *s, const SSL_METHOD *method);
#define SSL_R_WRONG_VERSION_NUMBER 247
#define SSL_R_X509_LIB 248
#define SSL_R_X509_VERIFICATION_SETUP_PROBLEMS 249
+#define SSL_R_SHUTDOWN_WHILE_IN_INIT 250
#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/thread.h b/src/include/openssl/thread.h
index 568a8583..ac4ced07 100644
--- a/src/include/openssl/thread.h
+++ b/src/include/openssl/thread.h
@@ -67,7 +67,9 @@ extern "C" {
#if defined(OPENSSL_NO_THREADS)
-typedef struct crypto_mutex_st {} CRYPTO_MUTEX;
+typedef struct crypto_mutex_st {
+ char padding; /* Empty structs have different sizes in C and C++. */
+} CRYPTO_MUTEX;
#elif defined(OPENSSL_WINDOWS)
/* CRYPTO_MUTEX can appear in public header files so we really don't want to
* pull in windows.h. It's statically asserted that this structure is large
diff --git a/src/include/openssl/time_support.h b/src/include/openssl/time_support.h
index cec430d3..274b17d1 100644
--- a/src/include/openssl/time_support.h
+++ b/src/include/openssl/time_support.h
@@ -60,6 +60,7 @@
#include <openssl/base.h>
+#include <time.h>
#if defined(__cplusplus)
extern "C" {
diff --git a/src/include/openssl/tls1.h b/src/include/openssl/tls1.h
index 92d27522..e0f13997 100644
--- a/src/include/openssl/tls1.h
+++ b/src/include/openssl/tls1.h
@@ -218,7 +218,7 @@ extern "C" {
/* ExtensionType value from RFC7685 */
#define TLSEXT_TYPE_padding 21
-/* https://tools.ietf.org/html/draft-ietf-tls-session-hash-01 */
+/* ExtensionType value from RFC7627 */
#define TLSEXT_TYPE_extended_master_secret 23
/* ExtensionType value from RFC4507 */
diff --git a/src/include/openssl/x509.h b/src/include/openssl/x509.h
index a5aaf31b..4b977b90 100644
--- a/src/include/openssl/x509.h
+++ b/src/include/openssl/x509.h
@@ -76,6 +76,7 @@
#include <openssl/ecdsa.h>
#include <openssl/ec.h>
#include <openssl/evp.h>
+#include <openssl/obj.h>
#include <openssl/rsa.h>
#include <openssl/sha.h>
#include <openssl/stack.h>
@@ -1153,6 +1154,17 @@ OPENSSL_EXPORT int X509_TRUST_get_flags(X509_TRUST *xp);
OPENSSL_EXPORT char *X509_TRUST_get0_name(X509_TRUST *xp);
OPENSSL_EXPORT int X509_TRUST_get_trust(X509_TRUST *xp);
+
+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)
+
+
/* PKCS7_get_certificates parses a PKCS#7, SignedData structure from |cbs| and
* appends the included certificates to |out_certs|. It returns one on success
* and zero on error. */
@@ -1227,30 +1239,28 @@ OPENSSL_EXPORT int PKCS7_get_PEM_CRLs(STACK_OF(X509_CRL) *out_crls,
#define X509_R_INVALID_BIT_STRING_BITS_LEFT 109
#define X509_R_INVALID_DIRECTORY 110
#define X509_R_INVALID_FIELD_NAME 111
-#define X509_R_INVALID_TRUST 112
-#define X509_R_ISSUER_MISMATCH 113
-#define X509_R_KEY_TYPE_MISMATCH 114
-#define X509_R_KEY_VALUES_MISMATCH 115
-#define X509_R_LOADING_CERT_DIR 116
-#define X509_R_LOADING_DEFAULTS 117
-#define X509_R_METHOD_NOT_SUPPORTED 118
+#define X509_R_INVALID_PSS_PARAMETERS 112
+#define X509_R_INVALID_TRUST 113
+#define X509_R_ISSUER_MISMATCH 114
+#define X509_R_KEY_TYPE_MISMATCH 115
+#define X509_R_KEY_VALUES_MISMATCH 116
+#define X509_R_LOADING_CERT_DIR 117
+#define X509_R_LOADING_DEFAULTS 118
#define X509_R_NEWER_CRL_NOT_NEWER 119
#define X509_R_NOT_PKCS7_SIGNED_DATA 120
#define X509_R_NO_CERTIFICATES_INCLUDED 121
#define X509_R_NO_CERT_SET_FOR_US_TO_VERIFY 122
-#define X509_R_NO_CRL_NUMBER 123
-#define X509_R_PUBLIC_KEY_DECODE_ERROR 124
-#define X509_R_PUBLIC_KEY_ENCODE_ERROR 125
-#define X509_R_SHOULD_RETRY 126
-#define X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN 127
-#define X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY 128
-#define X509_R_UNKNOWN_KEY_TYPE 129
-#define X509_R_UNKNOWN_NID 130
-#define X509_R_UNKNOWN_PURPOSE_ID 131
-#define X509_R_UNKNOWN_TRUST_ID 132
-#define X509_R_UNSUPPORTED_ALGORITHM 133
-#define X509_R_WRONG_LOOKUP_TYPE 134
-#define X509_R_WRONG_TYPE 135
-#define X509_R_NO_CRLS_INCLUDED 136
+#define X509_R_NO_CRLS_INCLUDED 123
+#define X509_R_NO_CRL_NUMBER 124
+#define X509_R_PUBLIC_KEY_DECODE_ERROR 125
+#define X509_R_PUBLIC_KEY_ENCODE_ERROR 126
+#define X509_R_SHOULD_RETRY 127
+#define X509_R_UNKNOWN_KEY_TYPE 128
+#define X509_R_UNKNOWN_NID 129
+#define X509_R_UNKNOWN_PURPOSE_ID 130
+#define X509_R_UNKNOWN_TRUST_ID 131
+#define X509_R_UNSUPPORTED_ALGORITHM 132
+#define X509_R_WRONG_LOOKUP_TYPE 133
+#define X509_R_WRONG_TYPE 134
#endif
diff --git a/src/include/openssl/x509_vfy.h b/src/include/openssl/x509_vfy.h
index b39ef49c..a9d05195 100644
--- a/src/include/openssl/x509_vfy.h
+++ b/src/include/openssl/x509_vfy.h
@@ -412,6 +412,11 @@ OPENSSL_EXPORT void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth);
/* Allow partial chains if at least one certificate is in trusted store */
#define X509_V_FLAG_PARTIAL_CHAIN 0x80000
+/* If the initial chain is not trusted, do not attempt to build an alternative
+ * chain. Alternate chain checking was introduced in 1.0.2b. Setting this flag
+ * will force the behaviour to match that of previous versions. */
+#define X509_V_FLAG_NO_ALT_CHAINS 0x100000
+
#define X509_VP_FLAG_DEFAULT 0x1
#define X509_VP_FLAG_OVERWRITE 0x2
#define X509_VP_FLAG_RESET_FLAGS 0x4
@@ -431,6 +436,7 @@ OPENSSL_EXPORT X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h,
OPENSSL_EXPORT void X509_OBJECT_up_ref_count(X509_OBJECT *a);
OPENSSL_EXPORT void X509_OBJECT_free_contents(X509_OBJECT *a);
OPENSSL_EXPORT X509_STORE *X509_STORE_new(void );
+OPENSSL_EXPORT void X509_STORE_up_ref(X509_STORE *store);
OPENSSL_EXPORT void X509_STORE_free(X509_STORE *v);
OPENSSL_EXPORT STACK_OF(X509)* X509_STORE_get1_certs(X509_STORE_CTX *st, X509_NAME *nm);
diff --git a/src/include/openssl/x509v3.h b/src/include/openssl/x509v3.h
index b7b8ba71..fa78f33a 100644
--- a/src/include/openssl/x509v3.h
+++ b/src/include/openssl/x509v3.h
@@ -600,6 +600,7 @@ OPENSSL_EXPORT GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out,
X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc);
OPENSSL_EXPORT void X509V3_conf_free(CONF_VALUE *val);
+OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, int ext_nid, char *value);
OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, char *value);
OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, char *name, char *value);
OPENSSL_EXPORT int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, char *section, STACK_OF(X509_EXTENSION) **sk);
@@ -646,6 +647,7 @@ OPENSSL_EXPORT int X509V3_add_standard_extensions(void);
OPENSSL_EXPORT STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line);
OPENSSL_EXPORT void *X509V3_EXT_d2i(X509_EXTENSION *ext);
OPENSSL_EXPORT void *X509V3_get_d2i(STACK_OF(X509_EXTENSION) *x, int nid, int *crit, int *idx);
+OPENSSL_EXPORT int X509V3_EXT_free(int nid, void *ext_data);
OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc);
diff --git a/src/ssl/d1_both.c b/src/ssl/d1_both.c
index ee4cbc9e..cc95a70b 100644
--- a/src/ssl/d1_both.c
+++ b/src/ssl/d1_both.c
@@ -115,14 +115,12 @@
#include <assert.h>
#include <limits.h>
-#include <stdio.h>
#include <string.h>
#include <openssl/buf.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/mem.h>
-#include <openssl/obj.h>
#include <openssl/rand.h>
#include <openssl/x509.h>
@@ -292,12 +290,11 @@ static int dtls1_write_change_cipher_spec(SSL *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) {
+ ssl->rwstate = SSL_WRITING;
return ret;
}
- ssl->rwstate = SSL_NOTHING;
}
static const uint8_t kChangeCipherSpec[1] = {SSL3_MT_CCS};
@@ -342,13 +339,12 @@ int dtls1_do_handshake_write(SSL *ssl, enum dtls1_use_epoch_t use_epoch) {
/* 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) {
+ ssl->rwstate = SSL_WRITING;
ret = flush_ret;
goto err;
}
- ssl->rwstate = SSL_NOTHING;
assert(BIO_wpending(SSL_get_wbio(ssl)) == 0);
}
diff --git a/src/ssl/d1_clnt.c b/src/ssl/d1_clnt.c
index ad5eb506..2fc9094b 100644
--- a/src/ssl/d1_clnt.c
+++ b/src/ssl/d1_clnt.c
@@ -115,7 +115,6 @@
#include <openssl/ssl.h>
#include <assert.h>
-#include <stdio.h>
#include <string.h>
#include <openssl/bn.h>
@@ -125,7 +124,6 @@
#include <openssl/err.h>
#include <openssl/md5.h>
#include <openssl/mem.h>
-#include <openssl/obj.h>
#include <openssl/rand.h>
#include "internal.h"
@@ -143,7 +141,6 @@ int dtls1_connect(SSL *ssl) {
assert(!ssl->server);
assert(SSL_IS_DTLS(ssl));
- ERR_clear_error();
ERR_clear_system_error();
if (ssl->info_callback != NULL) {
@@ -152,8 +149,6 @@ int dtls1_connect(SSL *ssl) {
cb = ssl->ctx->info_callback;
}
- ssl->in_handshake++;
-
for (;;) {
state = ssl->state;
@@ -368,10 +363,7 @@ int dtls1_connect(SSL *ssl) {
ssl->state = SSL3_ST_CW_FINISHED_A;
ssl->init_num = 0;
- 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)) {
+ if (!tls1_change_cipher_state(ssl, SSL3_CHANGE_CIPHER_CLIENT_WRITE)) {
ret = -1;
goto end;
}
@@ -383,10 +375,8 @@ int dtls1_connect(SSL *ssl) {
dtls1_start_timer(ssl);
}
- 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);
+ ret = ssl3_send_finished(ssl, SSL3_ST_CW_FINISHED_A,
+ SSL3_ST_CW_FINISHED_B);
if (ret <= 0) {
goto end;
}
@@ -431,7 +421,7 @@ int dtls1_connect(SSL *ssl) {
goto end;
}
- if (!ssl3_do_change_cipher_spec(ssl)) {
+ if (!tls1_change_cipher_state(ssl, SSL3_CHANGE_CIPHER_CLIENT_READ)) {
ret = -1;
goto end;
}
@@ -457,12 +447,11 @@ int dtls1_connect(SSL *ssl) {
break;
case SSL3_ST_CW_FLUSH:
- ssl->rwstate = SSL_WRITING;
if (BIO_flush(ssl->wbio) <= 0) {
+ ssl->rwstate = SSL_WRITING;
ret = -1;
goto end;
}
- ssl->rwstate = SSL_NOTHING;
ssl->state = ssl->s3->tmp.next_state;
break;
@@ -508,8 +497,6 @@ int dtls1_connect(SSL *ssl) {
}
end:
- ssl->in_handshake--;
-
BUF_MEM_free(buf);
if (cb != NULL) {
cb(ssl, SSL_CB_CONNECT_EXIT, ret);
diff --git a/src/ssl/d1_lib.c b/src/ssl/d1_lib.c
index 7f08b067..e48fbf1a 100644
--- a/src/ssl/d1_lib.c
+++ b/src/ssl/d1_lib.c
@@ -57,12 +57,11 @@
#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 <openssl/nid.h>
#include "internal.h"
@@ -110,11 +109,11 @@ int dtls1_new(SSL *ssl) {
ssl->d1 = d1;
- /* Set the version to the highest version for DTLS. This controls the initial
- * state of |ssl->enc_method| and what the API reports as the version prior to
- * negotiation.
+ /* Set the version to the highest supported version.
*
- * TODO(davidben): This is fragile and confusing. */
+ * TODO(davidben): Move this field into |s3|, have it store the normalized
+ * protocol version, and implement this pre-negotiation quirk in |SSL_version|
+ * at the API boundary rather than in internal state. */
ssl->version = DTLS1_2_VERSION;
return 1;
}
@@ -272,6 +271,10 @@ int dtls1_check_timeout_num(SSL *ssl) {
}
int DTLSv1_handle_timeout(SSL *ssl) {
+ ssl->rwstate = SSL_NOTHING;
+ /* Functions which use SSL_get_error must clear the error queue on entry. */
+ ERR_clear_error();
+
if (!SSL_IS_DTLS(ssl)) {
return -1;
}
diff --git a/src/ssl/d1_pkt.c b/src/ssl/d1_pkt.c
index f2ade3a0..4690486c 100644
--- a/src/ssl/d1_pkt.c
+++ b/src/ssl/d1_pkt.c
@@ -112,7 +112,6 @@
#include <openssl/ssl.h>
#include <assert.h>
-#include <stdio.h>
#include <string.h>
#include <openssl/buf.h>
@@ -186,6 +185,7 @@ again:
}
int dtls1_read_app_data(SSL *ssl, uint8_t *buf, int len, int peek) {
+ assert(!SSL_in_init(ssl));
return dtls1_read_bytes(ssl, SSL3_RT_APPLICATION_DATA, buf, len, peek);
}
@@ -233,7 +233,7 @@ void dtls1_read_close_notify(SSL *ssl) {
* This function must handle any surprises the peer may have for us, such as
* 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;
+ int al, ret;
unsigned int n;
SSL3_RECORD *rr;
void (*cb)(const SSL *ssl, int type, int value) = NULL;
@@ -245,21 +245,7 @@ int dtls1_read_bytes(SSL *ssl, int type, unsigned char *buf, int len, int peek)
return -1;
}
- if (!ssl->in_handshake && SSL_in_init(ssl)) {
- /* type == SSL3_RT_APPLICATION_DATA */
- i = ssl->handshake_func(ssl);
- if (i < 0) {
- return i;
- }
- if (i == 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_HANDSHAKE_FAILURE);
- return -1;
- }
- }
-
start:
- ssl->rwstate = SSL_NOTHING;
-
/* ssl->s3->rrec.type - is the type of record
* ssl->s3->rrec.data - data
* ssl->s3->rrec.off - offset into 'data' for next read
@@ -291,7 +277,6 @@ start:
* 'peek' mode) */
if (ssl->shutdown & SSL_RECEIVED_SHUTDOWN) {
rr->length = 0;
- ssl->rwstate = SSL_NOTHING;
return 0;
}
@@ -300,7 +285,7 @@ start:
/* 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)) {
+ (ssl->s3->aead_read_ctx == NULL)) {
/* TODO(davidben): Is this check redundant with the handshake_func
* check? */
al = SSL_AD_UNEXPECTED_MESSAGE;
@@ -338,11 +323,10 @@ start:
/* If we get here, then type != rr->type. */
- /* If an alert record, process one alert out of the record. Note that we allow
- * a single record to contain multiple alerts. */
+ /* If an alert record, process the alert. */
if (rr->type == SSL3_RT_ALERT) {
- /* Alerts may not be fragmented. */
- if (rr->length < 2) {
+ /* Alerts records may not contain fragmented or multiple alerts. */
+ if (rr->length != 2) {
al = SSL_AD_DECODE_ERROR;
OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ALERT);
goto f_err;
@@ -369,16 +353,14 @@ start:
}
if (alert_level == SSL3_AL_WARNING) {
- ssl->s3->warn_alert = alert_descr;
if (alert_descr == SSL_AD_CLOSE_NOTIFY) {
+ ssl->s3->clean_shutdown = 1;
ssl->shutdown |= SSL_RECEIVED_SHUTDOWN;
return 0;
}
} else if (alert_level == SSL3_AL_FATAL) {
char tmp[16];
- 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);
@@ -403,8 +385,10 @@ start:
* 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)) {
+ if ((rr->type == SSL3_RT_APPLICATION_DATA &&
+ ssl->s3->aead_read_ctx != NULL) ||
+ (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC &&
+ ssl->s3->aead_read_ctx == NULL)) {
rr->length = 0;
goto start;
}
@@ -458,39 +442,23 @@ f_err:
}
int dtls1_write_app_data(SSL *ssl, const void *buf_, int len) {
- int i;
-
- 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, SSL_R_SSL_HANDSHAKE_FAILURE);
- return -1;
- }
- }
+ assert(!SSL_in_init(ssl));
if (len > SSL3_RT_MAX_PLAIN_LENGTH) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DTLS_MESSAGE_TOO_BIG);
return -1;
}
- i = dtls1_write_bytes(ssl, SSL3_RT_APPLICATION_DATA, buf_, len,
- dtls1_use_current_epoch);
- return i;
+ return dtls1_write_bytes(ssl, SSL3_RT_APPLICATION_DATA, buf_, len,
+ dtls1_use_current_epoch);
}
/* 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 *ssl, int type, const void *buf, int len,
enum dtls1_use_epoch_t use_epoch) {
- int i;
-
assert(len <= SSL3_RT_MAX_PLAIN_LENGTH);
- ssl->rwstate = SSL_NOTHING;
- i = do_dtls1_write(ssl, type, buf, len, use_epoch);
- return i;
+ return do_dtls1_write(ssl, type, buf, len, use_epoch);
}
static int do_dtls1_write(SSL *ssl, int type, const uint8_t *buf,
@@ -537,42 +505,35 @@ static int do_dtls1_write(SSL *ssl, int type, const uint8_t *buf,
}
int dtls1_dispatch_alert(SSL *ssl) {
- int i, j;
- void (*cb)(const SSL *ssl, int type, int value) = NULL;
- uint8_t buf[DTLS1_AL_HEADER_LENGTH];
- uint8_t *ptr = &buf[0];
-
ssl->s3->alert_dispatch = 0;
-
- memset(buf, 0x00, sizeof(buf));
- *ptr++ = ssl->s3->send_alert[0];
- *ptr++ = ssl->s3->send_alert[1];
-
- i = do_dtls1_write(ssl, SSL3_RT_ALERT, &buf[0], sizeof(buf),
- dtls1_use_current_epoch);
- if (i <= 0) {
+ int ret = do_dtls1_write(ssl, SSL3_RT_ALERT, &ssl->s3->send_alert[0], 2,
+ dtls1_use_current_epoch);
+ if (ret <= 0) {
ssl->s3->alert_dispatch = 1;
- } else {
- if (ssl->s3->send_alert[0] == SSL3_AL_FATAL) {
- (void)BIO_flush(ssl->wbio);
- }
+ return ret;
+ }
- if (ssl->msg_callback) {
- ssl->msg_callback(1, ssl->version, SSL3_RT_ALERT, ssl->s3->send_alert, 2,
- ssl, ssl->msg_callback_arg);
- }
+ /* If the alert is fatal, flush the BIO now. */
+ if (ssl->s3->send_alert[0] == SSL3_AL_FATAL) {
+ BIO_flush(ssl->wbio);
+ }
- if (ssl->info_callback != NULL) {
- cb = ssl->info_callback;
- } else if (ssl->ctx->info_callback != NULL) {
- cb = ssl->ctx->info_callback;
- }
+ if (ssl->msg_callback != NULL) {
+ ssl->msg_callback(1 /* write */, ssl->version, SSL3_RT_ALERT,
+ ssl->s3->send_alert, 2, ssl, ssl->msg_callback_arg);
+ }
- if (cb != NULL) {
- j = (ssl->s3->send_alert[0] << 8) | ssl->s3->send_alert[1];
- cb(ssl, SSL_CB_WRITE_ALERT, j);
- }
+ void (*cb)(const SSL *ssl, int type, int value) = NULL;
+ if (ssl->info_callback != NULL) {
+ cb = ssl->info_callback;
+ } else if (ssl->ctx->info_callback != NULL) {
+ cb = ssl->ctx->info_callback;
+ }
+
+ if (cb != NULL) {
+ int alert = (ssl->s3->send_alert[0] << 8) | ssl->s3->send_alert[1];
+ cb(ssl, SSL_CB_WRITE_ALERT, alert);
}
- return i;
+ return 1;
}
diff --git a/src/ssl/d1_srtp.c b/src/ssl/d1_srtp.c
index 5dba8ef8..e7b1607a 100644
--- a/src/ssl/d1_srtp.c
+++ b/src/ssl/d1_srtp.c
@@ -116,12 +116,10 @@
#include <openssl/ssl.h>
-#include <stdio.h>
#include <string.h>
#include <openssl/bytestring.h>
#include <openssl/err.h>
-#include <openssl/obj.h>
#include "internal.h"
@@ -212,7 +210,7 @@ STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *ssl) {
return ssl->srtp_profiles;
}
- if (ssl->ctx != NULL && ssl->ctx->srtp_profiles != NULL) {
+ if (ssl->ctx->srtp_profiles != NULL) {
return ssl->ctx->srtp_profiles;
}
diff --git a/src/ssl/d1_srvr.c b/src/ssl/d1_srvr.c
index 3ba9411c..d3532810 100644
--- a/src/ssl/d1_srvr.c
+++ b/src/ssl/d1_srvr.c
@@ -115,7 +115,6 @@
#include <openssl/ssl.h>
#include <assert.h>
-#include <stdio.h>
#include <openssl/bn.h>
#include <openssl/buf.h>
@@ -123,7 +122,6 @@
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/md5.h>
-#include <openssl/obj.h>
#include <openssl/rand.h>
#include <openssl/x509.h>
@@ -141,7 +139,6 @@ int dtls1_accept(SSL *ssl) {
assert(ssl->server);
assert(SSL_IS_DTLS(ssl));
- ERR_clear_error();
ERR_clear_system_error();
if (ssl->info_callback != NULL) {
@@ -150,8 +147,6 @@ int dtls1_accept(SSL *ssl) {
cb = ssl->ctx->info_callback;
}
- ssl->in_handshake++;
-
for (;;) {
state = ssl->state;
@@ -307,12 +302,11 @@ int dtls1_accept(SSL *ssl) {
break;
case SSL3_ST_SW_FLUSH:
- ssl->rwstate = SSL_WRITING;
if (BIO_flush(ssl->wbio) <= 0) {
+ ssl->rwstate = SSL_WRITING;
ret = -1;
goto end;
}
- ssl->rwstate = SSL_NOTHING;
ssl->state = ssl->s3->tmp.next_state;
break;
@@ -355,7 +349,7 @@ int dtls1_accept(SSL *ssl) {
goto end;
}
- if (!ssl3_do_change_cipher_spec(ssl)) {
+ if (!tls1_change_cipher_state(ssl, SSL3_CHANGE_CIPHER_SERVER_READ)) {
ret = -1;
goto end;
}
@@ -393,12 +387,6 @@ int dtls1_accept(SSL *ssl) {
case SSL3_ST_SW_CHANGE_A:
case SSL3_ST_SW_CHANGE_B:
- 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(ssl, SSL3_ST_SW_CHANGE_A,
SSL3_ST_SW_CHANGE_B);
@@ -409,8 +397,7 @@ int dtls1_accept(SSL *ssl) {
ssl->state = SSL3_ST_SW_FINISHED_A;
ssl->init_num = 0;
- if (!ssl->enc_method->change_cipher_state(
- ssl, SSL3_CHANGE_CIPHER_SERVER_WRITE)) {
+ if (!tls1_change_cipher_state(ssl, SSL3_CHANGE_CIPHER_SERVER_WRITE)) {
ret = -1;
goto end;
}
@@ -419,9 +406,7 @@ int dtls1_accept(SSL *ssl) {
case SSL3_ST_SW_FINISHED_A:
case SSL3_ST_SW_FINISHED_B:
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);
+ SSL3_ST_SW_FINISHED_B);
if (ret <= 0) {
goto end;
}
@@ -476,7 +461,6 @@ int dtls1_accept(SSL *ssl) {
}
end:
- ssl->in_handshake--;
BUF_MEM_free(buf);
if (cb != NULL) {
cb(ssl, SSL_CB_ACCEPT_EXIT, ret);
diff --git a/src/ssl/dtls_record.c b/src/ssl/dtls_record.c
index 940494a1..eaf6df76 100644
--- a/src/ssl/dtls_record.c
+++ b/src/ssl/dtls_record.c
@@ -213,7 +213,7 @@ enum ssl_open_record_t dtls_open_record(
/* Decrypt the body. */
size_t plaintext_len;
- if (!SSL_AEAD_CTX_open(ssl->aead_read_ctx, out, &plaintext_len, max_out,
+ if (!SSL_AEAD_CTX_open(ssl->s3->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.
@@ -250,7 +250,7 @@ int dtls_seal_record(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out,
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;
+ SSL_AEAD_CTX *aead = ssl->s3->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
@@ -286,7 +286,7 @@ int dtls_seal_record(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out,
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)) {
+ !ssl_record_sequence_update(&seq[2], 6)) {
return 0;
}
diff --git a/src/ssl/internal.h b/src/ssl/internal.h
index 5acb598d..982f3040 100644
--- a/src/ssl/internal.h
+++ b/src/ssl/internal.h
@@ -346,6 +346,10 @@ typedef struct dtls1_bitmap_st {
/* Record layer. */
+/* ssl_record_sequence_update increments the sequence number in |seq|. It
+ * returns one on success and zero on wraparound. */
+int ssl_record_sequence_update(uint8_t *seq, size_t seq_len);
+
/* ssl_record_prefix_len returns the length of the prefix before the ciphertext
* of a record for |ssl|.
*
@@ -432,6 +436,14 @@ 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);
+/* ssl_set_read_state sets |ssl|'s read cipher state to |aead_ctx|. It takes
+ * ownership of |aead_ctx|. */
+void ssl_set_read_state(SSL *ssl, SSL_AEAD_CTX *aead_ctx);
+
+/* ssl_set_write_state sets |ssl|'s write cipher state to |aead_ctx|. It takes
+ * ownership of |aead_ctx|. */
+void ssl_set_write_state(SSL *ssl, SSL_AEAD_CTX *aead_ctx);
+
/* Private key operations. */
@@ -519,7 +531,7 @@ int ssl3_update_handshake_hash(SSL *ssl, const uint8_t *in, size_t in_len);
#define SSL_CURVE_SECP256R1 23
#define SSL_CURVE_SECP384R1 24
#define SSL_CURVE_SECP521R1 25
-#define SSL_CURVE_ECDH_X25519 29
+#define SSL_CURVE_X25519 29
/* An SSL_ECDH_METHOD is an implementation of ECDH-like key exchanges for
* TLS. */
@@ -735,12 +747,6 @@ void ssl_write_buffer_clear(SSL *ssl);
/* Check if an SSL structure is using DTLS */
#define SSL_IS_DTLS(ssl) (ssl->method->is_dtls)
-/* See if we need 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(ssl) (ssl->enc_method->enc_flags & SSL_ENC_FLAG_SIGALGS)
/* From RFC4492, used in encoding the curve type in ECParameters */
#define NAMED_CURVE_TYPE 3
@@ -797,6 +803,10 @@ typedef struct cert_st {
* supported signature algorithms or curves. */
int (*cert_cb)(SSL *ssl, void *arg);
void *cert_cb_arg;
+
+ /* Optional X509_STORE for certificate validation. If NULL the parent SSL_CTX
+ * store is used instead. */
+ X509_STORE *verify_store;
} CERT;
/* SSL_METHOD is a compatibility structure to support the legacy version-locked
@@ -840,22 +850,16 @@ struct ssl_protocol_method_st {
/* This is for the SSLv3/TLSv1.0 differences in crypto/hash stuff It is a bit
* of a mess of functions, but hell, think of it as an opaque structure. */
struct ssl3_enc_method {
- int (*prf)(SSL *, uint8_t *, size_t, const uint8_t *, size_t, const char *,
- size_t, const uint8_t *, size_t, const uint8_t *, size_t);
- int (*setup_key_block)(SSL *);
- int (*generate_master_secret)(SSL *, uint8_t *, const uint8_t *, size_t);
- int (*change_cipher_state)(SSL *, int);
- int (*final_finish_mac)(SSL *, const char *, int, uint8_t *);
+ /* prf computes the PRF function for |ssl|. 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 (*prf)(const 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 (*final_finish_mac)(SSL *ssl, int from_server, uint8_t *out);
int (*cert_verify_mac)(SSL *, int, uint8_t *);
- const char *client_finished_label;
- int client_finished_label_len;
- const char *server_finished_label;
- int server_finished_label_len;
- int (*alert_value)(int);
- int (*export_keying_material)(SSL *, uint8_t *, size_t, const char *, size_t,
- const uint8_t *, size_t, int use_context);
- /* Various flags indicating protocol version requirements */
- unsigned int enc_flags;
};
#define SSL_HM_HEADER_LENGTH(ssl) ssl->method->hhlen
@@ -865,15 +869,6 @@ struct ssl3_enc_method {
ssl->method->set_handshake_header(ssl, htype, len)
#define ssl_do_write(ssl) ssl->method->do_write(ssl)
-/* Values for enc_flags */
-
-/* Uses explicit IV for CBC mode */
-#define SSL_ENC_FLAG_EXPLICIT_IV 0x1
-/* Uses signature algorithms extension */
-#define SSL_ENC_FLAG_SIGALGS 0x2
-/* Uses SHA256 default PRF */
-#define SSL_ENC_FLAG_SHA256_PRF 0x4
-
/* lengths of messages */
#define DTLS1_COOKIE_LENGTH 256
@@ -966,12 +961,9 @@ typedef struct dtls1_state_st {
} 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 *ssl);
int ssl_clear_bad_session(SSL *ssl);
CERT *ssl_cert_new(void);
CERT *ssl_cert_dup(CERT *cert);
@@ -1030,10 +1022,6 @@ 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 *ssl);
int ssl3_do_write(SSL *ssl, int type);
int ssl3_send_alert(SSL *ssl, int level, int desc);
@@ -1054,7 +1042,7 @@ int ssl3_hash_current_message(SSL *ssl);
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 *ssl, int a, int b, const char *sender, int slen);
+int ssl3_send_finished(SSL *ssl, int a, int b);
int ssl3_supports_cipher(const SSL_CIPHER *cipher);
int ssl3_dispatch_alert(SSL *ssl);
int ssl3_read_app_data(SSL *ssl, uint8_t *buf, int len, int peek);
@@ -1063,8 +1051,6 @@ void ssl3_read_close_notify(SSL *ssl);
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 *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,
@@ -1075,12 +1061,6 @@ 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. */
-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 *ssl, int htype, unsigned long len);
int ssl3_handshake_write(SSL *ssl);
@@ -1159,29 +1139,11 @@ int dtls1_dispatch_alert(SSL *ssl);
int ssl_init_wbio_buffer(SSL *ssl, int push);
void ssl_free_wbio_buffer(SSL *ssl);
-/* 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 *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 *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 *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);
char ssl_early_callback_init(struct ssl_early_callback_ctx *ctx);
@@ -1219,13 +1181,13 @@ int ssl_parse_serverhello_tlsext(SSL *ssl, CBS *cbs);
#define tlsext_tick_md EVP_sha256
-/* 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
+/* tls_process_ticket processes a session ticket from the client. On success,
+ * it sets |*out_session| to the decrypted session or NULL if the ticket was
+ * rejected. If the ticket was valid, it sets |*out_renew_ticket| to whether
+ * the ticket should be renewed. 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,
+ int *out_renew_ticket, const uint8_t *ticket,
size_t ticket_len, const uint8_t *session_id,
size_t session_id_len);
@@ -1294,9 +1256,13 @@ int ssl3_is_version_enabled(SSL *ssl, 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 *ssl, uint16_t wire_version);
+uint16_t ssl3_version_from_wire(const SSL *ssl, uint16_t wire_version);
+
+/* ssl3_protocol_version returns |ssl|'s protocol version. It is an error to
+ * call this function before the version is determined. */
+uint16_t ssl3_protocol_version(const SSL *ssl);
-uint32_t ssl_get_algorithm_prf(SSL *ssl);
+uint32_t ssl_get_algorithm_prf(const 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
diff --git a/src/ssl/pqueue/pqueue.c b/src/ssl/pqueue/pqueue.c
index 14bd9b63..e6897611 100644
--- a/src/ssl/pqueue/pqueue.c
+++ b/src/ssl/pqueue/pqueue.c
@@ -69,7 +69,7 @@ typedef struct _pqueue {
pitem *pitem_new(uint8_t prio64be[8], void *data) {
- pitem *item = (pitem *)OPENSSL_malloc(sizeof(pitem));
+ pitem *item = OPENSSL_malloc(sizeof(pitem));
if (item == NULL) {
return NULL;
}
@@ -91,7 +91,7 @@ void pitem_free(pitem *item) {
}
pqueue pqueue_new(void) {
- pqueue_s *pq = (pqueue_s *)OPENSSL_malloc(sizeof(pqueue_s));
+ pqueue_s *pq = OPENSSL_malloc(sizeof(pqueue_s));
if (pq == NULL) {
return NULL;
}
diff --git a/src/ssl/s3_both.c b/src/ssl/s3_both.c
index 01a7e8c5..5d364abf 100644
--- a/src/ssl/s3_both.c
+++ b/src/ssl/s3_both.c
@@ -114,7 +114,6 @@
#include <assert.h>
#include <limits.h>
-#include <stdio.h>
#include <string.h>
#include <openssl/buf.h>
@@ -122,7 +121,7 @@
#include <openssl/evp.h>
#include <openssl/mem.h>
#include <openssl/md5.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
#include <openssl/rand.h>
#include <openssl/sha.h>
#include <openssl/x509.h>
@@ -156,15 +155,15 @@ int ssl3_do_write(SSL *ssl, int type) {
return 0;
}
-int ssl3_send_finished(SSL *ssl, int a, int b, const char *sender, int slen) {
+int ssl3_send_finished(SSL *ssl, int a, int b) {
uint8_t *p;
int n;
if (ssl->state == a) {
p = ssl_handshake_start(ssl);
- n = ssl->enc_method->final_finish_mac(ssl, sender, slen,
- ssl->s3->tmp.finish_md);
+ n = ssl->s3->enc_method->final_finish_mac(ssl, ssl->server,
+ ssl->s3->tmp.finish_md);
if (n == 0) {
return 0;
}
@@ -202,25 +201,14 @@ int ssl3_send_finished(SSL *ssl, int a, int b, const char *sender, int slen) {
/* ssl3_take_mac calculates the Finished MAC for the handshakes messages seen
* so far. */
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 (ssl->s3->tmp.new_cipher == NULL) {
return;
}
- if (ssl->state & SSL_ST_CONNECT) {
- sender = ssl->enc_method->server_finished_label;
- slen = ssl->enc_method->server_finished_label_len;
- } else {
- sender = ssl->enc_method->client_finished_label;
- slen = ssl->enc_method->client_finished_label_len;
- }
-
- ssl->s3->tmp.peer_finish_md_len = ssl->enc_method->final_finish_mac(
- ssl, sender, slen, ssl->s3->tmp.peer_finish_md);
+ ssl->s3->tmp.peer_finish_md_len = ssl->s3->enc_method->final_finish_mac(
+ ssl, !ssl->server, ssl->s3->tmp.peer_finish_md);
}
int ssl3_get_finished(SSL *ssl, int a, int b) {
@@ -250,7 +238,12 @@ int ssl3_get_finished(SSL *ssl, int a, int b) {
goto f_err;
}
- if (CRYPTO_memcmp(p, ssl->s3->tmp.peer_finish_md, finished_len) != 0) {
+ int finished_ret =
+ CRYPTO_memcmp(p, ssl->s3->tmp.peer_finish_md, finished_len);
+#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
+ finished_ret = 0;
+#endif
+ if (finished_ret != 0) {
al = SSL_AD_DECRYPT_ERROR;
OPENSSL_PUT_ERROR(SSL, SSL_R_DIGEST_CHECK_FAILED);
goto f_err;
@@ -277,13 +270,6 @@ 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 *ssl, int a, int b) {
if (ssl->state == a) {
*((uint8_t *)ssl->init_buf->data) = SSL3_MT_CCS;
@@ -407,7 +393,6 @@ long ssl3_get_message(SSL *ssl, int header_state, int body_state, int msg_type,
int bytes_read =
ssl3_read_bytes(ssl, SSL3_RT_HANDSHAKE, &p[ssl->init_num], n, 0);
if (bytes_read <= 0) {
- ssl->rwstate = SSL_READING;
*ok = 0;
return bytes_read;
}
@@ -452,7 +437,7 @@ int ssl3_cert_verify_hash(SSL *ssl, uint8_t *out, size_t *out_len,
/* 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(ssl)) {
+ if (ssl3_protocol_version(ssl) >= TLS1_2_VERSION) {
EVP_MD_CTX mctx;
unsigned len;
@@ -467,15 +452,15 @@ int ssl3_cert_verify_hash(SSL *ssl, uint8_t *out, size_t *out_len,
}
*out_len = len;
} 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) {
+ if (ssl->s3->enc_method->cert_verify_mac(ssl, NID_md5, out) == 0 ||
+ ssl->s3->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 (ssl->enc_method->cert_verify_mac(ssl, NID_sha1, out) == 0) {
+ if (ssl->s3->enc_method->cert_verify_mac(ssl, NID_sha1, out) == 0) {
return 0;
}
*out_len = SHA_DIGEST_LENGTH;
diff --git a/src/ssl/s3_clnt.c b/src/ssl/s3_clnt.c
index 5f68037e..6f381cfa 100644
--- a/src/ssl/s3_clnt.c
+++ b/src/ssl/s3_clnt.c
@@ -150,7 +150,6 @@
#include <openssl/ssl.h>
#include <assert.h>
-#include <stdio.h>
#include <string.h>
#include <openssl/bn.h>
@@ -163,7 +162,6 @@
#include <openssl/evp.h>
#include <openssl/md5.h>
#include <openssl/mem.h>
-#include <openssl/obj.h>
#include <openssl/rand.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
@@ -182,7 +180,6 @@ int ssl3_connect(SSL *ssl) {
assert(!ssl->server);
assert(!SSL_IS_DTLS(ssl));
- ERR_clear_error();
ERR_clear_system_error();
if (ssl->info_callback != NULL) {
@@ -191,8 +188,6 @@ int ssl3_connect(SSL *ssl) {
cb = ssl->ctx->info_callback;
}
- ssl->in_handshake++;
-
for (;;) {
state = ssl->state;
@@ -388,10 +383,7 @@ int ssl3_connect(SSL *ssl) {
}
ssl->init_num = 0;
- 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)) {
+ if (!tls1_change_cipher_state(ssl, SSL3_CHANGE_CIPHER_CLIENT_WRITE)) {
ret = -1;
goto end;
}
@@ -424,9 +416,7 @@ int ssl3_connect(SSL *ssl) {
case SSL3_ST_CW_FINISHED_A:
case SSL3_ST_CW_FINISHED_B:
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);
+ SSL3_ST_CW_FINISHED_B);
if (ret <= 0) {
goto end;
}
@@ -487,7 +477,7 @@ int ssl3_connect(SSL *ssl) {
goto end;
}
- if (!ssl3_do_change_cipher_spec(ssl)) {
+ if (!tls1_change_cipher_state(ssl, SSL3_CHANGE_CIPHER_CLIENT_READ)) {
ret = -1;
goto end;
}
@@ -511,12 +501,11 @@ int ssl3_connect(SSL *ssl) {
break;
case SSL3_ST_CW_FLUSH:
- ssl->rwstate = SSL_WRITING;
if (BIO_flush(ssl->wbio) <= 0) {
+ ssl->rwstate = SSL_WRITING;
ret = -1;
goto end;
}
- ssl->rwstate = SSL_NOTHING;
ssl->state = ssl->s3->tmp.next_state;
break;
@@ -581,7 +570,6 @@ int ssl3_connect(SSL *ssl) {
}
end:
- ssl->in_handshake--;
BUF_MEM_free(buf);
if (cb != NULL) {
cb(ssl, SSL_CB_CONNECT_EXIT, ret);
@@ -676,13 +664,12 @@ int ssl3_send_client_hello(SSL *ssl) {
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 the configured session has expired or was created at a disabled
+ * 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))) {
+ !ssl3_is_version_enabled(ssl, ssl->session->ssl_version))) {
SSL_set_session(ssl, NULL);
}
@@ -791,8 +778,8 @@ int ssl3_get_server_hello(SSL *ssl) {
goto f_err;
}
ssl->version = server_version;
- ssl->enc_method = ssl3_get_enc_method(server_version);
- assert(ssl->enc_method != NULL);
+ ssl->s3->enc_method = ssl3_get_enc_method(server_version);
+ assert(ssl->s3->enc_method != NULL);
/* At this point, the connection's version is known and ssl->version is
* fixed. Begin enforcing the record-layer version. */
ssl->s3->have_version = 1;
@@ -841,8 +828,7 @@ int ssl3_get_server_hello(SSL *ssl) {
/* If the cipher is disabled then we didn't sent it in the ClientHello, so if
* the server selected it, it's an error. */
if ((c->algorithm_mkey & ct->mask_k) || (c->algorithm_auth & ct->mask_a) ||
- SSL_CIPHER_get_min_version(c) >
- ssl3_version_from_wire(ssl, ssl->version)) {
+ SSL_CIPHER_get_min_version(c) > ssl3_protocol_version(ssl)) {
al = SSL_AD_ILLEGAL_PARAMETER;
OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CIPHER_RETURNED);
goto f_err;
@@ -867,6 +853,8 @@ int ssl3_get_server_hello(SSL *ssl) {
OPENSSL_PUT_ERROR(SSL, SSL_R_OLD_SESSION_VERSION_NOT_RETURNED);
goto f_err;
}
+ } else {
+ ssl->session->cipher = c;
}
ssl->s3->tmp.new_cipher = c;
@@ -878,7 +866,7 @@ int ssl3_get_server_hello(SSL *ssl) {
/* If doing a full handshake with TLS 1.2, the server may request a client
* certificate which requires hashing the handshake transcript under a
* different hash. Otherwise, the handshake buffer may be released. */
- if (!SSL_USE_SIGALGS(ssl) || ssl->hit) {
+ if (ssl->hit || ssl3_protocol_version(ssl) < TLS1_2_VERSION) {
ssl3_free_handshake_buffer(ssl);
}
@@ -1060,19 +1048,16 @@ err:
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;
DH *dh = NULL;
EC_KEY *ecdh = 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 = 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);
+ long 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;
}
@@ -1097,11 +1082,12 @@ int ssl3_get_server_key_exchange(SSL *ssl) {
}
/* Retain a copy of the original CBS to compute the signature over. */
+ CBS server_key_exchange;
CBS_init(&server_key_exchange, ssl->init_msg, n);
- server_key_exchange_orig = server_key_exchange;
+ CBS server_key_exchange_orig = server_key_exchange;
- alg_k = ssl->s3->tmp.new_cipher->algorithm_mkey;
- alg_a = ssl->s3->tmp.new_cipher->algorithm_auth;
+ uint32_t alg_k = ssl->s3->tmp.new_cipher->algorithm_mkey;
+ uint32_t alg_a = ssl->s3->tmp.new_cipher->algorithm_auth;
EVP_MD_CTX_init(&md_ctx);
if (alg_a & SSL_aPSK) {
@@ -1224,6 +1210,7 @@ int ssl3_get_server_key_exchange(SSL *ssl) {
/* At this point, |server_key_exchange| contains the signature, if any, while
* |server_key_exchange_orig| contains the entire message. From that, derive
* a CBS containing just the parameter. */
+ CBS parameter;
CBS_init(&parameter, CBS_data(&server_key_exchange_orig),
CBS_len(&server_key_exchange_orig) - CBS_len(&server_key_exchange));
@@ -1234,7 +1221,8 @@ int ssl3_get_server_key_exchange(SSL *ssl) {
goto err;
}
- if (SSL_USE_SIGALGS(ssl)) {
+ const EVP_MD *md = NULL;
+ if (ssl3_protocol_version(ssl) >= TLS1_2_VERSION) {
uint8_t hash, signature;
if (!CBS_get_u8(&server_key_exchange, &hash) ||
!CBS_get_u8(&server_key_exchange, &signature)) {
@@ -1261,15 +1249,20 @@ int ssl3_get_server_key_exchange(SSL *ssl) {
goto f_err;
}
- if (!EVP_DigestVerifyInit(&md_ctx, NULL, md, NULL, pkey) ||
- !EVP_DigestVerifyUpdate(&md_ctx, ssl->s3->client_random,
- SSL3_RANDOM_SIZE) ||
- !EVP_DigestVerifyUpdate(&md_ctx, ssl->s3->server_random,
- SSL3_RANDOM_SIZE) ||
- !EVP_DigestVerifyUpdate(&md_ctx, CBS_data(&parameter),
- CBS_len(&parameter)) ||
- !EVP_DigestVerifyFinal(&md_ctx, CBS_data(&signature),
- CBS_len(&signature))) {
+ int sig_ok = EVP_DigestVerifyInit(&md_ctx, NULL, md, NULL, pkey) &&
+ EVP_DigestVerifyUpdate(&md_ctx, ssl->s3->client_random,
+ SSL3_RANDOM_SIZE) &&
+ EVP_DigestVerifyUpdate(&md_ctx, ssl->s3->server_random,
+ SSL3_RANDOM_SIZE) &&
+ EVP_DigestVerifyUpdate(&md_ctx, CBS_data(&parameter),
+ CBS_len(&parameter)) &&
+ EVP_DigestVerifyFinal(&md_ctx, CBS_data(&signature),
+ CBS_len(&signature));
+#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
+ sig_ok = 1;
+ ERR_clear_error();
+#endif
+ if (!sig_ok) {
/* bad signature */
al = SSL_AD_DECRYPT_ERROR;
OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SIGNATURE);
@@ -1306,17 +1299,12 @@ static int ca_dn_cmp(const X509_NAME **a, const X509_NAME **b) {
int ssl3_get_certificate_request(SSL *ssl) {
int ok, ret = 0;
- unsigned long n;
X509_NAME *xn = NULL;
STACK_OF(X509_NAME) *ca_sk = NULL;
- CBS cbs;
- CBS certificate_types;
- CBS certificate_authorities;
- const uint8_t *data;
- 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);
+ long 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;
@@ -1334,10 +1322,11 @@ int ssl3_get_certificate_request(SSL *ssl) {
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);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
goto err;
}
+ CBS cbs;
CBS_init(&cbs, ssl->init_msg, n);
ca_sk = sk_X509_NAME_new(ca_dn_cmp);
@@ -1347,6 +1336,7 @@ int ssl3_get_certificate_request(SSL *ssl) {
}
/* get the certificate types */
+ CBS certificate_types;
if (!CBS_get_u8_length_prefixed(&cbs, &certificate_types)) {
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
@@ -1359,7 +1349,7 @@ int ssl3_get_certificate_request(SSL *ssl) {
goto err;
}
- if (SSL_USE_SIGALGS(ssl)) {
+ if (ssl3_protocol_version(ssl) >= TLS1_2_VERSION) {
CBS supported_signature_algorithms;
if (!CBS_get_u16_length_prefixed(&cbs, &supported_signature_algorithms) ||
!tls1_parse_peer_sigalgs(ssl, &supported_signature_algorithms)) {
@@ -1370,6 +1360,7 @@ int ssl3_get_certificate_request(SSL *ssl) {
}
/* get the CA RDNs */
+ CBS certificate_authorities;
if (!CBS_get_u16_length_prefixed(&cbs, &certificate_authorities)) {
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
OPENSSL_PUT_ERROR(SSL, SSL_R_LENGTH_MISMATCH);
@@ -1385,25 +1376,13 @@ int ssl3_get_certificate_request(SSL *ssl) {
goto err;
}
- data = CBS_data(&distinguished_name);
-
+ const uint8_t *data = CBS_data(&distinguished_name);
/* A u16 length cannot overflow a long. */
xn = d2i_X509_NAME(NULL, &data, (long)CBS_len(&distinguished_name));
- if (xn == NULL) {
+ if (xn == NULL ||
+ data != CBS_data(&distinguished_name) + CBS_len(&distinguished_name)) {
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(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(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
- OPENSSL_PUT_ERROR(SSL, SSL_R_CA_DN_LENGTH_MISMATCH);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
goto err;
}
@@ -1411,6 +1390,7 @@ int ssl3_get_certificate_request(SSL *ssl) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
+ xn = NULL;
}
/* we should setup a certificate to return.... */
@@ -1422,6 +1402,7 @@ int ssl3_get_certificate_request(SSL *ssl) {
ret = 1;
err:
+ X509_NAME_free(xn);
sk_X509_NAME_pop_free(ca_sk, X509_NAME_free);
return ret;
}
@@ -1755,8 +1736,8 @@ int ssl3_send_client_key_exchange(SSL *ssl) {
}
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);
+ ssl->session->master_key_length =
+ tls1_generate_master_secret(ssl, ssl->session->master_key, pms, pms_len);
if (ssl->session->master_key_length == 0) {
goto err;
}
@@ -1768,6 +1749,7 @@ int ssl3_send_client_key_exchange(SSL *ssl) {
return ssl_do_write(ssl);
err:
+ CBB_cleanup(&cbb);
if (pms != NULL) {
OPENSSL_cleanse(pms, pms_len);
OPENSSL_free(pms);
@@ -1794,7 +1776,7 @@ int ssl3_send_cert_verify(SSL *ssl) {
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)) {
+ if (ssl3_protocol_version(ssl) >= TLS1_2_VERSION) {
md = tls1_choose_signing_digest(ssl);
if (!tls12_add_sigandhash(ssl, &cbb, md)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
@@ -1828,7 +1810,8 @@ int ssl3_send_cert_verify(SSL *ssl) {
/* Skip over the already written signature algorithm and retry the
* signature. */
uint8_t *ptr;
- if ((SSL_USE_SIGALGS(ssl) && !CBB_did_write(&cbb, 2)) ||
+ if ((ssl3_protocol_version(ssl) >= TLS1_2_VERSION &&
+ !CBB_did_write(&cbb, 2)) ||
!CBB_add_u16_length_prefixed(&cbb, &child) ||
!CBB_reserve(&child, &ptr, max_sig_len)) {
goto err;
@@ -1839,10 +1822,8 @@ int ssl3_send_cert_verify(SSL *ssl) {
switch (sign_result) {
case ssl_private_key_success:
- ssl->rwstate = SSL_NOTHING;
break;
case ssl_private_key_failure:
- ssl->rwstate = SSL_NOTHING;
goto err;
case ssl_private_key_retry:
ssl->rwstate = SSL_PRIVATE_KEY_OPERATION;
@@ -1872,23 +1853,18 @@ static int ssl3_has_client_certificate(SSL *ssl) {
}
int ssl3_send_client_certificate(SSL *ssl) {
- X509 *x509 = NULL;
- EVP_PKEY *pkey = NULL;
- int i;
-
if (ssl->state == SSL3_ST_CW_CERT_A) {
- /* Let cert callback update client certificates if required */
+ /* Call cert_cb to update the certificate. */
if (ssl->cert->cert_cb) {
- i = ssl->cert->cert_cb(ssl, ssl->cert->cert_cb_arg);
- if (i < 0) {
+ int ret = ssl->cert->cert_cb(ssl, ssl->cert->cert_cb_arg);
+ if (ret < 0) {
ssl->rwstate = SSL_X509_LOOKUP;
return -1;
}
- if (i == 0) {
+ if (ret == 0) {
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
- return 0;
+ return -1;
}
- ssl->rwstate = SSL_NOTHING;
}
if (ssl3_has_client_certificate(ssl)) {
@@ -1898,52 +1874,42 @@ int ssl3_send_client_certificate(SSL *ssl) {
}
}
- /* We need to get a client cert */
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(ssl, &x509, &pkey);
- if (i < 0) {
+ /* Call client_cert_cb to update the certificate. */
+ X509 *x509 = NULL;
+ EVP_PKEY *pkey = NULL;
+ int ret = ssl_do_client_cert_cb(ssl, &x509, &pkey);
+ if (ret < 0) {
ssl->rwstate = SSL_X509_LOOKUP;
return -1;
}
- ssl->rwstate = SSL_NOTHING;
- if (i == 1 && pkey != NULL && x509 != NULL) {
- 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, SSL_R_BAD_DATA_RETURNED_BY_CALLBACK);
- }
+ int setup_error = ret == 1 && (!SSL_use_certificate(ssl, x509) ||
+ !SSL_use_PrivateKey(ssl, pkey));
X509_free(x509);
EVP_PKEY_free(pkey);
- if (i && !ssl3_has_client_certificate(ssl)) {
- i = 0;
+ if (setup_error) {
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ return -1;
}
- if (i == 0) {
+
+ ssl->state = SSL3_ST_CW_CERT_C;
+ }
+
+ if (ssl->state == SSL3_ST_CW_CERT_C) {
+ if (!ssl3_has_client_certificate(ssl)) {
+ /* Without a client certificate, the handshake buffer may be released. */
+ ssl3_free_handshake_buffer(ssl);
+
if (ssl->version == SSL3_VERSION) {
+ /* In SSL 3.0, send no certificate by skipping both messages. */
ssl->s3->tmp.cert_req = 0;
ssl3_send_alert(ssl, SSL3_AL_WARNING, SSL_AD_NO_CERTIFICATE);
return 1;
- } else {
- ssl->s3->tmp.cert_req = 2;
- /* There is no client certificate, so the handshake buffer may be
- * released. */
- ssl3_free_handshake_buffer(ssl);
}
- }
- /* Ok, we have a cert */
- ssl->state = SSL3_ST_CW_CERT_C;
- }
-
- if (ssl->state == SSL3_ST_CW_CERT_C) {
- if (ssl->s3->tmp.cert_req == 2) {
- /* Send an empty Certificate message. */
+ /* In TLS, send an empty Certificate message. */
+ ssl->s3->tmp.cert_req = 2;
uint8_t *p = ssl_handshake_start(ssl);
l2n3(0, p);
if (!ssl_set_handshake_header(ssl, SSL3_MT_CERTIFICATE, 3)) {
@@ -1955,7 +1921,7 @@ int ssl3_send_client_certificate(SSL *ssl) {
ssl->state = SSL3_ST_CW_CERT_D;
}
- /* SSL3_ST_CW_CERT_D */
+ assert(ssl->state == SSL3_ST_CW_CERT_D);
return ssl_do_write(ssl);
}
@@ -1967,7 +1933,7 @@ int ssl3_send_next_proto(SSL *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);
+ size_t padding_len = 32 - ((ssl->s3->next_proto_negotiated_len + 2) % 32);
CBB cbb, child;
size_t length;
@@ -1975,8 +1941,8 @@ int ssl3_send_next_proto(SSL *ssl) {
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_bytes(&child, ssl->s3->next_proto_negotiated,
+ ssl->s3->next_proto_negotiated_len) ||
!CBB_add_u8_length_prefixed(&cbb, &child) ||
!CBB_add_bytes(&child, kZero, padding_len) ||
!CBB_finish(&cbb, NULL, &length) ||
@@ -2013,7 +1979,6 @@ int ssl3_send_channel_id(SSL *ssl) {
ssl->rwstate = SSL_CHANNEL_ID_LOOKUP;
return -1;
}
- ssl->rwstate = SSL_NOTHING;
EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(ssl->tlsext_channel_id_private);
if (ec_key == NULL) {
@@ -2075,7 +2040,15 @@ 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 ssl->ctx->client_cert_cb(ssl, out_x509, out_pkey);
+
+ int ret = ssl->ctx->client_cert_cb(ssl, out_x509, out_pkey);
+ if (ret <= 0) {
+ return ret;
+ }
+
+ assert(*out_x509 != NULL);
+ assert(*out_pkey != NULL);
+ return 1;
}
int ssl3_verify_server_cert(SSL *ssl) {
diff --git a/src/ssl/s3_enc.c b/src/ssl/s3_enc.c
index 89d861a5..04aa08c9 100644
--- a/src/ssl/s3_enc.c
+++ b/src/ssl/s3_enc.c
@@ -136,39 +136,24 @@
#include <openssl/ssl.h>
#include <assert.h>
-#include <stdio.h>
#include <string.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/mem.h>
#include <openssl/md5.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
#include "internal.h"
-static const uint8_t ssl3_pad_1[48] = {
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-};
-
-static const uint8_t ssl3_pad_2[48] = {
- 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
- 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
- 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
- 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
-};
+static int ssl3_handshake_mac(SSL *ssl, int md_nid, const char *sender,
+ size_t sender_len, uint8_t *p);
-static int ssl3_handshake_mac(SSL *ssl, int md_nid, const char *sender, int len,
- uint8_t *p);
-
-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) {
+static int ssl3_prf(const 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) {
EVP_MD_CTX md5;
EVP_MD_CTX sha1;
uint8_t buf[16], smd[SHA_DIGEST_LENGTH];
@@ -309,20 +294,23 @@ int ssl3_update_handshake_hash(SSL *ssl, const uint8_t *in, size_t in_len) {
return 1;
}
-int ssl3_cert_verify_mac(SSL *ssl, int md_nid, uint8_t *p) {
+static 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 *ssl, const char *sender, int len, uint8_t *p) {
+static int ssl3_final_finish_mac(SSL *ssl, int from_server, uint8_t *out) {
+ const char *sender = from_server ? SSL3_MD_SERVER_FINISHED_CONST
+ : SSL3_MD_CLIENT_FINISHED_CONST;
+ const size_t sender_len = 4;
int ret, sha1len;
- ret = ssl3_handshake_mac(ssl, NID_md5, sender, len, p);
+ ret = ssl3_handshake_mac(ssl, NID_md5, sender, sender_len, out);
if (ret == 0) {
return 0;
}
- p += ret;
+ out += ret;
- sha1len = ssl3_handshake_mac(ssl, NID_sha1, sender, len, p);
+ sha1len = ssl3_handshake_mac(ssl, NID_sha1, sender, sender_len, out);
if (sha1len == 0) {
return 0;
}
@@ -331,8 +319,8 @@ int ssl3_final_finish_mac(SSL *ssl, const char *sender, int len, uint8_t *p) {
return ret;
}
-static int ssl3_handshake_mac(SSL *ssl, int md_nid, const char *sender, int len,
- uint8_t *p) {
+static int ssl3_handshake_mac(SSL *ssl, int md_nid, const char *sender,
+ size_t sender_len, uint8_t *p) {
unsigned int ret;
size_t npad, n;
unsigned int i;
@@ -356,15 +344,29 @@ static int ssl3_handshake_mac(SSL *ssl, int md_nid, const char *sender, int len,
return 0;
}
+ static const uint8_t kPad1[48] = {
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ };
+
+ static const uint8_t kPad2[48] = {
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ };
+
n = EVP_MD_CTX_size(&ctx);
npad = (48 / n) * n;
if (sender != NULL) {
- EVP_DigestUpdate(&ctx, sender, len);
+ EVP_DigestUpdate(&ctx, sender, sender_len);
}
EVP_DigestUpdate(&ctx, ssl->session->master_key,
ssl->session->master_key_length);
- EVP_DigestUpdate(&ctx, ssl3_pad_1, npad);
+ EVP_DigestUpdate(&ctx, kPad1, npad);
EVP_DigestFinal_ex(&ctx, md_buf, &i);
if (!EVP_DigestInit_ex(&ctx, EVP_MD_CTX_md(&ctx), NULL)) {
@@ -374,7 +376,7 @@ static int ssl3_handshake_mac(SSL *ssl, int md_nid, const char *sender, int len,
}
EVP_DigestUpdate(&ctx, ssl->session->master_key,
ssl->session->master_key_length);
- EVP_DigestUpdate(&ctx, ssl3_pad_2, npad);
+ EVP_DigestUpdate(&ctx, kPad2, npad);
EVP_DigestUpdate(&ctx, md_buf, i);
EVP_DigestFinal_ex(&ctx, p, &ret);
@@ -383,114 +385,10 @@ static int ssl3_handshake_mac(SSL *ssl, int md_nid, const char *sender, int len,
return ret;
}
-int ssl3_record_sequence_update(uint8_t *seq, size_t seq_len) {
- size_t i;
- for (i = seq_len - 1; i < seq_len; i--) {
- ++seq[i];
- if (seq[i] != 0) {
- return 1;
- }
- }
- OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
- return 0;
-}
-
-int ssl3_alert_code(int code) {
- switch (code) {
- case SSL_AD_CLOSE_NOTIFY:
- return SSL3_AD_CLOSE_NOTIFY;
-
- case SSL_AD_UNEXPECTED_MESSAGE:
- return SSL3_AD_UNEXPECTED_MESSAGE;
-
- case SSL_AD_BAD_RECORD_MAC:
- return SSL3_AD_BAD_RECORD_MAC;
-
- case SSL_AD_DECRYPTION_FAILED:
- return SSL3_AD_BAD_RECORD_MAC;
-
- case SSL_AD_RECORD_OVERFLOW:
- return SSL3_AD_BAD_RECORD_MAC;
-
- case SSL_AD_DECOMPRESSION_FAILURE:
- return SSL3_AD_DECOMPRESSION_FAILURE;
-
- case SSL_AD_HANDSHAKE_FAILURE:
- return SSL3_AD_HANDSHAKE_FAILURE;
-
- case SSL_AD_NO_CERTIFICATE:
- return SSL3_AD_NO_CERTIFICATE;
-
- case SSL_AD_BAD_CERTIFICATE:
- return SSL3_AD_BAD_CERTIFICATE;
-
- case SSL_AD_UNSUPPORTED_CERTIFICATE:
- return SSL3_AD_UNSUPPORTED_CERTIFICATE;
-
- case SSL_AD_CERTIFICATE_REVOKED:
- return SSL3_AD_CERTIFICATE_REVOKED;
-
- case SSL_AD_CERTIFICATE_EXPIRED:
- return SSL3_AD_CERTIFICATE_EXPIRED;
- case SSL_AD_CERTIFICATE_UNKNOWN:
- return SSL3_AD_CERTIFICATE_UNKNOWN;
- case SSL_AD_ILLEGAL_PARAMETER:
- return SSL3_AD_ILLEGAL_PARAMETER;
-
- case SSL_AD_UNKNOWN_CA:
- return SSL3_AD_BAD_CERTIFICATE;
-
- case SSL_AD_ACCESS_DENIED:
- return SSL3_AD_HANDSHAKE_FAILURE;
-
- case SSL_AD_DECODE_ERROR:
- return SSL3_AD_HANDSHAKE_FAILURE;
-
- case SSL_AD_DECRYPT_ERROR:
- return SSL3_AD_HANDSHAKE_FAILURE;
-
- case SSL_AD_EXPORT_RESTRICTION:
- return SSL3_AD_HANDSHAKE_FAILURE;
-
- case SSL_AD_PROTOCOL_VERSION:
- return SSL3_AD_HANDSHAKE_FAILURE;
-
- case SSL_AD_INSUFFICIENT_SECURITY:
- return SSL3_AD_HANDSHAKE_FAILURE;
-
- case SSL_AD_INTERNAL_ERROR:
- return SSL3_AD_HANDSHAKE_FAILURE;
-
- case SSL_AD_USER_CANCELLED:
- return SSL3_AD_HANDSHAKE_FAILURE;
-
- case SSL_AD_NO_RENEGOTIATION:
- return -1; /* Don't send it. */
-
- case SSL_AD_UNSUPPORTED_EXTENSION:
- return SSL3_AD_HANDSHAKE_FAILURE;
-
- case SSL_AD_CERTIFICATE_UNOBTAINABLE:
- return SSL3_AD_HANDSHAKE_FAILURE;
-
- case SSL_AD_UNRECOGNIZED_NAME:
- return SSL3_AD_HANDSHAKE_FAILURE;
-
- case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE:
- return SSL3_AD_HANDSHAKE_FAILURE;
-
- case SSL_AD_BAD_CERTIFICATE_HASH_VALUE:
- return SSL3_AD_HANDSHAKE_FAILURE;
-
- case SSL_AD_UNKNOWN_PSK_IDENTITY:
- return TLS1_AD_UNKNOWN_PSK_IDENTITY;
-
- case SSL_AD_INAPPROPRIATE_FALLBACK:
- return SSL3_AD_INAPPROPRIATE_FALLBACK;
-
- default:
- return -1;
- }
-}
+const SSL3_ENC_METHOD SSLv3_enc_data = {
+ ssl3_prf,
+ ssl3_final_finish_mac,
+ ssl3_cert_verify_mac,
+};
diff --git a/src/ssl/s3_lib.c b/src/ssl/s3_lib.c
index 64f9f8c5..7df046f0 100644
--- a/src/ssl/s3_lib.c
+++ b/src/ssl/s3_lib.c
@@ -149,7 +149,6 @@
#include <openssl/ssl.h>
#include <assert.h>
-#include <stdio.h>
#include <string.h>
#include <openssl/buf.h>
@@ -158,25 +157,11 @@
#include <openssl/err.h>
#include <openssl/md5.h>
#include <openssl/mem.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
#include "internal.h"
-const SSL3_ENC_METHOD SSLv3_enc_data = {
- ssl3_prf,
- tls1_setup_key_block,
- tls1_generate_master_secret,
- tls1_change_cipher_state,
- ssl3_final_finish_mac,
- ssl3_cert_verify_mac,
- SSL3_MD_CLIENT_FINISHED_CONST, 4,
- SSL3_MD_SERVER_FINISHED_CONST, 4,
- ssl3_alert_code,
- tls1_export_keying_material,
- 0,
-};
-
int ssl3_supports_cipher(const SSL_CIPHER *cipher) {
return 1;
}
@@ -211,11 +196,11 @@ int ssl3_new(SSL *ssl) {
ssl->s3 = s3;
- /* Set the version to the highest supported version for TLS. This controls the
- * initial state of |ssl->enc_method| and what the API reports as the version
- * prior to negotiation.
+ /* Set the version to the highest supported version.
*
- * TODO(davidben): This is fragile and confusing. */
+ * TODO(davidben): Move this field into |s3|, have it store the normalized
+ * protocol version, and implement this pre-negotiation quirk in |SSL_version|
+ * at the API boundary rather than in internal state. */
ssl->version = TLS1_2_VERSION;
return 1;
err:
@@ -239,7 +224,10 @@ void ssl3_free(SSL *ssl) {
OPENSSL_free(ssl->s3->tmp.peer_psk_identity_hint);
ssl3_free_handshake_buffer(ssl);
ssl3_free_handshake_hash(ssl);
+ OPENSSL_free(ssl->s3->next_proto_negotiated);
OPENSSL_free(ssl->s3->alpn_selected);
+ SSL_AEAD_CTX_free(ssl->s3->aead_read_ctx);
+ SSL_AEAD_CTX_free(ssl->s3->aead_write_ctx);
OPENSSL_cleanse(ssl->s3, sizeof *ssl->s3);
OPENSSL_free(ssl->s3);
@@ -262,7 +250,7 @@ int SSL_CTX_need_tmp_RSA(const SSL_CTX *ctx) {
return 0;
}
-int SSL_need_rsa(const SSL *ssl) {
+int SSL_need_tmp_RSA(const SSL *ssl) {
return 0;
}
@@ -322,23 +310,28 @@ int SSL_enable_tls_channel_id(SSL *ssl) {
return 1;
}
+static int is_p256_key(EVP_PKEY *private_key) {
+ const EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(private_key);
+ return ec_key != NULL &&
+ EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)) ==
+ NID_X9_62_prime256v1;
+}
+
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) {
+ if (!is_p256_key(private_key)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_CHANNEL_ID_NOT_P256);
return 0;
}
+
EVP_PKEY_free(ctx->tlsext_channel_id_private);
ctx->tlsext_channel_id_private = EVP_PKEY_up_ref(private_key);
+ ctx->tlsext_channel_id_enabled = 1;
+
return 1;
}
int SSL_set1_tls_channel_id(SSL *ssl, EVP_PKEY *private_key) {
- 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) {
+ if (!is_p256_key(private_key)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_CHANNEL_ID_NOT_P256);
return 0;
}
@@ -365,7 +358,9 @@ int SSL_set_tlsext_host_name(SSL *ssl, const char *name) {
if (name == NULL) {
return 1;
}
- if (strlen(name) > TLSEXT_MAXLEN_host_name) {
+
+ size_t len = strlen(name);
+ if (len == 0 || len > TLSEXT_MAXLEN_host_name) {
OPENSSL_PUT_ERROR(SSL, SSL_R_SSL3_EXT_INVALID_SERVERNAME);
return 0;
}
@@ -452,17 +447,15 @@ struct ssl_cipher_preference_list_st *ssl_get_cipher_preferences(SSL *ssl) {
return ssl->cipher_list;
}
- if (ssl->version >= TLS1_1_VERSION && ssl->ctx != NULL &&
- ssl->ctx->cipher_list_tls11 != NULL) {
+ if (ssl->version >= TLS1_1_VERSION && ssl->ctx->cipher_list_tls11 != NULL) {
return ssl->ctx->cipher_list_tls11;
}
- if (ssl->version >= TLS1_VERSION && ssl->ctx != NULL &&
- ssl->ctx->cipher_list_tls10 != NULL) {
+ if (ssl->version >= TLS1_VERSION && ssl->ctx->cipher_list_tls10 != NULL) {
return ssl->ctx->cipher_list_tls10;
}
- if (ssl->ctx != NULL && ssl->ctx->cipher_list != NULL) {
+ if (ssl->ctx->cipher_list != NULL) {
return ssl->ctx->cipher_list;
}
@@ -505,8 +498,7 @@ const SSL_CIPHER *ssl3_choose_cipher(
ok = 1;
/* Check the TLS version. */
- if (SSL_CIPHER_get_min_version(c) >
- ssl3_version_from_wire(ssl, ssl->version)) {
+ if (SSL_CIPHER_get_min_version(c) > ssl3_protocol_version(ssl)) {
ok = 0;
}
@@ -578,10 +570,10 @@ int ssl3_get_req_cert_type(SSL *ssl, uint8_t *p) {
/* If we are using default SHA1+MD5 algorithms switch to new SHA256 PRF and
* handshake macs if required. */
-uint32_t ssl_get_algorithm_prf(SSL *ssl) {
+uint32_t ssl_get_algorithm_prf(const 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) {
+ if (algorithm_prf == SSL_HANDSHAKE_MAC_DEFAULT &&
+ ssl3_protocol_version(ssl) >= TLS1_2_VERSION) {
return SSL_HANDSHAKE_MAC_SHA256;
}
return algorithm_prf;
diff --git a/src/ssl/s3_pkt.c b/src/ssl/s3_pkt.c
index 4c1133c1..d9c21d42 100644
--- a/src/ssl/s3_pkt.c
+++ b/src/ssl/s3_pkt.c
@@ -110,7 +110,6 @@
#include <assert.h>
#include <limits.h>
-#include <stdio.h>
#include <string.h>
#include <openssl/buf.h>
@@ -183,6 +182,8 @@ again:
}
int ssl3_write_app_data(SSL *ssl, const void *buf, int len) {
+ assert(!SSL_in_init(ssl) || SSL_in_false_start(ssl));
+
return ssl3_write_bytes(ssl, SSL3_RT_APPLICATION_DATA, buf, len);
}
@@ -190,25 +191,12 @@ int ssl3_write_app_data(SSL *ssl, const void *buf, int len) {
* not all data has been sent or non-blocking IO. */
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;
+ unsigned tot, n, nw;
- ssl->rwstate = SSL_NOTHING;
assert(ssl->s3->wnum <= INT_MAX);
tot = ssl->s3->wnum;
ssl->s3->wnum = 0;
- 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, SSL_R_SSL_HANDSHAKE_FAILURE);
- return -1;
- }
- }
-
/* Ensure that if we end up with a smaller value of data to write out than
* the the original len from a write which didn't complete for non-blocking
* I/O and also somehow ended up avoiding the check for this in
@@ -232,19 +220,19 @@ int ssl3_write_bytes(SSL *ssl, int type, const void *buf_, int len) {
nw = n;
}
- i = do_ssl3_write(ssl, type, &buf[tot], nw);
- if (i <= 0) {
+ int ret = do_ssl3_write(ssl, type, &buf[tot], nw);
+ if (ret <= 0) {
ssl->s3->wnum = tot;
- return i;
+ return ret;
}
- if (i == (int)n || (type == SSL3_RT_APPLICATION_DATA &&
- (ssl->mode & SSL_MODE_ENABLE_PARTIAL_WRITE))) {
- return tot + i;
+ if (ret == (int)n || (type == SSL3_RT_APPLICATION_DATA &&
+ (ssl->mode & SSL_MODE_ENABLE_PARTIAL_WRITE))) {
+ return tot + ret;
}
- n -= i;
- tot += i;
+ n -= ret;
+ tot += ret;
}
}
@@ -315,6 +303,7 @@ static int do_ssl3_write(SSL *ssl, int type, const uint8_t *buf, unsigned len) {
}
int ssl3_read_app_data(SSL *ssl, uint8_t *buf, int len, int peek) {
+ assert(!SSL_in_init(ssl));
return ssl3_read_bytes(ssl, SSL3_RT_APPLICATION_DATA, buf, len, peek);
}
@@ -387,26 +376,7 @@ int ssl3_read_bytes(SSL *ssl, int type, uint8_t *buf, int len, int peek) {
return -1;
}
- /* This may require multiple iterations. False Start will cause
- * |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 (!ssl->in_handshake && SSL_in_init(ssl)) {
- assert(type == SSL3_RT_APPLICATION_DATA);
- i = ssl->handshake_func(ssl);
- if (i < 0) {
- return i;
- }
- if (i == 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_HANDSHAKE_FAILURE);
- return -1;
- }
- }
-
start:
- ssl->rwstate = SSL_NOTHING;
-
/* ssl->s3->rrec.type - is the type of record
* ssl->s3->rrec.data - data
* ssl->s3->rrec.off - offset into 'data' for next read
@@ -427,7 +397,6 @@ start:
* 'peek' mode) */
if (ssl->shutdown & SSL_RECEIVED_SHUTDOWN) {
rr->length = 0;
- ssl->rwstate = SSL_NOTHING;
return 0;
}
@@ -437,7 +406,7 @@ start:
/* 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) {
+ ssl->s3->aead_read_ctx == NULL) {
/* TODO(davidben): Is this check redundant with the handshake_func
* check? */
al = SSL_AD_UNEXPECTED_MESSAGE;
@@ -546,11 +515,10 @@ start:
goto start;
}
- /* If an alert record, process one alert out of the record. Note that we allow
- * a single record to contain multiple alerts. */
+ /* If an alert record, process the alert. */
if (rr->type == SSL3_RT_ALERT) {
- /* Alerts may not be fragmented. */
- if (rr->length < 2) {
+ /* Alerts records may not contain fragmented or multiple alerts. */
+ if (rr->length != 2) {
al = SSL_AD_DECODE_ERROR;
OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ALERT);
goto f_err;
@@ -577,25 +545,12 @@ start:
}
if (alert_level == SSL3_AL_WARNING) {
- ssl->s3->warn_alert = alert_descr;
if (alert_descr == SSL_AD_CLOSE_NOTIFY) {
+ ssl->s3->clean_shutdown = 1;
ssl->shutdown |= SSL_RECEIVED_SHUTDOWN;
return 0;
}
- /* This is a warning but we receive it if we requested renegotiation and
- * the peer denied it. Terminate with a fatal alert because if
- * application tried to renegotiatie it presumably had a good reason and
- * expects it to succeed.
- *
- * In future we might have a renegotiation where we don't care if the
- * peer refused it where we carry on. */
- else if (alert_descr == SSL_AD_NO_RENEGOTIATION) {
- al = SSL_AD_HANDSHAKE_FAILURE;
- 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;
@@ -605,8 +560,6 @@ start:
} else if (alert_level == SSL3_AL_FATAL) {
char tmp[16];
- 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);
@@ -637,46 +590,7 @@ err:
return -1;
}
-int ssl3_do_change_cipher_spec(SSL *ssl) {
- int i;
-
- if (ssl->state & SSL_ST_ACCEPT) {
- i = SSL3_CHANGE_CIPHER_SERVER_READ;
- } else {
- i = SSL3_CHANGE_CIPHER_CLIENT_READ;
- }
-
- if (ssl->s3->tmp.key_block == NULL) {
- if (ssl->session == NULL || ssl->session->master_key_length == 0) {
- /* might happen if dtls1_read_bytes() calls this */
- OPENSSL_PUT_ERROR(SSL, SSL_R_CCS_RECEIVED_EARLY);
- return 0;
- }
-
- ssl->session->cipher = ssl->s3->tmp.new_cipher;
- if (!ssl->enc_method->setup_key_block(ssl)) {
- return 0;
- }
- }
-
- if (!ssl->enc_method->change_cipher_state(ssl, i)) {
- return 0;
- }
-
- return 1;
-}
-
int ssl3_send_alert(SSL *ssl, int level, int desc) {
- /* Map tls/ssl alert value to correct one */
- 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;
- }
- if (desc < 0) {
- return -1;
- }
-
/* If a fatal one, remove from cache */
if (level == 2 && ssl->session != NULL) {
SSL_CTX_remove_session(ssl->ctx, ssl->session);
@@ -697,36 +611,34 @@ int ssl3_send_alert(SSL *ssl, int level, int desc) {
}
int ssl3_dispatch_alert(SSL *ssl) {
- int i, j;
- void (*cb)(const SSL *ssl, int type, int value) = NULL;
-
ssl->s3->alert_dispatch = 0;
- i = do_ssl3_write(ssl, SSL3_RT_ALERT, &ssl->s3->send_alert[0], 2);
- if (i <= 0) {
+ int ret = do_ssl3_write(ssl, SSL3_RT_ALERT, &ssl->s3->send_alert[0], 2);
+ if (ret <= 0) {
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 (ssl->s3->send_alert[0] == SSL3_AL_FATAL) {
- BIO_flush(ssl->wbio);
- }
+ return ret;
+ }
- if (ssl->msg_callback) {
- ssl->msg_callback(1, ssl->version, SSL3_RT_ALERT, ssl->s3->send_alert, 2,
- ssl, ssl->msg_callback_arg);
- }
+ /* If the alert is fatal, flush the BIO now. */
+ if (ssl->s3->send_alert[0] == SSL3_AL_FATAL) {
+ BIO_flush(ssl->wbio);
+ }
- if (ssl->info_callback != NULL) {
- cb = ssl->info_callback;
- } else if (ssl->ctx->info_callback != NULL) {
- cb = ssl->ctx->info_callback;
- }
+ if (ssl->msg_callback != NULL) {
+ ssl->msg_callback(1 /* write */, ssl->version, SSL3_RT_ALERT,
+ ssl->s3->send_alert, 2, ssl, ssl->msg_callback_arg);
+ }
- if (cb != NULL) {
- j = (ssl->s3->send_alert[0] << 8) | ssl->s3->send_alert[1];
- cb(ssl, SSL_CB_WRITE_ALERT, j);
- }
+ void (*cb)(const SSL *ssl, int type, int value) = NULL;
+ if (ssl->info_callback != NULL) {
+ cb = ssl->info_callback;
+ } else if (ssl->ctx->info_callback != NULL) {
+ cb = ssl->ctx->info_callback;
+ }
+
+ if (cb != NULL) {
+ int alert = (ssl->s3->send_alert[0] << 8) | ssl->s3->send_alert[1];
+ cb(ssl, SSL_CB_WRITE_ALERT, alert);
}
- return i;
+ return 1;
}
diff --git a/src/ssl/s3_srvr.c b/src/ssl/s3_srvr.c
index 49a1a95c..f06ee568 100644
--- a/src/ssl/s3_srvr.c
+++ b/src/ssl/s3_srvr.c
@@ -149,7 +149,6 @@
#include <openssl/ssl.h>
#include <assert.h>
-#include <stdio.h>
#include <string.h>
#include <openssl/bn.h>
@@ -164,7 +163,7 @@
#include <openssl/hmac.h>
#include <openssl/md5.h>
#include <openssl/mem.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
#include <openssl/rand.h>
#include <openssl/sha.h>
#include <openssl/x509.h>
@@ -185,7 +184,6 @@ int ssl3_accept(SSL *ssl) {
assert(ssl->server);
assert(!SSL_IS_DTLS(ssl));
- ERR_clear_error();
ERR_clear_system_error();
if (ssl->info_callback != NULL) {
@@ -194,8 +192,6 @@ int ssl3_accept(SSL *ssl) {
cb = ssl->ctx->info_callback;
}
- ssl->in_handshake++;
-
if (ssl->cert == NULL) {
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET);
return -1;
@@ -375,12 +371,11 @@ int ssl3_accept(SSL *ssl) {
* 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. */
- ssl->rwstate = SSL_WRITING;
if (BIO_flush(ssl->wbio) <= 0) {
+ ssl->rwstate = SSL_WRITING;
ret = -1;
goto end;
}
- ssl->rwstate = SSL_NOTHING;
ssl->state = ssl->s3->tmp.next_state;
break;
@@ -425,7 +420,7 @@ int ssl3_accept(SSL *ssl) {
goto end;
}
- if (!ssl3_do_change_cipher_spec(ssl)) {
+ if (!tls1_change_cipher_state(ssl, SSL3_CHANGE_CIPHER_SERVER_READ)) {
ret = -1;
goto end;
}
@@ -502,12 +497,6 @@ int ssl3_accept(SSL *ssl) {
case SSL3_ST_SW_CHANGE_A:
case SSL3_ST_SW_CHANGE_B:
- 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(ssl, SSL3_ST_SW_CHANGE_A,
SSL3_ST_SW_CHANGE_B);
if (ret <= 0) {
@@ -516,8 +505,7 @@ int ssl3_accept(SSL *ssl) {
ssl->state = SSL3_ST_SW_FINISHED_A;
ssl->init_num = 0;
- if (!ssl->enc_method->change_cipher_state(
- ssl, SSL3_CHANGE_CIPHER_SERVER_WRITE)) {
+ if (!tls1_change_cipher_state(ssl, SSL3_CHANGE_CIPHER_SERVER_WRITE)) {
ret = -1;
goto end;
}
@@ -526,9 +514,7 @@ int ssl3_accept(SSL *ssl) {
case SSL3_ST_SW_FINISHED_A:
case SSL3_ST_SW_FINISHED_B:
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);
+ SSL3_ST_SW_FINISHED_B);
if (ret <= 0) {
goto end;
}
@@ -590,7 +576,6 @@ int ssl3_accept(SSL *ssl) {
}
end:
- ssl->in_handshake--;
BUF_MEM_free(buf);
if (cb != NULL) {
cb(ssl, SSL_CB_ACCEPT_EXIT, ret);
@@ -880,8 +865,8 @@ int ssl3_get_client_hello(SSL *ssl) {
goto f_err;
}
ssl->version = version;
- ssl->enc_method = ssl3_get_enc_method(version);
- assert(ssl->enc_method != NULL);
+ ssl->s3->enc_method = ssl3_get_enc_method(version);
+ assert(ssl->s3->enc_method != NULL);
/* At this point, the connection's version is known and |ssl->version| is
* fixed. Begin enforcing the record-layer version. */
ssl->s3->have_version = 1;
@@ -1050,7 +1035,6 @@ int ssl3_get_client_hello(SSL *ssl) {
ssl->rwstate = SSL_X509_LOOKUP;
goto err;
}
- ssl->rwstate = SSL_NOTHING;
}
c = ssl3_choose_cipher(ssl, ciphers, ssl_get_cipher_preferences(ssl));
@@ -1059,6 +1043,7 @@ int ssl3_get_client_hello(SSL *ssl) {
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_CIPHER);
goto f_err;
}
+ ssl->session->cipher = c;
ssl->s3->tmp.new_cipher = c;
/* Determine whether to request a client certificate. */
@@ -1085,7 +1070,8 @@ int ssl3_get_client_hello(SSL *ssl) {
/* In TLS 1.2, client authentication requires hashing the handshake transcript
* under a different hash. Otherwise, release the handshake buffer. */
- if (!SSL_USE_SIGALGS(ssl) || !ssl->s3->tmp.cert_request) {
+ if (!ssl->s3->tmp.cert_request ||
+ ssl3_protocol_version(ssl) < TLS1_2_VERSION) {
ssl3_free_handshake_buffer(ssl);
}
@@ -1305,7 +1291,7 @@ int ssl3_send_server_key_exchange(SSL *ssl) {
/* Determine signature algorithm. */
const EVP_MD *md;
- if (SSL_USE_SIGALGS(ssl)) {
+ if (ssl3_protocol_version(ssl) >= TLS1_2_VERSION) {
md = tls1_choose_signing_digest(ssl);
if (!tls12_add_sigandhash(ssl, &cbb, md)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
@@ -1353,13 +1339,11 @@ int ssl3_send_server_key_exchange(SSL *ssl) {
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
@@ -1405,7 +1389,7 @@ int ssl3_send_certificate_request(SSL *ssl) {
p += n;
n++;
- if (SSL_USE_SIGALGS(ssl)) {
+ if (ssl3_protocol_version(ssl) >= TLS1_2_VERSION) {
const uint8_t *psigs;
nl = tls12_get_psigalgs(ssl, &psigs);
s2n(nl, p);
@@ -1576,10 +1560,8 @@ int ssl3_get_client_key_exchange(SSL *ssl) {
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;
@@ -1587,7 +1569,11 @@ int ssl3_get_client_key_exchange(SSL *ssl) {
goto err;
}
- assert(decrypt_len == rsa_size);
+ if (decrypt_len != rsa_size) {
+ al = SSL_AD_DECRYPT_ERROR;
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED);
+ goto f_err;
+ }
/* Prepare a random premaster, to be used on invalid padding. See RFC 5246,
* section 7.4.7.1. */
@@ -1706,7 +1692,7 @@ int ssl3_get_client_key_exchange(SSL *ssl) {
}
/* Compute the master secret */
- ssl->session->master_key_length = ssl->enc_method->generate_master_secret(
+ ssl->session->master_key_length = tls1_generate_master_secret(
ssl, ssl->session->master_key, premaster_secret, premaster_secret_len);
if (ssl->session->master_key_length == 0) {
goto err;
@@ -1772,7 +1758,7 @@ int ssl3_get_cert_verify(SSL *ssl) {
CBS_init(&certificate_verify, ssl->init_msg, n);
/* Determine the digest type if needbe. */
- if (SSL_USE_SIGALGS(ssl)) {
+ if (ssl3_protocol_version(ssl) >= TLS1_2_VERSION) {
uint8_t hash, signature_type;
if (!CBS_get_u8(&certificate_verify, &hash) ||
!CBS_get_u8(&certificate_verify, &signature_type)) {
@@ -1809,10 +1795,15 @@ int ssl3_get_cert_verify(SSL *ssl) {
if (pctx == NULL) {
goto err;
}
- if (!EVP_PKEY_verify_init(pctx) ||
- !EVP_PKEY_CTX_set_signature_md(pctx, md) ||
- !EVP_PKEY_verify(pctx, CBS_data(&signature), CBS_len(&signature), digest,
- digest_length)) {
+ int sig_ok = EVP_PKEY_verify_init(pctx) &&
+ EVP_PKEY_CTX_set_signature_md(pctx, md) &&
+ EVP_PKEY_verify(pctx, CBS_data(&signature), CBS_len(&signature),
+ digest, digest_length);
+#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
+ sig_ok = 1;
+ ERR_clear_error();
+#endif
+ if (!sig_ok) {
al = SSL_AD_DECRYPT_ERROR;
OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SIGNATURE);
goto f_err;
@@ -1833,7 +1824,7 @@ err:
}
int ssl3_get_client_certificate(SSL *ssl) {
- int i, ok, al, ret = -1;
+ int ok, al, ret = -1;
X509 *x = NULL;
unsigned long n;
STACK_OF(X509) *sk = NULL;
@@ -1841,6 +1832,7 @@ int ssl3_get_client_certificate(SSL *ssl) {
CBS certificate_msg, certificate_list;
int is_first_certificate = 1;
+ assert(ssl->s3->tmp.cert_request);
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);
@@ -1849,29 +1841,23 @@ int ssl3_get_client_certificate(SSL *ssl) {
return n;
}
- 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 (ssl->s3->tmp.message_type != SSL3_MT_CERTIFICATE) {
+ if (ssl->version == SSL3_VERSION &&
+ ssl->s3->tmp.message_type == SSL3_MT_CLIENT_KEY_EXCHANGE) {
+ /* In SSL 3.0, the Certificate message is omitted to signal no certificate. */
+ 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 (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;
+ ssl->s3->tmp.reuse_message = 1;
+ return 1;
}
- ssl->s3->tmp.reuse_message = 1;
-
- return 1;
- }
- if (ssl->s3->tmp.message_type != SSL3_MT_CERTIFICATE) {
al = SSL_AD_UNEXPECTED_MESSAGE;
- OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_MESSAGE_TYPE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
goto f_err;
}
@@ -1940,15 +1926,14 @@ int ssl3_get_client_certificate(SSL *ssl) {
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATES_RETURNED);
goto f_err;
} else if ((ssl->verify_mode & SSL_VERIFY_PEER) &&
- (ssl->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) {
+ (ssl->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) {
/* Fail for TLS only if we required a certificate */
OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
al = SSL_AD_HANDSHAKE_FAILURE;
goto f_err;
}
} else {
- i = ssl_verify_cert_chain(ssl, sk);
- if (i <= 0) {
+ if (ssl_verify_cert_chain(ssl, sk) <= 0) {
al = ssl_verify_alarm_type(ssl->verify_result);
OPENSSL_PUT_ERROR(SSL, SSL_R_CERTIFICATE_VERIFY_FAILED);
goto f_err;
@@ -2156,8 +2141,8 @@ int ssl3_get_next_proto(SSL *ssl) {
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, &ssl->next_proto_negotiated,
- &ssl->next_proto_negotiated_len)) {
+ !CBS_stow(&selected_protocol, &ssl->s3->next_proto_negotiated,
+ &ssl->s3->next_proto_negotiated_len)) {
return 0;
}
diff --git a/src/ssl/ssl_aead_ctx.c b/src/ssl/ssl_aead_ctx.c
index 8829679b..4de9d45e 100644
--- a/src/ssl/ssl_aead_ctx.c
+++ b/src/ssl/ssl_aead_ctx.c
@@ -56,7 +56,7 @@ SSL_AEAD_CTX *SSL_AEAD_CTX_new(enum evp_aead_direction_t direction,
enc_key_len += fixed_iv_len;
}
- SSL_AEAD_CTX *aead_ctx = (SSL_AEAD_CTX *)OPENSSL_malloc(sizeof(SSL_AEAD_CTX));
+ SSL_AEAD_CTX *aead_ctx = OPENSSL_malloc(sizeof(SSL_AEAD_CTX));
if (aead_ctx == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return NULL;
@@ -111,6 +111,10 @@ void SSL_AEAD_CTX_free(SSL_AEAD_CTX *aead) {
}
size_t SSL_AEAD_CTX_explicit_nonce_len(SSL_AEAD_CTX *aead) {
+#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
+ aead = NULL;
+#endif
+
if (aead != NULL && aead->variable_nonce_included_in_record) {
return aead->variable_nonce_len;
}
@@ -118,11 +122,15 @@ size_t SSL_AEAD_CTX_explicit_nonce_len(SSL_AEAD_CTX *aead) {
}
size_t SSL_AEAD_CTX_max_overhead(SSL_AEAD_CTX *aead) {
+#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
+ aead = NULL;
+#endif
+
if (aead == NULL) {
return 0;
}
return EVP_AEAD_max_overhead(aead->ctx.aead) +
- SSL_AEAD_CTX_explicit_nonce_len(aead);
+ SSL_AEAD_CTX_explicit_nonce_len(aead);
}
/* ssl_aead_ctx_get_ad writes the additional data for |aead| into |out| and
@@ -149,6 +157,10 @@ int SSL_AEAD_CTX_open(SSL_AEAD_CTX *aead, uint8_t *out, size_t *out_len,
size_t max_out, uint8_t type, uint16_t wire_version,
const uint8_t seqnum[8], const uint8_t *in,
size_t in_len) {
+#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
+ aead = NULL;
+#endif
+
if (aead == NULL) {
/* Handle the initial NULL cipher. */
if (in_len > max_out) {
@@ -222,6 +234,10 @@ int SSL_AEAD_CTX_seal(SSL_AEAD_CTX *aead, uint8_t *out, size_t *out_len,
size_t max_out, uint8_t type, uint16_t wire_version,
const uint8_t seqnum[8], const uint8_t *in,
size_t in_len) {
+#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
+ aead = NULL;
+#endif
+
if (aead == NULL) {
/* Handle the initial NULL cipher. */
if (in_len > max_out) {
diff --git a/src/ssl/ssl_buffer.c b/src/ssl/ssl_buffer.c
index 7fd74e48..272b13b0 100644
--- a/src/ssl/ssl_buffer.c
+++ b/src/ssl/ssl_buffer.c
@@ -113,12 +113,11 @@ static int dtls_read_buffer_next_packet(SSL *ssl) {
}
/* 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) {
+ ssl->rwstate = SSL_READING;
return ret;
}
- ssl->rwstate = SSL_NOTHING;
/* |BIO_read| was bound by |buf->cap|, so this cannot overflow. */
buf->len = (uint16_t)ret;
return 1;
@@ -136,13 +135,12 @@ static int tls_read_buffer_extend_to(SSL *ssl, size_t len) {
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) {
+ ssl->rwstate = SSL_READING;
return ret;
}
- ssl->rwstate = SSL_NOTHING;
/* |BIO_read| was bound by |buf->cap - buf->len|, so this cannot
* overflow. */
buf->len += (uint16_t)ret;
@@ -268,12 +266,11 @@ 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) {
+ ssl->rwstate = SSL_WRITING;
return ret;
}
- ssl->rwstate = SSL_NOTHING;
consume_buffer(buf, (size_t)ret);
}
ssl_write_buffer_clear(ssl);
@@ -286,16 +283,15 @@ static int dtls_write_buffer_flush(SSL *ssl) {
return 1;
}
- ssl->rwstate = SSL_WRITING;
int ret = BIO_write(ssl->wbio, buf->buf + buf->offset, buf->len);
if (ret <= 0) {
+ ssl->rwstate = SSL_WRITING;
/* 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;
}
diff --git a/src/ssl/ssl_cert.c b/src/ssl/ssl_cert.c
index 4952cfde..0eb0d8bf 100644
--- a/src/ssl/ssl_cert.c
+++ b/src/ssl/ssl_cert.c
@@ -139,7 +139,7 @@ int SSL_get_ex_data_X509_STORE_CTX_idx(void) {
}
CERT *ssl_cert_new(void) {
- CERT *ret = (CERT *)OPENSSL_malloc(sizeof(CERT));
+ CERT *ret = OPENSSL_malloc(sizeof(CERT));
if (ret == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return NULL;
@@ -150,7 +150,7 @@ CERT *ssl_cert_new(void) {
}
CERT *ssl_cert_dup(CERT *cert) {
- CERT *ret = (CERT *)OPENSSL_malloc(sizeof(CERT));
+ CERT *ret = OPENSSL_malloc(sizeof(CERT));
if (ret == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return NULL;
@@ -185,9 +185,16 @@ CERT *ssl_cert_dup(CERT *cert) {
}
}
+ ret->key_method = cert->key_method;
+
ret->cert_cb = cert->cert_cb;
ret->cert_cb_arg = cert->cert_cb_arg;
+ if (cert->verify_store != NULL) {
+ X509_STORE_up_ref(cert->verify_store);
+ ret->verify_store = cert->verify_store;
+ }
+
return ret;
err:
@@ -220,6 +227,7 @@ void ssl_cert_free(CERT *c) {
ssl_cert_clear_certs(c);
OPENSSL_free(c->peer_sigalgs);
OPENSSL_free(c->digest_nids);
+ X509_STORE_free(c->verify_store);
OPENSSL_free(c);
}
@@ -279,10 +287,15 @@ int ssl_verify_cert_chain(SSL *ssl, STACK_OF(X509) *cert_chain) {
return 0;
}
+ X509_STORE *verify_store = ssl->ctx->cert_store;
+ if (ssl->cert->verify_store != NULL) {
+ verify_store = ssl->cert->verify_store;
+ }
+
X509 *leaf = sk_X509_value(cert_chain, 0);
int ret = 0;
X509_STORE_CTX ctx;
- if (!X509_STORE_CTX_init(&ctx, ssl->ctx->cert_store, leaf, cert_chain)) {
+ if (!X509_STORE_CTX_init(&ctx, verify_store, leaf, cert_chain)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_X509_LIB);
return 0;
}
@@ -409,13 +422,18 @@ static int ssl_add_cert_to_buf(BUF_MEM *buf, unsigned long *l, X509 *x) {
uint8_t *p;
n = i2d_X509(x, NULL);
- if (!BUF_MEM_grow_clean(buf, (int)(n + (*l) + 3))) {
+ if (n < 0 || !BUF_MEM_grow_clean(buf, (int)(n + (*l) + 3))) {
OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
return 0;
}
p = (uint8_t *)&(buf->data[*l]);
l2n3(n, p);
- i2d_X509(x, &p);
+ n = i2d_X509(x, &p);
+ if (n < 0) {
+ /* This shouldn't happen. */
+ OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
+ return 0;
+ }
*l += n + 3;
return 1;
@@ -475,6 +493,33 @@ int ssl_add_cert_chain(SSL *ssl, unsigned long *l) {
return 1;
}
+static int set_cert_store(X509_STORE **store_ptr, X509_STORE *new_store, int take_ref) {
+ X509_STORE_free(*store_ptr);
+ *store_ptr = new_store;
+
+ if (new_store != NULL && take_ref) {
+ X509_STORE_up_ref(new_store);
+ }
+
+ return 1;
+}
+
+int SSL_CTX_set0_verify_cert_store(SSL_CTX *ctx, X509_STORE *store) {
+ return set_cert_store(&ctx->cert->verify_store, store, 0);
+}
+
+int SSL_CTX_set1_verify_cert_store(SSL_CTX *ctx, X509_STORE *store) {
+ return set_cert_store(&ctx->cert->verify_store, store, 1);
+}
+
+int SSL_set0_verify_cert_store(SSL *ssl, X509_STORE *store) {
+ return set_cert_store(&ssl->cert->verify_store, store, 0);
+}
+
+int SSL_set1_verify_cert_store(SSL *ssl, X509_STORE *store) {
+ return set_cert_store(&ssl->cert->verify_store, store, 1);
+}
+
int SSL_CTX_set0_chain(SSL_CTX *ctx, STACK_OF(X509) *chain) {
return ssl_cert_set0_chain(ctx->cert, chain);
}
diff --git a/src/ssl/ssl_cipher.c b/src/ssl/ssl_cipher.c
index 77fa8fa6..58ce582c 100644
--- a/src/ssl/ssl_cipher.c
+++ b/src/ssl/ssl_cipher.c
@@ -141,7 +141,6 @@
#include <openssl/ssl.h>
#include <assert.h>
-#include <stdio.h>
#include <string.h>
#include <openssl/buf.h>
@@ -1392,7 +1391,7 @@ ssl_create_cipher_list(const SSL_PROTOCOL_METHOD *ssl_method,
/* Now we have to collect the available ciphers from the compiled in ciphers.
* We cannot get more than the number compiled in, so it is used for
* allocation. */
- co_list = (CIPHER_ORDER *)OPENSSL_malloc(sizeof(CIPHER_ORDER) * kCiphersLen);
+ co_list = OPENSSL_malloc(sizeof(CIPHER_ORDER) * kCiphersLen);
if (co_list == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return NULL;
@@ -1417,10 +1416,10 @@ ssl_create_cipher_list(const SSL_PROTOCOL_METHOD *ssl_method,
* 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, 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_AES256GCM, ~0u, 0, CIPHER_ADD, -1, 0,
+ &head, &tail);
ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_CHACHA20POLY1305, ~0u, 0, CIPHER_ADD,
-1, 0, &head, &tail);
ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_CHACHA20POLY1305_OLD, ~0u, 0,
@@ -1430,24 +1429,24 @@ ssl_create_cipher_list(const SSL_PROTOCOL_METHOD *ssl_method,
-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);
+ ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256GCM, ~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, 0, CIPHER_ADD, -1, 0,
- &head, &tail);
+ /* Then the legacy non-AEAD ciphers: AES_128_CBC, AES_256_CBC,
+ * 3DES_EDE_CBC_SHA, RC4_128_SHA, RC4_128_MD5. */
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_AES256, ~0u, 0, CIPHER_ADD, -1, 0,
+ &head, &tail);
+ ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_3DES, ~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, 0, CIPHER_ADD, -1, 0, &head,
@@ -1577,6 +1576,10 @@ int SSL_CIPHER_has_SHA1_HMAC(const SSL_CIPHER *cipher) {
return (cipher->algorithm_mac & SSL_SHA1) != 0;
}
+int SSL_CIPHER_has_SHA256_HMAC(const SSL_CIPHER *cipher) {
+ return (cipher->algorithm_mac & SSL_SHA256) != 0;
+}
+
int SSL_CIPHER_is_AESGCM(const SSL_CIPHER *cipher) {
return (cipher->algorithm_enc & (SSL_AES128GCM | SSL_AES256GCM)) != 0;
}
@@ -1804,7 +1807,6 @@ const char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf,
int len) {
const char *kx, *au, *enc, *mac;
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;
@@ -1928,7 +1930,8 @@ const char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf,
return "Buffer too small";
}
- BIO_snprintf(buf, len, format, cipher->name, kx, au, enc, mac);
+ BIO_snprintf(buf, len, "%-23s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s\n",
+ cipher->name, kx, au, enc, mac);
return buf;
}
diff --git a/src/ssl/ssl_ecdh.c b/src/ssl/ssl_ecdh.c
index 45c5b26b..d48c93f7 100644
--- a/src/ssl/ssl_ecdh.c
+++ b/src/ssl/ssl_ecdh.c
@@ -23,7 +23,7 @@
#include <openssl/ec.h>
#include <openssl/err.h>
#include <openssl/mem.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
#include "internal.h"
@@ -65,21 +65,12 @@ static int ssl_ec_point_generate_keypair(SSL_ECDH_CTX *ctx, CBB *out) {
}
} while (BN_is_zero(private_key));
- /* Compute the corresponding public key. */
+ /* Compute the corresponding public key and serialize it. */
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) {
+ !EC_POINT_mul(group, public_key, private_key, NULL, NULL, bn_ctx) ||
+ !EC_POINT_point2cbb(out, group, public_key, POINT_CONVERSION_UNCOMPRESSED,
+ bn_ctx)) {
goto err;
}
@@ -93,9 +84,12 @@ err:
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) {
+static 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;
@@ -297,8 +291,8 @@ static const SSL_ECDH_METHOD kMethods[] = {
ssl_ec_point_compute_secret,
},
{
- NID_x25519,
- SSL_CURVE_ECDH_X25519,
+ NID_X25519,
+ SSL_CURVE_X25519,
"X25519",
ssl_x25519_cleanup,
ssl_x25519_generate_keypair,
diff --git a/src/ssl/ssl_file.c b/src/ssl/ssl_file.c
index 42cf800c..748d50ca 100644
--- a/src/ssl/ssl_file.c
+++ b/src/ssl/ssl_file.c
@@ -121,7 +121,6 @@
#include <openssl/stack.h>
#include <openssl/x509.h>
-#include "../crypto/directory.h"
#include "internal.h"
@@ -247,53 +246,6 @@ int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
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;
diff --git a/src/ssl/ssl_lib.c b/src/ssl/ssl_lib.c
index 08578a61..d62cdae0 100644
--- a/src/ssl/ssl_lib.c
+++ b/src/ssl/ssl_lib.c
@@ -141,7 +141,6 @@
#include <openssl/ssl.h>
#include <assert.h>
-#include <stdio.h>
#include <string.h>
#include <openssl/bytestring.h>
@@ -150,7 +149,6 @@
#include <openssl/err.h>
#include <openssl/lhash.h>
#include <openssl/mem.h>
-#include <openssl/obj.h>
#include <openssl/rand.h>
#include <openssl/x509v3.h>
@@ -181,12 +179,21 @@ int SSL_library_init(void) {
return 1;
}
-static uint32_t ssl_session_hash(const SSL_SESSION *a) {
+static uint32_t ssl_session_hash(const SSL_SESSION *sess) {
+ const uint8_t *session_id = sess->session_id;
+
+ uint8_t tmp_storage[sizeof(uint32_t)];
+ if (sess->session_id_length < sizeof(tmp_storage)) {
+ memset(tmp_storage, 0, sizeof(tmp_storage));
+ memcpy(tmp_storage, sess->session_id, sess->session_id_length);
+ session_id = tmp_storage;
+ }
+
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);
+ ((uint32_t)session_id[0]) |
+ ((uint32_t)session_id[1] << 8) |
+ ((uint32_t)session_id[2] << 16) |
+ ((uint32_t)session_id[3] << 24);
return hash;
}
@@ -221,7 +228,7 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *method) {
goto err;
}
- ret = (SSL_CTX *)OPENSSL_malloc(sizeof(SSL_CTX));
+ ret = OPENSSL_malloc(sizeof(SSL_CTX));
if (ret == NULL) {
goto err;
}
@@ -353,7 +360,7 @@ SSL *SSL_new(SSL_CTX *ctx) {
return NULL;
}
- SSL *ssl = (SSL *)OPENSSL_malloc(sizeof(SSL));
+ SSL *ssl = OPENSSL_malloc(sizeof(SSL));
if (ssl == NULL) {
goto err;
}
@@ -417,8 +424,6 @@ SSL *SSL_new(SSL_CTX *ctx) {
if (!ssl->method->ssl_new(ssl)) {
goto err;
}
- ssl->enc_method = ssl3_get_enc_method(ssl->version);
- assert(ssl->enc_method != NULL);
ssl->rwstate = SSL_NOTHING;
@@ -486,8 +491,6 @@ void SSL_free(SSL *ssl) {
ssl_clear_bad_session(ssl);
SSL_SESSION_free(ssl->session);
- ssl_clear_cipher_ctx(ssl);
-
ssl_cert_free(ssl->cert);
OPENSSL_free(ssl->tlsext_hostname);
@@ -497,7 +500,6 @@ void SSL_free(SSL *ssl) {
EVP_PKEY_free(ssl->tlsext_channel_id_private);
OPENSSL_free(ssl->psk_identity_hint);
sk_X509_NAME_pop_free(ssl->client_CA, X509_NAME_free);
- OPENSSL_free(ssl->next_proto_negotiated);
sk_SRTP_PROTECTION_PROFILE_free(ssl->srtp_profiles);
if (ssl->method != NULL) {
@@ -513,8 +515,6 @@ void SSL_set_connect_state(SSL *ssl) {
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) {
@@ -522,8 +522,6 @@ void SSL_set_accept_state(SSL *ssl) {
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) {
@@ -550,6 +548,10 @@ BIO *SSL_get_rbio(const SSL *ssl) { return ssl->rbio; }
BIO *SSL_get_wbio(const SSL *ssl) { return ssl->wbio; }
int SSL_do_handshake(SSL *ssl) {
+ ssl->rwstate = SSL_NOTHING;
+ /* Functions which use SSL_get_error must clear the error queue on entry. */
+ ERR_clear_error();
+
if (ssl->handshake_func == NULL) {
OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_TYPE_NOT_SET);
return -1;
@@ -563,91 +565,117 @@ int SSL_do_handshake(SSL *ssl) {
}
int SSL_connect(SSL *ssl) {
- if (ssl->handshake_func == 0) {
+ if (ssl->handshake_func == NULL) {
/* Not properly initialized yet */
SSL_set_connect_state(ssl);
}
- if (ssl->handshake_func != ssl->method->ssl_connect) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- return -1;
- }
+ assert(ssl->handshake_func == ssl->method->ssl_connect);
- return ssl->handshake_func(ssl);
+ return SSL_do_handshake(ssl);
}
int SSL_accept(SSL *ssl) {
- if (ssl->handshake_func == 0) {
+ if (ssl->handshake_func == NULL) {
/* Not properly initialized yet */
SSL_set_accept_state(ssl);
}
- if (ssl->handshake_func != ssl->method->ssl_accept) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- return -1;
- }
+ assert(ssl->handshake_func == ssl->method->ssl_accept);
- return ssl->handshake_func(ssl);
+ return SSL_do_handshake(ssl);
}
-int SSL_read(SSL *ssl, void *buf, int num) {
- if (ssl->handshake_func == 0) {
+static int ssl_read_impl(SSL *ssl, void *buf, int num, int peek) {
+ ssl->rwstate = SSL_NOTHING;
+ /* Functions which use SSL_get_error must clear the error queue on entry. */
+ ERR_clear_error();
+ ERR_clear_system_error();
+
+ if (ssl->handshake_func == NULL) {
OPENSSL_PUT_ERROR(SSL, SSL_R_UNINITIALIZED);
return -1;
}
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_peek(SSL *ssl, void *buf, int num) {
- if (ssl->handshake_func == 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_UNINITIALIZED);
- return -1;
+ /* This may require multiple iterations. False Start will cause
+ * |ssl->handshake_func| to signal success one step early, but the handshake
+ * must be completely finished before other modes are accepted. */
+ while (SSL_in_init(ssl)) {
+ int ret = SSL_do_handshake(ssl);
+ if (ret < 0) {
+ return ret;
+ }
+ if (ret == 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_HANDSHAKE_FAILURE);
+ return -1;
+ }
}
- if (ssl->shutdown & SSL_RECEIVED_SHUTDOWN) {
- return 0;
- }
+ return ssl->method->ssl_read_app_data(ssl, buf, num, peek);
+}
- ERR_clear_system_error();
- return ssl->method->ssl_read_app_data(ssl, buf, num, 1);
+int SSL_read(SSL *ssl, void *buf, int num) {
+ return ssl_read_impl(ssl, buf, num, 0 /* consume bytes */);
+}
+
+int SSL_peek(SSL *ssl, void *buf, int num) {
+ return ssl_read_impl(ssl, buf, num, 1 /* peek */);
}
int SSL_write(SSL *ssl, const void *buf, int num) {
- if (ssl->handshake_func == 0) {
+ ssl->rwstate = SSL_NOTHING;
+ /* Functions which use SSL_get_error must clear the error queue on entry. */
+ ERR_clear_error();
+ ERR_clear_system_error();
+
+ if (ssl->handshake_func == NULL) {
OPENSSL_PUT_ERROR(SSL, SSL_R_UNINITIALIZED);
return -1;
}
if (ssl->shutdown & SSL_SENT_SHUTDOWN) {
- ssl->rwstate = SSL_NOTHING;
OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN);
return -1;
}
- ERR_clear_system_error();
+ /* If necessary, complete the handshake implicitly. */
+ if (SSL_in_init(ssl) && !SSL_in_false_start(ssl)) {
+ int ret = SSL_do_handshake(ssl);
+ if (ret < 0) {
+ return ret;
+ }
+ if (ret == 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_HANDSHAKE_FAILURE);
+ return -1;
+ }
+ }
+
return ssl->method->ssl_write_app_data(ssl, buf, num);
}
int SSL_shutdown(SSL *ssl) {
+ ssl->rwstate = SSL_NOTHING;
+ /* Functions which use SSL_get_error must clear the error queue on entry. */
+ ERR_clear_error();
+
/* 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 (ssl->handshake_func == 0) {
+ if (ssl->handshake_func == NULL) {
OPENSSL_PUT_ERROR(SSL, SSL_R_UNINITIALIZED);
return -1;
}
+ /* We can't shutdown properly if we are in the middle of a handshake. */
if (SSL_in_init(ssl)) {
- return 1;
+ OPENSSL_PUT_ERROR(SSL, SSL_R_SHUTDOWN_WHILE_IN_INIT);
+ return -1;
}
/* Do nothing if configured not to send a close_notify. */
@@ -710,8 +738,7 @@ int SSL_get_error(const SSL *ssl, int ret_code) {
}
if (ret_code == 0) {
- if ((ssl->shutdown & SSL_RECEIVED_SHUTDOWN) &&
- (ssl->s3->warn_alert == SSL_AD_CLOSE_NOTIFY)) {
+ if ((ssl->shutdown & SSL_RECEIVED_SHUTDOWN) && ssl->s3->clean_shutdown) {
/* The socket was cleanly shut down with a close_notify. */
return SSL_ERROR_ZERO_RETURN;
}
@@ -997,7 +1024,7 @@ int SSL_get_wfd(const SSL *ssl) {
}
int SSL_set_fd(SSL *ssl, int fd) {
- BIO *bio = BIO_new(BIO_s_fd());
+ BIO *bio = BIO_new(BIO_s_socket());
if (bio == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
return 0;
@@ -1009,9 +1036,9 @@ int SSL_set_fd(SSL *ssl, int fd) {
int SSL_set_wfd(SSL *ssl, int fd) {
if (ssl->rbio == NULL ||
- BIO_method_type(ssl->rbio) != BIO_TYPE_FD ||
+ BIO_method_type(ssl->rbio) != BIO_TYPE_SOCKET ||
BIO_get_fd(ssl->rbio, NULL) != fd) {
- BIO *bio = BIO_new(BIO_s_fd());
+ BIO *bio = BIO_new(BIO_s_socket());
if (bio == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
return 0;
@@ -1026,9 +1053,9 @@ int SSL_set_wfd(SSL *ssl, int fd) {
}
int SSL_set_rfd(SSL *ssl, int fd) {
- if (ssl->wbio == NULL || BIO_method_type(ssl->wbio) != BIO_TYPE_FD ||
+ if (ssl->wbio == NULL || BIO_method_type(ssl->wbio) != BIO_TYPE_SOCKET ||
BIO_get_fd(ssl->wbio, NULL) != fd) {
- BIO *bio = BIO_new(BIO_s_fd());
+ BIO *bio = BIO_new(BIO_s_socket());
if (bio == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
return 0;
@@ -1187,7 +1214,7 @@ void SSL_set_max_cert_list(SSL *ssl, size_t max_cert_list) {
ssl->max_cert_list = (uint32_t)max_cert_list;
}
-void SSL_CTX_set_max_send_fragment(SSL_CTX *ctx, size_t max_send_fragment) {
+int SSL_CTX_set_max_send_fragment(SSL_CTX *ctx, size_t max_send_fragment) {
if (max_send_fragment < 512) {
max_send_fragment = 512;
}
@@ -1195,9 +1222,11 @@ void SSL_CTX_set_max_send_fragment(SSL_CTX *ctx, size_t max_send_fragment) {
max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH;
}
ctx->max_send_fragment = (uint16_t)max_send_fragment;
+
+ return 1;
}
-void SSL_set_max_send_fragment(SSL *ssl, size_t max_send_fragment) {
+int SSL_set_max_send_fragment(SSL *ssl, size_t max_send_fragment) {
if (max_send_fragment < 512) {
max_send_fragment = 512;
}
@@ -1205,6 +1234,8 @@ void SSL_set_max_send_fragment(SSL *ssl, size_t max_send_fragment) {
max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH;
}
ssl->max_send_fragment = (uint16_t)max_send_fragment;
+
+ return 1;
}
int SSL_set_mtu(SSL *ssl, unsigned mtu) {
@@ -1254,17 +1285,15 @@ STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *ssl) {
return ssl->cipher_list->ciphers;
}
- if (ssl->version >= TLS1_1_VERSION && ssl->ctx != NULL &&
- ssl->ctx->cipher_list_tls11 != NULL) {
+ if (ssl->version >= TLS1_1_VERSION && ssl->ctx->cipher_list_tls11 != NULL) {
return ssl->ctx->cipher_list_tls11->ciphers;
}
- if (ssl->version >= TLS1_VERSION && ssl->ctx != NULL &&
- ssl->ctx->cipher_list_tls10 != NULL) {
+ if (ssl->version >= TLS1_VERSION && ssl->ctx->cipher_list_tls10 != NULL) {
return ssl->ctx->cipher_list_tls10->ciphers;
}
- if (ssl->ctx != NULL && ssl->ctx->cipher_list != NULL) {
+ if (ssl->ctx->cipher_list != NULL) {
return ssl->ctx->cipher_list->ciphers;
}
@@ -1282,7 +1311,7 @@ STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *ssl) {
return ssl->cipher_list_by_id;
}
- if (ssl->ctx != NULL && ssl->ctx->cipher_list_by_id != NULL) {
+ if (ssl->ctx->cipher_list_by_id != NULL) {
return ssl->ctx->cipher_list_by_id;
}
@@ -1574,11 +1603,11 @@ found:
void SSL_get0_next_proto_negotiated(const SSL *ssl, const uint8_t **out_data,
unsigned *out_len) {
- *out_data = ssl->next_proto_negotiated;
+ *out_data = ssl->s3->next_proto_negotiated;
if (*out_data == NULL) {
*out_len = 0;
} else {
- *out_len = ssl->next_proto_negotiated_len;
+ *out_len = ssl->s3->next_proto_negotiated_len;
}
}
@@ -1643,18 +1672,6 @@ void SSL_get0_alpn_selected(const SSL *ssl, const uint8_t **out_data,
}
}
-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 (ssl->version < TLS1_VERSION) {
- return 0;
- }
-
- 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 *store_ctx,
void *arg),
@@ -1822,13 +1839,6 @@ const char *SSL_SESSION_get_version(const SSL_SESSION *session) {
return ssl_get_version(session->ssl_version);
}
-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 *ssl) {
if (ssl->cert != NULL) {
return ssl->cert->x509;
@@ -1862,16 +1872,18 @@ EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx) {
}
const SSL_CIPHER *SSL_get_current_cipher(const SSL *ssl) {
- if (ssl->aead_write_ctx == NULL) {
+ if (ssl->s3->aead_write_ctx == NULL) {
return NULL;
}
- return ssl->aead_write_ctx->cipher;
+ return ssl->s3->aead_write_ctx->cipher;
}
const COMP_METHOD *SSL_get_current_compression(SSL *ssl) { return NULL; }
const COMP_METHOD *SSL_get_current_expansion(SSL *ssl) { return NULL; }
+int *SSL_get_server_tmp_key(SSL *ssl, EVP_PKEY **out_key) { return 0; }
+
int ssl_init_wbio_buffer(SSL *ssl, int push) {
BIO *bbio;
@@ -1995,6 +2007,14 @@ int SSL_state(const SSL *ssl) { return ssl->state; }
void SSL_set_state(SSL *ssl, int state) { }
+char *SSL_get_shared_ciphers(const SSL *ssl, char *buf, int len) {
+ if (len <= 0) {
+ return NULL;
+ }
+ buf[0] = '\0';
+ return buf;
+}
+
void SSL_set_verify_result(SSL *ssl, long result) {
ssl->verify_result = result;
}
@@ -2305,15 +2325,11 @@ const SSL3_ENC_METHOD *ssl3_get_enc_method(uint16_t version) {
return &SSLv3_enc_data;
case TLS1_VERSION:
- return &TLSv1_enc_data;
-
- case DTLS1_VERSION:
case TLS1_1_VERSION:
- return &TLSv1_1_enc_data;
-
- case DTLS1_2_VERSION:
case TLS1_2_VERSION:
- return &TLSv1_2_enc_data;
+ case DTLS1_VERSION:
+ case DTLS1_2_VERSION:
+ return &TLSv1_enc_data;
default:
return NULL;
@@ -2495,7 +2511,7 @@ int ssl3_is_version_enabled(SSL *ssl, uint16_t version) {
}
}
-uint16_t ssl3_version_from_wire(SSL *ssl, uint16_t wire_version) {
+uint16_t ssl3_version_from_wire(const SSL *ssl, uint16_t wire_version) {
if (!SSL_IS_DTLS(ssl)) {
return wire_version;
}
@@ -2516,6 +2532,11 @@ uint16_t ssl3_version_from_wire(SSL *ssl, uint16_t wire_version) {
return version;
}
+uint16_t ssl3_protocol_version(const SSL *ssl) {
+ assert(ssl->s3->have_version);
+ return ssl3_version_from_wire(ssl, ssl->version);
+}
+
int SSL_cache_hit(SSL *ssl) { return SSL_session_reused(ssl); }
int SSL_is_server(SSL *ssl) { return ssl->server; }
@@ -2541,23 +2562,24 @@ void SSL_set_reject_peer_renegotiations(SSL *ssl, int reject) {
int SSL_get_rc4_state(const SSL *ssl, const RC4_KEY **read_key,
const RC4_KEY **write_key) {
- if (ssl->aead_read_ctx == NULL || ssl->aead_write_ctx == NULL) {
+ if (ssl->s3->aead_read_ctx == NULL || ssl->s3->aead_write_ctx == NULL) {
return 0;
}
- return EVP_AEAD_CTX_get_rc4_state(&ssl->aead_read_ctx->ctx, read_key) &&
- EVP_AEAD_CTX_get_rc4_state(&ssl->aead_write_ctx->ctx, write_key);
+ return EVP_AEAD_CTX_get_rc4_state(&ssl->s3->aead_read_ctx->ctx, read_key) &&
+ EVP_AEAD_CTX_get_rc4_state(&ssl->s3->aead_write_ctx->ctx, write_key);
}
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) {
+ if (ssl->s3->aead_read_ctx == NULL || ssl->s3->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,
+ if (!EVP_AEAD_CTX_get_iv(&ssl->s3->aead_read_ctx->ctx, out_read_iv,
+ out_iv_len) ||
+ !EVP_AEAD_CTX_get_iv(&ssl->s3->aead_write_ctx->ctx, out_write_iv,
&write_iv_len) ||
*out_iv_len != write_iv_len) {
return 0;
@@ -2566,10 +2588,69 @@ int SSL_get_ivs(const SSL *ssl, const uint8_t **out_read_iv,
return 1;
}
+static uint64_t be_to_u64(const uint8_t in[8]) {
+ return (((uint64_t)in[0]) << 56) | (((uint64_t)in[1]) << 48) |
+ (((uint64_t)in[2]) << 40) | (((uint64_t)in[3]) << 32) |
+ (((uint64_t)in[4]) << 24) | (((uint64_t)in[5]) << 16) |
+ (((uint64_t)in[6]) << 8) | ((uint64_t)in[7]);
+}
+
+uint64_t SSL_get_read_sequence(const SSL *ssl) {
+ /* TODO(davidben): Internally represent sequence numbers as uint64_t. */
+ if (SSL_IS_DTLS(ssl)) {
+ /* max_seq_num already includes the epoch. */
+ assert(ssl->d1->r_epoch == (ssl->d1->bitmap.max_seq_num >> 48));
+ return ssl->d1->bitmap.max_seq_num;
+ }
+ return be_to_u64(ssl->s3->read_sequence);
+}
+
+uint64_t SSL_get_write_sequence(const SSL *ssl) {
+ uint64_t ret = be_to_u64(ssl->s3->write_sequence);
+ if (SSL_IS_DTLS(ssl)) {
+ assert((ret >> 48) == 0);
+ ret |= ((uint64_t)ssl->d1->w_epoch) << 48;
+ }
+ return ret;
+}
+
uint8_t SSL_get_server_key_exchange_hash(const SSL *ssl) {
return ssl->s3->tmp.server_key_exchange_hash;
}
+size_t SSL_get_client_random(const SSL *ssl, uint8_t *out, size_t max_out) {
+ if (max_out == 0) {
+ return sizeof(ssl->s3->client_random);
+ }
+ if (max_out > sizeof(ssl->s3->client_random)) {
+ max_out = sizeof(ssl->s3->client_random);
+ }
+ memcpy(out, ssl->s3->client_random, max_out);
+ return max_out;
+}
+
+size_t SSL_get_server_random(const SSL *ssl, uint8_t *out, size_t max_out) {
+ if (max_out == 0) {
+ return sizeof(ssl->s3->server_random);
+ }
+ if (max_out > sizeof(ssl->s3->server_random)) {
+ max_out = sizeof(ssl->s3->server_random);
+ }
+ memcpy(out, ssl->s3->server_random, max_out);
+ return max_out;
+}
+
+const SSL_CIPHER *SSL_get_pending_cipher(const SSL *ssl) {
+ if (!SSL_in_init(ssl)) {
+ return NULL;
+ }
+ return ssl->s3->tmp.new_cipher;
+}
+
+void SSL_CTX_set_retain_only_sha256_of_client_certs(SSL_CTX *ctx, int enabled) {
+ ctx->retain_only_sha256_of_client_certs = !!enabled;
+}
+
int SSL_clear(SSL *ssl) {
if (ssl->method == NULL) {
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_METHOD_SPECIFIED);
@@ -2608,12 +2689,6 @@ int SSL_clear(SSL *ssl) {
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).
*
@@ -2627,8 +2702,6 @@ int SSL_clear(SSL *ssl) {
if (!ssl->method->ssl_new(ssl)) {
return 0;
}
- 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;
diff --git a/src/ssl/ssl_rsa.c b/src/ssl/ssl_rsa.c
index 990979b1..c17d2da4 100644
--- a/src/ssl/ssl_rsa.c
+++ b/src/ssl/ssl_rsa.c
@@ -326,6 +326,11 @@ void SSL_set_private_key_method(SSL *ssl,
ssl->cert->key_method = key_method;
}
+void SSL_CTX_set_private_key_method(SSL_CTX *ctx,
+ const SSL_PRIVATE_KEY_METHOD *key_method) {
+ ctx->cert->key_method = key_method;
+}
+
int SSL_set_private_key_digest_prefs(SSL *ssl, const int *digest_nids,
size_t num_digests) {
OPENSSL_free(ssl->cert->digest_nids);
diff --git a/src/ssl/ssl_session.c b/src/ssl/ssl_session.c
index 3d59bc32..12d065e7 100644
--- a/src/ssl/ssl_session.c
+++ b/src/ssl/ssl_session.c
@@ -136,7 +136,6 @@
#include <openssl/ssl.h>
#include <assert.h>
-#include <stdio.h>
#include <string.h>
#include <openssl/err.h>
@@ -161,7 +160,7 @@ 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));
+ SSL_SESSION *session = OPENSSL_malloc(sizeof(SSL_SESSION));
if (session == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return 0;
@@ -232,6 +231,19 @@ X509 *SSL_SESSION_get0_peer(const SSL_SESSION *session) {
return session->peer;
}
+size_t SSL_SESSION_get_master_key(const SSL_SESSION *session, uint8_t *out,
+ size_t max_out) {
+ /* TODO(davidben): Fix master_key_length's type and remove these casts. */
+ if (max_out == 0) {
+ return (size_t)session->master_key_length;
+ }
+ if (max_out > (size_t)session->master_key_length) {
+ max_out = (size_t)session->master_key_length;
+ }
+ memcpy(out, session->master_key, max_out);
+ return max_out;
+}
+
long SSL_SESSION_set_time(SSL_SESSION *session, long time) {
if (session == NULL) {
return 0;
@@ -430,7 +442,7 @@ enum ssl_session_result_t ssl_get_prev_session(
/* This is used only by servers. */
assert(ssl->server);
SSL_SESSION *session = NULL;
- int send_ticket = 0;
+ int renew_ticket = 0;
/* If tickets are disabled, always behave as if no tickets are present. */
const uint8_t *ticket = NULL;
@@ -440,24 +452,27 @@ enum ssl_session_result_t ssl_get_prev_session(
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,
+ int from_cache = 0;
+ if (tickets_supported && ticket_len > 0) {
+ if (!tls_process_ticket(ssl, &session, &renew_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. */
+ /* The client didn't send a ticket, so the session ID is a real ID. */
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;
}
+ from_cache = 1;
}
if (session == NULL ||
session->sid_ctx_length != ssl->sid_ctx_length ||
memcmp(session->sid_ctx, ssl->sid_ctx, ssl->sid_ctx_length) != 0) {
+ /* The client did not offer a suitable ticket or session ID. If supported,
+ * the new session should use a ticket. */
goto no_session;
}
@@ -471,11 +486,12 @@ enum ssl_session_result_t ssl_get_prev_session(
* effectively disable the session cache by accident without anyone
* noticing). */
OPENSSL_PUT_ERROR(SSL, SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED);
- goto fatal_error;
+ SSL_SESSION_free(session);
+ return ssl_session_error;
}
if (session->timeout < (long)(time(NULL) - session->time)) {
- if (!tickets_supported) {
+ if (from_cache) {
/* The session was from the cache, so remove it. */
SSL_CTX_remove_session(ssl->initial_ctx, session);
}
@@ -483,13 +499,9 @@ enum ssl_session_result_t ssl_get_prev_session(
}
*out_session = session;
- *out_send_ticket = send_ticket;
+ *out_send_ticket = renew_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;
diff --git a/src/ssl/ssl_test.cc b/src/ssl/ssl_test.cc
index 9558f1c3..590a2c16 100644
--- a/src/ssl/ssl_test.cc
+++ b/src/ssl/ssl_test.cc
@@ -18,13 +18,16 @@
#include <algorithm>
#include <string>
+#include <utility>
#include <vector>
#include <openssl/base64.h>
#include <openssl/bio.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
+#include <openssl/pem.h>
#include <openssl/ssl.h>
+#include <openssl/x509.h>
#include "test/scoped_types.h"
#include "../crypto/test/test_util.h"
@@ -38,215 +41,178 @@ struct ExpectedCipher {
struct CipherTest {
// The rule string to apply.
const char *rule;
- // The list of expected ciphers, in order, terminated with -1.
- const ExpectedCipher *expected;
+ // The list of expected ciphers, in order.
+ std::vector<ExpectedCipher> expected;
};
-// Selecting individual ciphers should work.
-static const char kRule1[] =
- "ECDHE-ECDSA-CHACHA20-POLY1305:"
- "ECDHE-RSA-CHACHA20-POLY1305:"
- "ECDHE-ECDSA-AES128-GCM-SHA256:"
- "ECDHE-RSA-AES128-GCM-SHA256";
-
-static const ExpectedCipher kExpected1[] = {
- { TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0 },
- { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0 },
- { TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0 },
- { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0 },
- { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0 },
- { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0 },
- { 0, 0 },
-};
-
-// + reorders selected ciphers to the end, keeping their relative
-// order.
-static const char kRule2[] =
- "ECDHE-ECDSA-CHACHA20-POLY1305:"
- "ECDHE-RSA-CHACHA20-POLY1305:"
- "ECDHE-ECDSA-AES128-GCM-SHA256:"
- "ECDHE-RSA-AES128-GCM-SHA256:"
- "+aRSA";
-
-static const ExpectedCipher kExpected2[] = {
- { TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0 },
- { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0 },
- { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0 },
- { TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0 },
- { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0 },
- { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0 },
- { 0, 0 },
-};
-
-// ! banishes ciphers from future selections.
-static const char kRule3[] =
- "!aRSA:"
- "ECDHE-ECDSA-CHACHA20-POLY1305:"
- "ECDHE-RSA-CHACHA20-POLY1305:"
- "ECDHE-ECDSA-AES128-GCM-SHA256:"
- "ECDHE-RSA-AES128-GCM-SHA256";
-
-static const ExpectedCipher kExpected3[] = {
- { TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0 },
- { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0 },
- { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0 },
- { 0, 0 },
-};
-
-// Multiple masks can be ANDed in a single rule.
-static const char kRule4[] = "kRSA+AESGCM+AES128";
-
-static const ExpectedCipher kExpected4[] = {
- { TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0 },
- { 0, 0 },
-};
-
-// - removes selected ciphers, but preserves their order for future
-// selections. Select AES_128_GCM, but order the key exchanges RSA,
-// DHE_RSA, ECDHE_RSA.
-static const char kRule5[] =
- "ALL:-kECDHE:-kDHE:-kRSA:-ALL:"
- "AESGCM+AES128+aRSA";
-
-static const ExpectedCipher kExpected5[] = {
- { TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0 },
- { TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256, 0 },
- { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0 },
- { 0, 0 },
-};
-
-// Unknown selectors are no-ops.
-static const char kRule6[] =
- "ECDHE-ECDSA-CHACHA20-POLY1305:"
- "ECDHE-RSA-CHACHA20-POLY1305:"
- "ECDHE-ECDSA-AES128-GCM-SHA256:"
- "ECDHE-RSA-AES128-GCM-SHA256:"
- "BOGUS1:-BOGUS2:+BOGUS3:!BOGUS4";
-
-static const ExpectedCipher kExpected6[] = {
- { TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0 },
- { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0 },
- { TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0 },
- { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0 },
- { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0 },
- { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0 },
- { 0, 0 },
-};
-
-// Square brackets specify equi-preference groups.
-static const char kRule7[] =
- "[ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256]:"
- "[ECDHE-RSA-CHACHA20-POLY1305]:"
- "ECDHE-RSA-AES128-GCM-SHA256";
-
-static const ExpectedCipher kExpected7[] = {
- { TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1 },
- { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 1 },
- { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0 },
- { TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 1 },
- { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0 },
- { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0 },
- { 0, 0 },
-};
-
-// @STRENGTH performs a stable strength-sort of the selected
-// ciphers and only the selected ciphers.
-static const char kRule8[] =
- // To simplify things, banish all but {ECDHE_RSA,RSA} x
- // {CHACHA20,AES_256_CBC,AES_128_CBC,RC4} x SHA1.
- "!kEDH:!AESGCM:!3DES:!SHA256:!MD5:!SHA384:"
- // Order some ciphers backwards by strength.
- "ALL:-CHACHA20:-AES256:-AES128:-RC4:-ALL:"
- // Select ECDHE ones and sort them by strength. Ties should resolve
- // based on the order above.
- "kECDHE:@STRENGTH:-ALL:"
- // Now bring back everything uses RSA. ECDHE_RSA should be first,
- // sorted by strength. Then RSA, backwards by strength.
- "aRSA";
-
-static const ExpectedCipher kExpected8[] = {
- { TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0 },
- { TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0 },
- { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0 },
- { TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA, 0 },
- { TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0 },
- { SSL3_CK_RSA_RC4_128_SHA, 0 },
- { TLS1_CK_RSA_WITH_AES_128_SHA, 0 },
- { TLS1_CK_RSA_WITH_AES_256_SHA, 0 },
- { 0, 0 },
-};
-
-// 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 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 },
-};
-
-static CipherTest kCipherTests[] = {
- { kRule1, kExpected1 },
- { kRule2, kExpected2 },
- { kRule3, kExpected3 },
- { kRule4, kExpected4 },
- { kRule5, kExpected5 },
- { kRule6, kExpected6 },
- { kRule7, kExpected7 },
- { kRule8, kExpected8 },
- { kRule9, kExpected9 },
- { kRule10, kExpected10 },
- { kRule11, kExpected11 },
- { kRule12, kExpected12 },
- { kRule13, kExpected13 },
- { NULL, NULL },
+static const CipherTest kCipherTests[] = {
+ // Selecting individual ciphers should work.
+ {
+ "ECDHE-ECDSA-CHACHA20-POLY1305:"
+ "ECDHE-RSA-CHACHA20-POLY1305:"
+ "ECDHE-ECDSA-AES128-GCM-SHA256:"
+ "ECDHE-RSA-AES128-GCM-SHA256",
+ {
+ {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},
+ },
+ },
+ // + reorders selected ciphers to the end, keeping their relative order.
+ {
+ "ECDHE-ECDSA-CHACHA20-POLY1305:"
+ "ECDHE-RSA-CHACHA20-POLY1305:"
+ "ECDHE-ECDSA-AES128-GCM-SHA256:"
+ "ECDHE-RSA-AES128-GCM-SHA256:"
+ "+aRSA",
+ {
+ {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
+ {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
+ {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
+ {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
+ {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
+ {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
+ },
+ },
+ // ! banishes ciphers from future selections.
+ {
+ "!aRSA:"
+ "ECDHE-ECDSA-CHACHA20-POLY1305:"
+ "ECDHE-RSA-CHACHA20-POLY1305:"
+ "ECDHE-ECDSA-AES128-GCM-SHA256:"
+ "ECDHE-RSA-AES128-GCM-SHA256",
+ {
+ {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},
+ },
+ },
+ // Multiple masks can be ANDed in a single rule.
+ {
+ "kRSA+AESGCM+AES128",
+ {
+ {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
+ },
+ },
+ // - removes selected ciphers, but preserves their order for future
+ // selections. Select AES_128_GCM, but order the key exchanges RSA, DHE_RSA,
+ // ECDHE_RSA.
+ {
+ "ALL:-kECDHE:-kDHE:-kRSA:-ALL:"
+ "AESGCM+AES128+aRSA",
+ {
+ {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
+ {TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256, 0},
+ {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
+ },
+ },
+ // Unknown selectors are no-ops.
+ {
+ "ECDHE-ECDSA-CHACHA20-POLY1305:"
+ "ECDHE-RSA-CHACHA20-POLY1305:"
+ "ECDHE-ECDSA-AES128-GCM-SHA256:"
+ "ECDHE-RSA-AES128-GCM-SHA256:"
+ "BOGUS1:-BOGUS2:+BOGUS3:!BOGUS4",
+ {
+ {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},
+ },
+ },
+ // Square brackets specify equi-preference groups.
+ {
+ "[ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256]:"
+ "[ECDHE-RSA-CHACHA20-POLY1305]:"
+ "ECDHE-RSA-AES128-GCM-SHA256",
+ {
+ {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
+ {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 1},
+ {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
+ {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 1},
+ {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
+ {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
+ },
+ },
+ // @STRENGTH performs a stable strength-sort of the selected ciphers and
+ // only the selected ciphers.
+ {
+ // To simplify things, banish all but {ECDHE_RSA,RSA} x
+ // {CHACHA20,AES_256_CBC,AES_128_CBC,RC4} x SHA1.
+ "!kEDH:!AESGCM:!3DES:!SHA256:!MD5:!SHA384:"
+ // Order some ciphers backwards by strength.
+ "ALL:-CHACHA20:-AES256:-AES128:-RC4:-ALL:"
+ // Select ECDHE ones and sort them by strength. Ties should resolve
+ // based on the order above.
+ "kECDHE:@STRENGTH:-ALL:"
+ // Now bring back everything uses RSA. ECDHE_RSA should be first, sorted
+ // by strength. Then RSA, backwards by strength.
+ "aRSA",
+ {
+ {TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0},
+ {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
+ {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
+ {TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA, 0},
+ {TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0},
+ {SSL3_CK_RSA_RC4_128_SHA, 0},
+ {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
+ {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
+ },
+ },
+ // Exact ciphers may not be used in multi-part rules; they are treated
+ // as unknown aliases.
+ {
+ "ECDHE-ECDSA-AES128-GCM-SHA256:"
+ "ECDHE-RSA-AES128-GCM-SHA256:"
+ "!ECDHE-RSA-AES128-GCM-SHA256+RSA:"
+ "!ECDSA+ECDHE-ECDSA-AES128-GCM-SHA256",
+ {
+ {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
+ {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
+ },
+ },
+ // SSLv3 matches everything that existed before TLS 1.2.
+ {
+ "AES128-SHA:AES128-SHA256:!SSLv3",
+ {
+ {TLS1_CK_RSA_WITH_AES_128_SHA256, 0},
+ },
+ },
+ // TLSv1.2 matches everything added in TLS 1.2.
+ {
+ "AES128-SHA:AES128-SHA256:!TLSv1.2",
+ {
+ {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
+ },
+ },
+ // The two directives have no intersection.
+ {
+ "AES128-SHA:AES128-SHA256:!TLSv1.2+SSLv3",
+ {
+ {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
+ {TLS1_CK_RSA_WITH_AES_128_SHA256, 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.)
+ {
+ "ECDHE-ECDSA-CHACHA20-POLY1305:"
+ "ECDHE-RSA-CHACHA20-POLY1305:"
+ "!ECDHE-RSA-CHACHA20-POLY1305+RSA:"
+ "!ECDSA+ECDHE-ECDSA-CHACHA20-POLY1305",
+ {
+ {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},
+ },
+ },
};
static const char *kBadRules[] = {
@@ -270,7 +236,6 @@ static const char *kBadRules[] = {
"[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:!FOO",
"[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:-FOO",
"[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:@STRENGTH",
- NULL,
};
static const char *kMustNotIncludeNull[] = {
@@ -287,7 +252,6 @@ static const char *kMustNotIncludeNull[] = {
"SSLv3",
"TLSv1",
"TLSv1.2",
- NULL
};
static void PrintCipherPreferenceList(ssl_cipher_preference_list_st *list) {
@@ -310,36 +274,35 @@ static void PrintCipherPreferenceList(ssl_cipher_preference_list_st *list) {
}
}
-static bool TestCipherRule(CipherTest *t) {
+static bool TestCipherRule(const CipherTest &t) {
ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
if (!ctx) {
return false;
}
- if (!SSL_CTX_set_cipher_list(ctx.get(), t->rule)) {
- fprintf(stderr, "Error testing cipher rule '%s'\n", t->rule);
+ if (!SSL_CTX_set_cipher_list(ctx.get(), t.rule)) {
+ fprintf(stderr, "Error testing cipher rule '%s'\n", t.rule);
return false;
}
// Compare the two lists.
- size_t i;
- for (i = 0; i < sk_SSL_CIPHER_num(ctx->cipher_list->ciphers); i++) {
+ if (sk_SSL_CIPHER_num(ctx->cipher_list->ciphers) != t.expected.size()) {
+ fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t.rule);
+ PrintCipherPreferenceList(ctx->cipher_list);
+ return false;
+ }
+
+ for (size_t i = 0; i < t.expected.size(); i++) {
const SSL_CIPHER *cipher =
sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i);
- if (t->expected[i].id != SSL_CIPHER_get_id(cipher) ||
- t->expected[i].in_group_flag != ctx->cipher_list->in_group_flags[i]) {
- fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t->rule);
+ if (t.expected[i].id != SSL_CIPHER_get_id(cipher) ||
+ t.expected[i].in_group_flag != ctx->cipher_list->in_group_flags[i]) {
+ fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t.rule);
PrintCipherPreferenceList(ctx->cipher_list);
return false;
}
}
- if (t->expected[i].id != 0) {
- fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t->rule);
- PrintCipherPreferenceList(ctx->cipher_list);
- return false;
- }
-
return true;
}
@@ -362,26 +325,26 @@ static bool TestRuleDoesNotIncludeNull(const char *rule) {
}
static bool TestCipherRules() {
- for (size_t i = 0; kCipherTests[i].rule != NULL; i++) {
- if (!TestCipherRule(&kCipherTests[i])) {
+ for (const CipherTest &test : kCipherTests) {
+ if (!TestCipherRule(test)) {
return false;
}
}
- for (size_t i = 0; kBadRules[i] != NULL; i++) {
+ for (const char *rule : kBadRules) {
ScopedSSL_CTX ctx(SSL_CTX_new(SSLv23_server_method()));
if (!ctx) {
return false;
}
- if (SSL_CTX_set_cipher_list(ctx.get(), kBadRules[i])) {
- fprintf(stderr, "Cipher rule '%s' unexpectedly succeeded\n", kBadRules[i]);
+ if (SSL_CTX_set_cipher_list(ctx.get(), rule)) {
+ fprintf(stderr, "Cipher rule '%s' unexpectedly succeeded\n", rule);
return false;
}
ERR_clear_error();
}
- for (size_t i = 0; kMustNotIncludeNull[i] != NULL; i++) {
- if (!TestRuleDoesNotIncludeNull(kMustNotIncludeNull[i])) {
+ for (const char *rule : kMustNotIncludeNull) {
+ if (!TestRuleDoesNotIncludeNull(rule)) {
return false;
}
}
@@ -932,23 +895,6 @@ static ScopedSSL_SESSION CreateTestSession(uint32_t 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()));
@@ -957,38 +903,38 @@ static bool TestInternalSessionCache() {
}
// Prepare 10 test sessions.
- std::vector<SSL_SESSION*> sessions;
- ScopedSessionVector cleanup(&sessions);
+ std::vector<ScopedSSL_SESSION> sessions;
for (int i = 0; i < 10; i++) {
ScopedSSL_SESSION session = CreateTestSession(i);
if (!session) {
return false;
}
- sessions.push_back(session.release());
+ sessions.push_back(std::move(session));
}
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)) {
+ for (const auto &session : sessions) {
+ if (!SSL_CTX_add_session(ctx.get(), session.get())) {
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]);
+ std::vector<SSL_SESSION*> expected = {
+ sessions[9].get(),
+ sessions[8].get(),
+ sessions[7].get(),
+ sessions[6].get(),
+ sessions[5].get(),
+ };
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]) ||
+ if (SSL_CTX_add_session(ctx.get(), sessions[7].get()) ||
!ExpectCache(ctx.get(), expected)) {
return false;
}
@@ -999,32 +945,34 @@ static bool TestInternalSessionCache() {
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]);
+ expected = {
+ collision.get(),
+ sessions[9].get(),
+ sessions[8].get(),
+ sessions[6].get(),
+ sessions[5].get(),
+ };
if (!ExpectCache(ctx.get(), expected)) {
return false;
}
// Removing sessions behaves correctly.
- if (!SSL_CTX_remove_session(ctx.get(), sessions[6])) {
+ if (!SSL_CTX_remove_session(ctx.get(), sessions[6].get())) {
return false;
}
- expected.clear();
- expected.push_back(collision.get());
- expected.push_back(sessions[9]);
- expected.push_back(sessions[8]);
- expected.push_back(sessions[5]);
+ expected = {
+ collision.get(),
+ sessions[9].get(),
+ sessions[8].get(),
+ sessions[5].get(),
+ };
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]) ||
+ if (SSL_CTX_remove_session(ctx.get(), sessions[0].get()) ||
+ SSL_CTX_remove_session(ctx.get(), sessions[7].get()) ||
!ExpectCache(ctx.get(), expected)) {
return false;
}
@@ -1032,6 +980,157 @@ static bool TestInternalSessionCache() {
return true;
}
+static uint16_t EpochFromSequence(uint64_t seq) {
+ return static_cast<uint16_t>(seq >> 48);
+}
+
+static ScopedX509 GetTestCertificate() {
+ static const char kCertPEM[] =
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
+ "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n"
+ "aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF\n"
+ "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n"
+ "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
+ "gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci\n"
+ "HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV\n"
+ "W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV\n"
+ "HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f\n"
+ "Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht\n"
+ "ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr\n"
+ "T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
+ "j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
+ "-----END CERTIFICATE-----\n";
+ ScopedBIO bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
+ return ScopedX509(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
+}
+
+static ScopedEVP_PKEY GetTestKey() {
+ static const char kKeyPEM[] =
+ "-----BEGIN RSA PRIVATE KEY-----\n"
+ "MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
+ "kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
+ "KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
+ "AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
+ "i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
+ "WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
+ "m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
+ "QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
+ "aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
+ "LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
+ "104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
+ "tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
+ "moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
+ "-----END RSA PRIVATE KEY-----\n";
+ ScopedBIO bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
+ return ScopedEVP_PKEY(
+ PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
+}
+
+static bool TestSequenceNumber(bool dtls) {
+ ScopedSSL_CTX client_ctx(SSL_CTX_new(dtls ? DTLS_method() : TLS_method()));
+ ScopedSSL_CTX server_ctx(SSL_CTX_new(dtls ? DTLS_method() : TLS_method()));
+ if (!client_ctx || !server_ctx) {
+ return false;
+ }
+
+ ScopedX509 cert = GetTestCertificate();
+ ScopedEVP_PKEY key = GetTestKey();
+ if (!cert || !key ||
+ !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
+ !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
+ return false;
+ }
+
+ // Create a client and server connected to each other.
+ ScopedSSL client(SSL_new(client_ctx.get())), server(SSL_new(server_ctx.get()));
+ if (!client || !server) {
+ return false;
+ }
+ SSL_set_connect_state(client.get());
+ SSL_set_accept_state(server.get());
+
+ BIO *bio1, *bio2;
+ if (!BIO_new_bio_pair(&bio1, 0, &bio2, 0)) {
+ return false;
+ }
+ // SSL_set_bio takes ownership.
+ SSL_set_bio(client.get(), bio1, bio1);
+ SSL_set_bio(server.get(), bio2, bio2);
+
+ // Drive both their handshakes to completion.
+ for (;;) {
+ int client_ret = SSL_do_handshake(client.get());
+ int client_err = SSL_get_error(client.get(), client_ret);
+ if (client_err != SSL_ERROR_NONE &&
+ client_err != SSL_ERROR_WANT_READ &&
+ client_err != SSL_ERROR_WANT_WRITE) {
+ fprintf(stderr, "Client error: %d\n", client_err);
+ return false;
+ }
+
+ int server_ret = SSL_do_handshake(server.get());
+ int server_err = SSL_get_error(server.get(), server_ret);
+ if (server_err != SSL_ERROR_NONE &&
+ server_err != SSL_ERROR_WANT_READ &&
+ server_err != SSL_ERROR_WANT_WRITE) {
+ fprintf(stderr, "Server error: %d\n", server_err);
+ return false;
+ }
+
+ if (client_ret == 1 && server_ret == 1) {
+ break;
+ }
+ }
+
+ uint64_t client_read_seq = SSL_get_read_sequence(client.get());
+ uint64_t client_write_seq = SSL_get_write_sequence(client.get());
+ uint64_t server_read_seq = SSL_get_read_sequence(server.get());
+ uint64_t server_write_seq = SSL_get_write_sequence(server.get());
+
+ if (dtls) {
+ // Both client and server must be at epoch 1.
+ if (EpochFromSequence(client_read_seq) != 1 ||
+ EpochFromSequence(client_write_seq) != 1 ||
+ EpochFromSequence(server_read_seq) != 1 ||
+ EpochFromSequence(server_write_seq) != 1) {
+ fprintf(stderr, "Bad epochs.\n");
+ return false;
+ }
+
+ // The next record to be written should exceed the largest received.
+ if (client_write_seq <= server_read_seq ||
+ server_write_seq <= client_read_seq) {
+ fprintf(stderr, "Inconsistent sequence numbers.\n");
+ return false;
+ }
+ } else {
+ // The next record to be written should equal the next to be received.
+ if (client_write_seq != server_read_seq ||
+ server_write_seq != client_write_seq) {
+ fprintf(stderr, "Inconsistent sequence numbers.\n");
+ return false;
+ }
+ }
+
+ // Send a record from client to server.
+ uint8_t byte = 0;
+ if (SSL_write(client.get(), &byte, 1) != 1 ||
+ SSL_read(server.get(), &byte, 1) != 1) {
+ fprintf(stderr, "Could not send byte.\n");
+ return false;
+ }
+
+ // The client write and server read sequence numbers should have incremented.
+ if (client_write_seq + 1 != SSL_get_write_sequence(client.get()) ||
+ server_read_seq + 1 != SSL_get_read_sequence(server.get())) {
+ fprintf(stderr, "Sequence numbers did not increment.\n");\
+ return false;
+ }
+
+ return true;
+}
+
int main() {
CRYPTO_library_init();
@@ -1053,7 +1152,9 @@ int main() {
!TestCipherGetRFCName() ||
!TestPaddingExtension() ||
!TestClientCAList() ||
- !TestInternalSessionCache()) {
+ !TestInternalSessionCache() ||
+ !TestSequenceNumber(false /* TLS */) ||
+ !TestSequenceNumber(true /* DTLS */)) {
ERR_print_errors_fp(stderr);
return 1;
}
diff --git a/src/ssl/t1_enc.c b/src/ssl/t1_enc.c
index 0f1d6833..b5992077 100644
--- a/src/ssl/t1_enc.c
+++ b/src/ssl/t1_enc.c
@@ -136,7 +136,6 @@
#include <openssl/ssl.h>
#include <assert.h>
-#include <stdio.h>
#include <string.h>
#include <openssl/err.h>
@@ -144,7 +143,7 @@
#include <openssl/hmac.h>
#include <openssl/md5.h>
#include <openssl/mem.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
#include <openssl/rand.h>
#include "internal.h"
@@ -224,11 +223,10 @@ err:
return ret;
}
-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) {
-
+static int tls1_prf(const 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) {
if (out_len == 0) {
return 1;
}
@@ -260,15 +258,12 @@ int tls1_prf(SSL *ssl, uint8_t *out, size_t out_len, const uint8_t *secret,
return 1;
}
-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 *ssl, int which) {
+ /* Ensure the key block is set up. */
+ if (!tls1_setup_key_block(ssl)) {
+ return 0;
+ }
+
/* 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;
@@ -277,63 +272,28 @@ int tls1_change_cipher_state(SSL *ssl, int which) {
* or a server reading a client's ChangeCipherSpec. */
const char use_client_keys = which == SSL3_CHANGE_CIPHER_CLIENT_WRITE ||
which == SSL3_CHANGE_CIPHER_SERVER_READ;
- 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 = 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 (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 = ssl->s3->tmp.new_mac_secret_len;
- iv_len = ssl->s3->tmp.new_fixed_iv_len;
-
- if (aead == NULL) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- return 0;
- }
- key_len = EVP_AEAD_key_length(aead);
- if (mac_secret_len > 0) {
- /* For "stateful" AEADs (i.e. compatibility with pre-AEAD cipher
- * 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, ERR_R_INTERNAL_ERROR);
- return 0;
- }
- key_len -= mac_secret_len + iv_len;
- }
+ size_t mac_secret_len = ssl->s3->tmp.new_mac_secret_len;
+ size_t key_len = ssl->s3->tmp.new_key_len;
+ size_t iv_len = ssl->s3->tmp.new_fixed_iv_len;
+ assert((mac_secret_len + key_len + iv_len) * 2 ==
+ ssl->s3->tmp.key_block_length);
- key_data = ssl->s3->tmp.key_block;
- client_write_mac_secret = key_data;
+ const uint8_t *key_data = ssl->s3->tmp.key_block;
+ const uint8_t *client_write_mac_secret = key_data;
key_data += mac_secret_len;
- server_write_mac_secret = key_data;
+ const uint8_t *server_write_mac_secret = key_data;
key_data += mac_secret_len;
- client_write_key = key_data;
+ const uint8_t *client_write_key = key_data;
key_data += key_len;
- server_write_key = key_data;
+ const uint8_t *server_write_key = key_data;
key_data += key_len;
- client_write_iv = key_data;
+ const uint8_t *client_write_iv = key_data;
key_data += iv_len;
- server_write_iv = key_data;
+ const uint8_t *server_write_iv = key_data;
key_data += iv_len;
+ const uint8_t *mac_secret, *key, *iv;
if (use_client_keys) {
mac_secret = client_write_mac_secret;
key = client_write_key;
@@ -344,50 +304,51 @@ int tls1_change_cipher_state(SSL *ssl, int which) {
iv = server_write_iv;
}
- if (key_data - ssl->s3->tmp.key_block != ssl->s3->tmp.key_block_length) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ SSL_AEAD_CTX *aead_ctx =
+ SSL_AEAD_CTX_new(is_read ? evp_aead_open : evp_aead_seal,
+ ssl3_protocol_version(ssl), ssl->s3->tmp.new_cipher, key,
+ key_len, mac_secret, mac_secret_len, iv, iv_len);
+ if (aead_ctx == NULL) {
return 0;
}
if (is_read) {
- 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 ssl->aead_read_ctx != NULL;
+ ssl_set_read_state(ssl, aead_ctx);
+ } else {
+ ssl_set_write_state(ssl, aead_ctx);
}
+ return 1;
+}
- 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;
+size_t SSL_get_key_block_len(const SSL *ssl) {
+ return 2 * ((size_t)ssl->s3->tmp.new_mac_secret_len +
+ (size_t)ssl->s3->tmp.new_key_len +
+ (size_t)ssl->s3->tmp.new_fixed_iv_len);
}
-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;
+int SSL_generate_key_block(const SSL *ssl, uint8_t *out, size_t out_len) {
+ return ssl->s3->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_setup_key_block(SSL *ssl) {
if (ssl->s3->tmp.key_block_length != 0) {
return 1;
}
- if (ssl->session->cipher == NULL) {
- goto cipher_unavailable_err;
- }
-
- if (!ssl_cipher_get_evp_aead(&aead, &mac_secret_len, &fixed_iv_len,
+ const EVP_AEAD *aead = NULL;
+ size_t mac_secret_len, fixed_iv_len;
+ if (ssl->session->cipher == NULL ||
+ !ssl_cipher_get_evp_aead(&aead, &mac_secret_len, &fixed_iv_len,
ssl->session->cipher,
- ssl3_version_from_wire(ssl, ssl->version))) {
- goto cipher_unavailable_err;
+ ssl3_protocol_version(ssl))) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
+ return 0;
}
- key_len = EVP_AEAD_key_length(aead);
- variable_iv_len = EVP_AEAD_nonce_length(aead);
+ size_t key_len = EVP_AEAD_key_length(aead);
if (mac_secret_len > 0) {
/* For "stateful" AEADs (i.e. compatibility with pre-AEAD cipher suites) the
* key length reported by |EVP_AEAD_key_length| will include the MAC key
@@ -397,53 +358,38 @@ int tls1_setup_key_block(SSL *ssl) {
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, ERR_R_INTERNAL_ERROR);
- return 0;
- }
- variable_iv_len -= fixed_iv_len;
}
assert(mac_secret_len < 256);
+ assert(key_len < 256);
assert(fixed_iv_len < 256);
- assert(variable_iv_len < 256);
- ssl->s3->tmp.new_aead = aead;
ssl->s3->tmp.new_mac_secret_len = (uint8_t)mac_secret_len;
+ ssl->s3->tmp.new_key_len = (uint8_t)key_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;
+ size_t key_block_len = SSL_get_key_block_len(ssl);
ssl3_cleanup_key_block(ssl);
- p = (uint8_t *)OPENSSL_malloc(key_block_len);
- if (p == NULL) {
+ uint8_t *keyblock = OPENSSL_malloc(key_block_len);
+ if (keyblock == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
- goto err;
+ return 0;
}
- ssl->s3->tmp.key_block_length = key_block_len;
- ssl->s3->tmp.key_block = p;
-
- if (!tls1_generate_key_block(ssl, p, key_block_len)) {
- goto err;
+ if (!SSL_generate_key_block(ssl, keyblock, key_block_len)) {
+ OPENSSL_free(keyblock);
+ return 0;
}
- ret = 1;
-
-err:
- return ret;
-
-cipher_unavailable_err:
- OPENSSL_PUT_ERROR(SSL, SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
- return 0;
+ assert(key_block_len < 256);
+ ssl->s3->tmp.key_block_length = (uint8_t)key_block_len;
+ ssl->s3->tmp.key_block = keyblock;
+ return 1;
}
-int tls1_cert_verify_mac(SSL *ssl, int md_nid, uint8_t *out) {
+static 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;
@@ -512,57 +458,58 @@ int tls1_handshake_digest(SSL *ssl, uint8_t *out, size_t out_len) {
return (int)(md5_len + len);
}
-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;
-
+static int tls1_final_finish_mac(SSL *ssl, int from_server, uint8_t *out) {
/* At this point, the handshake should have released the handshake buffer on
* its own. */
assert(ssl->s3->handshake_buffer == NULL);
- digests_len = tls1_handshake_digest(ssl, buf, sizeof(buf));
- if (digests_len < 0) {
- err = 1;
- digests_len = 0;
+ const char *label = TLS_MD_CLIENT_FINISH_CONST;
+ size_t label_len = TLS_MD_SERVER_FINISH_CONST_SIZE;
+ if (from_server) {
+ label = TLS_MD_SERVER_FINISH_CONST;
+ label_len = TLS_MD_SERVER_FINISH_CONST_SIZE;
}
- 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;
+ uint8_t buf[EVP_MAX_MD_SIZE];
+ int digests_len = tls1_handshake_digest(ssl, buf, sizeof(buf));
+ if (digests_len < 0) {
+ return 0;
}
- if (err) {
+ static const size_t kFinishedLen = 12;
+ if (!ssl->s3->enc_method->prf(ssl, out, kFinishedLen,
+ ssl->session->master_key,
+ ssl->session->master_key_length, label,
+ label_len, buf, digests_len, NULL, 0)) {
return 0;
- } else {
- return 12;
}
+
+ return (int)kFinishedLen;
}
int tls1_generate_master_secret(SSL *ssl, uint8_t *out,
const uint8_t *premaster,
size_t premaster_len) {
if (ssl->s3->tmp.extended_master_secret) {
- uint8_t digests[2 * EVP_MAX_MD_SIZE];
+ uint8_t digests[EVP_MAX_MD_SIZE];
int digests_len = tls1_handshake_digest(ssl, digests, sizeof(digests));
if (digests_len == -1) {
return 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)) {
+ if (!ssl->s3->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 (!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)) {
+ if (!ssl->s3->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;
}
}
@@ -570,12 +517,11 @@ int tls1_generate_master_secret(SSL *ssl, uint8_t *out,
return SSL3_MASTER_SECRET_SIZE;
}
-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 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 (!ssl->s3->have_version || ssl->version == SSL3_VERSION) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
@@ -601,108 +547,16 @@ int tls1_export_keying_material(SSL *ssl, uint8_t *out, size_t out_len,
memcpy(seed + 2 * SSL3_RANDOM_SIZE + 2, context, context_len);
}
- 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);
+ int ret =
+ ssl->s3->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;
}
-int tls1_alert_code(int code) {
- switch (code) {
- case SSL_AD_CLOSE_NOTIFY:
- return SSL3_AD_CLOSE_NOTIFY;
-
- case SSL_AD_UNEXPECTED_MESSAGE:
- return SSL3_AD_UNEXPECTED_MESSAGE;
-
- case SSL_AD_BAD_RECORD_MAC:
- return SSL3_AD_BAD_RECORD_MAC;
-
- case SSL_AD_DECRYPTION_FAILED:
- return TLS1_AD_DECRYPTION_FAILED;
-
- case SSL_AD_RECORD_OVERFLOW:
- return TLS1_AD_RECORD_OVERFLOW;
-
- case SSL_AD_DECOMPRESSION_FAILURE:
- return SSL3_AD_DECOMPRESSION_FAILURE;
-
- case SSL_AD_HANDSHAKE_FAILURE:
- return SSL3_AD_HANDSHAKE_FAILURE;
-
- case SSL_AD_NO_CERTIFICATE:
- return -1;
-
- case SSL_AD_BAD_CERTIFICATE:
- return SSL3_AD_BAD_CERTIFICATE;
-
- case SSL_AD_UNSUPPORTED_CERTIFICATE:
- return SSL3_AD_UNSUPPORTED_CERTIFICATE;
-
- case SSL_AD_CERTIFICATE_REVOKED:
- return SSL3_AD_CERTIFICATE_REVOKED;
-
- case SSL_AD_CERTIFICATE_EXPIRED:
- return SSL3_AD_CERTIFICATE_EXPIRED;
-
- case SSL_AD_CERTIFICATE_UNKNOWN:
- return SSL3_AD_CERTIFICATE_UNKNOWN;
-
- case SSL_AD_ILLEGAL_PARAMETER:
- return SSL3_AD_ILLEGAL_PARAMETER;
-
- case SSL_AD_UNKNOWN_CA:
- return TLS1_AD_UNKNOWN_CA;
-
- case SSL_AD_ACCESS_DENIED:
- return TLS1_AD_ACCESS_DENIED;
-
- case SSL_AD_DECODE_ERROR:
- return TLS1_AD_DECODE_ERROR;
-
- case SSL_AD_DECRYPT_ERROR:
- return TLS1_AD_DECRYPT_ERROR;
- case SSL_AD_EXPORT_RESTRICTION:
- return TLS1_AD_EXPORT_RESTRICTION;
-
- case SSL_AD_PROTOCOL_VERSION:
- return TLS1_AD_PROTOCOL_VERSION;
-
- case SSL_AD_INSUFFICIENT_SECURITY:
- return TLS1_AD_INSUFFICIENT_SECURITY;
-
- case SSL_AD_INTERNAL_ERROR:
- return TLS1_AD_INTERNAL_ERROR;
-
- case SSL_AD_USER_CANCELLED:
- return TLS1_AD_USER_CANCELLED;
-
- case SSL_AD_NO_RENEGOTIATION:
- return TLS1_AD_NO_RENEGOTIATION;
-
- case SSL_AD_UNSUPPORTED_EXTENSION:
- return TLS1_AD_UNSUPPORTED_EXTENSION;
-
- case SSL_AD_CERTIFICATE_UNOBTAINABLE:
- return TLS1_AD_CERTIFICATE_UNOBTAINABLE;
-
- case SSL_AD_UNRECOGNIZED_NAME:
- return TLS1_AD_UNRECOGNIZED_NAME;
-
- case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE:
- return TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE;
-
- case SSL_AD_BAD_CERTIFICATE_HASH_VALUE:
- return TLS1_AD_BAD_CERTIFICATE_HASH_VALUE;
-
- case SSL_AD_UNKNOWN_PSK_IDENTITY:
- return TLS1_AD_UNKNOWN_PSK_IDENTITY;
-
- case SSL_AD_INAPPROPRIATE_FALLBACK:
- return SSL3_AD_INAPPROPRIATE_FALLBACK;
-
- default:
- return -1;
- }
-}
+const SSL3_ENC_METHOD TLSv1_enc_data = {
+ tls1_prf,
+ tls1_final_finish_mac,
+ tls1_cert_verify_mac,
+};
diff --git a/src/ssl/t1_lib.c b/src/ssl/t1_lib.c
index 5aea08b2..eac9579d 100644
--- a/src/ssl/t1_lib.c
+++ b/src/ssl/t1_lib.c
@@ -110,7 +110,6 @@
#include <assert.h>
#include <limits.h>
-#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -120,7 +119,7 @@
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/mem.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
#include <openssl/rand.h>
#include <openssl/type_check.h>
@@ -130,48 +129,6 @@
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,
- tls1_setup_key_block,
- tls1_generate_master_secret,
- tls1_change_cipher_state,
- tls1_final_finish_mac,
- tls1_cert_verify_mac,
- TLS_MD_CLIENT_FINISH_CONST,TLS_MD_CLIENT_FINISH_CONST_SIZE,
- TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE,
- tls1_alert_code,
- tls1_export_keying_material,
- 0,
-};
-
-const SSL3_ENC_METHOD TLSv1_1_enc_data = {
- tls1_prf,
- tls1_setup_key_block,
- tls1_generate_master_secret,
- tls1_change_cipher_state,
- tls1_final_finish_mac,
- tls1_cert_verify_mac,
- TLS_MD_CLIENT_FINISH_CONST,TLS_MD_CLIENT_FINISH_CONST_SIZE,
- TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE,
- tls1_alert_code,
- tls1_export_keying_material,
- SSL_ENC_FLAG_EXPLICIT_IV,
-};
-
-const SSL3_ENC_METHOD TLSv1_2_enc_data = {
- tls1_prf,
- tls1_setup_key_block,
- tls1_generate_master_secret,
- tls1_change_cipher_state,
- tls1_final_finish_mac,
- tls1_cert_verify_mac,
- TLS_MD_CLIENT_FINISH_CONST,TLS_MD_CLIENT_FINISH_CONST_SIZE,
- 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,
-};
-
static int compare_uint16_t(const void *p1, const void *p2) {
uint16_t u1 = *((const uint16_t *)p1);
uint16_t u2 = *((const uint16_t *)p2);
@@ -211,8 +168,7 @@ static int tls1_check_duplicate_extensions(const CBS *cbs) {
return 1;
}
- extension_types =
- (uint16_t *)OPENSSL_malloc(sizeof(uint16_t) * num_extensions);
+ extension_types = OPENSSL_malloc(sizeof(uint16_t) * num_extensions);
if (extension_types == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto done;
@@ -336,6 +292,7 @@ int SSL_early_callback_ctx_extension_get(
}
static const uint16_t eccurves_default[] = {
+ SSL_CURVE_X25519,
SSL_CURVE_SECP256R1,
SSL_CURVE_SECP384R1,
#if defined(BORINGSSL_ANDROID_SYSTEM)
@@ -418,7 +375,7 @@ int tls1_set_curves(uint16_t **out_curve_ids, size_t *out_curve_ids_len,
uint16_t *curve_ids;
size_t i;
- curve_ids = (uint16_t *)OPENSSL_malloc(ncurves * sizeof(uint16_t));
+ curve_ids = OPENSSL_malloc(ncurves * sizeof(uint16_t));
if (curve_ids == NULL) {
return 0;
}
@@ -551,7 +508,6 @@ static const uint8_t tls12_sigalgs[] = {
tlsext_sigalg(TLSEXT_hash_sha512)
tlsext_sigalg(TLSEXT_hash_sha384)
tlsext_sigalg(TLSEXT_hash_sha256)
- tlsext_sigalg(TLSEXT_hash_sha224)
tlsext_sigalg(TLSEXT_hash_sha1)
};
@@ -731,82 +687,44 @@ static int ext_sni_parse_clienthello(SSL *ssl, uint8_t *out_alert,
return 1;
}
- /* 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;
-
+ CBS server_name_list, host_name;
+ uint8_t name_type;
if (!CBS_get_u16_length_prefixed(contents, &server_name_list) ||
- CBS_len(&server_name_list) == 0 ||
+ !CBS_get_u8(&server_name_list, &name_type) ||
+ /* Although the server_name extension was intended to be extensible to
+ * new name types and multiple names, OpenSSL 1.0.x had a bug which meant
+ * different name types will cause an error. Further, RFC 4366 originally
+ * defined syntax inextensibly. RFC 6066 corrected this mistake, but
+ * adding new name types is no longer feasible.
+ *
+ * Act as if the extensibility does not exist to simplify parsing. */
+ !CBS_get_u16_length_prefixed(&server_name_list, &host_name) ||
+ CBS_len(&server_name_list) != 0 ||
CBS_len(contents) != 0) {
return 0;
}
- /* Decode each ServerName in the extension. */
- while (CBS_len(&server_name_list) > 0) {
- uint8_t name_type;
- CBS host_name;
-
- if (!CBS_get_u8(&server_name_list, &name_type) ||
- !CBS_get_u16_length_prefixed(&server_name_list, &host_name)) {
- return 0;
- }
-
- /* Only host_name is supported. */
- if (name_type != TLSEXT_NAMETYPE_host_name) {
- continue;
- }
-
- if (have_seen_host_name) {
- /* The ServerNameList MUST NOT contain more than one name of the same
- * name_type. */
- return 0;
- }
+ if (name_type != TLSEXT_NAMETYPE_host_name ||
+ 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;
+ }
- have_seen_host_name = 1;
+ /* TODO(davidben): SNI should be resolved before resumption. We have the
+ * early callback as a replacement, but we should fix the current callback
+ * and avoid the need for |SSL_CTX_set_session_id_context|. */
+ if (!ssl->hit) {
+ assert(ssl->session->tlsext_hostname == NULL);
- 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;
+ /* Copy the hostname as a string. */
+ if (!CBS_strdup(&host_name, &ssl->session->tlsext_hostname)) {
+ *out_alert = SSL_AD_INTERNAL_ERROR;
return 0;
}
- 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;
- }
+ ssl->s3->tmp.should_ack_sni = 1;
}
return 1;
@@ -975,7 +893,7 @@ static int ext_ri_add_serverhello(SSL *ssl, CBB *out) {
/* Extended Master Secret.
*
- * https://tools.ietf.org/html/draft-ietf-tls-session-hash-05 */
+ * https://tools.ietf.org/html/rfc7627 */
static void ext_ems_init(SSL *ssl) {
ssl->s3->tmp.extended_master_secret = 0;
@@ -1185,6 +1103,7 @@ static int ext_sigalgs_add_serverhello(SSL *ssl, CBB *out) {
static void ext_ocsp_init(SSL *ssl) {
ssl->s3->tmp.certificate_status_expected = 0;
+ ssl->tlsext_status_type = -1;
}
static int ext_ocsp_add_clienthello(SSL *ssl, CBB *out) {
@@ -1202,6 +1121,7 @@ static int ext_ocsp_add_clienthello(SSL *ssl, CBB *out) {
return 0;
}
+ ssl->tlsext_status_type = TLSEXT_STATUSTYPE_ocsp;
return 1;
}
@@ -1317,14 +1237,14 @@ static int ext_npn_parse_serverhello(SSL *ssl, uint8_t *out_alert,
return 0;
}
- OPENSSL_free(ssl->next_proto_negotiated);
- ssl->next_proto_negotiated = BUF_memdup(selected, selected_len);
- if (ssl->next_proto_negotiated == NULL) {
+ OPENSSL_free(ssl->s3->next_proto_negotiated);
+ ssl->s3->next_proto_negotiated = BUF_memdup(selected, selected_len);
+ if (ssl->s3->next_proto_negotiated == NULL) {
*out_alert = SSL_AD_INTERNAL_ERROR;
return 0;
}
- ssl->next_proto_negotiated_len = selected_len;
+ ssl->s3->next_proto_negotiated_len = selected_len;
ssl->s3->next_proto_neg_seen = 1;
return 1;
@@ -1945,9 +1865,7 @@ static int ext_ec_curves_parse_clienthello(SSL *ssl, uint8_t *out_alert,
return 0;
}
- ssl->s3->tmp.peer_ellipticcurvelist =
- (uint16_t *)OPENSSL_malloc(CBS_len(&elliptic_curve_list));
-
+ ssl->s3->tmp.peer_ellipticcurvelist = OPENSSL_malloc(CBS_len(&elliptic_curve_list));
if (ssl->s3->tmp.peer_ellipticcurvelist == NULL) {
*out_alert = SSL_AD_INTERNAL_ERROR;
return 0;
@@ -2081,6 +1999,9 @@ static const struct tls_extension kExtensions[] = {
ext_ec_point_parse_clienthello,
ext_ec_point_add_serverhello,
},
+ /* The final extension must be non-empty. WebSphere Application Server 7.0 is
+ * intolerant to the last extension being zero-length. See
+ * https://crbug.com/363583. */
{
TLSEXT_TYPE_elliptic_curves,
ext_ec_curves_init,
@@ -2167,9 +2088,10 @@ int ssl_add_clienthello_tlsext(SSL *ssl, CBB *out, size_t header_len) {
* 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
+ /* Extensions take at least four bytes to encode. Always include at least
* one byte of data if including the extension. WebSphere Application
- * Server 7.0 is intolerant to the last extension being zero-length. */
+ * Server 7.0 is intolerant to the last extension being zero-length. See
+ * https://crbug.com/363583. */
if (padding_len >= 4 + 1) {
padding_len -= 4;
} else {
@@ -2411,14 +2333,10 @@ 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 (ssl->ctx != NULL && ssl->ctx->tlsext_servername_callback != 0) {
+ if (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) {
+ ssl->ctx->tlsext_servername_arg);
+ } else if (ssl->initial_ctx->tlsext_servername_callback != 0) {
ret = ssl->initial_ctx->tlsext_servername_callback(
ssl, &al, ssl->initial_ctx->tlsext_servername_arg);
}
@@ -2445,11 +2363,10 @@ static int ssl_check_serverhello_tlsext(SSL *ssl) {
int ret = SSL_TLSEXT_ERR_OK;
int al = SSL_AD_UNRECOGNIZED_NAME;
- if (ssl->ctx != NULL && ssl->ctx->tlsext_servername_callback != 0) {
+ if (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) {
+ ssl->ctx->tlsext_servername_arg);
+ } else if (ssl->initial_ctx->tlsext_servername_callback != 0) {
ret = ssl->initial_ctx->tlsext_servername_callback(
ssl, &al, ssl->initial_ctx->tlsext_servername_arg);
}
@@ -2484,7 +2401,7 @@ int ssl_parse_serverhello_tlsext(SSL *ssl, CBS *cbs) {
}
int tls_process_ticket(SSL *ssl, SSL_SESSION **out_session,
- int *out_send_ticket, const uint8_t *ticket,
+ int *out_renew_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. */
@@ -2496,19 +2413,13 @@ int tls_process_ticket(SSL *ssl, SSL_SESSION **out_session,
EVP_CIPHER_CTX cipher_ctx;
EVP_CIPHER_CTX_init(&cipher_ctx);
- *out_send_ticket = 0;
+ *out_renew_ticket = 0;
*out_session = NULL;
if (session_id_len > SSL_MAX_SSL_SESSION_ID_LENGTH) {
goto done;
}
- 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
@@ -2530,7 +2441,7 @@ int tls_process_ticket(SSL *ssl, SSL_SESSION **out_session,
goto done;
}
if (cb_ret == 2) {
- *out_send_ticket = 1;
+ *out_renew_ticket = 1;
}
} else {
/* Check the key name matches. */
@@ -2609,12 +2520,12 @@ typedef struct {
int id;
} tls12_lookup;
-static const tls12_lookup tls12_md[] = {{NID_md5, TLSEXT_hash_md5},
- {NID_sha1, TLSEXT_hash_sha1},
- {NID_sha224, TLSEXT_hash_sha224},
- {NID_sha256, TLSEXT_hash_sha256},
- {NID_sha384, TLSEXT_hash_sha384},
- {NID_sha512, TLSEXT_hash_sha512}};
+static const tls12_lookup tls12_md[] = {
+ {NID_sha1, TLSEXT_hash_sha1},
+ {NID_sha256, TLSEXT_hash_sha256},
+ {NID_sha384, TLSEXT_hash_sha384},
+ {NID_sha512, TLSEXT_hash_sha512},
+};
static const tls12_lookup tls12_sig[] = {{EVP_PKEY_RSA, TLSEXT_signature_rsa},
{EVP_PKEY_EC, TLSEXT_signature_ecdsa}};
@@ -2648,15 +2559,9 @@ int tls12_add_sigandhash(SSL *ssl, CBB *out, const EVP_MD *md) {
const EVP_MD *tls12_get_hash(uint8_t hash_alg) {
switch (hash_alg) {
- case TLSEXT_hash_md5:
- return EVP_md5();
-
case TLSEXT_hash_sha1:
return EVP_sha1();
- case TLSEXT_hash_sha224:
- return EVP_sha224();
-
case TLSEXT_hash_sha256:
return EVP_sha256();
@@ -2691,7 +2596,7 @@ OPENSSL_COMPILE_ASSERT(sizeof(TLS_SIGALGS) == 2,
int tls1_parse_peer_sigalgs(SSL *ssl, const CBS *in_sigalgs) {
/* Extension ignored for inappropriate versions */
- if (!SSL_USE_SIGALGS(ssl)) {
+ if (ssl3_protocol_version(ssl) < TLS1_2_VERSION) {
return 1;
}
@@ -2742,7 +2647,7 @@ const EVP_MD *tls1_choose_signing_digest(SSL *ssl) {
size_t i, j;
static const int kDefaultDigestList[] = {NID_sha256, NID_sha384, NID_sha512,
- NID_sha224, NID_sha1};
+ NID_sha1};
const int *digest_nids = kDefaultDigestList;
size_t num_digest_nids =
diff --git a/src/ssl/test/bssl_shim.cc b/src/ssl/test/bssl_shim.cc
index 74674a49..5effa580 100644
--- a/src/ssl/test/bssl_shim.cc
+++ b/src/ssl/test/bssl_shim.cc
@@ -46,7 +46,7 @@
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/hmac.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
#include <openssl/rand.h>
#include <openssl/ssl.h>
@@ -138,13 +138,20 @@ static TestState *GetTestState(const SSL *ssl) {
return (TestState *)SSL_get_ex_data(ssl, g_state_index);
}
+static ScopedX509 LoadCertificate(const std::string &file) {
+ ScopedBIO bio(BIO_new(BIO_s_file()));
+ if (!bio || !BIO_read_filename(bio.get(), file.c_str())) {
+ return nullptr;
+ }
+ return ScopedX509(PEM_read_bio_X509(bio.get(), NULL, NULL, NULL));
+}
+
static ScopedEVP_PKEY LoadPrivateKey(const std::string &file) {
ScopedBIO bio(BIO_new(BIO_s_file()));
if (!bio || !BIO_read_filename(bio.get(), file.c_str())) {
return nullptr;
}
- ScopedEVP_PKEY pkey(PEM_read_bio_PrivateKey(bio.get(), NULL, NULL, NULL));
- return pkey;
+ return ScopedEVP_PKEY(PEM_read_bio_PrivateKey(bio.get(), NULL, NULL, NULL));
}
static int AsyncPrivateKeyType(SSL *ssl) {
@@ -291,9 +298,9 @@ struct Free {
}
};
-static bool InstallCertificate(SSL *ssl) {
+static bool GetCertificate(SSL *ssl, ScopedX509 *out_x509,
+ ScopedEVP_PKEY *out_pkey) {
const TestConfig *config = GetConfigPtr(ssl);
- TestState *test_state = GetTestState(ssl);
if (!config->digest_prefs.empty()) {
std::unique_ptr<char, Free<char>> digest_prefs(
@@ -317,21 +324,16 @@ static bool InstallCertificate(SSL *ssl) {
}
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)) {
+ *out_pkey = LoadPrivateKey(config->key_file.c_str());
+ if (!*out_pkey) {
return false;
}
}
- if (!config->cert_file.empty() &&
- !SSL_use_certificate_file(ssl, config->cert_file.c_str(),
- SSL_FILETYPE_PEM)) {
- return false;
+ if (!config->cert_file.empty()) {
+ *out_x509 = LoadCertificate(config->cert_file.c_str());
+ if (!*out_x509) {
+ return false;
+ }
}
if (!config->ocsp_response.empty() &&
!SSL_CTX_set_ocsp_response(ssl->ctx,
@@ -342,6 +344,31 @@ static bool InstallCertificate(SSL *ssl) {
return true;
}
+static bool InstallCertificate(SSL *ssl) {
+ ScopedX509 x509;
+ ScopedEVP_PKEY pkey;
+ if (!GetCertificate(ssl, &x509, &pkey)) {
+ return false;
+ }
+
+ if (pkey) {
+ TestState *test_state = GetTestState(ssl);
+ const TestConfig *config = GetConfigPtr(ssl);
+ if (config->async) {
+ test_state->private_key = std::move(pkey);
+ SSL_set_private_key_method(ssl, &g_async_private_key_method);
+ } else if (!SSL_use_PrivateKey(ssl, pkey.get())) {
+ return false;
+ }
+ }
+
+ if (x509 && !SSL_use_certificate(ssl, x509.get())) {
+ return false;
+ }
+
+ return true;
+}
+
static int SelectCertificateCallback(const struct ssl_early_callback_ctx *ctx) {
const TestConfig *config = GetConfigPtr(ctx->ssl);
GetTestState(ctx->ssl)->early_callback_called = true;
@@ -394,6 +421,28 @@ static int SelectCertificateCallback(const struct ssl_early_callback_ctx *ctx) {
return 1;
}
+static int ClientCertCallback(SSL *ssl, X509 **out_x509, EVP_PKEY **out_pkey) {
+ if (GetConfigPtr(ssl)->async && !GetTestState(ssl)->cert_ready) {
+ return -1;
+ }
+
+ ScopedX509 x509;
+ ScopedEVP_PKEY pkey;
+ if (!GetCertificate(ssl, &x509, &pkey)) {
+ return -1;
+ }
+
+ // Return zero for no certificate.
+ if (!x509) {
+ return 0;
+ }
+
+ // Asynchronous private keys are not supported with client_cert_cb.
+ *out_x509 = x509.release();
+ *out_pkey = pkey.release();
+ return 1;
+}
+
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());
@@ -444,7 +493,7 @@ static int NextProtoSelectCallback(SSL* ssl, uint8_t** out, uint8_t* outlen,
static int AlpnSelectCallback(SSL* ssl, const uint8_t** out, uint8_t* outlen,
const uint8_t* in, unsigned inlen, void* arg) {
const TestConfig *config = GetConfigPtr(ssl);
- if (config->select_alpn.empty()) {
+ if (config->decline_alpn) {
return SSL_TLSEXT_ERR_NOACK;
}
@@ -732,6 +781,9 @@ static ScopedSSL_CTX SetupCtx(const TestConfig *config) {
}
ScopedDH dh(DH_get_2048_256(NULL));
+ if (!dh) {
+ return nullptr;
+ }
if (config->use_sparse_dh_prime) {
// This prime number is 2^1024 + 643 – a value just above a power of two.
@@ -747,10 +799,12 @@ static ScopedSSL_CTX SetupCtx(const TestConfig *config) {
!BN_set_word(dh->g, 2)) {
return nullptr;
}
+ BN_free(dh->q);
+ dh->q = NULL;
dh->priv_length = 0;
}
- if (!dh || !SSL_CTX_set_tmp_dh(ssl_ctx.get(), dh.get())) {
+ if (!SSL_CTX_set_tmp_dh(ssl_ctx.get(), dh.get())) {
return nullptr;
}
@@ -766,6 +820,10 @@ static ScopedSSL_CTX SetupCtx(const TestConfig *config) {
SSL_CTX_set_select_certificate_cb(ssl_ctx.get(), SelectCertificateCallback);
+ if (config->use_old_client_cert_callback) {
+ SSL_CTX_set_client_cert_cb(ssl_ctx.get(), ClientCertCallback);
+ }
+
SSL_CTX_set_next_protos_advertised_cb(
ssl_ctx.get(), NextProtosAdvertisedCallback, NULL);
if (!config->select_next_proto.empty()) {
@@ -773,7 +831,7 @@ static ScopedSSL_CTX SetupCtx(const TestConfig *config) {
NULL);
}
- if (!config->select_alpn.empty()) {
+ if (!config->select_alpn.empty() || config->decline_alpn) {
SSL_CTX_set_alpn_select_cb(ssl_ctx.get(), AlpnSelectCallback, NULL);
}
@@ -1138,9 +1196,8 @@ static bool DoExchange(ScopedSSL_SESSION *out_session, SSL_CTX *ssl_ctx,
!SSL_set_mode(ssl.get(), SSL_MODE_SEND_FALLBACK_SCSV)) {
return false;
}
- if (!config->use_early_callback) {
+ if (!config->use_early_callback && !config->use_old_client_cert_callback) {
if (config->async) {
- // TODO(davidben): Also test |s->ctx->client_cert_cb| on the client.
SSL_set_cert_cb(ssl.get(), CertCallback, NULL);
} else if (!InstallCertificate(ssl.get())) {
return false;
@@ -1253,7 +1310,7 @@ static bool DoExchange(ScopedSSL_SESSION *out_session, SSL_CTX *ssl_ctx,
}
if (config->enable_all_curves) {
static const int kAllCurves[] = {
- NID_X9_62_prime256v1, NID_secp384r1, NID_secp521r1, NID_x25519,
+ NID_X9_62_prime256v1, NID_secp384r1, NID_secp521r1, NID_X25519,
};
if (!SSL_set1_curves(ssl.get(), kAllCurves,
sizeof(kAllCurves) / sizeof(kAllCurves[0]))) {
@@ -1274,12 +1331,18 @@ static bool DoExchange(ScopedSSL_SESSION *out_session, SSL_CTX *ssl_ctx,
if (config->is_dtls) {
ScopedBIO packeted =
PacketedBioCreate(&GetTestState(ssl.get())->clock_delta);
+ if (!packeted) {
+ return false;
+ }
BIO_push(packeted.get(), bio.release());
bio = std::move(packeted);
}
if (config->async) {
ScopedBIO async_scoped =
config->is_dtls ? AsyncBioCreateDatagram() : AsyncBioCreate();
+ if (!async_scoped) {
+ return false;
+ }
BIO_push(async_scoped.get(), bio.release());
GetTestState(ssl.get())->async_bio = async_scoped.get();
bio = std::move(async_scoped);
@@ -1483,7 +1546,16 @@ static bool DoExchange(ScopedSSL_SESSION *out_session, SSL_CTX *ssl_ctx,
return true;
}
+class StderrDelimiter {
+ public:
+ ~StderrDelimiter() { fprintf(stderr, "--- DONE ---\n"); }
+};
+
int main(int argc, char **argv) {
+ // To distinguish ASan's output from ours, add a trailing message to stderr.
+ // Anything following this line will be considered an error.
+ StderrDelimiter delimiter;
+
#if defined(OPENSSL_WINDOWS)
/* Initialize Winsock. */
WORD wsa_version = MAKEWORD(2, 2);
diff --git a/src/ssl/test/runner/alert.go b/src/ssl/test/runner/alert.go
index 541216ed..7db68267 100644
--- a/src/ssl/test/runner/alert.go
+++ b/src/ssl/test/runner/alert.go
@@ -22,6 +22,7 @@ const (
alertRecordOverflow alert = 22
alertDecompressionFailure alert = 30
alertHandshakeFailure alert = 40
+ alertNoCertficate alert = 41
alertBadCertificate alert = 42
alertUnsupportedCertificate alert = 43
alertCertificateRevoked alert = 44
diff --git a/src/ssl/test/runner/common.go b/src/ssl/test/runner/common.go
index db3c6757..2e9ce045 100644
--- a/src/ssl/test/runner/common.go
+++ b/src/ssl/test/runner/common.go
@@ -424,6 +424,10 @@ type ProtocolBugs struct {
// to be wrong.
InvalidSKXCurve bool
+ // InvalidECDHPoint, if true, causes the ECC points in
+ // ServerKeyExchange or ClientKeyExchange messages to be invalid.
+ InvalidECDHPoint bool
+
// BadECDSAR controls ways in which the 'r' value of an ECDSA signature
// can be invalid.
BadECDSAR BadValue
@@ -469,6 +473,10 @@ type ProtocolBugs struct {
// NewSessionTicket message despite promising to in ServerHello.
SkipNewSessionTicket bool
+ // SkipClientCertificate causes the client to skip the Certificate
+ // message.
+ SkipClientCertificate bool
+
// SkipChangeCipherSpec causes the implementation to skip
// sending the ChangeCipherSpec message (and adjusting cipher
// state accordingly for the Finished message).
@@ -517,6 +525,10 @@ type ProtocolBugs struct {
// two records.
FragmentAlert bool
+ // DoubleAlert will cause all alerts to be sent as two copies packed
+ // within one record.
+ DoubleAlert bool
+
// SendSpuriousAlert, if non-zero, will cause an spurious, unwanted
// alert to be sent.
SendSpuriousAlert alert
@@ -814,6 +826,14 @@ type ProtocolBugs struct {
// BadHelloRequest, if not nil, is what to send instead of a
// HelloRequest.
BadHelloRequest []byte
+
+ // RequireSessionTickets, if true, causes the client to require new
+ // sessions use session tickets instead of session IDs.
+ RequireSessionTickets bool
+
+ // NullAllCiphers, if true, causes every cipher to behave like the null
+ // cipher.
+ NullAllCiphers bool
}
func (c *Config) serverInit() {
diff --git a/src/ssl/test/runner/conn.go b/src/ssl/test/runner/conn.go
index cb60a928..43548e8a 100644
--- a/src/ssl/test/runner/conn.go
+++ b/src/ssl/test/runner/conn.go
@@ -189,6 +189,11 @@ func (hc *halfConn) changeCipherSpec(config *Config) error {
hc.nextMac = nil
hc.config = config
hc.incEpoch()
+
+ if config.Bugs.NullAllCiphers {
+ hc.cipher = nil
+ hc.mac = nil
+ }
return nil
}
@@ -837,6 +842,9 @@ func (c *Conn) sendAlertLocked(level byte, err alert) error {
if c.config.Bugs.FragmentAlert {
c.writeRecord(recordTypeAlert, c.tmp[0:1])
c.writeRecord(recordTypeAlert, c.tmp[1:2])
+ } else if c.config.Bugs.DoubleAlert {
+ copy(c.tmp[2:4], c.tmp[0:2])
+ c.writeRecord(recordTypeAlert, c.tmp[0:4])
} else {
c.writeRecord(recordTypeAlert, c.tmp[0:2])
}
@@ -851,7 +859,7 @@ func (c *Conn) sendAlertLocked(level byte, err alert) error {
// L < c.out.Mutex.
func (c *Conn) sendAlert(err alert) error {
level := byte(alertLevelError)
- if err == alertNoRenegotiation || err == alertCloseNotify {
+ if err == alertNoRenegotiation || err == alertCloseNotify || err == alertNoCertficate {
level = alertLevelWarning
}
return c.SendAlert(level, err)
diff --git a/src/ssl/test/runner/handshake_client.go b/src/ssl/test/runner/handshake_client.go
index 64630ba3..67609fcd 100644
--- a/src/ssl/test/runner/handshake_client.go
+++ b/src/ssl/test/runner/handshake_client.go
@@ -363,6 +363,9 @@ NextCipherSuite:
}
if sessionCache != nil && hs.session != nil && session != hs.session {
+ if c.config.Bugs.RequireSessionTickets && len(hs.session.sessionTicket) == 0 {
+ return errors.New("tls: new session used session IDs instead of tickets")
+ }
sessionCache.Put(cacheKey, hs.session)
}
@@ -561,15 +564,20 @@ func (hs *clientHandshakeState) doFullHandshake() error {
hs.writeServerHash(shd.marshal())
// If the server requested a certificate then we have to send a
- // Certificate message, even if it's empty because we don't have a
- // certificate to send.
+ // Certificate message in TLS, even if it's empty because we don't have
+ // a certificate to send. In SSL 3.0, skip the message and send a
+ // no_certificate warning alert.
if certRequested {
- certMsg := new(certificateMsg)
- if chainToSend != nil {
- certMsg.certificates = chainToSend.Certificate
+ if c.vers == VersionSSL30 && chainToSend == nil {
+ c.sendAlert(alertNoCertficate)
+ } else if !c.config.Bugs.SkipClientCertificate {
+ certMsg := new(certificateMsg)
+ if chainToSend != nil {
+ certMsg.certificates = chainToSend.Certificate
+ }
+ hs.writeClientHash(certMsg.marshal())
+ c.writeRecord(recordTypeHandshake, certMsg.marshal())
}
- hs.writeClientHash(certMsg.marshal())
- c.writeRecord(recordTypeHandshake, certMsg.marshal())
}
preMasterSecret, ckx, err := keyAgreement.generateClientKeyExchange(c.config, hs.hello, leaf)
diff --git a/src/ssl/test/runner/handshake_messages.go b/src/ssl/test/runner/handshake_messages.go
index 530ddbcf..092f51ef 100644
--- a/src/ssl/test/runner/handshake_messages.go
+++ b/src/ssl/test/runner/handshake_messages.go
@@ -349,7 +349,7 @@ func (m *clientHelloMsg) marshal() []byte {
z = z[4:]
}
if m.extendedMasterSecret {
- // https://tools.ietf.org/html/draft-ietf-tls-session-hash-01
+ // https://tools.ietf.org/html/rfc7627
z[0] = byte(extensionExtendedMasterSecret >> 8)
z[1] = byte(extensionExtendedMasterSecret & 0xff)
z = z[4:]
diff --git a/src/ssl/test/runner/handshake_server.go b/src/ssl/test/runner/handshake_server.go
index 0232772f..d2cac98c 100644
--- a/src/ssl/test/runner/handshake_server.go
+++ b/src/ssl/test/runner/handshake_server.go
@@ -626,13 +626,22 @@ func (hs *serverHandshakeState) doFullHandshake() error {
// certificate message, even if it's empty.
if config.ClientAuth >= RequestClientCert {
var certMsg *certificateMsg
- if certMsg, ok = msg.(*certificateMsg); !ok {
+ var certificates [][]byte
+ if certMsg, ok = msg.(*certificateMsg); ok {
+ if c.vers == VersionSSL30 && len(certMsg.certificates) == 0 {
+ return errors.New("tls: empty certificate message in SSL 3.0")
+ }
+
+ hs.writeClientHash(certMsg.marshal())
+ certificates = certMsg.certificates
+ } else if c.vers != VersionSSL30 {
+ // In TLS, the Certificate message is required. In SSL
+ // 3.0, the peer skips it when sending no certificates.
c.sendAlert(alertUnexpectedMessage)
return unexpectedMessageError(certMsg, msg)
}
- hs.writeClientHash(certMsg.marshal())
- if len(certMsg.certificates) == 0 {
+ if len(certificates) == 0 {
// The client didn't actually send a certificate
switch config.ClientAuth {
case RequireAnyClientCert, RequireAndVerifyClientCert:
@@ -641,14 +650,16 @@ func (hs *serverHandshakeState) doFullHandshake() error {
}
}
- pub, err = hs.processCertsFromClient(certMsg.certificates)
+ pub, err = hs.processCertsFromClient(certificates)
if err != nil {
return err
}
- msg, err = c.readHandshake()
- if err != nil {
- return err
+ if ok {
+ msg, err = c.readHandshake()
+ if err != nil {
+ return err
+ }
}
}
diff --git a/src/ssl/test/runner/key_agreement.go b/src/ssl/test/runner/key_agreement.go
index 4f399d95..54aa3d31 100644
--- a/src/ssl/test/runner/key_agreement.go
+++ b/src/ssl/test/runner/key_agreement.go
@@ -312,8 +312,7 @@ func (e *x25519ECDHCurve) computeSecret(peerKey []byte) (preMasterSecret []byte,
copy(peerKeyCopy[:], peerKey)
curve25519.ScalarMult(&out, &e.privateKey, &peerKeyCopy)
- // Per draft-irtf-cfrg-curves-11, reject the all-zero value in constant
- // time.
+ // Per RFC 7748, 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")
@@ -567,6 +566,9 @@ NextCandidate:
}
serverECDHParams[3] = byte(len(publicKey))
copy(serverECDHParams[4:], publicKey)
+ if config.Bugs.InvalidECDHPoint {
+ serverECDHParams[4] ^= 0xff
+ }
return ka.auth.signParameters(config, cert, clientHello, hello, serverECDHParams)
}
@@ -623,6 +625,9 @@ func (ka *ecdheKeyAgreement) generateClientKeyExchange(config *Config, clientHel
ckx.ciphertext = make([]byte, 1+len(publicKey))
ckx.ciphertext[0] = byte(len(publicKey))
copy(ckx.ciphertext[1:], publicKey)
+ if config.Bugs.InvalidECDHPoint {
+ ckx.ciphertext[1] ^= 0xff
+ }
return preMasterSecret, ckx, nil
}
diff --git a/src/ssl/test/runner/prf.go b/src/ssl/test/runner/prf.go
index 8521abaa..f1b26de0 100644
--- a/src/ssl/test/runner/prf.go
+++ b/src/ssl/test/runner/prf.go
@@ -153,7 +153,7 @@ func masterFromPreMasterSecret(version uint16, suite *cipherSuite, preMasterSecr
// extendedMasterFromPreMasterSecret generates the master secret from the
// pre-master secret when the Triple Handshake fix is in effect. See
-// https://tools.ietf.org/html/draft-ietf-tls-session-hash-01
+// https://tools.ietf.org/html/rfc7627
func extendedMasterFromPreMasterSecret(version uint16, suite *cipherSuite, preMasterSecret []byte, h finishedHash) []byte {
masterSecret := make([]byte, masterSecretLength)
prfForVersion(version, suite)(masterSecret, preMasterSecret, extendedMasterSecretLabel, h.Sum())
diff --git a/src/ssl/test/runner/recordingconn.go b/src/ssl/test/runner/recordingconn.go
index 39deb194..752610e6 100644
--- a/src/ssl/test/runner/recordingconn.go
+++ b/src/ssl/test/runner/recordingconn.go
@@ -92,6 +92,17 @@ func (r *recordingConn) WriteTo(w io.Writer) {
}
}
+func (r *recordingConn) Transcript() []byte {
+ var ret []byte
+ for _, flow := range r.flows {
+ if flow.flowType != writeFlow {
+ continue
+ }
+ ret = append(ret, flow.data...)
+ }
+ return ret
+}
+
func parseTestData(r io.Reader) (flows [][]byte, err error) {
var currentFlow []byte
diff --git a/src/ssl/test/runner/runner.go b/src/ssl/test/runner/runner.go
index 45bb0b7a..5b746c62 100644
--- a/src/ssl/test/runner/runner.go
+++ b/src/ssl/test/runner/runner.go
@@ -37,6 +37,9 @@ var (
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.")
+ fuzzer = flag.Bool("fuzzer", false, "If true, tests against a BoringSSL built in fuzzer mode.")
+ transcriptDir = flag.String("transcript-dir", "", "The directory in which to write transcripts.")
+ timeout = flag.Int("timeout", 15, "The number of seconds to wait for a read or write to bssl_shim.")
)
const (
@@ -244,15 +247,68 @@ type testCase struct {
var testCases []testCase
+func writeTranscript(test *testCase, isResume bool, data []byte) {
+ if len(data) == 0 {
+ return
+ }
+
+ protocol := "tls"
+ if test.protocol == dtls {
+ protocol = "dtls"
+ }
+
+ side := "client"
+ if test.testType == serverTest {
+ side = "server"
+ }
+
+ dir := path.Join(*transcriptDir, protocol, side)
+ if err := os.MkdirAll(dir, 0755); err != nil {
+ fmt.Fprintf(os.Stderr, "Error making %s: %s\n", dir, err)
+ return
+ }
+
+ name := test.name
+ if isResume {
+ name += "-Resume"
+ } else {
+ name += "-Normal"
+ }
+
+ if err := ioutil.WriteFile(path.Join(dir, name), data, 0644); err != nil {
+ fmt.Fprintf(os.Stderr, "Error writing %s: %s\n", name, err)
+ }
+}
+
+// A timeoutConn implements an idle timeout on each Read and Write operation.
+type timeoutConn struct {
+ net.Conn
+ timeout time.Duration
+}
+
+func (t *timeoutConn) Read(b []byte) (int, error) {
+ if err := t.SetReadDeadline(time.Now().Add(t.timeout)); err != nil {
+ return 0, err
+ }
+ return t.Conn.Read(b)
+}
+
+func (t *timeoutConn) Write(b []byte) (int, error) {
+ if err := t.SetWriteDeadline(time.Now().Add(t.timeout)); err != nil {
+ return 0, err
+ }
+ return t.Conn.Write(b)
+}
+
func doExchange(test *testCase, config *Config, conn net.Conn, isResume bool) error {
- var connDamage *damageAdaptor
+ conn = &timeoutConn{conn, time.Duration(*timeout) * time.Second}
if test.protocol == dtls {
config.Bugs.PacketAdaptor = newPacketAdaptor(conn)
conn = config.Bugs.PacketAdaptor
}
- if *flagDebug {
+ if *flagDebug || len(*transcriptDir) != 0 {
local, peer := "client", "server"
if test.testType == clientTest {
local, peer = peer, local
@@ -264,9 +320,14 @@ func doExchange(test *testCase, config *Config, conn net.Conn, isResume bool) er
peer: peer,
}
conn = connDebug
- defer func() {
- connDebug.WriteTo(os.Stdout)
- }()
+ if *flagDebug {
+ defer connDebug.WriteTo(os.Stdout)
+ }
+ if len(*transcriptDir) != 0 {
+ defer func() {
+ writeTranscript(test, isResume, connDebug.Transcript())
+ }()
+ }
if config.Bugs.PacketAdaptor != nil {
config.Bugs.PacketAdaptor.debug = connDebug
@@ -277,6 +338,7 @@ func doExchange(test *testCase, config *Config, conn net.Conn, isResume bool) er
conn = newReplayAdaptor(conn)
}
+ var connDamage *damageAdaptor
if test.damageFirstWrite {
connDamage = newDamageAdaptor(conn)
conn = connDamage
@@ -686,6 +748,9 @@ func runTest(test *testCase, shimPath string, mallocNumToFail int64) error {
config.ServerName = "test"
}
}
+ if *fuzzer {
+ config.Bugs.NullAllCiphers = true
+ }
conn, err := acceptOrWait(listener, waitChan)
if err == nil {
@@ -713,6 +778,9 @@ func runTest(test *testCase, shimPath string, mallocNumToFail int64) error {
resumeConfig.ClientSessionCache = config.ClientSessionCache
resumeConfig.ServerSessionCache = config.ServerSessionCache
}
+ if *fuzzer {
+ resumeConfig.Bugs.NullAllCiphers = true
+ }
} else {
resumeConfig = config
}
@@ -736,8 +804,18 @@ func runTest(test *testCase, shimPath string, mallocNumToFail int64) error {
}
}
- stdout := string(stdoutBuf.Bytes())
- stderr := string(stderrBuf.Bytes())
+ // Account for Windows line endings.
+ stdout := strings.Replace(string(stdoutBuf.Bytes()), "\r\n", "\n", -1)
+ stderr := strings.Replace(string(stderrBuf.Bytes()), "\r\n", "\n", -1)
+
+ // Separate the errors from the shim and those from tools like
+ // AddressSanitizer.
+ var extraStderr string
+ if stderrParts := strings.SplitN(stderr, "--- DONE ---\n", 2); len(stderrParts) == 2 {
+ stderr = stderrParts[0]
+ extraStderr = stderrParts[1]
+ }
+
failed := err != nil || childErr != nil
correctFailure := len(test.expectedError) == 0 || strings.Contains(stderr, test.expectedError)
localError := "none"
@@ -769,8 +847,8 @@ func runTest(test *testCase, shimPath string, mallocNumToFail int64) error {
return fmt.Errorf("%s: local error '%s', child error '%s', stdout:\n%s\nstderr:\n%s", msg, localError, childError, stdout, stderr)
}
- if !*useValgrind && !failed && len(stderr) > 0 {
- println(stderr)
+ if !*useValgrind && (len(extraStderr) > 0 || (!failed && len(stderr) > 0)) {
+ return fmt.Errorf("unexpected error output:\n%s\n%s", stderr, extraStderr)
}
return nil
@@ -1128,6 +1206,31 @@ func addBasicTests() {
},
{
testType: serverTest,
+ name: "DoubleAlert",
+ config: Config{
+ Bugs: ProtocolBugs{
+ DoubleAlert: true,
+ SendSpuriousAlert: alertRecordOverflow,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":BAD_ALERT:",
+ },
+ {
+ protocol: dtls,
+ testType: serverTest,
+ name: "DoubleAlert-DTLS",
+ config: Config{
+ Bugs: ProtocolBugs{
+ DoubleAlert: true,
+ SendSpuriousAlert: alertRecordOverflow,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":BAD_ALERT:",
+ },
+ {
+ testType: serverTest,
name: "EarlyChangeCipherSpec-server-1",
config: Config{
Bugs: ProtocolBugs{
@@ -1708,7 +1811,18 @@ func addBasicTests() {
expectedError: ":WRONG_CURVE:",
},
{
- name: "BadFinished",
+ name: "BadFinished-Client",
+ config: Config{
+ Bugs: ProtocolBugs{
+ BadFinished: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":DIGEST_CHECK_FAILED:",
+ },
+ {
+ testType: serverTest,
+ name: "BadFinished-Server",
config: Config{
Bugs: ProtocolBugs{
BadFinished: true,
@@ -2088,6 +2202,40 @@ func addBasicTests() {
shouldFail: true,
expectedError: ":BAD_HELLO_REQUEST:",
},
+ {
+ testType: serverTest,
+ name: "SupportTicketsWithSessionID",
+ config: Config{
+ SessionTicketsDisabled: true,
+ },
+ resumeConfig: &Config{},
+ resumeSession: true,
+ },
+ {
+ name: "InvalidECDHPoint-Client",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ CurvePreferences: []CurveID{CurveP256},
+ Bugs: ProtocolBugs{
+ InvalidECDHPoint: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":INVALID_ENCODING:",
+ },
+ {
+ testType: serverTest,
+ name: "InvalidECDHPoint-Server",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ CurvePreferences: []CurveID{CurveP256},
+ Bugs: ProtocolBugs{
+ InvalidECDHPoint: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":INVALID_ENCODING:",
+ },
}
testCases = append(testCases, basicTests...)
}
@@ -2280,6 +2428,16 @@ func addCipherSuiteTests() {
flags: []string{"-use-sparse-dh-prime"},
})
+ // The server must be tolerant to bogus ciphers.
+ const bogusCipher = 0x1234
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "UnknownCipher",
+ config: Config{
+ CipherSuites: []uint16{bogusCipher, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ },
+ })
+
// 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
@@ -2383,7 +2541,7 @@ func addBadECDSASignatureTests() {
},
},
shouldFail: true,
- expectedError: "SIGNATURE",
+ expectedError: ":BAD_SIGNATURE:",
})
}
}
@@ -2409,7 +2567,7 @@ func addCBCPaddingTests() {
},
},
shouldFail: true,
- expectedError: "DECRYPTION_FAILED_OR_BAD_RECORD_MAC",
+ expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
})
// OpenSSL previously had an issue where the first byte of padding in
// 255 bytes of padding wasn't checked.
@@ -2424,7 +2582,7 @@ func addCBCPaddingTests() {
},
messageLen: 12, // 20 bytes of SHA-1 + 12 == 0 % block size
shouldFail: true,
- expectedError: "DECRYPTION_FAILED_OR_BAD_RECORD_MAC",
+ expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
})
}
@@ -2523,6 +2681,39 @@ func addClientAuthTests() {
})
}
}
+
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "RequireAnyClientCertificate",
+ flags: []string{"-require-any-client-certificate"},
+ shouldFail: true,
+ expectedError: ":PEER_DID_NOT_RETURN_A_CERTIFICATE:",
+ })
+
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "RequireAnyClientCertificate-SSL3",
+ config: Config{
+ MaxVersion: VersionSSL30,
+ },
+ flags: []string{"-require-any-client-certificate"},
+ shouldFail: true,
+ expectedError: ":PEER_DID_NOT_RETURN_A_CERTIFICATE:",
+ })
+
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "SkipClientCertificate",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SkipClientCertificate: true,
+ },
+ },
+ // Setting SSL_VERIFY_PEER allows anonymous clients.
+ flags: []string{"-verify-peer"},
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_MESSAGE:",
+ })
}
func addExtendedMasterSecretTests() {
@@ -2667,6 +2858,8 @@ func addStateMachineCoverageTests(async, splitHandshake bool, protocol protocol)
tests = append(tests, testCase{
name: "Basic-Client",
resumeSession: true,
+ // Ensure session tickets are used, not session IDs.
+ noSessionCache: true,
})
tests = append(tests, testCase{
name: "Basic-Client-RenewTicket",
@@ -2691,8 +2884,13 @@ func addStateMachineCoverageTests(async, splitHandshake bool, protocol protocol)
resumeSession: true,
})
tests = append(tests, testCase{
- testType: serverTest,
- name: "Basic-Server",
+ testType: serverTest,
+ name: "Basic-Server",
+ config: Config{
+ Bugs: ProtocolBugs{
+ RequireSessionTickets: true,
+ },
+ },
resumeSession: true,
})
tests = append(tests, testCase{
@@ -2719,6 +2917,46 @@ func addStateMachineCoverageTests(async, splitHandshake bool, protocol protocol)
// TLS client auth.
tests = append(tests, testCase{
testType: clientTest,
+ name: "ClientAuth-NoCertificate-Client",
+ config: Config{
+ ClientAuth: RequestClientCert,
+ },
+ })
+ tests = append(tests, testCase{
+ testType: serverTest,
+ name: "ClientAuth-NoCertificate-Server",
+ // Setting SSL_VERIFY_PEER allows anonymous clients.
+ flags: []string{"-verify-peer"},
+ })
+ if protocol == tls {
+ tests = append(tests, testCase{
+ testType: clientTest,
+ name: "ClientAuth-NoCertificate-Client-SSL3",
+ config: Config{
+ MaxVersion: VersionSSL30,
+ ClientAuth: RequestClientCert,
+ },
+ })
+ tests = append(tests, testCase{
+ testType: serverTest,
+ name: "ClientAuth-NoCertificate-Server-SSL3",
+ config: Config{
+ MaxVersion: VersionSSL30,
+ },
+ // Setting SSL_VERIFY_PEER allows anonymous clients.
+ flags: []string{"-verify-peer"},
+ })
+ }
+ tests = append(tests, testCase{
+ testType: clientTest,
+ name: "ClientAuth-NoCertificate-OldCallback",
+ config: Config{
+ ClientAuth: RequestClientCert,
+ },
+ flags: []string{"-use-old-client-cert-callback"},
+ })
+ tests = append(tests, testCase{
+ testType: clientTest,
name: "ClientAuth-RSA-Client",
config: Config{
ClientAuth: RequireAnyClientCert,
@@ -2739,6 +2977,19 @@ func addStateMachineCoverageTests(async, splitHandshake bool, protocol protocol)
"-key-file", path.Join(*resourceDir, ecdsaKeyFile),
},
})
+ tests = append(tests, testCase{
+ testType: clientTest,
+ name: "ClientAuth-OldCallback",
+ config: Config{
+ ClientAuth: RequireAnyClientCert,
+ },
+ flags: []string{
+ "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
+ "-key-file", path.Join(*resourceDir, rsaKeyFile),
+ "-use-old-client-cert-callback",
+ },
+ })
+
if async {
// Test async keys against each key exchange.
tests = append(tests, testCase{
@@ -3223,11 +3474,7 @@ func addMinimumVersionTests() {
} else {
shouldFail = true
expectedError = ":UNSUPPORTED_PROTOCOL:"
- if runnerVers.version > VersionSSL30 {
- expectedLocalError = "remote error: protocol version not supported"
- } else {
- expectedLocalError = "remote error: handshake failure"
- }
+ expectedLocalError = "remote error: protocol version not supported"
}
testCases = append(testCases, testCase{
@@ -3381,6 +3628,16 @@ func addExtensionTests() {
expectedNextProtoType: alpn,
resumeSession: true,
})
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "ALPNServer-Decline",
+ config: Config{
+ NextProtos: []string{"foo", "bar", "baz"},
+ },
+ flags: []string{"-decline-alpn"},
+ expectNoNextProto: true,
+ resumeSession: true,
+ })
// Test that the server prefers ALPN over NPN.
testCases = append(testCases, testCase{
testType: serverTest,
@@ -4087,7 +4344,6 @@ var testHashes = []struct {
id uint8
}{
{"SHA1", hashSHA1},
- {"SHA224", hashSHA224},
{"SHA256", hashSHA256},
{"SHA384", hashSHA384},
{"SHA512", hashSHA512},
@@ -4668,6 +4924,17 @@ func addCurveTests() {
flags: []string{"-enable-all-curves"},
})
}
+
+ // The server must be tolerant to bogus curves.
+ const bogusCurve = 0x1234
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "UnknownCurve",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ CurvePreferences: []CurveID{bogusCurve, CurveP256},
+ },
+ })
}
func addKeyExchangeInfoTests() {
@@ -4845,11 +5112,17 @@ func main() {
go worker(statusChan, testChan, *shimPath, &wg)
}
+ var foundTest bool
for i := range testCases {
if len(*testToRun) == 0 || *testToRun == testCases[i].name {
+ foundTest = true
testChan <- &testCases[i]
}
}
+ if !foundTest {
+ fmt.Fprintf(os.Stderr, "No test named '%s'\n", *testToRun)
+ os.Exit(1)
+ }
close(testChan)
wg.Wait()
diff --git a/src/ssl/test/test_config.cc b/src/ssl/test/test_config.cc
index 1cf316d5..67a017d8 100644
--- a/src/ssl/test/test_config.cc
+++ b/src/ssl/test/test_config.cc
@@ -62,6 +62,7 @@ const Flag<bool> kBoolFlags[] = {
{ "-no-ssl3", &TestConfig::no_ssl3 },
{ "-shim-writes-first", &TestConfig::shim_writes_first },
{ "-expect-session-miss", &TestConfig::expect_session_miss },
+ { "-decline-alpn", &TestConfig::decline_alpn },
{ "-expect-extended-master-secret",
&TestConfig::expect_extended_master_secret },
{ "-enable-ocsp-stapling", &TestConfig::enable_ocsp_stapling },
@@ -98,6 +99,8 @@ const Flag<bool> kBoolFlags[] = {
{ "-p384-only", &TestConfig::p384_only },
{ "-enable-all-curves", &TestConfig::enable_all_curves },
{ "-use-sparse-dh-prime", &TestConfig::use_sparse_dh_prime },
+ { "-use-old-client-cert-callback",
+ &TestConfig::use_old_client_cert_callback },
};
const Flag<std::string> kStringFlags[] = {
@@ -178,12 +181,14 @@ bool ParseConfig(int argc, char **argv, TestConfig *out_config) {
size_t len;
if (!EVP_DecodedLength(&len, strlen(argv[i]))) {
fprintf(stderr, "Invalid base64: %s\n", argv[i]);
+ return false;
}
std::unique_ptr<uint8_t[]> decoded(new uint8_t[len]);
if (!EVP_DecodeBase64(decoded.get(), &len, len,
reinterpret_cast<const uint8_t *>(argv[i]),
strlen(argv[i]))) {
fprintf(stderr, "Invalid base64: %s\n", argv[i]);
+ return false;
}
base64_field->assign(reinterpret_cast<const char *>(decoded.get()), len);
continue;
diff --git a/src/ssl/test/test_config.h b/src/ssl/test/test_config.h
index 4e0a46ae..fe117d8b 100644
--- a/src/ssl/test/test_config.h
+++ b/src/ssl/test/test_config.h
@@ -50,6 +50,7 @@ struct TestConfig {
std::string expected_alpn;
std::string expected_advertised_alpn;
std::string select_alpn;
+ bool decline_alpn = false;
bool expect_session_miss = false;
bool expect_extended_master_secret = false;
std::string psk;
@@ -102,6 +103,7 @@ struct TestConfig {
bool enable_all_curves = false;
bool use_sparse_dh_prime = false;
int expect_key_exchange_info = 0;
+ bool use_old_client_cert_callback = false;
};
bool ParseConfig(int argc, char **argv, TestConfig *out_config);
diff --git a/src/ssl/tls_record.c b/src/ssl/tls_record.c
index 3381eae3..b71da17f 100644
--- a/src/ssl/tls_record.c
+++ b/src/ssl/tls_record.c
@@ -109,6 +109,7 @@
#include <openssl/ssl.h>
#include <assert.h>
+#include <string.h>
#include <openssl/bytestring.h>
#include <openssl/err.h>
@@ -125,31 +126,44 @@ 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 &&
+ return ssl->s3->aead_write_ctx != NULL &&
+ ssl3_protocol_version(ssl) < TLS1_1_VERSION &&
(ssl->mode & SSL_MODE_CBC_RECORD_SPLITTING) != 0 &&
- SSL_CIPHER_is_block_cipher(ssl->aead_write_ctx->cipher);
+ SSL_CIPHER_is_block_cipher(ssl->s3->aead_write_ctx->cipher);
+}
+
+int ssl_record_sequence_update(uint8_t *seq, size_t seq_len) {
+ size_t i;
+ for (i = seq_len - 1; i < seq_len; i--) {
+ ++seq[i];
+ if (seq[i] != 0) {
+ return 1;
+ }
+ }
+ OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
+ return 0;
}
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);
+ SSL_AEAD_CTX_explicit_nonce_len(ssl->s3->aead_read_ctx);
} else {
return SSL3_RT_HEADER_LENGTH +
- SSL_AEAD_CTX_explicit_nonce_len(ssl->aead_read_ctx);
+ SSL_AEAD_CTX_explicit_nonce_len(ssl->s3->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);
+ SSL_AEAD_CTX_explicit_nonce_len(ssl->s3->aead_write_ctx);
} else {
size_t ret = SSL3_RT_HEADER_LENGTH +
- SSL_AEAD_CTX_explicit_nonce_len(ssl->aead_write_ctx);
+ SSL_AEAD_CTX_explicit_nonce_len(ssl->s3->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);
+ ret += ssl_cipher_get_record_split_len(ssl->s3->aead_write_ctx->cipher);
}
return ret;
}
@@ -158,10 +172,10 @@ size_t ssl_seal_prefix_len(const SSL *ssl) {
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);
+ SSL_AEAD_CTX_max_overhead(ssl->s3->aead_write_ctx);
} else {
size_t ret = SSL3_RT_HEADER_LENGTH +
- SSL_AEAD_CTX_max_overhead(ssl->aead_write_ctx);
+ SSL_AEAD_CTX_max_overhead(ssl->s3->aead_write_ctx);
if (ssl_needs_record_splitting(ssl)) {
ret *= 2;
}
@@ -215,14 +229,14 @@ enum ssl_open_record_t tls_open_record(
/* Decrypt the body. */
size_t plaintext_len;
- if (!SSL_AEAD_CTX_open(ssl->aead_read_ctx, out, &plaintext_len, max_out,
+ if (!SSL_AEAD_CTX_open(ssl->s3->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)) {
+ if (!ssl_record_sequence_update(ssl->s3->read_sequence, 8)) {
*out_alert = SSL_AD_INTERNAL_ERROR;
return ssl_open_record_error;
}
@@ -280,11 +294,11 @@ static int do_seal_record(SSL *ssl, uint8_t *out, size_t *out_len,
out[2] = wire_version & 0xff;
size_t ciphertext_len;
- if (!SSL_AEAD_CTX_seal(ssl->aead_write_ctx, out + SSL3_RT_HEADER_LENGTH,
+ if (!SSL_AEAD_CTX_seal(ssl->s3->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)) {
+ !ssl_record_sequence_update(ssl->s3->write_sequence, 8)) {
return 0;
}
@@ -329,9 +343,11 @@ int tls_seal_record(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out,
out += frag_len;
max_out -= frag_len;
- assert(SSL3_RT_HEADER_LENGTH +
- ssl_cipher_get_record_split_len(ssl->aead_write_ctx->cipher) ==
+#if !defined(BORINGSSL_UNSAFE_FUZZER_MODE)
+ assert(SSL3_RT_HEADER_LENGTH + ssl_cipher_get_record_split_len(
+ ssl->s3->aead_write_ctx->cipher) ==
frag_len);
+#endif
}
if (!do_seal_record(ssl, out, out_len, max_out, type, in, in_len)) {
@@ -340,3 +356,26 @@ int tls_seal_record(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out,
*out_len += frag_len;
return 1;
}
+
+void ssl_set_read_state(SSL *ssl, SSL_AEAD_CTX *aead_ctx) {
+ 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));
+
+ SSL_AEAD_CTX_free(ssl->s3->aead_read_ctx);
+ ssl->s3->aead_read_ctx = aead_ctx;
+}
+
+void ssl_set_write_state(SSL *ssl, SSL_AEAD_CTX *aead_ctx) {
+ 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));
+
+ SSL_AEAD_CTX_free(ssl->s3->aead_write_ctx);
+ ssl->s3->aead_write_ctx = aead_ctx;
+}
diff --git a/src/tool/digest.cc b/src/tool/digest.cc
index 7cd88278..012202ce 100644
--- a/src/tool/digest.cc
+++ b/src/tool/digest.cc
@@ -41,6 +41,8 @@ typedef int ssize_t;
#include <openssl/digest.h>
+#include "internal.h"
+
struct close_delete {
void operator()(int *fd) {
diff --git a/src/tool/internal.h b/src/tool/internal.h
index 84f8c4d4..6d26209f 100644
--- a/src/tool/internal.h
+++ b/src/tool/internal.h
@@ -55,6 +55,21 @@ bool GetUnsigned(unsigned *out, const std::string &arg_name,
unsigned default_value,
const std::map<std::string, std::string> &args);
+bool Ciphers(const std::vector<std::string> &args);
+bool Client(const std::vector<std::string> &args);
+bool DoPKCS12(const std::vector<std::string> &args);
+bool GenerateEd25519Key(const std::vector<std::string> &args);
+bool GenerateRSAKey(const std::vector<std::string> &args);
+bool MD5Sum(const std::vector<std::string> &args);
+bool Rand(const std::vector<std::string> &args);
+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 Server(const std::vector<std::string> &args);
+bool Speed(const std::vector<std::string> &args);
+
// These values are DER encoded, RSA private keys.
extern const uint8_t kDERRSAPrivate2048[];
extern const size_t kDERRSAPrivate2048Len;
diff --git a/src/tool/rand.cc b/src/tool/rand.cc
index 10078e22..3701748c 100644
--- a/src/tool/rand.cc
+++ b/src/tool/rand.cc
@@ -71,7 +71,7 @@ bool Rand(const std::vector<std::string> &args) {
}
RAND_bytes(buf, todo);
if (hex) {
- static const char hextable[] = "0123456789abdef";
+ static const char hextable[16 + 1] = "0123456789abcdef";
for (unsigned i = 0; i < todo; i++) {
hex_buf[i*2] = hextable[buf[i] >> 4];
hex_buf[i*2 + 1] = hextable[buf[i] & 0xf];
diff --git a/src/tool/speed.cc b/src/tool/speed.cc
index db7c5fa7..68d78e2b 100644
--- a/src/tool/speed.cc
+++ b/src/tool/speed.cc
@@ -24,7 +24,8 @@
#include <openssl/curve25519.h>
#include <openssl/digest.h>
#include <openssl/err.h>
-#include <openssl/obj.h>
+#include <openssl/newhope.h>
+#include <openssl/nid.h>
#include <openssl/rand.h>
#include <openssl/rsa.h>
@@ -467,6 +468,82 @@ static bool Speed25519(const std::string &selected) {
return true;
}
+static bool SpeedSPAKE2(const std::string &selected) {
+ if (!selected.empty() && selected.find("SPAKE2") == std::string::npos) {
+ return true;
+ }
+
+ TimeResults results;
+
+ static const uint8_t kAliceName[] = {'A'};
+ static const uint8_t kBobName[] = {'B'};
+ static const uint8_t kPassword[] = "password";
+ ScopedSPAKE2_CTX alice(SPAKE2_CTX_new(spake2_role_alice, kAliceName,
+ sizeof(kAliceName), kBobName,
+ sizeof(kBobName)));
+ uint8_t alice_msg[SPAKE2_MAX_MSG_SIZE];
+ size_t alice_msg_len;
+
+ if (!SPAKE2_generate_msg(alice.get(), alice_msg, &alice_msg_len,
+ sizeof(alice_msg),
+ kPassword, sizeof(kPassword))) {
+ fprintf(stderr, "SPAKE2_generate_msg failed.\n");
+ return false;
+ }
+
+ if (!TimeFunction(&results, [&alice_msg, alice_msg_len]() -> bool {
+ ScopedSPAKE2_CTX bob(SPAKE2_CTX_new(spake2_role_bob, kBobName,
+ sizeof(kBobName), kAliceName,
+ sizeof(kAliceName)));
+ uint8_t bob_msg[SPAKE2_MAX_MSG_SIZE], bob_key[64];
+ size_t bob_msg_len, bob_key_len;
+ if (!SPAKE2_generate_msg(bob.get(), bob_msg, &bob_msg_len,
+ sizeof(bob_msg), kPassword,
+ sizeof(kPassword)) ||
+ !SPAKE2_process_msg(bob.get(), bob_key, &bob_key_len,
+ sizeof(bob_key), alice_msg, alice_msg_len)) {
+ return false;
+ }
+
+ return true;
+ })) {
+ fprintf(stderr, "SPAKE2 failed.\n");
+ }
+
+ results.Print("SPAKE2 over Ed25519");
+
+ return true;
+}
+
+static bool SpeedNewHope(const std::string &selected) {
+ if (!selected.empty() && selected.find("newhope") == std::string::npos) {
+ return true;
+ }
+
+ TimeResults results;
+ NEWHOPE_POLY *sk = NEWHOPE_POLY_new();
+ uint8_t clientmsg[NEWHOPE_CLIENTMSG_LENGTH];
+ RAND_bytes(clientmsg, sizeof(clientmsg));
+
+ if (!TimeFunction(&results, [sk, &clientmsg]() -> bool {
+ uint8_t server_key[SHA256_DIGEST_LENGTH];
+ uint8_t servermsg[NEWHOPE_SERVERMSG_LENGTH];
+ NEWHOPE_keygen(servermsg, sk);
+ if (!NEWHOPE_server_compute_key(server_key, sk, clientmsg,
+ NEWHOPE_CLIENTMSG_LENGTH)) {
+ return false;
+ }
+ return true;
+ })) {
+ fprintf(stderr, "failed to exchange key.\n");
+ return false;
+ }
+
+ NEWHOPE_POLY_free(sk);
+ results.Print("newhope server key exchange");
+ return true;
+}
+
bool Speed(const std::vector<std::string> &args) {
std::string selected;
if (args.size() > 1) {
@@ -546,7 +623,9 @@ bool Speed(const std::vector<std::string> &args) {
!SpeedRandom(selected) ||
!SpeedECDH(selected) ||
!SpeedECDSA(selected) ||
- !Speed25519(selected)) {
+ !Speed25519(selected) ||
+ !SpeedSPAKE2(selected) ||
+ !SpeedNewHope(selected)) {
return false;
}
diff --git a/src/tool/tool.cc b/src/tool/tool.cc
index b8250089..34851b47 100644
--- a/src/tool/tool.cc
+++ b/src/tool/tool.cc
@@ -26,21 +26,8 @@
#include <libgen.h>
#endif
+#include "internal.h"
-bool Ciphers(const std::vector<std::string> &args);
-bool Client(const std::vector<std::string> &args);
-bool DoPKCS12(const std::vector<std::string> &args);
-bool GenerateEd25519Key(const std::vector<std::string> &args);
-bool GenerateRSAKey(const std::vector<std::string> &args);
-bool MD5Sum(const std::vector<std::string> &args);
-bool Rand(const std::vector<std::string> &args);
-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 Server(const std::vector<std::string> &args);
-bool Speed(const std::vector<std::string> &args);
typedef bool (*tool_func_t)(const std::vector<std::string> &args);
@@ -83,7 +70,7 @@ static void usage(const char *name) {
}
}
-tool_func_t FindTool(const std::string &name) {
+static tool_func_t FindTool(const std::string &name) {
for (size_t i = 0;; i++) {
const Tool &tool = kTools[i];
if (tool.func == nullptr || name == tool.name) {
diff --git a/src/tool/transport_common.cc b/src/tool/transport_common.cc
index 2c15c00b..91152143 100644
--- a/src/tool/transport_common.cc
+++ b/src/tool/transport_common.cc
@@ -44,8 +44,10 @@ typedef int ssize_t;
#include <openssl/err.h>
#include <openssl/ssl.h>
+#include <openssl/x509.h>
#include "internal.h"
+#include "transport_common.h"
#if !defined(OPENSSL_WINDOWS)
@@ -190,6 +192,19 @@ void PrintConnectionInfo(const SSL *ssl) {
unsigned alpn_len;
SSL_get0_alpn_selected(ssl, &alpn, &alpn_len);
fprintf(stderr, " ALPN protocol: %.*s\n", alpn_len, alpn);
+
+ // Print the server cert subject and issuer names.
+ X509 *peer = SSL_get_peer_certificate(ssl);
+ if (peer != NULL) {
+ fprintf(stderr, " Cert subject: ");
+ X509_NAME_print_ex_fp(stderr, X509_get_subject_name(peer), 0,
+ XN_FLAG_ONELINE);
+ fprintf(stderr, "\n Cert issuer: ");
+ X509_NAME_print_ex_fp(stderr, X509_get_issuer_name(peer), 0,
+ XN_FLAG_ONELINE);
+ fprintf(stderr, "\n");
+ X509_free(peer);
+ }
}
bool SocketSetNonBlocking(int sock, bool is_non_blocking) {
diff --git a/src/util/all_tests.go b/src/util/all_tests.go
index 566c3f70..d361651e 100644
--- a/src/util/all_tests.go
+++ b/src/util/all_tests.go
@@ -24,6 +24,7 @@ import (
"path"
"strconv"
"strings"
+ "sync"
"syscall"
"time"
)
@@ -32,8 +33,10 @@ import (
var (
useValgrind = flag.Bool("valgrind", false, "If true, run code under valgrind")
+ useCallgrind = flag.Bool("callgrind", false, "If true, run code under valgrind to generate callgrind traces.")
useGDB = flag.Bool("gdb", false, "If true, run BoringSSL code under gdb")
buildDir = flag.String("build-dir", "build", "The build directory to run the tests from.")
+ numWorkers = flag.Int("num-workers", 1, "Runs the given number of workers when testing.")
jsonOutput = flag.String("json-output", "", "The file to output JSON results to.")
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 each test 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.")
@@ -41,6 +44,12 @@ var (
type test []string
+type result struct {
+ Test test
+ Passed bool
+ Error error
+}
+
// 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 {
@@ -105,6 +114,14 @@ func valgrindOf(dbAttach bool, path string, args ...string) *exec.Cmd {
return exec.Command("valgrind", valgrindArgs...)
}
+func callgrindOf(path string, args ...string) *exec.Cmd {
+ valgrindArgs := []string{"-q", "--tool=callgrind", "--dump-instr=yes", "--collect-jumps=yes", "--callgrind-out-file=" + *buildDir + "/callgrind/callgrind.out.%p"}
+ valgrindArgs = append(valgrindArgs, path)
+ valgrindArgs = append(valgrindArgs, args...)
+
+ return exec.Command("valgrind", valgrindArgs...)
+}
+
func gdbOf(path string, args ...string) *exec.Cmd {
xtermArgs := []string{"-e", "gdb", "--args"}
xtermArgs = append(xtermArgs, path)
@@ -127,6 +144,8 @@ func runTestOnce(test test, mallocNumToFail int64) (passed bool, err error) {
var cmd *exec.Cmd
if *useValgrind {
cmd = valgrindOf(false, prog, args...)
+ } else if *useCallgrind {
+ cmd = callgrindOf(prog, args...)
} else if *useGDB {
cmd = gdbOf(prog, args...)
} else {
@@ -225,28 +244,55 @@ func parseTestConfig(filename string) ([]test, error) {
return result, nil
}
+func worker(tests <-chan test, results chan<- result, done *sync.WaitGroup) {
+ defer done.Done()
+ for test := range tests {
+ passed, err := runTest(test)
+ results <- result{test, passed, err}
+ }
+}
+
func main() {
flag.Parse()
setWorkingDirectory()
- tests, err := parseTestConfig("util/all_tests.json")
+ testCases, err := parseTestConfig("util/all_tests.json")
if err != nil {
fmt.Printf("Failed to parse input: %s\n", err)
os.Exit(1)
}
+ var wg sync.WaitGroup
+ tests := make(chan test, *numWorkers)
+ results := make(chan result, *numWorkers)
+
+ for i := 0; i < *numWorkers; i++ {
+ wg.Add(1)
+ go worker(tests, results, &wg)
+ }
+
+ go func() {
+ for _, test := range testCases {
+ tests <- test
+ }
+ close(tests)
+
+ wg.Wait()
+ close(results)
+ }()
+
testOutput := newTestOutput()
var failed []test
- for _, test := range tests {
- fmt.Printf("%s\n", strings.Join([]string(test), " "))
+ for testResult := range results {
+ test := testResult.Test
+ fmt.Printf("%s\n", strings.Join([]string(test), " "))
name := shortTestName(test)
- passed, err := runTest(test)
- if err != nil {
- fmt.Printf("%s failed to complete: %s\n", test[0], err)
+ if testResult.Error != nil {
+ fmt.Printf("%s failed to complete: %s\n", test[0], testResult.Error)
failed = append(failed, test)
testOutput.addResult(name, "CRASHED")
- } else if !passed {
+ } else if !testResult.Passed {
fmt.Printf("%s failed to print PASS on the last line.\n", test[0])
failed = append(failed, test)
testOutput.addResult(name, "FAIL")
@@ -262,7 +308,7 @@ func main() {
}
if len(failed) > 0 {
- fmt.Printf("\n%d of %d tests failed:\n", len(failed), len(tests))
+ fmt.Printf("\n%d of %d tests failed:\n", len(failed), len(testCases))
for _, test := range failed {
fmt.Printf("\t%s\n", strings.Join([]string(test), " "))
}
diff --git a/src/util/all_tests.json b/src/util/all_tests.json
index c6217997..3de06946 100644
--- a/src/util/all_tests.json
+++ b/src/util/all_tests.json
@@ -1,9 +1,11 @@
[
["crypto/aes/aes_test"],
+ ["crypto/asn1/asn1_test"],
["crypto/base64/base64_test"],
["crypto/bio/bio_test"],
["crypto/bn/bn_test"],
["crypto/bytestring/bytestring_test"],
+ ["crypto/chacha/chacha_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"],
@@ -33,6 +35,7 @@
["crypto/constant_time_test"],
["crypto/curve25519/ed25519_test", "crypto/curve25519/ed25519_tests.txt"],
["crypto/curve25519/x25519_test"],
+ ["crypto/curve25519/spake25519_test"],
["crypto/dh/dh_test"],
["crypto/digest/digest_test"],
["crypto/dsa/dsa_test"],
@@ -47,15 +50,19 @@
["crypto/hmac/hmac_test", "crypto/hmac/hmac_tests.txt"],
["crypto/lhash/lhash_test"],
["crypto/modes/gcm_test"],
- ["crypto/pkcs8/pkcs8_test"],
+ ["crypto/newhope/newhope_test"],
+ ["crypto/obj/obj_test"],
["crypto/pkcs8/pkcs12_test"],
+ ["crypto/pkcs8/pkcs8_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/x509/x509_test"],
["crypto/x509v3/tab_test"],
["crypto/x509v3/v3name_test"],
+ ["decrepit/ripemd/ripemd_test"],
["ssl/pqueue/pqueue_test"],
["ssl/ssl_test"]
]
diff --git a/src/util/bot/DEPS b/src/util/bot/DEPS
index 738fbd3d..0a4de211 100644
--- a/src/util/bot/DEPS
+++ b/src/util/bot/DEPS
@@ -18,7 +18,7 @@ vars = {
deps = {
'boringssl/util/bot/gyp':
- Var('chromium_git') + '/external/gyp.git' + '@' + '4a9b712d5cb4a5ba7a9950128a7219569caf7263',
+ Var('chromium_git') + '/external/gyp.git' + '@' + '61259d585ce99d9de8b35188cd0025bdbcb58411',
}
hooks = [
diff --git a/src/util/bot/UPDATING b/src/util/bot/UPDATING
new file mode 100644
index 00000000..4e16c6dd
--- /dev/null
+++ b/src/util/bot/UPDATING
@@ -0,0 +1,46 @@
+This directory consumes tools from other repositories for use on the
+bots. To update to newer revisions, follow these instructions:
+
+DEPS: Set the external/gyp.git revision to the revision used in Chromium, found at
+ https://chromium.googlesource.com/chromium/src/+/master/DEPS
+ (Search for 'gyp.git'.)
+
+go/bootstrap.py: Set TOOLSET_VERSION to the latest release of Go, found at
+ https://golang.org/dl/.
+
+update_clang.py: Set CLANG_REVISION and CLANG_SUB_REVISION to the values used in
+ Chromium, found at
+ https://chromium.googlesource.com/chromium/src/+/master/tools/clang/scripts/update.py
+
+vs_toolchain.py: Set the hash in _GetDesiredVsToolchainHashes to the toolchain
+ used in Chromium, found at
+ https://chromium.googlesource.com/chromium/src/+/master/build/vs_toolchain.py
+ This may require taking other updates to that file.
+
+The .sha1 files correspond to files downloaded from Google Cloud Storage. To
+update, place the updated files in their intended location and run:
+
+ upload_to_google_storage.py -b chromium-tools FILE
+
+cmake-linux64.tar.gz: Download the latest CMake source tarball, found at
+ https://cmake.org/download/. Build it with:
+
+ ./bootstrap --prefix=$PWD/cmake-linux64 && make && make install
+ tar -czf cmake-linux64.tar.gz cmake-linux64/
+
+cmake-mac.tar.gz: Follow the same instructions as above on a Mac, but replace
+ cmake-linux64 with cmake-mac.
+
+cmake-win32.zip: Update to the latest prebuilt release of CMake, found at
+ https://cmake.org/download/. Use the file labeled "Windows ZIP". The
+ download will be named cmake-VERSION-win32-x86.zip.
+
+perl-win32.zip: Update to the latest 32-bit prebuilt "PortableZip" edition of
+ Strawberry Perl, found at http://strawberryperl.com/releases.html. The
+ download will be named strawberry-perl-VERSION-32bit-portable.zip.
+
+yasm-win32.exe: Update to the appropriate release of Yasm. Use the same version
+ as Chromium, found at
+ https://chromium.googlesource.com/chromium/src/+/master/third_party/yasm/README.chromium
+ Use the release at http://yasm.tortall.net/Download.html labeled
+ "Win32 .exe". The download will be named yasm-VERSION-win32.exe.
diff --git a/src/util/bot/cmake-linux64.tar.gz.sha1 b/src/util/bot/cmake-linux64.tar.gz.sha1
index 6a8aa1c9..404570f6 100644
--- a/src/util/bot/cmake-linux64.tar.gz.sha1
+++ b/src/util/bot/cmake-linux64.tar.gz.sha1
@@ -1 +1 @@
-32cd1d5fe84ae569dbb36f5767650d62efb8be38 \ No newline at end of file
+6ea4ad07a4bab113ea74c45fafb14b8d0b0feab5 \ No newline at end of file
diff --git a/src/util/bot/cmake-mac.tar.gz.sha1 b/src/util/bot/cmake-mac.tar.gz.sha1
index cb7251ba..19c9b61f 100644
--- a/src/util/bot/cmake-mac.tar.gz.sha1
+++ b/src/util/bot/cmake-mac.tar.gz.sha1
@@ -1 +1 @@
-310df6945ae7f8c9da559d22f5794ee8e578a663 \ No newline at end of file
+f3166dab96234c9516ece56dc2851bf4c8e70fe8 \ No newline at end of file
diff --git a/src/util/bot/cmake-win32.zip.sha1 b/src/util/bot/cmake-win32.zip.sha1
index 9196b58c..6bb460eb 100644
--- a/src/util/bot/cmake-win32.zip.sha1
+++ b/src/util/bot/cmake-win32.zip.sha1
@@ -1 +1 @@
-e9493171de0edd8879755aa7229a701010a19561 \ No newline at end of file
+ed4e1939d246374b0bae724a1a4200fd60e7efe8 \ No newline at end of file
diff --git a/src/util/bot/go/bootstrap.py b/src/util/bot/go/bootstrap.py
index 4a52d9eb..28aa13da 100755
--- a/src/util/bot/go/bootstrap.py
+++ b/src/util/bot/go/bootstrap.py
@@ -45,7 +45,7 @@ WORKSPACE = os.path.join(ROOT, 'go')
EXE_SFX = '.exe' if sys.platform == 'win32' else ''
# Pinned version of Go toolset to download.
-TOOLSET_VERSION = 'go1.5.1'
+TOOLSET_VERSION = 'go1.6'
# Platform dependent portion of a download URL. See http://golang.org/dl/.
TOOLSET_VARIANTS = {
diff --git a/src/util/bot/perl-win32.zip.sha1 b/src/util/bot/perl-win32.zip.sha1
index a5559d8a..8874fbbb 100644
--- a/src/util/bot/perl-win32.zip.sha1
+++ b/src/util/bot/perl-win32.zip.sha1
@@ -1 +1 @@
-ab6e7aee6a915c4d820b86f5227094763b649fce \ No newline at end of file
+3db2b4964d56f6e23cc48ced40a6cee05419a0af \ No newline at end of file
diff --git a/src/util/bot/update_clang.py b/src/util/bot/update_clang.py
index 18243934..48d0d9bb 100644
--- a/src/util/bot/update_clang.py
+++ b/src/util/bot/update_clang.py
@@ -22,7 +22,7 @@ import urllib
# CLANG_REVISION and CLANG_SUB_REVISION determine the build of clang
# to use. These should be synced with tools/clang/scripts/update.py in
# Chromium.
-CLANG_REVISION = "233105"
+CLANG_REVISION = "261368"
CLANG_SUB_REVISION = "1"
PACKAGE_VERSION = "%s-%s" % (CLANG_REVISION, CLANG_SUB_REVISION)
diff --git a/src/util/bot/vs_toolchain.py b/src/util/bot/vs_toolchain.py
index 2a54b9e5..175502e7 100644
--- a/src/util/bot/vs_toolchain.py
+++ b/src/util/bot/vs_toolchain.py
@@ -65,7 +65,7 @@ def _GetDesiredVsToolchainHashes():
"""Load a list of SHA1s corresponding to the toolchains that we want installed
to build with."""
# Use Chromium's VS2013.
- return ['ee7d718ec60c2dc5d255bbe325909c2021a7efef']
+ return ['4087e065abebdca6dbd0caca2910c6718d2ec67f']
def FindDepotTools():
diff --git a/src/util/doc.config b/src/util/doc.config
index cbee5438..e7cfa82d 100644
--- a/src/util/doc.config
+++ b/src/util/doc.config
@@ -33,8 +33,10 @@
"include/openssl/ecdh.h",
"include/openssl/ecdsa.h",
"include/openssl/engine.h",
+ "include/openssl/hkdf.h",
"include/openssl/hmac.h",
"include/openssl/md5.h",
+ "include/openssl/newhope.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 7d15d9ba..ace7a580 100644
--- a/src/util/doc.go
+++ b/src/util/doc.go
@@ -203,15 +203,28 @@ func getNameFromDecl(decl string) (string, bool) {
for strings.HasPrefix(decl, "#if") || strings.HasPrefix(decl, "#elif") {
decl = skipLine(decl)
}
- if strings.HasPrefix(decl, "struct ") {
+
+ if strings.HasPrefix(decl, "typedef ") {
return "", false
}
- if strings.HasPrefix(decl, "#define ") {
- // This is a preprocessor #define. The name is the next symbol.
- decl = strings.TrimPrefix(decl, "#define ")
+
+ for _, prefix := range []string{"struct ", "enum ", "#define "} {
+ if !strings.HasPrefix(decl, prefix) {
+ continue
+ }
+
+ decl = strings.TrimPrefix(decl, prefix)
+
for len(decl) > 0 && decl[0] == ' ' {
decl = decl[1:]
}
+
+ // struct and enum types can be the return type of a
+ // function.
+ if prefix[0] != '#' && strings.Index(decl, "{") == -1 {
+ break
+ }
+
i := strings.IndexAny(decl, "( ")
if i < 0 {
return "", false
diff --git a/src/util/generate-asm-lcov.py b/src/util/generate-asm-lcov.py
new file mode 100755
index 00000000..257ae841
--- /dev/null
+++ b/src/util/generate-asm-lcov.py
@@ -0,0 +1,152 @@
+#!/usr/bin/python
+# Copyright (c) 2016, 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.
+import os
+import os.path
+import subprocess
+import sys
+
+# The LCOV output format for each source file is:
+#
+# SF:<filename>
+# DA:<line>,<execution count>
+# ...
+# end_of_record
+#
+# The <execution count> can either be 0 for an unexecuted instruction or a
+# value representing the number of executions. The DA line should be omitted
+# for lines not representing an instruction.
+
+SECTION_SEPERATOR = '-' * 80
+
+def is_asm(l):
+ """Returns whether a line should be considered to be an instruction."""
+ l = l.strip()
+ # Empty lines
+ if l == '':
+ return False
+ # Comments
+ if l.startswith('#'):
+ return False
+ # Assembly Macros
+ if l.startswith('.'):
+ return False
+ # Label
+ if l.endswith(':'):
+ return False
+ return True
+
+def merge(callgrind_files, srcs):
+ """Calls callgrind_annotate over the set of callgrind output
+ |callgrind_files| using the sources |srcs| and merges the results
+ together."""
+ out = ''
+ for file in callgrind_files:
+ data = subprocess.check_output(['callgrind_annotate', file] + srcs)
+ out += '%s\n%s\n' % (data, SECTION_SEPERATOR)
+ return out
+
+def parse(filename, data, current):
+ """Parses an annotated execution flow |data| from callgrind_annotate for
+ source |filename| and updates the current execution counts from |current|."""
+ with open(filename) as f:
+ source = f.read().split('\n')
+
+ out = current
+ if out == None:
+ out = [0 if is_asm(l) else None for l in source]
+
+ # Lines are of the following formats:
+ # -- line: Indicates that analysis continues from a different place.
+ # Ir : Indicates the start of a file.
+ # => : Indicates a call/jump in the control flow.
+ # <Count> <Code>: Indicates that the line has been executed that many times.
+ line = None
+ for l in data:
+ l = l.strip() + ' '
+ if l.startswith('-- line'):
+ line = int(l.split(' ')[2]) - 1
+ elif l.strip() == 'Ir':
+ line = 0
+ elif line != None and l.strip() and '=>' not in l and 'unidentified lines' not in l:
+ count = l.split(' ')[0].replace(',', '').replace('.', '0')
+ instruction = l.split(' ', 1)[1].strip()
+ if count != '0' or is_asm(instruction):
+ if out[line] == None:
+ out[line] = 0
+ out[line] += int(count)
+ line += 1
+
+ return out
+
+
+def generate(data):
+ """Parses the merged callgrind_annotate output |data| and generates execution
+ counts for all annotated files."""
+ out = {}
+ data = [p.strip() for p in data.split(SECTION_SEPERATOR)]
+
+
+ # Most sections are ignored, but a section with:
+ # User-annotated source: <file>
+ # precedes a listing of execution count for that <file>.
+ for i in range(len(data)):
+ if 'User-annotated source' in data[i] and i < len(data) - 1:
+ filename = data[i].split(':', 1)[1].strip()
+ res = data[i + 1]
+ if filename not in out:
+ out[filename] = None
+ if 'No information' in res:
+ res = []
+ else:
+ res = res.split('\n')
+ out[filename] = parse(filename, res, out[filename])
+ return out
+
+def output(data):
+ """Takes a dictionary |data| of filenames and execution counts and generates
+ a LCOV coverage output."""
+ out = ''
+ for filename, counts in data.iteritems():
+ out += 'SF:%s\n' % (os.path.abspath(filename))
+ for line, count in enumerate(counts):
+ if count != None:
+ out += 'DA:%d,%s\n' % (line + 1, count)
+ out += 'end_of_record\n'
+ return out
+
+if __name__ == '__main__':
+ if len(sys.argv) != 3:
+ print '%s <Callgrind Folder> <Build Folder>' % (__file__)
+ sys.exit()
+
+ cg_folder = sys.argv[1]
+ build_folder = sys.argv[2]
+
+ cg_files = []
+ for (cwd, _, files) in os.walk(cg_folder):
+ for f in files:
+ if f.startswith('callgrind.out'):
+ cg_files.append(os.path.abspath(os.path.join(cwd, f)))
+
+ srcs = []
+ for (cwd, _, files) in os.walk(build_folder):
+ for f in files:
+ fn = os.path.join(cwd, f)
+ if fn.endswith('.S'):
+ srcs.append(fn)
+
+ annotated = merge(cg_files, srcs)
+ lcov = generate(annotated)
+ print output(lcov)
diff --git a/src/util/generate-coverage.sh b/src/util/generate-coverage.sh
new file mode 100755
index 00000000..2fbe6b83
--- /dev/null
+++ b/src/util/generate-coverage.sh
@@ -0,0 +1,60 @@
+#!/bin/sh
+# Copyright (c) 2016, 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.
+
+set -xe
+
+SRC=$PWD
+
+BUILD=$(mktemp -d '/tmp/boringssl.XXXXXX')
+BUILD_SRC=$(mktemp -d '/tmp/boringssl-src.XXXXXX')
+LCOV=$(mktemp -d '/tmp/boringssl-lcov.XXXXXX')
+
+if [ -n "$1" ]; then
+ LCOV=$(readlink -f "$1")
+ mkdir -p "$LCOV"
+fi
+
+cd "$BUILD"
+cmake "$SRC" -GNinja -DCMAKE_C_FLAGS='-fprofile-arcs -ftest-coverage' \
+ -DCMAKE_CXX_FLAGS='-fprofile-arcs -ftest-coverage' -DCMAKE_ASM_FLAGS='-Wa,-g'
+ninja
+
+cp -r "$SRC/crypto" "$SRC/decrepit" "$SRC/include" "$SRC/ssl" "$SRC/tool" \
+ "$BUILD_SRC"
+cp -r "$BUILD"/* "$BUILD_SRC"
+mkdir "$BUILD/callgrind/"
+
+cd "$SRC"
+go run "$SRC/util/all_tests.go" -build-dir "$BUILD" -callgrind -num-workers 16
+util/generate-asm-lcov.py "$BUILD/callgrind" "$BUILD" > "$BUILD/asm.info"
+
+go run "util/all_tests.go" -build-dir "$BUILD"
+
+cd "$SRC/ssl/test/runner"
+go test -shim-path "$BUILD/ssl/test/bssl_shim" -num-workers 1
+
+cd "$LCOV"
+lcov -c -d "$BUILD" -b "$BUILD" -o "$BUILD/lcov.info"
+lcov -r "$BUILD/lcov.info" "*_test.c" -o "$BUILD/lcov-1.info"
+lcov -r "$BUILD/lcov-1.info" "*_test.cc" -o "$BUILD/lcov-2.info"
+cat "$BUILD/lcov-2.info" "$BUILD/asm.info" > "$BUILD/final.info"
+sed -i "s;$BUILD;$BUILD_SRC;g" "$BUILD/final.info"
+sed -i "s;$SRC;$BUILD_SRC;g" "$BUILD/final.info"
+genhtml -p "$BUILD_SRC" "$BUILD/final.info"
+
+rm -rf "$BUILD"
+rm -rf "$BUILD_SRC"
+
+xdg-open index.html
diff --git a/src/util/generate_build_files.py b/src/util/generate_build_files.py
index 6321c5cb..a3721fe5 100644
--- a/src/util/generate_build_files.py
+++ b/src/util/generate_build_files.py
@@ -39,84 +39,15 @@ OS_ARCH_COMBOS = [
# perlasm system.
NON_PERL_FILES = {
('linux', 'arm'): [
- '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_64'): [
+ 'src/crypto/curve25519/asm/x25519-asm-x86_64.S',
+ ],
}
-class Chromium(object):
-
- def __init__(self):
- self.header = \
-"""# Copyright (c) 2014 The Chromium 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 file is created by generate_build_files.py. Do not edit manually.
-
-"""
-
- def PrintVariableSection(self, out, name, files):
- 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('boringssl.gypi', 'w+') as gypi:
- gypi.write(self.header + '{\n \'variables\': {\n')
-
- self.PrintVariableSection(
- 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' %
- (osname, arch), asm_files)
-
- gypi.write(' }\n}\n')
-
- with open('boringssl_tests.gypi', 'w+') as test_gypi:
- test_gypi.write(self.header + '{\n \'targets\': [\n')
-
- test_names = []
- for test in sorted(files['test']):
- test_name = 'boringssl_%s' % os.path.splitext(os.path.basename(test))[0]
- test_gypi.write(""" {
- 'target_name': '%s',
- 'type': 'executable',
- 'dependencies': [
- 'boringssl.gyp:boringssl',
- ],
- 'sources': [
- '%s',
- '<@(boringssl_test_support_sources)',
- ],
- # TODO(davidben): Fix size_t truncations in BoringSSL.
- # https://crbug.com/429039
- 'msvs_disabled_warnings': [ 4267, ],
- },\n""" % (test_name, test))
- test_names.append(test_name)
-
- test_names.sort()
-
- test_gypi.write(' ],\n \'variables\': {\n')
-
- self.PrintVariableSection(
- test_gypi, 'boringssl_test_support_sources', files['test_support'])
-
- test_gypi.write(' \'boringssl_test_targets\': [\n')
-
- for test in test_names:
- test_gypi.write(""" '%s',\n""" % test)
-
- test_gypi.write(' ],\n }\n}\n')
-
-
class Android(object):
def __init__(self):
@@ -283,6 +214,151 @@ class Bazel(object):
out.write(' )\n')
+class GN(object):
+
+ def __init__(self):
+ self.firstSection = True
+ self.header = \
+"""# Copyright (c) 2016 The Chromium 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 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.gni', 'w+') as out:
+ out.write(self.header)
+
+ self.PrintVariableSection(out, 'crypto_sources', files['crypto'])
+ self.PrintVariableSection(out, 'ssl_sources', files['ssl'])
+
+ for ((osname, arch), asm_files) in asm_outputs:
+ self.PrintVariableSection(
+ out, 'crypto_sources_%s_%s' % (osname, arch), asm_files)
+
+ fuzzers = [os.path.splitext(os.path.basename(fuzzer))[0]
+ for fuzzer in files['fuzz']]
+ self.PrintVariableSection(out, 'fuzzers', fuzzers)
+
+ with open('BUILD.generated_tests.gni', 'w+') as out:
+ self.firstSection = True
+ out.write(self.header)
+
+ self.PrintVariableSection(out, '_test_support_sources',
+ files['test_support'])
+ out.write('\n')
+
+ out.write('template("create_tests") {\n')
+
+ all_tests = []
+ for test in sorted(files['test']):
+ test_name = 'boringssl_%s' % os.path.splitext(os.path.basename(test))[0]
+ all_tests.append(test_name)
+
+ out.write(' executable("%s") {\n' % test_name)
+ out.write(' sources = [\n')
+ out.write(' "%s",\n' % test)
+ out.write(' ]\n')
+ out.write(' sources += _test_support_sources\n')
+ out.write(' if (defined(invoker.configs_exclude)) {\n')
+ out.write(' configs -= invoker.configs_exclude\n')
+ out.write(' }\n')
+ out.write(' configs += invoker.configs\n')
+ out.write(' deps = invoker.deps\n')
+ out.write(' }\n')
+ out.write('\n')
+
+ out.write(' group(target_name) {\n')
+ out.write(' deps = [\n')
+ for test_name in sorted(all_tests):
+ out.write(' ":%s",\n' % test_name)
+ out.write(' ]\n')
+ out.write(' }\n')
+ out.write('}\n')
+
+
+class GYP(object):
+
+ def __init__(self):
+ self.header = \
+"""# Copyright (c) 2016 The Chromium 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 file is created by generate_build_files.py. Do not edit manually.
+
+"""
+
+ def PrintVariableSection(self, out, name, files):
+ 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('boringssl.gypi', 'w+') as gypi:
+ gypi.write(self.header + '{\n \'variables\': {\n')
+
+ self.PrintVariableSection(
+ 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' %
+ (osname, arch), asm_files)
+
+ gypi.write(' }\n}\n')
+
+ with open('boringssl_tests.gypi', 'w+') as test_gypi:
+ test_gypi.write(self.header + '{\n \'targets\': [\n')
+
+ test_names = []
+ for test in sorted(files['test']):
+ test_name = 'boringssl_%s' % os.path.splitext(os.path.basename(test))[0]
+ test_gypi.write(""" {
+ 'target_name': '%s',
+ 'type': 'executable',
+ 'dependencies': [
+ 'boringssl.gyp:boringssl',
+ ],
+ 'sources': [
+ '%s',
+ '<@(boringssl_test_support_sources)',
+ ],
+ # TODO(davidben): Fix size_t truncations in BoringSSL.
+ # https://crbug.com/429039
+ 'msvs_disabled_warnings': [ 4267, ],
+ },\n""" % (test_name, test))
+ test_names.append(test_name)
+
+ test_names.sort()
+
+ test_gypi.write(' ],\n \'variables\': {\n')
+
+ self.PrintVariableSection(
+ test_gypi, 'boringssl_test_support_sources', files['test_support'])
+
+ test_gypi.write(' \'boringssl_test_targets\': [\n')
+
+ for test in sorted(test_names):
+ test_gypi.write(""" '%s',\n""" % test)
+
+ test_gypi.write(' ],\n }\n}\n')
+
+
def FindCMakeFiles(directory):
"""Returns list of all CMakeLists.txt files recursively in directory."""
cmakefiles = []
@@ -456,7 +532,7 @@ def WriteAsmFiles(perlasms):
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)
+ tool_c_files = FindCFiles(os.path.join('src', 'tool'), NoTests)
# Generate err_data.c
with open('err_data.c', 'w+') as err_data:
@@ -465,12 +541,14 @@ def main(platforms):
stdout=err_data)
crypto_c_files.append('err_data.c')
- test_support_cc_files = FindCFiles(os.path.join('src', 'crypto', 'test'),
- AllFiles)
+ test_support_c_files = FindCFiles(os.path.join('src', 'crypto', 'test'),
+ AllFiles)
test_c_files = FindCFiles(os.path.join('src', 'crypto'), OnlyTests)
test_c_files += FindCFiles(os.path.join('src', 'ssl'), OnlyTests)
+ fuzz_c_files = FindCFiles(os.path.join('src', 'fuzz'), NoTests)
+
ssl_h_files = (
FindHeaderFiles(
os.path.join('src', 'include', 'openssl'),
@@ -489,6 +567,8 @@ def main(platforms):
with open('src/util/all_tests.json', 'r') as f:
tests = json.load(f)
+ # Skip tests for libdecrepit. Consumers import that manually.
+ tests = [test for test in tests if not test[0].startswith("decrepit/")]
test_binaries = set([test[0] for test in tests])
test_sources = set([
test.replace('.cc', '').replace('.c', '').replace(
@@ -508,12 +588,13 @@ def main(platforms):
'crypto': crypto_c_files,
'crypto_headers': crypto_h_files,
'crypto_internal_headers': crypto_internal_h_files,
+ 'fuzz': fuzz_c_files,
'ssl': ssl_c_files,
'ssl_headers': ssl_h_files,
'ssl_internal_headers': ssl_internal_h_files,
- 'tool': tool_cc_files,
+ 'tool': tool_c_files,
'test': test_c_files,
- 'test_support': test_support_cc_files,
+ 'test_support': test_support_c_files,
'tests': tests,
}
@@ -526,7 +607,7 @@ def main(platforms):
def Usage():
- print 'Usage: python %s [chromium|android|android-standalone|bazel]' % sys.argv[0]
+ print 'Usage: python %s [android|android-standalone|bazel|gn|gyp]' % sys.argv[0]
sys.exit(1)
@@ -536,14 +617,16 @@ if __name__ == '__main__':
platforms = []
for s in sys.argv[1:]:
- if s == 'chromium' or s == 'gyp':
- platforms.append(Chromium())
- elif s == 'android':
+ if s == 'android':
platforms.append(Android())
elif s == 'android-standalone':
platforms.append(AndroidStandalone())
elif s == 'bazel':
platforms.append(Bazel())
+ elif s == 'gn':
+ platforms.append(GN())
+ elif s == 'gyp':
+ platforms.append(GYP())
else:
Usage()
diff --git a/src/util/run_android_tests.go b/src/util/run_android_tests.go
new file mode 100644
index 00000000..b0a388f7
--- /dev/null
+++ b/src/util/run_android_tests.go
@@ -0,0 +1,211 @@
+// Copyright (c) 2016, 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. */
+
+package main
+
+import (
+ "encoding/json"
+ "flag"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "strings"
+)
+
+var (
+ buildDir = flag.String("build-dir", "build", "Specifies the build directory to push.")
+ device = flag.String("device", "", "Specifies the device or emulator. See adb's -s argument.")
+ aarch64 = flag.Bool("aarch64", false, "Build the test runners for aarch64 instead of arm.")
+ arm = flag.Int("arm", 7, "Which arm revision to build for.")
+ allTestsArgs = flag.String("all-tests-args", "", "Specifies space-separated arguments to pass to all_tests.go")
+ runnerArgs = flag.String("runner-args", "", "Specifies space-separated arguments to pass to ssl/test/runner")
+)
+
+func adb(args ...string) error {
+ if len(*device) > 0 {
+ args = append([]string{"-s", *device}, args...)
+ }
+ cmd := exec.Command("adb", args...)
+ cmd.Stdout = os.Stdout
+ cmd.Stderr = os.Stderr
+ return cmd.Run()
+}
+
+func goTool(args ...string) error {
+ cmd := exec.Command("go", args...)
+ cmd.Stdout = os.Stdout
+ cmd.Stderr = os.Stderr
+
+ if *aarch64 {
+ cmd.Env = append(cmd.Env, "GOARCH=arm64")
+ } else {
+ cmd.Env = append(cmd.Env, "GOARCH=arm")
+ cmd.Env = append(cmd.Env, fmt.Sprintf("GOARM=%d", *arm))
+ }
+ return cmd.Run()
+}
+
+// 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!")
+}
+
+type test []string
+
+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 copyFile(dst, src string) error {
+ srcFile, err := os.Open(src)
+ if err != nil {
+ return err
+ }
+ defer srcFile.Close()
+
+ srcInfo, err := srcFile.Stat()
+ if err != nil {
+ return err
+ }
+
+ dir := filepath.Dir(dst)
+ if err := os.MkdirAll(dir, 0777); err != nil {
+ return err
+ }
+
+ dstFile, err := os.OpenFile(dst, os.O_CREATE|os.O_WRONLY, srcInfo.Mode())
+ if err != nil {
+ return err
+ }
+ defer dstFile.Close()
+
+ _, err = io.Copy(dstFile, srcFile)
+ return err
+}
+
+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)
+ }
+
+ // Clear the target directory.
+ if err := adb("shell", "rm -Rf /data/local/tmp/boringssl-tmp"); err != nil {
+ fmt.Printf("Failed to clear target directory: %s\n", err)
+ os.Exit(1)
+ }
+
+ // Stage everything in a temporary directory.
+ tmpDir, err := ioutil.TempDir("", "boringssl-android")
+ if err != nil {
+ fmt.Printf("Error making temporary directory: %s\n", err)
+ os.Exit(1)
+ }
+ defer os.RemoveAll(tmpDir)
+
+ seenBinary := make(map[string]struct{})
+ binaries := []string{"ssl/test/bssl_shim"}
+ files := []string{
+ "BUILDING.md",
+ "util/all_tests.json",
+ "ssl/test/runner/cert.pem",
+ "ssl/test/runner/channel_id_key.pem",
+ "ssl/test/runner/ecdsa_cert.pem",
+ "ssl/test/runner/ecdsa_key.pem",
+ "ssl/test/runner/key.pem",
+ }
+ for _, test := range tests {
+ if _, ok := seenBinary[test[0]]; !ok {
+ binaries = append(binaries, test[0])
+ seenBinary[test[0]] = struct{}{}
+ }
+ for _, arg := range test[1:] {
+ if strings.Contains(arg, "/") {
+ files = append(files, arg)
+ }
+ }
+ }
+
+ fmt.Printf("Copying test binaries...\n")
+ for _, binary := range binaries {
+ if err := copyFile(filepath.Join(tmpDir, "build", binary), filepath.Join(*buildDir, binary)); err != nil {
+ fmt.Printf("Failed to copy %s: %s\n", binary, err)
+ os.Exit(1)
+ }
+ }
+
+ fmt.Printf("Copying data files...\n")
+ for _, file := range files {
+ if err := copyFile(filepath.Join(tmpDir, file), file); err != nil {
+ fmt.Printf("Failed to copy %s: %s\n", file, err)
+ os.Exit(1)
+ }
+ }
+
+ fmt.Printf("Building all_tests...\n")
+ if err := goTool("build", "-o", filepath.Join(tmpDir, "util/all_tests"), "util/all_tests.go"); err != nil {
+ fmt.Printf("Error building all_tests.go: %s\n", err)
+ os.Exit(1)
+ }
+
+ fmt.Printf("Building runner...\n")
+ if err := goTool("test", "-c", "-o", filepath.Join(tmpDir, "ssl/test/runner/runner"), "./ssl/test/runner/"); err != nil {
+ fmt.Printf("Error building runner: %s\n", err)
+ os.Exit(1)
+ }
+
+ fmt.Printf("Uploading files...\n")
+ if err := adb("push", "-p", tmpDir, "/data/local/tmp/boringssl-tmp"); err != nil {
+ fmt.Printf("Failed to push runner: %s\n", err)
+ os.Exit(1)
+ }
+
+ fmt.Printf("Running unit tests...\n")
+ if err := adb("shell", fmt.Sprintf("cd /data/local/tmp/boringssl-tmp && ./util/all_tests %s", *allTestsArgs)); err != nil {
+ fmt.Printf("Failed to run unit tests: %s\n", err)
+ os.Exit(1)
+ }
+
+ fmt.Printf("Running SSL tests...\n")
+ if err := adb("shell", fmt.Sprintf("cd /data/local/tmp/boringssl-tmp/ssl/test/runner && ./runner %s", *runnerArgs)); err != nil {
+ fmt.Printf("Failed to run SSL tests: %s\n", err)
+ os.Exit(1)
+ }
+}
diff --git a/win-x86/crypto/chacha/chacha-x86.asm b/win-x86/crypto/chacha/chacha-x86.asm
new file mode 100644
index 00000000..283c8e4f
--- /dev/null
+++ b/win-x86/crypto/chacha/chacha-x86.asm
@@ -0,0 +1,997 @@
+%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 _ChaCha20_ctr32
+align 16
+_ChaCha20_ctr32:
+L$_ChaCha20_ctr32_begin:
+ push ebp
+ push ebx
+ push esi
+ push edi
+ xor eax,eax
+ cmp eax,DWORD [28+esp]
+ je NEAR L$000no_data
+ call L$pic_point
+L$pic_point:
+ pop eax
+ lea ebp,[_OPENSSL_ia32cap_P]
+ test DWORD [ebp],16777216
+ jz NEAR L$001x86
+ test DWORD [4+ebp],512
+ jz NEAR L$001x86
+ jmp NEAR L$ssse3_shortcut
+L$001x86:
+ mov esi,DWORD [32+esp]
+ mov edi,DWORD [36+esp]
+ sub esp,132
+ mov eax,DWORD [esi]
+ mov ebx,DWORD [4+esi]
+ mov ecx,DWORD [8+esi]
+ mov edx,DWORD [12+esi]
+ mov DWORD [80+esp],eax
+ mov DWORD [84+esp],ebx
+ mov DWORD [88+esp],ecx
+ mov DWORD [92+esp],edx
+ mov eax,DWORD [16+esi]
+ mov ebx,DWORD [20+esi]
+ mov ecx,DWORD [24+esi]
+ mov edx,DWORD [28+esi]
+ mov DWORD [96+esp],eax
+ mov DWORD [100+esp],ebx
+ mov DWORD [104+esp],ecx
+ mov DWORD [108+esp],edx
+ mov eax,DWORD [edi]
+ mov ebx,DWORD [4+edi]
+ mov ecx,DWORD [8+edi]
+ mov edx,DWORD [12+edi]
+ sub eax,1
+ mov DWORD [112+esp],eax
+ mov DWORD [116+esp],ebx
+ mov DWORD [120+esp],ecx
+ mov DWORD [124+esp],edx
+ jmp NEAR L$002entry
+align 16
+L$003outer_loop:
+ mov DWORD [156+esp],ebx
+ mov DWORD [152+esp],eax
+ mov DWORD [160+esp],ecx
+L$002entry:
+ mov eax,1634760805
+ mov DWORD [4+esp],857760878
+ mov DWORD [8+esp],2036477234
+ mov DWORD [12+esp],1797285236
+ mov ebx,DWORD [84+esp]
+ mov ebp,DWORD [88+esp]
+ mov ecx,DWORD [104+esp]
+ mov esi,DWORD [108+esp]
+ mov edx,DWORD [116+esp]
+ mov edi,DWORD [120+esp]
+ mov DWORD [20+esp],ebx
+ mov DWORD [24+esp],ebp
+ mov DWORD [40+esp],ecx
+ mov DWORD [44+esp],esi
+ mov DWORD [52+esp],edx
+ mov DWORD [56+esp],edi
+ mov ebx,DWORD [92+esp]
+ mov edi,DWORD [124+esp]
+ mov edx,DWORD [112+esp]
+ mov ebp,DWORD [80+esp]
+ mov ecx,DWORD [96+esp]
+ mov esi,DWORD [100+esp]
+ add edx,1
+ mov DWORD [28+esp],ebx
+ mov DWORD [60+esp],edi
+ mov DWORD [112+esp],edx
+ mov ebx,10
+ jmp NEAR L$004loop
+align 16
+L$004loop:
+ add eax,ebp
+ mov DWORD [128+esp],ebx
+ mov ebx,ebp
+ xor edx,eax
+ rol edx,16
+ add ecx,edx
+ xor ebx,ecx
+ mov edi,DWORD [52+esp]
+ rol ebx,12
+ mov ebp,DWORD [20+esp]
+ add eax,ebx
+ xor edx,eax
+ mov DWORD [esp],eax
+ rol edx,8
+ mov eax,DWORD [4+esp]
+ add ecx,edx
+ mov DWORD [48+esp],edx
+ xor ebx,ecx
+ add eax,ebp
+ rol ebx,7
+ xor edi,eax
+ mov DWORD [32+esp],ecx
+ rol edi,16
+ mov DWORD [16+esp],ebx
+ add esi,edi
+ mov ecx,DWORD [40+esp]
+ xor ebp,esi
+ mov edx,DWORD [56+esp]
+ rol ebp,12
+ mov ebx,DWORD [24+esp]
+ add eax,ebp
+ xor edi,eax
+ mov DWORD [4+esp],eax
+ rol edi,8
+ mov eax,DWORD [8+esp]
+ add esi,edi
+ mov DWORD [52+esp],edi
+ xor ebp,esi
+ add eax,ebx
+ rol ebp,7
+ xor edx,eax
+ mov DWORD [36+esp],esi
+ rol edx,16
+ mov DWORD [20+esp],ebp
+ add ecx,edx
+ mov esi,DWORD [44+esp]
+ xor ebx,ecx
+ mov edi,DWORD [60+esp]
+ rol ebx,12
+ mov ebp,DWORD [28+esp]
+ add eax,ebx
+ xor edx,eax
+ mov DWORD [8+esp],eax
+ rol edx,8
+ mov eax,DWORD [12+esp]
+ add ecx,edx
+ mov DWORD [56+esp],edx
+ xor ebx,ecx
+ add eax,ebp
+ rol ebx,7
+ xor edi,eax
+ rol edi,16
+ mov DWORD [24+esp],ebx
+ add esi,edi
+ xor ebp,esi
+ rol ebp,12
+ mov ebx,DWORD [20+esp]
+ add eax,ebp
+ xor edi,eax
+ mov DWORD [12+esp],eax
+ rol edi,8
+ mov eax,DWORD [esp]
+ add esi,edi
+ mov edx,edi
+ xor ebp,esi
+ add eax,ebx
+ rol ebp,7
+ xor edx,eax
+ rol edx,16
+ mov DWORD [28+esp],ebp
+ add ecx,edx
+ xor ebx,ecx
+ mov edi,DWORD [48+esp]
+ rol ebx,12
+ mov ebp,DWORD [24+esp]
+ add eax,ebx
+ xor edx,eax
+ mov DWORD [esp],eax
+ rol edx,8
+ mov eax,DWORD [4+esp]
+ add ecx,edx
+ mov DWORD [60+esp],edx
+ xor ebx,ecx
+ add eax,ebp
+ rol ebx,7
+ xor edi,eax
+ mov DWORD [40+esp],ecx
+ rol edi,16
+ mov DWORD [20+esp],ebx
+ add esi,edi
+ mov ecx,DWORD [32+esp]
+ xor ebp,esi
+ mov edx,DWORD [52+esp]
+ rol ebp,12
+ mov ebx,DWORD [28+esp]
+ add eax,ebp
+ xor edi,eax
+ mov DWORD [4+esp],eax
+ rol edi,8
+ mov eax,DWORD [8+esp]
+ add esi,edi
+ mov DWORD [48+esp],edi
+ xor ebp,esi
+ add eax,ebx
+ rol ebp,7
+ xor edx,eax
+ mov DWORD [44+esp],esi
+ rol edx,16
+ mov DWORD [24+esp],ebp
+ add ecx,edx
+ mov esi,DWORD [36+esp]
+ xor ebx,ecx
+ mov edi,DWORD [56+esp]
+ rol ebx,12
+ mov ebp,DWORD [16+esp]
+ add eax,ebx
+ xor edx,eax
+ mov DWORD [8+esp],eax
+ rol edx,8
+ mov eax,DWORD [12+esp]
+ add ecx,edx
+ mov DWORD [52+esp],edx
+ xor ebx,ecx
+ add eax,ebp
+ rol ebx,7
+ xor edi,eax
+ rol edi,16
+ mov DWORD [28+esp],ebx
+ add esi,edi
+ xor ebp,esi
+ mov edx,DWORD [48+esp]
+ rol ebp,12
+ mov ebx,DWORD [128+esp]
+ add eax,ebp
+ xor edi,eax
+ mov DWORD [12+esp],eax
+ rol edi,8
+ mov eax,DWORD [esp]
+ add esi,edi
+ mov DWORD [56+esp],edi
+ xor ebp,esi
+ rol ebp,7
+ dec ebx
+ jnz NEAR L$004loop
+ mov ebx,DWORD [160+esp]
+ add eax,1634760805
+ add ebp,DWORD [80+esp]
+ add ecx,DWORD [96+esp]
+ add esi,DWORD [100+esp]
+ cmp ebx,64
+ jb NEAR L$005tail
+ mov ebx,DWORD [156+esp]
+ add edx,DWORD [112+esp]
+ add edi,DWORD [120+esp]
+ xor eax,DWORD [ebx]
+ xor ebp,DWORD [16+ebx]
+ mov DWORD [esp],eax
+ mov eax,DWORD [152+esp]
+ xor ecx,DWORD [32+ebx]
+ xor esi,DWORD [36+ebx]
+ xor edx,DWORD [48+ebx]
+ xor edi,DWORD [56+ebx]
+ mov DWORD [16+esp],ebp
+ mov ebp,DWORD [esp]
+ mov DWORD [32+esp],ecx
+ mov DWORD [36+esp],esi
+ mov DWORD [48+esp],edx
+ mov DWORD [56+esp],edi
+ mov DWORD [eax],ebp
+ mov ebp,DWORD [4+esp]
+ mov ecx,DWORD [8+esp]
+ mov esi,DWORD [12+esp]
+ mov edx,DWORD [20+esp]
+ mov edi,DWORD [24+esp]
+ add ebp,857760878
+ add ecx,2036477234
+ add esi,1797285236
+ add edx,DWORD [84+esp]
+ add edi,DWORD [88+esp]
+ xor ebp,DWORD [4+ebx]
+ xor ecx,DWORD [8+ebx]
+ xor esi,DWORD [12+ebx]
+ xor edx,DWORD [20+ebx]
+ xor edi,DWORD [24+ebx]
+ mov DWORD [4+eax],ebp
+ mov ebp,DWORD [16+esp]
+ mov DWORD [8+eax],ecx
+ mov DWORD [12+eax],esi
+ mov DWORD [16+eax],ebp
+ mov DWORD [20+eax],edx
+ mov DWORD [24+eax],edi
+ mov ecx,DWORD [28+esp]
+ mov edx,DWORD [32+esp]
+ mov edi,DWORD [36+esp]
+ add ecx,DWORD [92+esp]
+ mov ebp,DWORD [40+esp]
+ xor ecx,DWORD [28+ebx]
+ mov esi,DWORD [44+esp]
+ mov DWORD [28+eax],ecx
+ mov DWORD [32+eax],edx
+ mov DWORD [36+eax],edi
+ add ebp,DWORD [104+esp]
+ add esi,DWORD [108+esp]
+ xor ebp,DWORD [40+ebx]
+ xor esi,DWORD [44+ebx]
+ mov DWORD [40+eax],ebp
+ mov DWORD [44+eax],esi
+ mov ecx,DWORD [48+esp]
+ mov esi,DWORD [56+esp]
+ mov edx,DWORD [52+esp]
+ mov edi,DWORD [60+esp]
+ add edx,DWORD [116+esp]
+ add edi,DWORD [124+esp]
+ xor edx,DWORD [52+ebx]
+ xor edi,DWORD [60+ebx]
+ lea ebx,[64+ebx]
+ mov DWORD [48+eax],ecx
+ mov ecx,DWORD [160+esp]
+ mov DWORD [52+eax],edx
+ mov DWORD [56+eax],esi
+ mov DWORD [60+eax],edi
+ lea eax,[64+eax]
+ sub ecx,64
+ jnz NEAR L$003outer_loop
+ jmp NEAR L$006done
+L$005tail:
+ add edx,DWORD [112+esp]
+ add edi,DWORD [120+esp]
+ mov DWORD [esp],eax
+ mov DWORD [16+esp],ebp
+ mov DWORD [32+esp],ecx
+ mov DWORD [36+esp],esi
+ mov DWORD [48+esp],edx
+ mov DWORD [56+esp],edi
+ mov ebp,DWORD [4+esp]
+ mov ecx,DWORD [8+esp]
+ mov esi,DWORD [12+esp]
+ mov edx,DWORD [20+esp]
+ mov edi,DWORD [24+esp]
+ add ebp,857760878
+ add ecx,2036477234
+ add esi,1797285236
+ add edx,DWORD [84+esp]
+ add edi,DWORD [88+esp]
+ mov DWORD [4+esp],ebp
+ mov DWORD [8+esp],ecx
+ mov DWORD [12+esp],esi
+ mov DWORD [20+esp],edx
+ mov DWORD [24+esp],edi
+ mov ebp,DWORD [28+esp]
+ mov ecx,DWORD [40+esp]
+ mov esi,DWORD [44+esp]
+ mov edx,DWORD [52+esp]
+ mov edi,DWORD [60+esp]
+ add ebp,DWORD [92+esp]
+ add ecx,DWORD [104+esp]
+ add esi,DWORD [108+esp]
+ add edx,DWORD [116+esp]
+ add edi,DWORD [124+esp]
+ mov DWORD [28+esp],ebp
+ mov ebp,DWORD [156+esp]
+ mov DWORD [40+esp],ecx
+ mov ecx,DWORD [152+esp]
+ mov DWORD [44+esp],esi
+ xor esi,esi
+ mov DWORD [52+esp],edx
+ mov DWORD [60+esp],edi
+ xor eax,eax
+ xor edx,edx
+L$007tail_loop:
+ mov al,BYTE [ebp*1+esi]
+ mov dl,BYTE [esi*1+esp]
+ lea esi,[1+esi]
+ xor al,dl
+ mov BYTE [esi*1+ecx-1],al
+ dec ebx
+ jnz NEAR L$007tail_loop
+L$006done:
+ add esp,132
+L$000no_data:
+ pop edi
+ pop esi
+ pop ebx
+ pop ebp
+ ret
+global _ChaCha20_ssse3
+align 16
+_ChaCha20_ssse3:
+L$_ChaCha20_ssse3_begin:
+ push ebp
+ push ebx
+ push esi
+ push edi
+L$ssse3_shortcut:
+ mov edi,DWORD [20+esp]
+ mov esi,DWORD [24+esp]
+ mov ecx,DWORD [28+esp]
+ mov edx,DWORD [32+esp]
+ mov ebx,DWORD [36+esp]
+ mov ebp,esp
+ sub esp,524
+ and esp,-64
+ mov DWORD [512+esp],ebp
+ lea eax,[(L$ssse3_data-L$pic_point)+eax]
+ movdqu xmm3,[ebx]
+ cmp ecx,256
+ jb NEAR L$0081x
+ mov DWORD [516+esp],edx
+ mov DWORD [520+esp],ebx
+ sub ecx,256
+ lea ebp,[384+esp]
+ movdqu xmm7,[edx]
+ pshufd xmm0,xmm3,0
+ pshufd xmm1,xmm3,85
+ pshufd xmm2,xmm3,170
+ pshufd xmm3,xmm3,255
+ paddd xmm0,[48+eax]
+ pshufd xmm4,xmm7,0
+ pshufd xmm5,xmm7,85
+ psubd xmm0,[64+eax]
+ pshufd xmm6,xmm7,170
+ pshufd xmm7,xmm7,255
+ movdqa [64+ebp],xmm0
+ movdqa [80+ebp],xmm1
+ movdqa [96+ebp],xmm2
+ movdqa [112+ebp],xmm3
+ movdqu xmm3,[16+edx]
+ movdqa [ebp-64],xmm4
+ movdqa [ebp-48],xmm5
+ movdqa [ebp-32],xmm6
+ movdqa [ebp-16],xmm7
+ movdqa xmm7,[32+eax]
+ lea ebx,[128+esp]
+ pshufd xmm0,xmm3,0
+ pshufd xmm1,xmm3,85
+ pshufd xmm2,xmm3,170
+ pshufd xmm3,xmm3,255
+ pshufd xmm4,xmm7,0
+ pshufd xmm5,xmm7,85
+ pshufd xmm6,xmm7,170
+ pshufd xmm7,xmm7,255
+ movdqa [ebp],xmm0
+ movdqa [16+ebp],xmm1
+ movdqa [32+ebp],xmm2
+ movdqa [48+ebp],xmm3
+ movdqa [ebp-128],xmm4
+ movdqa [ebp-112],xmm5
+ movdqa [ebp-96],xmm6
+ movdqa [ebp-80],xmm7
+ lea esi,[128+esi]
+ lea edi,[128+edi]
+ jmp NEAR L$009outer_loop
+align 16
+L$009outer_loop:
+ movdqa xmm1,[ebp-112]
+ movdqa xmm2,[ebp-96]
+ movdqa xmm3,[ebp-80]
+ movdqa xmm5,[ebp-48]
+ movdqa xmm6,[ebp-32]
+ movdqa xmm7,[ebp-16]
+ movdqa [ebx-112],xmm1
+ movdqa [ebx-96],xmm2
+ movdqa [ebx-80],xmm3
+ movdqa [ebx-48],xmm5
+ movdqa [ebx-32],xmm6
+ movdqa [ebx-16],xmm7
+ movdqa xmm2,[32+ebp]
+ movdqa xmm3,[48+ebp]
+ movdqa xmm4,[64+ebp]
+ movdqa xmm5,[80+ebp]
+ movdqa xmm6,[96+ebp]
+ movdqa xmm7,[112+ebp]
+ paddd xmm4,[64+eax]
+ movdqa [32+ebx],xmm2
+ movdqa [48+ebx],xmm3
+ movdqa [64+ebx],xmm4
+ movdqa [80+ebx],xmm5
+ movdqa [96+ebx],xmm6
+ movdqa [112+ebx],xmm7
+ movdqa [64+ebp],xmm4
+ movdqa xmm0,[ebp-128]
+ movdqa xmm6,xmm4
+ movdqa xmm3,[ebp-64]
+ movdqa xmm4,[ebp]
+ movdqa xmm5,[16+ebp]
+ mov edx,10
+ nop
+align 16
+L$010loop:
+ paddd xmm0,xmm3
+ movdqa xmm2,xmm3
+ pxor xmm6,xmm0
+ pshufb xmm6,[eax]
+ paddd xmm4,xmm6
+ pxor xmm2,xmm4
+ movdqa xmm3,[ebx-48]
+ movdqa xmm1,xmm2
+ pslld xmm2,12
+ psrld xmm1,20
+ por xmm2,xmm1
+ movdqa xmm1,[ebx-112]
+ paddd xmm0,xmm2
+ movdqa xmm7,[80+ebx]
+ pxor xmm6,xmm0
+ movdqa [ebx-128],xmm0
+ pshufb xmm6,[16+eax]
+ paddd xmm4,xmm6
+ movdqa [64+ebx],xmm6
+ pxor xmm2,xmm4
+ paddd xmm1,xmm3
+ movdqa xmm0,xmm2
+ pslld xmm2,7
+ psrld xmm0,25
+ pxor xmm7,xmm1
+ por xmm2,xmm0
+ movdqa [ebx],xmm4
+ pshufb xmm7,[eax]
+ movdqa [ebx-64],xmm2
+ paddd xmm5,xmm7
+ movdqa xmm4,[32+ebx]
+ pxor xmm3,xmm5
+ movdqa xmm2,[ebx-32]
+ movdqa xmm0,xmm3
+ pslld xmm3,12
+ psrld xmm0,20
+ por xmm3,xmm0
+ movdqa xmm0,[ebx-96]
+ paddd xmm1,xmm3
+ movdqa xmm6,[96+ebx]
+ pxor xmm7,xmm1
+ movdqa [ebx-112],xmm1
+ pshufb xmm7,[16+eax]
+ paddd xmm5,xmm7
+ movdqa [80+ebx],xmm7
+ pxor xmm3,xmm5
+ paddd xmm0,xmm2
+ movdqa xmm1,xmm3
+ pslld xmm3,7
+ psrld xmm1,25
+ pxor xmm6,xmm0
+ por xmm3,xmm1
+ movdqa [16+ebx],xmm5
+ pshufb xmm6,[eax]
+ movdqa [ebx-48],xmm3
+ paddd xmm4,xmm6
+ movdqa xmm5,[48+ebx]
+ pxor xmm2,xmm4
+ movdqa xmm3,[ebx-16]
+ movdqa xmm1,xmm2
+ pslld xmm2,12
+ psrld xmm1,20
+ por xmm2,xmm1
+ movdqa xmm1,[ebx-80]
+ paddd xmm0,xmm2
+ movdqa xmm7,[112+ebx]
+ pxor xmm6,xmm0
+ movdqa [ebx-96],xmm0
+ pshufb xmm6,[16+eax]
+ paddd xmm4,xmm6
+ movdqa [96+ebx],xmm6
+ pxor xmm2,xmm4
+ paddd xmm1,xmm3
+ movdqa xmm0,xmm2
+ pslld xmm2,7
+ psrld xmm0,25
+ pxor xmm7,xmm1
+ por xmm2,xmm0
+ pshufb xmm7,[eax]
+ movdqa [ebx-32],xmm2
+ paddd xmm5,xmm7
+ pxor xmm3,xmm5
+ movdqa xmm2,[ebx-48]
+ movdqa xmm0,xmm3
+ pslld xmm3,12
+ psrld xmm0,20
+ por xmm3,xmm0
+ movdqa xmm0,[ebx-128]
+ paddd xmm1,xmm3
+ pxor xmm7,xmm1
+ movdqa [ebx-80],xmm1
+ pshufb xmm7,[16+eax]
+ paddd xmm5,xmm7
+ movdqa xmm6,xmm7
+ pxor xmm3,xmm5
+ paddd xmm0,xmm2
+ movdqa xmm1,xmm3
+ pslld xmm3,7
+ psrld xmm1,25
+ pxor xmm6,xmm0
+ por xmm3,xmm1
+ pshufb xmm6,[eax]
+ movdqa [ebx-16],xmm3
+ paddd xmm4,xmm6
+ pxor xmm2,xmm4
+ movdqa xmm3,[ebx-32]
+ movdqa xmm1,xmm2
+ pslld xmm2,12
+ psrld xmm1,20
+ por xmm2,xmm1
+ movdqa xmm1,[ebx-112]
+ paddd xmm0,xmm2
+ movdqa xmm7,[64+ebx]
+ pxor xmm6,xmm0
+ movdqa [ebx-128],xmm0
+ pshufb xmm6,[16+eax]
+ paddd xmm4,xmm6
+ movdqa [112+ebx],xmm6
+ pxor xmm2,xmm4
+ paddd xmm1,xmm3
+ movdqa xmm0,xmm2
+ pslld xmm2,7
+ psrld xmm0,25
+ pxor xmm7,xmm1
+ por xmm2,xmm0
+ movdqa [32+ebx],xmm4
+ pshufb xmm7,[eax]
+ movdqa [ebx-48],xmm2
+ paddd xmm5,xmm7
+ movdqa xmm4,[ebx]
+ pxor xmm3,xmm5
+ movdqa xmm2,[ebx-16]
+ movdqa xmm0,xmm3
+ pslld xmm3,12
+ psrld xmm0,20
+ por xmm3,xmm0
+ movdqa xmm0,[ebx-96]
+ paddd xmm1,xmm3
+ movdqa xmm6,[80+ebx]
+ pxor xmm7,xmm1
+ movdqa [ebx-112],xmm1
+ pshufb xmm7,[16+eax]
+ paddd xmm5,xmm7
+ movdqa [64+ebx],xmm7
+ pxor xmm3,xmm5
+ paddd xmm0,xmm2
+ movdqa xmm1,xmm3
+ pslld xmm3,7
+ psrld xmm1,25
+ pxor xmm6,xmm0
+ por xmm3,xmm1
+ movdqa [48+ebx],xmm5
+ pshufb xmm6,[eax]
+ movdqa [ebx-32],xmm3
+ paddd xmm4,xmm6
+ movdqa xmm5,[16+ebx]
+ pxor xmm2,xmm4
+ movdqa xmm3,[ebx-64]
+ movdqa xmm1,xmm2
+ pslld xmm2,12
+ psrld xmm1,20
+ por xmm2,xmm1
+ movdqa xmm1,[ebx-80]
+ paddd xmm0,xmm2
+ movdqa xmm7,[96+ebx]
+ pxor xmm6,xmm0
+ movdqa [ebx-96],xmm0
+ pshufb xmm6,[16+eax]
+ paddd xmm4,xmm6
+ movdqa [80+ebx],xmm6
+ pxor xmm2,xmm4
+ paddd xmm1,xmm3
+ movdqa xmm0,xmm2
+ pslld xmm2,7
+ psrld xmm0,25
+ pxor xmm7,xmm1
+ por xmm2,xmm0
+ pshufb xmm7,[eax]
+ movdqa [ebx-16],xmm2
+ paddd xmm5,xmm7
+ pxor xmm3,xmm5
+ movdqa xmm0,xmm3
+ pslld xmm3,12
+ psrld xmm0,20
+ por xmm3,xmm0
+ movdqa xmm0,[ebx-128]
+ paddd xmm1,xmm3
+ movdqa xmm6,[64+ebx]
+ pxor xmm7,xmm1
+ movdqa [ebx-80],xmm1
+ pshufb xmm7,[16+eax]
+ paddd xmm5,xmm7
+ movdqa [96+ebx],xmm7
+ pxor xmm3,xmm5
+ movdqa xmm1,xmm3
+ pslld xmm3,7
+ psrld xmm1,25
+ por xmm3,xmm1
+ dec edx
+ jnz NEAR L$010loop
+ movdqa [ebx-64],xmm3
+ movdqa [ebx],xmm4
+ movdqa [16+ebx],xmm5
+ movdqa [64+ebx],xmm6
+ movdqa [96+ebx],xmm7
+ movdqa xmm1,[ebx-112]
+ movdqa xmm2,[ebx-96]
+ movdqa xmm3,[ebx-80]
+ paddd xmm0,[ebp-128]
+ paddd xmm1,[ebp-112]
+ paddd xmm2,[ebp-96]
+ paddd xmm3,[ebp-80]
+ movdqa xmm6,xmm0
+ punpckldq xmm0,xmm1
+ movdqa xmm7,xmm2
+ punpckldq xmm2,xmm3
+ punpckhdq xmm6,xmm1
+ punpckhdq xmm7,xmm3
+ movdqa xmm1,xmm0
+ punpcklqdq xmm0,xmm2
+ movdqa xmm3,xmm6
+ punpcklqdq xmm6,xmm7
+ punpckhqdq xmm1,xmm2
+ punpckhqdq xmm3,xmm7
+ movdqa [ebx-128],xmm0
+ movdqa xmm0,[ebx-64]
+ movdqa [ebx-112],xmm1
+ movdqa [ebx-96],xmm6
+ movdqa [ebx-80],xmm3
+ movdqa xmm1,[ebx-48]
+ movdqa xmm2,[ebx-32]
+ movdqa xmm3,[ebx-16]
+ paddd xmm0,[ebp-64]
+ paddd xmm1,[ebp-48]
+ paddd xmm2,[ebp-32]
+ paddd xmm3,[ebp-16]
+ movdqa xmm6,xmm0
+ punpckldq xmm0,xmm1
+ movdqa xmm7,xmm2
+ punpckldq xmm2,xmm3
+ punpckhdq xmm6,xmm1
+ punpckhdq xmm7,xmm3
+ movdqa xmm1,xmm0
+ punpcklqdq xmm0,xmm2
+ movdqa xmm3,xmm6
+ punpcklqdq xmm6,xmm7
+ punpckhqdq xmm1,xmm2
+ punpckhqdq xmm3,xmm7
+ movdqa [ebx-64],xmm0
+ movdqa xmm0,[ebx]
+ movdqa [ebx-48],xmm1
+ movdqa [ebx-32],xmm6
+ movdqa [ebx-16],xmm3
+ movdqa xmm1,[16+ebx]
+ movdqa xmm2,[32+ebx]
+ movdqa xmm3,[48+ebx]
+ paddd xmm0,[ebp]
+ paddd xmm1,[16+ebp]
+ paddd xmm2,[32+ebp]
+ paddd xmm3,[48+ebp]
+ movdqa xmm6,xmm0
+ punpckldq xmm0,xmm1
+ movdqa xmm7,xmm2
+ punpckldq xmm2,xmm3
+ punpckhdq xmm6,xmm1
+ punpckhdq xmm7,xmm3
+ movdqa xmm1,xmm0
+ punpcklqdq xmm0,xmm2
+ movdqa xmm3,xmm6
+ punpcklqdq xmm6,xmm7
+ punpckhqdq xmm1,xmm2
+ punpckhqdq xmm3,xmm7
+ movdqa [ebx],xmm0
+ movdqa xmm0,[64+ebx]
+ movdqa [16+ebx],xmm1
+ movdqa [32+ebx],xmm6
+ movdqa [48+ebx],xmm3
+ movdqa xmm1,[80+ebx]
+ movdqa xmm2,[96+ebx]
+ movdqa xmm3,[112+ebx]
+ paddd xmm0,[64+ebp]
+ paddd xmm1,[80+ebp]
+ paddd xmm2,[96+ebp]
+ paddd xmm3,[112+ebp]
+ movdqa xmm6,xmm0
+ punpckldq xmm0,xmm1
+ movdqa xmm7,xmm2
+ punpckldq xmm2,xmm3
+ punpckhdq xmm6,xmm1
+ punpckhdq xmm7,xmm3
+ movdqa xmm1,xmm0
+ punpcklqdq xmm0,xmm2
+ movdqa xmm3,xmm6
+ punpcklqdq xmm6,xmm7
+ punpckhqdq xmm1,xmm2
+ punpckhqdq xmm3,xmm7
+ movdqa [64+ebx],xmm0
+ movdqa [80+ebx],xmm1
+ movdqa [96+ebx],xmm6
+ movdqa [112+ebx],xmm3
+ movdqu xmm0,[esi-128]
+ movdqu xmm1,[esi-112]
+ movdqu xmm2,[esi-96]
+ movdqu xmm3,[esi-80]
+ pxor xmm0,[ebx-128]
+ pxor xmm1,[ebx-64]
+ pxor xmm2,[ebx]
+ pxor xmm3,[64+ebx]
+ movdqu [edi-128],xmm0
+ movdqu [edi-112],xmm1
+ movdqu [edi-96],xmm2
+ movdqu [edi-80],xmm3
+ movdqu xmm0,[esi-64]
+ movdqu xmm1,[esi-48]
+ movdqu xmm2,[esi-32]
+ movdqu xmm3,[esi-16]
+ pxor xmm0,[ebx-112]
+ pxor xmm1,[ebx-48]
+ pxor xmm2,[16+ebx]
+ pxor xmm3,[80+ebx]
+ movdqu [edi-64],xmm0
+ movdqu [edi-48],xmm1
+ movdqu [edi-32],xmm2
+ movdqu [edi-16],xmm3
+ movdqu xmm0,[esi]
+ movdqu xmm1,[16+esi]
+ movdqu xmm2,[32+esi]
+ movdqu xmm3,[48+esi]
+ pxor xmm0,[ebx-96]
+ pxor xmm1,[ebx-32]
+ pxor xmm2,[32+ebx]
+ pxor xmm3,[96+ebx]
+ movdqu [edi],xmm0
+ movdqu [16+edi],xmm1
+ movdqu [32+edi],xmm2
+ movdqu [48+edi],xmm3
+ movdqu xmm0,[64+esi]
+ movdqu xmm1,[80+esi]
+ movdqu xmm2,[96+esi]
+ movdqu xmm3,[112+esi]
+ pxor xmm0,[ebx-80]
+ pxor xmm1,[ebx-16]
+ pxor xmm2,[48+ebx]
+ pxor xmm3,[112+ebx]
+ movdqu [64+edi],xmm0
+ movdqu [80+edi],xmm1
+ movdqu [96+edi],xmm2
+ movdqu [112+edi],xmm3
+ lea esi,[256+esi]
+ lea edi,[256+edi]
+ sub ecx,256
+ jnc NEAR L$009outer_loop
+ add ecx,256
+ jz NEAR L$011done
+ mov ebx,DWORD [520+esp]
+ lea esi,[esi-128]
+ mov edx,DWORD [516+esp]
+ lea edi,[edi-128]
+ movd xmm2,DWORD [64+ebp]
+ movdqu xmm3,[ebx]
+ paddd xmm2,[96+eax]
+ pand xmm3,[112+eax]
+ por xmm3,xmm2
+L$0081x:
+ movdqa xmm0,[32+eax]
+ movdqu xmm1,[edx]
+ movdqu xmm2,[16+edx]
+ movdqa xmm6,[eax]
+ movdqa xmm7,[16+eax]
+ mov DWORD [48+esp],ebp
+ movdqa [esp],xmm0
+ movdqa [16+esp],xmm1
+ movdqa [32+esp],xmm2
+ movdqa [48+esp],xmm3
+ mov edx,10
+ jmp NEAR L$012loop1x
+align 16
+L$013outer1x:
+ movdqa xmm3,[80+eax]
+ movdqa xmm0,[esp]
+ movdqa xmm1,[16+esp]
+ movdqa xmm2,[32+esp]
+ paddd xmm3,[48+esp]
+ mov edx,10
+ movdqa [48+esp],xmm3
+ jmp NEAR L$012loop1x
+align 16
+L$012loop1x:
+ paddd xmm0,xmm1
+ pxor xmm3,xmm0
+db 102,15,56,0,222
+ paddd xmm2,xmm3
+ pxor xmm1,xmm2
+ movdqa xmm4,xmm1
+ psrld xmm1,20
+ pslld xmm4,12
+ por xmm1,xmm4
+ paddd xmm0,xmm1
+ pxor xmm3,xmm0
+db 102,15,56,0,223
+ paddd xmm2,xmm3
+ pxor xmm1,xmm2
+ movdqa xmm4,xmm1
+ psrld xmm1,25
+ pslld xmm4,7
+ por xmm1,xmm4
+ pshufd xmm2,xmm2,78
+ pshufd xmm1,xmm1,57
+ pshufd xmm3,xmm3,147
+ nop
+ paddd xmm0,xmm1
+ pxor xmm3,xmm0
+db 102,15,56,0,222
+ paddd xmm2,xmm3
+ pxor xmm1,xmm2
+ movdqa xmm4,xmm1
+ psrld xmm1,20
+ pslld xmm4,12
+ por xmm1,xmm4
+ paddd xmm0,xmm1
+ pxor xmm3,xmm0
+db 102,15,56,0,223
+ paddd xmm2,xmm3
+ pxor xmm1,xmm2
+ movdqa xmm4,xmm1
+ psrld xmm1,25
+ pslld xmm4,7
+ por xmm1,xmm4
+ pshufd xmm2,xmm2,78
+ pshufd xmm1,xmm1,147
+ pshufd xmm3,xmm3,57
+ dec edx
+ jnz NEAR L$012loop1x
+ paddd xmm0,[esp]
+ paddd xmm1,[16+esp]
+ paddd xmm2,[32+esp]
+ paddd xmm3,[48+esp]
+ cmp ecx,64
+ jb NEAR L$014tail
+ movdqu xmm4,[esi]
+ movdqu xmm5,[16+esi]
+ pxor xmm0,xmm4
+ movdqu xmm4,[32+esi]
+ pxor xmm1,xmm5
+ movdqu xmm5,[48+esi]
+ pxor xmm2,xmm4
+ pxor xmm3,xmm5
+ lea esi,[64+esi]
+ movdqu [edi],xmm0
+ movdqu [16+edi],xmm1
+ movdqu [32+edi],xmm2
+ movdqu [48+edi],xmm3
+ lea edi,[64+edi]
+ sub ecx,64
+ jnz NEAR L$013outer1x
+ jmp NEAR L$011done
+L$014tail:
+ movdqa [esp],xmm0
+ movdqa [16+esp],xmm1
+ movdqa [32+esp],xmm2
+ movdqa [48+esp],xmm3
+ xor eax,eax
+ xor edx,edx
+ xor ebp,ebp
+L$015tail_loop:
+ mov al,BYTE [ebp*1+esp]
+ mov dl,BYTE [ebp*1+esi]
+ lea ebp,[1+ebp]
+ xor al,dl
+ mov BYTE [ebp*1+edi-1],al
+ dec ecx
+ jnz NEAR L$015tail_loop
+L$011done:
+ mov esp,DWORD [512+esp]
+ pop edi
+ pop esi
+ pop ebx
+ pop ebp
+ ret
+align 64
+L$ssse3_data:
+db 2,3,0,1,6,7,4,5,10,11,8,9,14,15,12,13
+db 3,0,1,2,7,4,5,6,11,8,9,10,15,12,13,14
+dd 1634760805,857760878,2036477234,1797285236
+dd 0,1,2,3
+dd 4,4,4,4
+dd 1,0,0,0
+dd 4,0,0,0
+dd 0,-1,-1,-1
+align 64
+db 67,104,97,67,104,97,50,48,32,102,111,114,32,120,56,54
+db 44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32
+db 60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111
+db 114,103,62,0
+segment .bss
+common _OPENSSL_ia32cap_P 16
diff --git a/win-x86/crypto/rc4/rc4-586.asm b/win-x86/crypto/rc4/rc4-586.asm
index 08cd9f6d..0bab2bec 100644
--- a/win-x86/crypto/rc4/rc4-586.asm
+++ b/win-x86/crypto/rc4/rc4-586.asm
@@ -349,34 +349,5 @@ L$013exit:
pop ebx
pop ebp
ret
-global _RC4_options
-align 16
-_RC4_options:
-L$_RC4_options_begin:
- call L$016pic_point
-L$016pic_point:
- pop eax
- lea eax,[(L$017opts-L$016pic_point)+eax]
- lea edx,[_OPENSSL_ia32cap_P]
- mov edx,DWORD [edx]
- bt edx,20
- jc NEAR L$0181xchar
- bt edx,26
- jnc NEAR L$019ret
- add eax,25
- ret
-L$0181xchar:
- add eax,12
-L$019ret:
- ret
-align 64
-L$017opts:
-db 114,99,52,40,52,120,44,105,110,116,41,0
-db 114,99,52,40,49,120,44,99,104,97,114,41,0
-db 114,99,52,40,56,120,44,109,109,120,41,0
-db 82,67,52,32,102,111,114,32,120,56,54,44,32,67,82,89
-db 80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114
-db 111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
-align 64
segment .bss
common _OPENSSL_ia32cap_P 16
diff --git a/win-x86_64/crypto/bn/rsaz-x86_64.asm b/win-x86_64/crypto/bn/rsaz-x86_64.asm
index 04d5e391..72ec5052 100644
--- a/win-x86_64/crypto/bn/rsaz-x86_64.asm
+++ b/win-x86_64/crypto/bn/rsaz-x86_64.asm
@@ -504,48 +504,104 @@ $L$SEH_begin_rsaz_512_mul_gather4:
push r14
push r15
- mov r9d,r9d
- sub rsp,128+24
+ sub rsp,328
+ movaps XMMWORD[160+rsp],xmm6
+ movaps XMMWORD[176+rsp],xmm7
+ movaps XMMWORD[192+rsp],xmm8
+ movaps XMMWORD[208+rsp],xmm9
+ movaps XMMWORD[224+rsp],xmm10
+ movaps XMMWORD[240+rsp],xmm11
+ movaps XMMWORD[256+rsp],xmm12
+ movaps XMMWORD[272+rsp],xmm13
+ movaps XMMWORD[288+rsp],xmm14
+ movaps XMMWORD[304+rsp],xmm15
$L$mul_gather4_body:
- mov eax,DWORD[64+r9*4+rdx]
-DB 102,72,15,110,199
- mov ebx,DWORD[r9*4+rdx]
-DB 102,72,15,110,201
+ movd xmm8,r9d
+ movdqa xmm1,XMMWORD[(($L$inc+16))]
+ movdqa xmm0,XMMWORD[$L$inc]
+
+ pshufd xmm8,xmm8,0
+ movdqa xmm7,xmm1
+ movdqa xmm2,xmm1
+ paddd xmm1,xmm0
+ pcmpeqd xmm0,xmm8
+ movdqa xmm3,xmm7
+ paddd xmm2,xmm1
+ pcmpeqd xmm1,xmm8
+ movdqa xmm4,xmm7
+ paddd xmm3,xmm2
+ pcmpeqd xmm2,xmm8
+ movdqa xmm5,xmm7
+ paddd xmm4,xmm3
+ pcmpeqd xmm3,xmm8
+ movdqa xmm6,xmm7
+ paddd xmm5,xmm4
+ pcmpeqd xmm4,xmm8
+ paddd xmm6,xmm5
+ pcmpeqd xmm5,xmm8
+ paddd xmm7,xmm6
+ pcmpeqd xmm6,xmm8
+ pcmpeqd xmm7,xmm8
+
+ movdqa xmm8,XMMWORD[rdx]
+ movdqa xmm9,XMMWORD[16+rdx]
+ movdqa xmm10,XMMWORD[32+rdx]
+ movdqa xmm11,XMMWORD[48+rdx]
+ pand xmm8,xmm0
+ movdqa xmm12,XMMWORD[64+rdx]
+ pand xmm9,xmm1
+ movdqa xmm13,XMMWORD[80+rdx]
+ pand xmm10,xmm2
+ movdqa xmm14,XMMWORD[96+rdx]
+ pand xmm11,xmm3
+ movdqa xmm15,XMMWORD[112+rdx]
+ lea rbp,[128+rdx]
+ pand xmm12,xmm4
+ pand xmm13,xmm5
+ pand xmm14,xmm6
+ pand xmm15,xmm7
+ por xmm8,xmm10
+ por xmm9,xmm11
+ por xmm8,xmm12
+ por xmm9,xmm13
+ por xmm8,xmm14
+ por xmm9,xmm15
+
+ por xmm8,xmm9
+ pshufd xmm9,xmm8,0x4e
+ por xmm8,xmm9
+DB 102,76,15,126,195
+
mov QWORD[128+rsp],r8
+ mov QWORD[((128+8))+rsp],rdi
+ mov QWORD[((128+16))+rsp],rcx
- shl rax,32
- or rbx,rax
mov rax,QWORD[rsi]
mov rcx,QWORD[8+rsi]
- lea rbp,[128+r9*4+rdx]
mul rbx
mov QWORD[rsp],rax
mov rax,rcx
mov r8,rdx
mul rbx
- movd xmm4,DWORD[rbp]
add r8,rax
mov rax,QWORD[16+rsi]
mov r9,rdx
adc r9,0
mul rbx
- movd xmm5,DWORD[64+rbp]
add r9,rax
mov rax,QWORD[24+rsi]
mov r10,rdx
adc r10,0
mul rbx
- pslldq xmm5,4
add r10,rax
mov rax,QWORD[32+rsi]
mov r11,rdx
adc r11,0
mul rbx
- por xmm4,xmm5
add r11,rax
mov rax,QWORD[40+rsi]
mov r12,rdx
@@ -558,14 +614,12 @@ DB 102,72,15,110,201
adc r13,0
mul rbx
- lea rbp,[128+rbp]
add r13,rax
mov rax,QWORD[56+rsi]
mov r14,rdx
adc r14,0
mul rbx
-DB 102,72,15,126,227
add r14,rax
mov rax,QWORD[rsi]
mov r15,rdx
@@ -577,6 +631,35 @@ DB 102,72,15,126,227
ALIGN 32
$L$oop_mul_gather:
+ movdqa xmm8,XMMWORD[rbp]
+ movdqa xmm9,XMMWORD[16+rbp]
+ movdqa xmm10,XMMWORD[32+rbp]
+ movdqa xmm11,XMMWORD[48+rbp]
+ pand xmm8,xmm0
+ movdqa xmm12,XMMWORD[64+rbp]
+ pand xmm9,xmm1
+ movdqa xmm13,XMMWORD[80+rbp]
+ pand xmm10,xmm2
+ movdqa xmm14,XMMWORD[96+rbp]
+ pand xmm11,xmm3
+ movdqa xmm15,XMMWORD[112+rbp]
+ lea rbp,[128+rbp]
+ pand xmm12,xmm4
+ pand xmm13,xmm5
+ pand xmm14,xmm6
+ pand xmm15,xmm7
+ por xmm8,xmm10
+ por xmm9,xmm11
+ por xmm8,xmm12
+ por xmm9,xmm13
+ por xmm8,xmm14
+ por xmm9,xmm15
+
+ por xmm8,xmm9
+ pshufd xmm9,xmm8,0x4e
+ por xmm8,xmm9
+DB 102,76,15,126,195
+
mul rbx
add r8,rax
mov rax,QWORD[8+rsi]
@@ -585,7 +668,6 @@ $L$oop_mul_gather:
adc r8,0
mul rbx
- movd xmm4,DWORD[rbp]
add r9,rax
mov rax,QWORD[16+rsi]
adc rdx,0
@@ -594,7 +676,6 @@ $L$oop_mul_gather:
adc r9,0
mul rbx
- movd xmm5,DWORD[64+rbp]
add r10,rax
mov rax,QWORD[24+rsi]
adc rdx,0
@@ -603,7 +684,6 @@ $L$oop_mul_gather:
adc r10,0
mul rbx
- pslldq xmm5,4
add r11,rax
mov rax,QWORD[32+rsi]
adc rdx,0
@@ -612,7 +692,6 @@ $L$oop_mul_gather:
adc r11,0
mul rbx
- por xmm4,xmm5
add r12,rax
mov rax,QWORD[40+rsi]
adc rdx,0
@@ -637,7 +716,6 @@ $L$oop_mul_gather:
adc r14,0
mul rbx
-DB 102,72,15,126,227
add r15,rax
mov rax,QWORD[rsi]
adc rdx,0
@@ -645,7 +723,6 @@ DB 102,72,15,126,227
mov r15,rdx
adc r15,0
- lea rbp,[128+rbp]
lea rdi,[8+rdi]
dec ecx
@@ -660,8 +737,8 @@ DB 102,72,15,126,227
mov QWORD[48+rdi],r14
mov QWORD[56+rdi],r15
-DB 102,72,15,126,199
-DB 102,72,15,126,205
+ mov rdi,QWORD[((128+8))+rsp]
+ mov rbp,QWORD[((128+16))+rsp]
mov r8,QWORD[rsp]
mov r9,QWORD[8+rsp]
@@ -686,6 +763,17 @@ DB 102,72,15,126,205
call __rsaz_512_subtract
lea rax,[((128+24+48))+rsp]
+ movaps xmm6,XMMWORD[((160-200))+rax]
+ movaps xmm7,XMMWORD[((176-200))+rax]
+ movaps xmm8,XMMWORD[((192-200))+rax]
+ movaps xmm9,XMMWORD[((208-200))+rax]
+ movaps xmm10,XMMWORD[((224-200))+rax]
+ movaps xmm11,XMMWORD[((240-200))+rax]
+ movaps xmm12,XMMWORD[((256-200))+rax]
+ movaps xmm13,XMMWORD[((272-200))+rax]
+ movaps xmm14,XMMWORD[((288-200))+rax]
+ movaps xmm15,XMMWORD[((304-200))+rax]
+ lea rax,[176+rax]
mov r15,QWORD[((-48))+rax]
mov r14,QWORD[((-40))+rax]
mov r13,QWORD[((-32))+rax]
@@ -724,7 +812,7 @@ $L$SEH_begin_rsaz_512_mul_scatter4:
mov r9d,r9d
sub rsp,128+24
$L$mul_scatter4_body:
- lea r8,[r9*4+r8]
+ lea r8,[r9*8+r8]
DB 102,72,15,110,199
DB 102,72,15,110,202
DB 102,73,15,110,208
@@ -760,30 +848,14 @@ DB 102,72,15,126,214
call __rsaz_512_subtract
- mov DWORD[rsi],r8d
- shr r8,32
- mov DWORD[128+rsi],r9d
- shr r9,32
- mov DWORD[256+rsi],r10d
- shr r10,32
- mov DWORD[384+rsi],r11d
- shr r11,32
- mov DWORD[512+rsi],r12d
- shr r12,32
- mov DWORD[640+rsi],r13d
- shr r13,32
- mov DWORD[768+rsi],r14d
- shr r14,32
- mov DWORD[896+rsi],r15d
- shr r15,32
- mov DWORD[64+rsi],r8d
- mov DWORD[192+rsi],r9d
- mov DWORD[320+rsi],r10d
- mov DWORD[448+rsi],r11d
- mov DWORD[576+rsi],r12d
- mov DWORD[704+rsi],r13d
- mov DWORD[832+rsi],r14d
- mov DWORD[960+rsi],r15d
+ mov QWORD[rsi],r8
+ mov QWORD[128+rsi],r9
+ mov QWORD[256+rsi],r10
+ mov QWORD[384+rsi],r11
+ mov QWORD[512+rsi],r12
+ mov QWORD[640+rsi],r13
+ mov QWORD[768+rsi],r14
+ mov QWORD[896+rsi],r15
lea rax,[((128+24+48))+rsp]
mov r15,QWORD[((-48))+rax]
@@ -1150,16 +1222,14 @@ global rsaz_512_scatter4
ALIGN 16
rsaz_512_scatter4:
- lea rcx,[r8*4+rcx]
+ lea rcx,[r8*8+rcx]
mov r9d,8
jmp NEAR $L$oop_scatter
ALIGN 16
$L$oop_scatter:
mov rax,QWORD[rdx]
lea rdx,[8+rdx]
- mov DWORD[rcx],eax
- shr rax,32
- mov DWORD[64+rcx],eax
+ mov QWORD[rcx],rax
lea rcx,[128+rcx]
dec r9d
jnz NEAR $L$oop_scatter
@@ -1170,22 +1240,98 @@ global rsaz_512_gather4
ALIGN 16
rsaz_512_gather4:
- lea rdx,[r8*4+rdx]
+$L$SEH_begin_rsaz_512_gather4:
+DB 0x48,0x81,0xec,0xa8,0x00,0x00,0x00
+DB 0x0f,0x29,0x34,0x24
+DB 0x0f,0x29,0x7c,0x24,0x10
+DB 0x44,0x0f,0x29,0x44,0x24,0x20
+DB 0x44,0x0f,0x29,0x4c,0x24,0x30
+DB 0x44,0x0f,0x29,0x54,0x24,0x40
+DB 0x44,0x0f,0x29,0x5c,0x24,0x50
+DB 0x44,0x0f,0x29,0x64,0x24,0x60
+DB 0x44,0x0f,0x29,0x6c,0x24,0x70
+DB 0x44,0x0f,0x29,0xb4,0x24,0x80,0,0,0
+DB 0x44,0x0f,0x29,0xbc,0x24,0x90,0,0,0
+ movd xmm8,r8d
+ movdqa xmm1,XMMWORD[(($L$inc+16))]
+ movdqa xmm0,XMMWORD[$L$inc]
+
+ pshufd xmm8,xmm8,0
+ movdqa xmm7,xmm1
+ movdqa xmm2,xmm1
+ paddd xmm1,xmm0
+ pcmpeqd xmm0,xmm8
+ movdqa xmm3,xmm7
+ paddd xmm2,xmm1
+ pcmpeqd xmm1,xmm8
+ movdqa xmm4,xmm7
+ paddd xmm3,xmm2
+ pcmpeqd xmm2,xmm8
+ movdqa xmm5,xmm7
+ paddd xmm4,xmm3
+ pcmpeqd xmm3,xmm8
+ movdqa xmm6,xmm7
+ paddd xmm5,xmm4
+ pcmpeqd xmm4,xmm8
+ paddd xmm6,xmm5
+ pcmpeqd xmm5,xmm8
+ paddd xmm7,xmm6
+ pcmpeqd xmm6,xmm8
+ pcmpeqd xmm7,xmm8
mov r9d,8
jmp NEAR $L$oop_gather
ALIGN 16
$L$oop_gather:
- mov eax,DWORD[rdx]
- mov r8d,DWORD[64+rdx]
+ movdqa xmm8,XMMWORD[rdx]
+ movdqa xmm9,XMMWORD[16+rdx]
+ movdqa xmm10,XMMWORD[32+rdx]
+ movdqa xmm11,XMMWORD[48+rdx]
+ pand xmm8,xmm0
+ movdqa xmm12,XMMWORD[64+rdx]
+ pand xmm9,xmm1
+ movdqa xmm13,XMMWORD[80+rdx]
+ pand xmm10,xmm2
+ movdqa xmm14,XMMWORD[96+rdx]
+ pand xmm11,xmm3
+ movdqa xmm15,XMMWORD[112+rdx]
lea rdx,[128+rdx]
- shl r8,32
- or rax,r8
- mov QWORD[rcx],rax
+ pand xmm12,xmm4
+ pand xmm13,xmm5
+ pand xmm14,xmm6
+ pand xmm15,xmm7
+ por xmm8,xmm10
+ por xmm9,xmm11
+ por xmm8,xmm12
+ por xmm9,xmm13
+ por xmm8,xmm14
+ por xmm9,xmm15
+
+ por xmm8,xmm9
+ pshufd xmm9,xmm8,0x4e
+ por xmm8,xmm9
+ movq QWORD[rcx],xmm8
lea rcx,[8+rcx]
dec r9d
jnz NEAR $L$oop_gather
+ 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]
+ add rsp,0xa8
DB 0F3h,0C3h ;repret
+$L$SEH_end_rsaz_512_gather4:
+
+ALIGN 64
+$L$inc:
+ DD 0,0,1,1
+ DD 2,2,2,2
EXTERN __imp_RtlVirtualUnwind
ALIGN 16
@@ -1221,6 +1367,18 @@ se_handler:
lea rax,[((128+24+48))+rax]
+ lea rbx,[$L$mul_gather4_epilogue]
+ cmp rbx,r10
+ jne NEAR $L$se_not_in_mul_gather4
+
+ lea rax,[176+rax]
+
+ lea rsi,[((-48-168))+rax]
+ lea rdi,[512+r8]
+ mov ecx,20
+ DD 0xa548f3fc
+
+$L$se_not_in_mul_gather4:
mov rbx,QWORD[((-8))+rax]
mov rbp,QWORD[((-16))+rax]
mov r12,QWORD[((-24))+rax]
@@ -1296,6 +1454,10 @@ ALIGN 4
DD $L$SEH_end_rsaz_512_mul_by_one wrt ..imagebase
DD $L$SEH_info_rsaz_512_mul_by_one wrt ..imagebase
+ DD $L$SEH_begin_rsaz_512_gather4 wrt ..imagebase
+ DD $L$SEH_end_rsaz_512_gather4 wrt ..imagebase
+ DD $L$SEH_info_rsaz_512_gather4 wrt ..imagebase
+
section .xdata rdata align=8
ALIGN 8
$L$SEH_info_rsaz_512_sqr:
@@ -1318,3 +1480,16 @@ $L$SEH_info_rsaz_512_mul_by_one:
DB 9,0,0,0
DD se_handler wrt ..imagebase
DD $L$mul_by_one_body wrt ..imagebase,$L$mul_by_one_epilogue wrt ..imagebase
+$L$SEH_info_rsaz_512_gather4:
+DB 0x01,0x46,0x16,0x00
+DB 0x46,0xf8,0x09,0x00
+DB 0x3d,0xe8,0x08,0x00
+DB 0x34,0xd8,0x07,0x00
+DB 0x2e,0xc8,0x06,0x00
+DB 0x28,0xb8,0x05,0x00
+DB 0x22,0xa8,0x04,0x00
+DB 0x1c,0x98,0x03,0x00
+DB 0x16,0x88,0x02,0x00
+DB 0x10,0x78,0x01,0x00
+DB 0x0b,0x68,0x00,0x00
+DB 0x07,0x01,0x15,0x00
diff --git a/win-x86_64/crypto/bn/x86_64-mont.asm b/win-x86_64/crypto/bn/x86_64-mont.asm
index db0d1b97..4d8e1cb7 100644
--- a/win-x86_64/crypto/bn/x86_64-mont.asm
+++ b/win-x86_64/crypto/bn/x86_64-mont.asm
@@ -677,20 +677,20 @@ $L$sqr8x_enter:
- lea r11,[((-64))+r9*4+rsp]
+ lea r11,[((-64))+r9*2+rsp]
mov r8,QWORD[r8]
sub r11,rsi
and r11,4095
cmp r10,r11
jb NEAR $L$sqr8x_sp_alt
sub rsp,r11
- lea rsp,[((-64))+r9*4+rsp]
+ lea rsp,[((-64))+r9*2+rsp]
jmp NEAR $L$sqr8x_sp_done
ALIGN 32
$L$sqr8x_sp_alt:
- lea r10,[((4096-64))+r9*4]
- lea rsp,[((-64))+r9*4+rsp]
+ lea r10,[((4096-64))+r9*2]
+ lea rsp,[((-64))+r9*2+rsp]
sub r11,r10
mov r10,0
cmovc r11,r10
@@ -700,58 +700,80 @@ $L$sqr8x_sp_done:
mov r10,r9
neg r9
- lea r11,[64+r9*2+rsp]
mov QWORD[32+rsp],r8
mov QWORD[40+rsp],rax
$L$sqr8x_body:
- mov rbp,r9
-DB 102,73,15,110,211
- shr rbp,3+2
- mov eax,DWORD[((OPENSSL_ia32cap_P+8))]
- jmp NEAR $L$sqr8x_copy_n
-
-ALIGN 32
-$L$sqr8x_copy_n:
- movq xmm0,QWORD[rcx]
- movq xmm1,QWORD[8+rcx]
- movq xmm3,QWORD[16+rcx]
- movq xmm4,QWORD[24+rcx]
- lea rcx,[32+rcx]
- movdqa XMMWORD[r11],xmm0
- movdqa XMMWORD[16+r11],xmm1
- movdqa XMMWORD[32+r11],xmm3
- movdqa XMMWORD[48+r11],xmm4
- lea r11,[64+r11]
- dec rbp
- jnz NEAR $L$sqr8x_copy_n
-
+DB 102,72,15,110,209
pxor xmm0,xmm0
DB 102,72,15,110,207
DB 102,73,15,110,218
call bn_sqr8x_internal
+
+
+
+ lea rbx,[r9*1+rdi]
+ mov rcx,r9
+ mov rdx,r9
+DB 102,72,15,126,207
+ sar rcx,3+2
+ jmp NEAR $L$sqr8x_sub
+
+ALIGN 32
+$L$sqr8x_sub:
+ mov r12,QWORD[rbx]
+ mov r13,QWORD[8+rbx]
+ mov r14,QWORD[16+rbx]
+ mov r15,QWORD[24+rbx]
+ lea rbx,[32+rbx]
+ sbb r12,QWORD[rbp]
+ sbb r13,QWORD[8+rbp]
+ sbb r14,QWORD[16+rbp]
+ sbb r15,QWORD[24+rbp]
+ lea rbp,[32+rbp]
+ mov QWORD[rdi],r12
+ mov QWORD[8+rdi],r13
+ mov QWORD[16+rdi],r14
+ mov QWORD[24+rdi],r15
+ lea rdi,[32+rdi]
+ inc rcx
+ jnz NEAR $L$sqr8x_sub
+
+ sbb rax,0
+ lea rbx,[r9*1+rbx]
+ lea rdi,[r9*1+rdi]
+
+DB 102,72,15,110,200
pxor xmm0,xmm0
- lea rax,[48+rsp]
- lea rdx,[64+r9*2+rsp]
- shr r9,3+2
+ pshufd xmm1,xmm1,0
mov rsi,QWORD[40+rsp]
- jmp NEAR $L$sqr8x_zero
+ jmp NEAR $L$sqr8x_cond_copy
ALIGN 32
-$L$sqr8x_zero:
- movdqa XMMWORD[rax],xmm0
- movdqa XMMWORD[16+rax],xmm0
- movdqa XMMWORD[32+rax],xmm0
- movdqa XMMWORD[48+rax],xmm0
- lea rax,[64+rax]
- movdqa XMMWORD[rdx],xmm0
- movdqa XMMWORD[16+rdx],xmm0
- movdqa XMMWORD[32+rdx],xmm0
- movdqa XMMWORD[48+rdx],xmm0
- lea rdx,[64+rdx]
- dec r9
- jnz NEAR $L$sqr8x_zero
+$L$sqr8x_cond_copy:
+ movdqa xmm2,XMMWORD[rbx]
+ movdqa xmm3,XMMWORD[16+rbx]
+ lea rbx,[32+rbx]
+ movdqu xmm4,XMMWORD[rdi]
+ movdqu xmm5,XMMWORD[16+rdi]
+ lea rdi,[32+rdi]
+ movdqa XMMWORD[(-32)+rbx],xmm0
+ movdqa XMMWORD[(-16)+rbx],xmm0
+ movdqa XMMWORD[(-32)+rdx*1+rbx],xmm0
+ movdqa XMMWORD[(-16)+rdx*1+rbx],xmm0
+ pcmpeqd xmm0,xmm1
+ pand xmm2,xmm1
+ pand xmm3,xmm1
+ pand xmm4,xmm0
+ pand xmm5,xmm0
+ pxor xmm0,xmm0
+ por xmm4,xmm2
+ por xmm5,xmm3
+ movdqu XMMWORD[(-32)+rdi],xmm4
+ movdqu XMMWORD[(-16)+rdi],xmm5
+ add r9,32
+ jnz NEAR $L$sqr8x_cond_copy
mov rax,1
mov r15,QWORD[((-48))+rsi]
diff --git a/win-x86_64/crypto/bn/x86_64-mont5.asm b/win-x86_64/crypto/bn/x86_64-mont5.asm
index 560b384e..cd9a6e5d 100644
--- a/win-x86_64/crypto/bn/x86_64-mont5.asm
+++ b/win-x86_64/crypto/bn/x86_64-mont5.asm
@@ -31,49 +31,151 @@ ALIGN 16
$L$mul_enter:
mov r9d,r9d
mov rax,rsp
- mov r10d,DWORD[56+rsp]
+ movd xmm5,DWORD[56+rsp]
+ lea r10,[$L$inc]
push rbx
push rbp
push r12
push r13
push r14
push r15
- lea rsp,[((-40))+rsp]
- movaps XMMWORD[rsp],xmm6
- movaps XMMWORD[16+rsp],xmm7
+
lea r11,[2+r9]
neg r11
- lea rsp,[r11*8+rsp]
+ lea rsp,[((-264))+r11*8+rsp]
and rsp,-1024
mov QWORD[8+r9*8+rsp],rax
$L$mul_body:
- mov r12,rdx
- mov r11,r10
- shr r10,3
- and r11,7
- not r10
- lea rax,[$L$magic_masks]
- and r10,3
- lea r12,[96+r11*8+r12]
- movq xmm4,QWORD[r10*8+rax]
- movq xmm5,QWORD[8+r10*8+rax]
- movq xmm6,QWORD[16+r10*8+rax]
- movq xmm7,QWORD[24+r10*8+rax]
-
- movq xmm0,QWORD[(((-96)))+r12]
- movq xmm1,QWORD[((-32))+r12]
- pand xmm0,xmm4
- movq xmm2,QWORD[32+r12]
- pand xmm1,xmm5
- movq xmm3,QWORD[96+r12]
- pand xmm2,xmm6
- por xmm0,xmm1
- pand xmm3,xmm7
+ lea r12,[128+rdx]
+ movdqa xmm0,XMMWORD[r10]
+ movdqa xmm1,XMMWORD[16+r10]
+ lea r10,[((24-112))+r9*8+rsp]
+ and r10,-16
+
+ pshufd xmm5,xmm5,0
+ movdqa xmm4,xmm1
+ movdqa xmm2,xmm1
+ paddd xmm1,xmm0
+ pcmpeqd xmm0,xmm5
+DB 0x67
+ movdqa xmm3,xmm4
+ paddd xmm2,xmm1
+ pcmpeqd xmm1,xmm5
+ movdqa XMMWORD[112+r10],xmm0
+ movdqa xmm0,xmm4
+
+ paddd xmm3,xmm2
+ pcmpeqd xmm2,xmm5
+ movdqa XMMWORD[128+r10],xmm1
+ movdqa xmm1,xmm4
+
+ paddd xmm0,xmm3
+ pcmpeqd xmm3,xmm5
+ movdqa XMMWORD[144+r10],xmm2
+ movdqa xmm2,xmm4
+
+ paddd xmm1,xmm0
+ pcmpeqd xmm0,xmm5
+ movdqa XMMWORD[160+r10],xmm3
+ movdqa xmm3,xmm4
+ paddd xmm2,xmm1
+ pcmpeqd xmm1,xmm5
+ movdqa XMMWORD[176+r10],xmm0
+ movdqa xmm0,xmm4
+
+ paddd xmm3,xmm2
+ pcmpeqd xmm2,xmm5
+ movdqa XMMWORD[192+r10],xmm1
+ movdqa xmm1,xmm4
+
+ paddd xmm0,xmm3
+ pcmpeqd xmm3,xmm5
+ movdqa XMMWORD[208+r10],xmm2
+ movdqa xmm2,xmm4
+
+ paddd xmm1,xmm0
+ pcmpeqd xmm0,xmm5
+ movdqa XMMWORD[224+r10],xmm3
+ movdqa xmm3,xmm4
+ paddd xmm2,xmm1
+ pcmpeqd xmm1,xmm5
+ movdqa XMMWORD[240+r10],xmm0
+ movdqa xmm0,xmm4
+
+ paddd xmm3,xmm2
+ pcmpeqd xmm2,xmm5
+ movdqa XMMWORD[256+r10],xmm1
+ movdqa xmm1,xmm4
+
+ paddd xmm0,xmm3
+ pcmpeqd xmm3,xmm5
+ movdqa XMMWORD[272+r10],xmm2
+ movdqa xmm2,xmm4
+
+ paddd xmm1,xmm0
+ pcmpeqd xmm0,xmm5
+ movdqa XMMWORD[288+r10],xmm3
+ movdqa xmm3,xmm4
+ paddd xmm2,xmm1
+ pcmpeqd xmm1,xmm5
+ movdqa XMMWORD[304+r10],xmm0
+
+ paddd xmm3,xmm2
+DB 0x67
+ pcmpeqd xmm2,xmm5
+ movdqa XMMWORD[320+r10],xmm1
+
+ pcmpeqd xmm3,xmm5
+ movdqa XMMWORD[336+r10],xmm2
+ pand xmm0,XMMWORD[64+r12]
+
+ pand xmm1,XMMWORD[80+r12]
+ pand xmm2,XMMWORD[96+r12]
+ movdqa XMMWORD[352+r10],xmm3
+ pand xmm3,XMMWORD[112+r12]
+ por xmm0,xmm2
+ por xmm1,xmm3
+ movdqa xmm4,XMMWORD[((-128))+r12]
+ movdqa xmm5,XMMWORD[((-112))+r12]
+ movdqa xmm2,XMMWORD[((-96))+r12]
+ pand xmm4,XMMWORD[112+r10]
+ movdqa xmm3,XMMWORD[((-80))+r12]
+ pand xmm5,XMMWORD[128+r10]
+ por xmm0,xmm4
+ pand xmm2,XMMWORD[144+r10]
+ por xmm1,xmm5
+ pand xmm3,XMMWORD[160+r10]
por xmm0,xmm2
+ por xmm1,xmm3
+ movdqa xmm4,XMMWORD[((-64))+r12]
+ movdqa xmm5,XMMWORD[((-48))+r12]
+ movdqa xmm2,XMMWORD[((-32))+r12]
+ pand xmm4,XMMWORD[176+r10]
+ movdqa xmm3,XMMWORD[((-16))+r12]
+ pand xmm5,XMMWORD[192+r10]
+ por xmm0,xmm4
+ pand xmm2,XMMWORD[208+r10]
+ por xmm1,xmm5
+ pand xmm3,XMMWORD[224+r10]
+ por xmm0,xmm2
+ por xmm1,xmm3
+ movdqa xmm4,XMMWORD[r12]
+ movdqa xmm5,XMMWORD[16+r12]
+ movdqa xmm2,XMMWORD[32+r12]
+ pand xmm4,XMMWORD[240+r10]
+ movdqa xmm3,XMMWORD[48+r12]
+ pand xmm5,XMMWORD[256+r10]
+ por xmm0,xmm4
+ pand xmm2,XMMWORD[272+r10]
+ por xmm1,xmm5
+ pand xmm3,XMMWORD[288+r10]
+ por xmm0,xmm2
+ por xmm1,xmm3
+ por xmm0,xmm1
+ pshufd xmm1,xmm0,0x4e
+ por xmm0,xmm1
lea r12,[256+r12]
- por xmm0,xmm3
-
DB 102,72,15,126,195
mov r8,QWORD[r8]
@@ -82,29 +184,14 @@ DB 102,72,15,126,195
xor r14,r14
xor r15,r15
- movq xmm0,QWORD[(((-96)))+r12]
- movq xmm1,QWORD[((-32))+r12]
- pand xmm0,xmm4
- movq xmm2,QWORD[32+r12]
- pand xmm1,xmm5
-
mov rbp,r8
mul rbx
mov r10,rax
mov rax,QWORD[rcx]
- movq xmm3,QWORD[96+r12]
- pand xmm2,xmm6
- por xmm0,xmm1
- pand xmm3,xmm7
-
imul rbp,r10
mov r11,rdx
- por xmm0,xmm2
- lea r12,[256+r12]
- por xmm0,xmm3
-
mul rbp
add r10,rax
mov rax,QWORD[8+rsi]
@@ -137,14 +224,12 @@ $L$1st_enter:
cmp r15,r9
jne NEAR $L$1st
-DB 102,72,15,126,195
add r13,rax
- mov rax,QWORD[rsi]
adc rdx,0
add r13,r11
adc rdx,0
- mov QWORD[((-16))+r15*8+rsp],r13
+ mov QWORD[((-16))+r9*8+rsp],r13
mov r13,rdx
mov r11,r10
@@ -158,33 +243,78 @@ DB 102,72,15,126,195
jmp NEAR $L$outer
ALIGN 16
$L$outer:
+ lea rdx,[((24+128))+r9*8+rsp]
+ and rdx,-16
+ pxor xmm4,xmm4
+ pxor xmm5,xmm5
+ movdqa xmm0,XMMWORD[((-128))+r12]
+ movdqa xmm1,XMMWORD[((-112))+r12]
+ movdqa xmm2,XMMWORD[((-96))+r12]
+ movdqa xmm3,XMMWORD[((-80))+r12]
+ pand xmm0,XMMWORD[((-128))+rdx]
+ pand xmm1,XMMWORD[((-112))+rdx]
+ por xmm4,xmm0
+ pand xmm2,XMMWORD[((-96))+rdx]
+ por xmm5,xmm1
+ pand xmm3,XMMWORD[((-80))+rdx]
+ por xmm4,xmm2
+ por xmm5,xmm3
+ movdqa xmm0,XMMWORD[((-64))+r12]
+ movdqa xmm1,XMMWORD[((-48))+r12]
+ movdqa xmm2,XMMWORD[((-32))+r12]
+ movdqa xmm3,XMMWORD[((-16))+r12]
+ pand xmm0,XMMWORD[((-64))+rdx]
+ pand xmm1,XMMWORD[((-48))+rdx]
+ por xmm4,xmm0
+ pand xmm2,XMMWORD[((-32))+rdx]
+ por xmm5,xmm1
+ pand xmm3,XMMWORD[((-16))+rdx]
+ por xmm4,xmm2
+ por xmm5,xmm3
+ movdqa xmm0,XMMWORD[r12]
+ movdqa xmm1,XMMWORD[16+r12]
+ movdqa xmm2,XMMWORD[32+r12]
+ movdqa xmm3,XMMWORD[48+r12]
+ pand xmm0,XMMWORD[rdx]
+ pand xmm1,XMMWORD[16+rdx]
+ por xmm4,xmm0
+ pand xmm2,XMMWORD[32+rdx]
+ por xmm5,xmm1
+ pand xmm3,XMMWORD[48+rdx]
+ por xmm4,xmm2
+ por xmm5,xmm3
+ movdqa xmm0,XMMWORD[64+r12]
+ movdqa xmm1,XMMWORD[80+r12]
+ movdqa xmm2,XMMWORD[96+r12]
+ movdqa xmm3,XMMWORD[112+r12]
+ pand xmm0,XMMWORD[64+rdx]
+ pand xmm1,XMMWORD[80+rdx]
+ por xmm4,xmm0
+ pand xmm2,XMMWORD[96+rdx]
+ por xmm5,xmm1
+ pand xmm3,XMMWORD[112+rdx]
+ por xmm4,xmm2
+ por xmm5,xmm3
+ por xmm4,xmm5
+ pshufd xmm0,xmm4,0x4e
+ por xmm0,xmm4
+ lea r12,[256+r12]
+
+ mov rax,QWORD[rsi]
+DB 102,72,15,126,195
+
xor r15,r15
mov rbp,r8
mov r10,QWORD[rsp]
- movq xmm0,QWORD[(((-96)))+r12]
- movq xmm1,QWORD[((-32))+r12]
- pand xmm0,xmm4
- movq xmm2,QWORD[32+r12]
- pand xmm1,xmm5
-
mul rbx
add r10,rax
mov rax,QWORD[rcx]
adc rdx,0
- movq xmm3,QWORD[96+r12]
- pand xmm2,xmm6
- por xmm0,xmm1
- pand xmm3,xmm7
-
imul rbp,r10
mov r11,rdx
- por xmm0,xmm2
- lea r12,[256+r12]
- por xmm0,xmm3
-
mul rbp
add r10,rax
mov rax,QWORD[8+rsi]
@@ -220,15 +350,12 @@ $L$inner_enter:
cmp r15,r9
jne NEAR $L$inner
-DB 102,72,15,126,195
-
add r13,rax
- mov rax,QWORD[rsi]
adc rdx,0
add r13,r10
- mov r10,QWORD[r15*8+rsp]
+ mov r10,QWORD[r9*8+rsp]
adc rdx,0
- mov QWORD[((-16))+r15*8+rsp],r13
+ mov QWORD[((-16))+r9*8+rsp],r13
mov r13,rdx
xor rdx,rdx
@@ -274,8 +401,7 @@ $L$copy:
mov rsi,QWORD[8+r9*8+rsp]
mov rax,1
- movaps xmm6,XMMWORD[((-88))+rsi]
- movaps xmm7,XMMWORD[((-72))+rsi]
+
mov r15,QWORD[((-48))+rsi]
mov r14,QWORD[((-40))+rsi]
mov r13,QWORD[((-32))+rsi]
@@ -312,13 +438,10 @@ DB 0x67
push r13
push r14
push r15
- lea rsp,[((-40))+rsp]
- movaps XMMWORD[rsp],xmm6
- movaps XMMWORD[16+rsp],xmm7
+
DB 0x67
- mov r10d,r9d
shl r9d,3
- shl r10d,3+2
+ lea r10,[r9*2+r9]
neg r9
@@ -328,19 +451,21 @@ DB 0x67
- lea r11,[((-64))+r9*2+rsp]
- sub r11,rsi
+
+
+ lea r11,[((-320))+r9*2+rsp]
+ sub r11,rdi
and r11,4095
cmp r10,r11
jb NEAR $L$mul4xsp_alt
sub rsp,r11
- lea rsp,[((-64))+r9*2+rsp]
+ lea rsp,[((-320))+r9*2+rsp]
jmp NEAR $L$mul4xsp_done
ALIGN 32
$L$mul4xsp_alt:
- lea r10,[((4096-64))+r9*2]
- lea rsp,[((-64))+r9*2+rsp]
+ lea r10,[((4096-320))+r9*2]
+ lea rsp,[((-320))+r9*2+rsp]
sub r11,r10
mov r10,0
cmovc r11,r10
@@ -356,8 +481,7 @@ $L$mul4x_body:
mov rsi,QWORD[40+rsp]
mov rax,1
- movaps xmm6,XMMWORD[((-88))+rsi]
- movaps xmm7,XMMWORD[((-72))+rsi]
+
mov r15,QWORD[((-48))+rsi]
mov r14,QWORD[((-40))+rsi]
mov r13,QWORD[((-32))+rsi]
@@ -375,47 +499,141 @@ $L$SEH_end_bn_mul4x_mont_gather5:
ALIGN 32
mul4x_internal:
shl r9,5
- mov r10d,DWORD[56+rax]
- lea r13,[256+r9*1+rdx]
+ movd xmm5,DWORD[56+rax]
+ lea rax,[$L$inc]
+ lea r13,[128+r9*1+rdx]
shr r9,5
- mov r11,r10
- shr r10,3
- and r11,7
- not r10
- lea rax,[$L$magic_masks]
- and r10,3
- lea r12,[96+r11*8+rdx]
- movq xmm4,QWORD[r10*8+rax]
- movq xmm5,QWORD[8+r10*8+rax]
- add r11,7
- movq xmm6,QWORD[16+r10*8+rax]
- movq xmm7,QWORD[24+r10*8+rax]
- and r11,7
-
- movq xmm0,QWORD[(((-96)))+r12]
- lea r14,[256+r12]
- movq xmm1,QWORD[((-32))+r12]
- pand xmm0,xmm4
- movq xmm2,QWORD[32+r12]
- pand xmm1,xmm5
- movq xmm3,QWORD[96+r12]
- pand xmm2,xmm6
-DB 0x67
- por xmm0,xmm1
- movq xmm1,QWORD[((-96))+r14]
-DB 0x67
- pand xmm3,xmm7
-DB 0x67
- por xmm0,xmm2
- movq xmm2,QWORD[((-32))+r14]
+ movdqa xmm0,XMMWORD[rax]
+ movdqa xmm1,XMMWORD[16+rax]
+ lea r10,[((88-112))+r9*1+rsp]
+ lea r12,[128+rdx]
+
+ pshufd xmm5,xmm5,0
+ movdqa xmm4,xmm1
+DB 0x67,0x67
+ movdqa xmm2,xmm1
+ paddd xmm1,xmm0
+ pcmpeqd xmm0,xmm5
DB 0x67
- pand xmm1,xmm4
+ movdqa xmm3,xmm4
+ paddd xmm2,xmm1
+ pcmpeqd xmm1,xmm5
+ movdqa XMMWORD[112+r10],xmm0
+ movdqa xmm0,xmm4
+
+ paddd xmm3,xmm2
+ pcmpeqd xmm2,xmm5
+ movdqa XMMWORD[128+r10],xmm1
+ movdqa xmm1,xmm4
+
+ paddd xmm0,xmm3
+ pcmpeqd xmm3,xmm5
+ movdqa XMMWORD[144+r10],xmm2
+ movdqa xmm2,xmm4
+
+ paddd xmm1,xmm0
+ pcmpeqd xmm0,xmm5
+ movdqa XMMWORD[160+r10],xmm3
+ movdqa xmm3,xmm4
+ paddd xmm2,xmm1
+ pcmpeqd xmm1,xmm5
+ movdqa XMMWORD[176+r10],xmm0
+ movdqa xmm0,xmm4
+
+ paddd xmm3,xmm2
+ pcmpeqd xmm2,xmm5
+ movdqa XMMWORD[192+r10],xmm1
+ movdqa xmm1,xmm4
+
+ paddd xmm0,xmm3
+ pcmpeqd xmm3,xmm5
+ movdqa XMMWORD[208+r10],xmm2
+ movdqa xmm2,xmm4
+
+ paddd xmm1,xmm0
+ pcmpeqd xmm0,xmm5
+ movdqa XMMWORD[224+r10],xmm3
+ movdqa xmm3,xmm4
+ paddd xmm2,xmm1
+ pcmpeqd xmm1,xmm5
+ movdqa XMMWORD[240+r10],xmm0
+ movdqa xmm0,xmm4
+
+ paddd xmm3,xmm2
+ pcmpeqd xmm2,xmm5
+ movdqa XMMWORD[256+r10],xmm1
+ movdqa xmm1,xmm4
+
+ paddd xmm0,xmm3
+ pcmpeqd xmm3,xmm5
+ movdqa XMMWORD[272+r10],xmm2
+ movdqa xmm2,xmm4
+
+ paddd xmm1,xmm0
+ pcmpeqd xmm0,xmm5
+ movdqa XMMWORD[288+r10],xmm3
+ movdqa xmm3,xmm4
+ paddd xmm2,xmm1
+ pcmpeqd xmm1,xmm5
+ movdqa XMMWORD[304+r10],xmm0
+
+ paddd xmm3,xmm2
DB 0x67
- por xmm0,xmm3
- movq xmm3,QWORD[32+r14]
+ pcmpeqd xmm2,xmm5
+ movdqa XMMWORD[320+r10],xmm1
+ pcmpeqd xmm3,xmm5
+ movdqa XMMWORD[336+r10],xmm2
+ pand xmm0,XMMWORD[64+r12]
+
+ pand xmm1,XMMWORD[80+r12]
+ pand xmm2,XMMWORD[96+r12]
+ movdqa XMMWORD[352+r10],xmm3
+ pand xmm3,XMMWORD[112+r12]
+ por xmm0,xmm2
+ por xmm1,xmm3
+ movdqa xmm4,XMMWORD[((-128))+r12]
+ movdqa xmm5,XMMWORD[((-112))+r12]
+ movdqa xmm2,XMMWORD[((-96))+r12]
+ pand xmm4,XMMWORD[112+r10]
+ movdqa xmm3,XMMWORD[((-80))+r12]
+ pand xmm5,XMMWORD[128+r10]
+ por xmm0,xmm4
+ pand xmm2,XMMWORD[144+r10]
+ por xmm1,xmm5
+ pand xmm3,XMMWORD[160+r10]
+ por xmm0,xmm2
+ por xmm1,xmm3
+ movdqa xmm4,XMMWORD[((-64))+r12]
+ movdqa xmm5,XMMWORD[((-48))+r12]
+ movdqa xmm2,XMMWORD[((-32))+r12]
+ pand xmm4,XMMWORD[176+r10]
+ movdqa xmm3,XMMWORD[((-16))+r12]
+ pand xmm5,XMMWORD[192+r10]
+ por xmm0,xmm4
+ pand xmm2,XMMWORD[208+r10]
+ por xmm1,xmm5
+ pand xmm3,XMMWORD[224+r10]
+ por xmm0,xmm2
+ por xmm1,xmm3
+ movdqa xmm4,XMMWORD[r12]
+ movdqa xmm5,XMMWORD[16+r12]
+ movdqa xmm2,XMMWORD[32+r12]
+ pand xmm4,XMMWORD[240+r10]
+ movdqa xmm3,XMMWORD[48+r12]
+ pand xmm5,XMMWORD[256+r10]
+ por xmm0,xmm4
+ pand xmm2,XMMWORD[272+r10]
+ por xmm1,xmm5
+ pand xmm3,XMMWORD[288+r10]
+ por xmm0,xmm2
+ por xmm1,xmm3
+ por xmm0,xmm1
+ pshufd xmm1,xmm0,0x4e
+ por xmm0,xmm1
+ lea r12,[256+r12]
DB 102,72,15,126,195
- movq xmm0,QWORD[96+r14]
+
mov QWORD[((16+8))+rsp],r13
mov QWORD[((56+8))+rsp],rdi
@@ -429,26 +647,10 @@ DB 102,72,15,126,195
mov r10,rax
mov rax,QWORD[rcx]
- pand xmm2,xmm5
- pand xmm3,xmm6
- por xmm1,xmm2
-
imul rbp,r10
-
-
-
-
-
-
-
- lea r14,[((64+8))+r11*8+rsp]
+ lea r14,[((64+8))+rsp]
mov r11,rdx
- pand xmm0,xmm7
- por xmm1,xmm3
- lea r12,[512+r12]
- por xmm0,xmm1
-
mul rbp
add r10,rax
mov rax,QWORD[8+r9*1+rsi]
@@ -457,7 +659,7 @@ DB 102,72,15,126,195
mul rbx
add r11,rax
- mov rax,QWORD[16+rcx]
+ mov rax,QWORD[8+rcx]
adc rdx,0
mov r10,rdx
@@ -467,7 +669,7 @@ DB 102,72,15,126,195
adc rdx,0
add rdi,r11
lea r15,[32+r9]
- lea rcx,[64+rcx]
+ lea rcx,[32+rcx]
adc rdx,0
mov QWORD[r14],rdi
mov r13,rdx
@@ -477,7 +679,7 @@ ALIGN 32
$L$1st4x:
mul rbx
add r10,rax
- mov rax,QWORD[((-32))+rcx]
+ mov rax,QWORD[((-16))+rcx]
lea r14,[32+r14]
adc rdx,0
mov r11,rdx
@@ -493,7 +695,7 @@ $L$1st4x:
mul rbx
add r11,rax
- mov rax,QWORD[((-16))+rcx]
+ mov rax,QWORD[((-8))+rcx]
adc rdx,0
mov r10,rdx
@@ -523,7 +725,7 @@ $L$1st4x:
mul rbx
add r11,rax
- mov rax,QWORD[16+rcx]
+ mov rax,QWORD[8+rcx]
adc rdx,0
mov r10,rdx
@@ -532,7 +734,7 @@ $L$1st4x:
mov rax,QWORD[16+r15*1+rsi]
adc rdx,0
add rdi,r11
- lea rcx,[64+rcx]
+ lea rcx,[32+rcx]
adc rdx,0
mov QWORD[r14],rdi
mov r13,rdx
@@ -542,7 +744,7 @@ $L$1st4x:
mul rbx
add r10,rax
- mov rax,QWORD[((-32))+rcx]
+ mov rax,QWORD[((-16))+rcx]
lea r14,[32+r14]
adc rdx,0
mov r11,rdx
@@ -558,7 +760,7 @@ $L$1st4x:
mul rbx
add r11,rax
- mov rax,QWORD[((-16))+rcx]
+ mov rax,QWORD[((-8))+rcx]
adc rdx,0
mov r10,rdx
@@ -571,8 +773,7 @@ $L$1st4x:
mov QWORD[((-16))+r14],rdi
mov r13,rdx
-DB 102,72,15,126,195
- lea rcx,[r9*2+rcx]
+ lea rcx,[r9*1+rcx]
xor rdi,rdi
add r13,r10
@@ -583,6 +784,63 @@ DB 102,72,15,126,195
ALIGN 32
$L$outer4x:
+ lea rdx,[((16+128))+r14]
+ pxor xmm4,xmm4
+ pxor xmm5,xmm5
+ movdqa xmm0,XMMWORD[((-128))+r12]
+ movdqa xmm1,XMMWORD[((-112))+r12]
+ movdqa xmm2,XMMWORD[((-96))+r12]
+ movdqa xmm3,XMMWORD[((-80))+r12]
+ pand xmm0,XMMWORD[((-128))+rdx]
+ pand xmm1,XMMWORD[((-112))+rdx]
+ por xmm4,xmm0
+ pand xmm2,XMMWORD[((-96))+rdx]
+ por xmm5,xmm1
+ pand xmm3,XMMWORD[((-80))+rdx]
+ por xmm4,xmm2
+ por xmm5,xmm3
+ movdqa xmm0,XMMWORD[((-64))+r12]
+ movdqa xmm1,XMMWORD[((-48))+r12]
+ movdqa xmm2,XMMWORD[((-32))+r12]
+ movdqa xmm3,XMMWORD[((-16))+r12]
+ pand xmm0,XMMWORD[((-64))+rdx]
+ pand xmm1,XMMWORD[((-48))+rdx]
+ por xmm4,xmm0
+ pand xmm2,XMMWORD[((-32))+rdx]
+ por xmm5,xmm1
+ pand xmm3,XMMWORD[((-16))+rdx]
+ por xmm4,xmm2
+ por xmm5,xmm3
+ movdqa xmm0,XMMWORD[r12]
+ movdqa xmm1,XMMWORD[16+r12]
+ movdqa xmm2,XMMWORD[32+r12]
+ movdqa xmm3,XMMWORD[48+r12]
+ pand xmm0,XMMWORD[rdx]
+ pand xmm1,XMMWORD[16+rdx]
+ por xmm4,xmm0
+ pand xmm2,XMMWORD[32+rdx]
+ por xmm5,xmm1
+ pand xmm3,XMMWORD[48+rdx]
+ por xmm4,xmm2
+ por xmm5,xmm3
+ movdqa xmm0,XMMWORD[64+r12]
+ movdqa xmm1,XMMWORD[80+r12]
+ movdqa xmm2,XMMWORD[96+r12]
+ movdqa xmm3,XMMWORD[112+r12]
+ pand xmm0,XMMWORD[64+rdx]
+ pand xmm1,XMMWORD[80+rdx]
+ por xmm4,xmm0
+ pand xmm2,XMMWORD[96+rdx]
+ por xmm5,xmm1
+ pand xmm3,XMMWORD[112+rdx]
+ por xmm4,xmm2
+ por xmm5,xmm3
+ por xmm4,xmm5
+ pshufd xmm0,xmm4,0x4e
+ por xmm0,xmm4
+ lea r12,[256+r12]
+DB 102,72,15,126,195
+
mov r10,QWORD[r9*1+r14]
mov rbp,r8
mul rbx
@@ -590,25 +848,11 @@ $L$outer4x:
mov rax,QWORD[rcx]
adc rdx,0
- movq xmm0,QWORD[(((-96)))+r12]
- movq xmm1,QWORD[((-32))+r12]
- pand xmm0,xmm4
- movq xmm2,QWORD[32+r12]
- pand xmm1,xmm5
- movq xmm3,QWORD[96+r12]
-
imul rbp,r10
-DB 0x67
mov r11,rdx
mov QWORD[r14],rdi
- pand xmm2,xmm6
- por xmm0,xmm1
- pand xmm3,xmm7
- por xmm0,xmm2
lea r14,[r9*1+r14]
- lea r12,[256+r12]
- por xmm0,xmm3
mul rbp
add r10,rax
@@ -618,7 +862,7 @@ DB 0x67
mul rbx
add r11,rax
- mov rax,QWORD[16+rcx]
+ mov rax,QWORD[8+rcx]
adc rdx,0
add r11,QWORD[8+r14]
adc rdx,0
@@ -630,7 +874,7 @@ DB 0x67
adc rdx,0
add rdi,r11
lea r15,[32+r9]
- lea rcx,[64+rcx]
+ lea rcx,[32+rcx]
adc rdx,0
mov r13,rdx
jmp NEAR $L$inner4x
@@ -639,7 +883,7 @@ ALIGN 32
$L$inner4x:
mul rbx
add r10,rax
- mov rax,QWORD[((-32))+rcx]
+ mov rax,QWORD[((-16))+rcx]
adc rdx,0
add r10,QWORD[16+r14]
lea r14,[32+r14]
@@ -657,7 +901,7 @@ $L$inner4x:
mul rbx
add r11,rax
- mov rax,QWORD[((-16))+rcx]
+ mov rax,QWORD[((-8))+rcx]
adc rdx,0
add r11,QWORD[((-8))+r14]
adc rdx,0
@@ -691,7 +935,7 @@ $L$inner4x:
mul rbx
add r11,rax
- mov rax,QWORD[16+rcx]
+ mov rax,QWORD[8+rcx]
adc rdx,0
add r11,QWORD[8+r14]
adc rdx,0
@@ -702,7 +946,7 @@ $L$inner4x:
mov rax,QWORD[16+r15*1+rsi]
adc rdx,0
add rdi,r11
- lea rcx,[64+rcx]
+ lea rcx,[32+rcx]
adc rdx,0
mov QWORD[((-8))+r14],r13
mov r13,rdx
@@ -712,7 +956,7 @@ $L$inner4x:
mul rbx
add r10,rax
- mov rax,QWORD[((-32))+rcx]
+ mov rax,QWORD[((-16))+rcx]
adc rdx,0
add r10,QWORD[16+r14]
lea r14,[32+r14]
@@ -731,7 +975,7 @@ $L$inner4x:
mul rbx
add r11,rax
mov rax,rbp
- mov rbp,QWORD[((-16))+rcx]
+ mov rbp,QWORD[((-8))+rcx]
adc rdx,0
add r11,QWORD[((-8))+r14]
adc rdx,0
@@ -746,9 +990,8 @@ $L$inner4x:
mov QWORD[((-24))+r14],r13
mov r13,rdx
-DB 102,72,15,126,195
mov QWORD[((-16))+r14],rdi
- lea rcx,[r9*2+rcx]
+ lea rcx,[r9*1+rcx]
xor rdi,rdi
add r13,r10
@@ -759,16 +1002,23 @@ DB 102,72,15,126,195
cmp r12,QWORD[((16+8))+rsp]
jb NEAR $L$outer4x
+ xor rax,rax
sub rbp,r13
adc r15,r15
or rdi,r15
- xor rdi,1
+ sub rax,rdi
lea rbx,[r9*1+r14]
- lea rbp,[rdi*8+rcx]
+ mov r12,QWORD[rcx]
+ lea rbp,[rcx]
mov rcx,r9
sar rcx,3+2
mov rdi,QWORD[((56+8))+rsp]
- jmp NEAR $L$sqr4x_sub
+ dec r12
+ xor r10,r10
+ mov r13,QWORD[8+rbp]
+ mov r14,QWORD[16+rbp]
+ mov r15,QWORD[24+rbp]
+ jmp NEAR $L$sqr4x_sub_entry
global bn_power5
@@ -793,12 +1043,9 @@ $L$SEH_begin_bn_power5:
push r13
push r14
push r15
- lea rsp,[((-40))+rsp]
- movaps XMMWORD[rsp],xmm6
- movaps XMMWORD[16+rsp],xmm7
- mov r10d,r9d
+
shl r9d,3
- shl r10d,3+2
+ lea r10d,[r9*2+r9]
neg r9
mov r8,QWORD[r8]
@@ -808,19 +1055,20 @@ $L$SEH_begin_bn_power5:
- lea r11,[((-64))+r9*2+rsp]
- sub r11,rsi
+
+ lea r11,[((-320))+r9*2+rsp]
+ sub r11,rdi
and r11,4095
cmp r10,r11
jb NEAR $L$pwr_sp_alt
sub rsp,r11
- lea rsp,[((-64))+r9*2+rsp]
+ lea rsp,[((-320))+r9*2+rsp]
jmp NEAR $L$pwr_sp_done
ALIGN 32
$L$pwr_sp_alt:
- lea r10,[((4096-64))+r9*2]
- lea rsp,[((-64))+r9*2+rsp]
+ lea r10,[((4096-320))+r9*2]
+ lea rsp,[((-320))+r9*2+rsp]
sub r11,r10
mov r10,0
cmovc r11,r10
@@ -848,10 +1096,15 @@ DB 102,73,15,110,218
DB 102,72,15,110,226
call __bn_sqr8x_internal
+ call __bn_post4x_internal
call __bn_sqr8x_internal
+ call __bn_post4x_internal
call __bn_sqr8x_internal
+ call __bn_post4x_internal
call __bn_sqr8x_internal
+ call __bn_post4x_internal
call __bn_sqr8x_internal
+ call __bn_post4x_internal
DB 102,72,15,126,209
DB 102,72,15,126,226
@@ -1397,9 +1650,9 @@ DB 0x67
mov QWORD[((-16))+rdi],rbx
mov QWORD[((-8))+rdi],r8
DB 102,72,15,126,213
-sqr8x_reduction:
+__bn_sqr8x_reduction:
xor rax,rax
- lea rcx,[r9*2+rbp]
+ lea rcx,[rbp*1+r9]
lea rdx,[((48+8))+r9*2+rsp]
mov QWORD[((0+8))+rsp],rcx
lea rdi,[((48+8))+r9*1+rsp]
@@ -1432,14 +1685,14 @@ DB 0x67
ALIGN 32
$L$8x_reduce:
mul rbx
- mov rax,QWORD[16+rbp]
+ mov rax,QWORD[8+rbp]
neg r8
mov r8,rdx
adc r8,0
mul rbx
add r9,rax
- mov rax,QWORD[32+rbp]
+ mov rax,QWORD[16+rbp]
adc rdx,0
add r8,r9
mov QWORD[((48-8+8))+rcx*8+rsp],rbx
@@ -1448,7 +1701,7 @@ $L$8x_reduce:
mul rbx
add r10,rax
- mov rax,QWORD[48+rbp]
+ mov rax,QWORD[24+rbp]
adc rdx,0
add r9,r10
mov rsi,QWORD[((32+8))+rsp]
@@ -1457,7 +1710,7 @@ $L$8x_reduce:
mul rbx
add r11,rax
- mov rax,QWORD[64+rbp]
+ mov rax,QWORD[32+rbp]
adc rdx,0
imul rsi,r8
add r10,r11
@@ -1466,7 +1719,7 @@ $L$8x_reduce:
mul rbx
add r12,rax
- mov rax,QWORD[80+rbp]
+ mov rax,QWORD[40+rbp]
adc rdx,0
add r11,r12
mov r12,rdx
@@ -1474,7 +1727,7 @@ $L$8x_reduce:
mul rbx
add r13,rax
- mov rax,QWORD[96+rbp]
+ mov rax,QWORD[48+rbp]
adc rdx,0
add r12,r13
mov r13,rdx
@@ -1482,7 +1735,7 @@ $L$8x_reduce:
mul rbx
add r14,rax
- mov rax,QWORD[112+rbp]
+ mov rax,QWORD[56+rbp]
adc rdx,0
add r13,r14
mov r14,rdx
@@ -1500,7 +1753,7 @@ $L$8x_reduce:
dec ecx
jnz NEAR $L$8x_reduce
- lea rbp,[128+rbp]
+ lea rbp,[64+rbp]
xor rax,rax
mov rdx,QWORD[((8+8))+rsp]
cmp rbp,QWORD[((0+8))+rsp]
@@ -1526,14 +1779,14 @@ ALIGN 32
$L$8x_tail:
mul rbx
add r8,rax
- mov rax,QWORD[16+rbp]
+ mov rax,QWORD[8+rbp]
mov QWORD[rdi],r8
mov r8,rdx
adc r8,0
mul rbx
add r9,rax
- mov rax,QWORD[32+rbp]
+ mov rax,QWORD[16+rbp]
adc rdx,0
add r8,r9
lea rdi,[8+rdi]
@@ -1542,7 +1795,7 @@ $L$8x_tail:
mul rbx
add r10,rax
- mov rax,QWORD[48+rbp]
+ mov rax,QWORD[24+rbp]
adc rdx,0
add r9,r10
mov r10,rdx
@@ -1550,7 +1803,7 @@ $L$8x_tail:
mul rbx
add r11,rax
- mov rax,QWORD[64+rbp]
+ mov rax,QWORD[32+rbp]
adc rdx,0
add r10,r11
mov r11,rdx
@@ -1558,7 +1811,7 @@ $L$8x_tail:
mul rbx
add r12,rax
- mov rax,QWORD[80+rbp]
+ mov rax,QWORD[40+rbp]
adc rdx,0
add r11,r12
mov r12,rdx
@@ -1566,7 +1819,7 @@ $L$8x_tail:
mul rbx
add r13,rax
- mov rax,QWORD[96+rbp]
+ mov rax,QWORD[48+rbp]
adc rdx,0
add r12,r13
mov r13,rdx
@@ -1574,7 +1827,7 @@ $L$8x_tail:
mul rbx
add r14,rax
- mov rax,QWORD[112+rbp]
+ mov rax,QWORD[56+rbp]
adc rdx,0
add r13,r14
mov r14,rdx
@@ -1592,7 +1845,7 @@ $L$8x_tail:
dec ecx
jnz NEAR $L$8x_tail
- lea rbp,[128+rbp]
+ lea rbp,[64+rbp]
mov rdx,QWORD[((8+8))+rsp]
cmp rbp,QWORD[((0+8))+rsp]
jae NEAR $L$8x_tail_done
@@ -1638,7 +1891,7 @@ $L$8x_no_tail:
adc r14,QWORD[48+rdi]
adc r15,QWORD[56+rdi]
adc rax,0
- mov rcx,QWORD[((-16))+rbp]
+ mov rcx,QWORD[((-8))+rbp]
xor rsi,rsi
DB 102,72,15,126,213
@@ -1656,40 +1909,58 @@ DB 102,73,15,126,217
cmp rdi,rdx
jb NEAR $L$8x_reduction_loop
+ DB 0F3h,0C3h ;repret
+
- sub rcx,r15
+ALIGN 32
+__bn_post4x_internal:
+ mov r12,QWORD[rbp]
lea rbx,[r9*1+rdi]
- adc rsi,rsi
mov rcx,r9
- or rax,rsi
DB 102,72,15,126,207
- xor rax,1
+ neg rax
DB 102,72,15,126,206
- lea rbp,[rax*8+rbp]
sar rcx,3+2
- jmp NEAR $L$sqr4x_sub
+ dec r12
+ xor r10,r10
+ mov r13,QWORD[8+rbp]
+ mov r14,QWORD[16+rbp]
+ mov r15,QWORD[24+rbp]
+ jmp NEAR $L$sqr4x_sub_entry
-ALIGN 32
+ALIGN 16
$L$sqr4x_sub:
-DB 0x66
- mov r12,QWORD[rbx]
- mov r13,QWORD[8+rbx]
- sbb r12,QWORD[rbp]
- mov r14,QWORD[16+rbx]
- sbb r13,QWORD[16+rbp]
- mov r15,QWORD[24+rbx]
- lea rbx,[32+rbx]
- sbb r14,QWORD[32+rbp]
+ mov r12,QWORD[rbp]
+ mov r13,QWORD[8+rbp]
+ mov r14,QWORD[16+rbp]
+ mov r15,QWORD[24+rbp]
+$L$sqr4x_sub_entry:
+ lea rbp,[32+rbp]
+ not r12
+ not r13
+ not r14
+ not r15
+ and r12,rax
+ and r13,rax
+ and r14,rax
+ and r15,rax
+
+ neg r10
+ adc r12,QWORD[rbx]
+ adc r13,QWORD[8+rbx]
+ adc r14,QWORD[16+rbx]
+ adc r15,QWORD[24+rbx]
mov QWORD[rdi],r12
- sbb r15,QWORD[48+rbp]
- lea rbp,[64+rbp]
+ lea rbx,[32+rbx]
mov QWORD[8+rdi],r13
+ sbb r10,r10
mov QWORD[16+rdi],r14
mov QWORD[24+rdi],r15
lea rdi,[32+rdi]
inc rcx
jnz NEAR $L$sqr4x_sub
+
mov r10,r9
neg r9
DB 0F3h,0C3h ;repret
@@ -1727,13 +1998,9 @@ DB 0x67
push r13
push r14
push r15
- lea rsp,[((-40))+rsp]
- movaps XMMWORD[rsp],xmm6
- movaps XMMWORD[16+rsp],xmm7
-DB 0x67
- mov r10d,r9d
+
shl r9d,3
- shl r10d,3+2
+ lea r10,[r9*2+r9]
neg r9
mov r8,QWORD[r8]
@@ -1743,19 +2010,20 @@ DB 0x67
- lea r11,[((-64))+r9*2+rsp]
- sub r11,rsi
+
+ lea r11,[((-320))+r9*2+rsp]
+ sub r11,rdi
and r11,4095
cmp r10,r11
jb NEAR $L$from_sp_alt
sub rsp,r11
- lea rsp,[((-64))+r9*2+rsp]
+ lea rsp,[((-320))+r9*2+rsp]
jmp NEAR $L$from_sp_done
ALIGN 32
$L$from_sp_alt:
- lea r10,[((4096-64))+r9*2]
- lea rsp,[((-64))+r9*2+rsp]
+ lea r10,[((4096-320))+r9*2]
+ lea rsp,[((-320))+r9*2+rsp]
sub r11,r10
mov r10,0
cmovc r11,r10
@@ -1806,7 +2074,8 @@ DB 102,72,15,110,209
DB 0x67
mov rbp,rcx
DB 102,73,15,110,218
- call sqr8x_reduction
+ call __bn_sqr8x_reduction
+ call __bn_post4x_internal
pxor xmm0,xmm0
lea rax,[48+rsp]
@@ -1856,55 +2125,171 @@ $L$scatter_epilogue:
global bn_gather5
-ALIGN 16
+ALIGN 32
bn_gather5:
$L$SEH_begin_bn_gather5:
-DB 0x48,0x83,0xec,0x28
-DB 0x0f,0x29,0x34,0x24
-DB 0x0f,0x29,0x7c,0x24,0x10
- mov r11d,r9d
- shr r9d,3
- and r11,7
- not r9d
- lea rax,[$L$magic_masks]
- and r9d,3
- lea r8,[128+r11*8+r8]
- movq xmm4,QWORD[r9*8+rax]
- movq xmm5,QWORD[8+r9*8+rax]
- movq xmm6,QWORD[16+r9*8+rax]
- movq xmm7,QWORD[24+r9*8+rax]
+DB 0x4c,0x8d,0x14,0x24
+DB 0x48,0x81,0xec,0x08,0x01,0x00,0x00
+ lea rax,[$L$inc]
+ and rsp,-16
+
+ movd xmm5,r9d
+ movdqa xmm0,XMMWORD[rax]
+ movdqa xmm1,XMMWORD[16+rax]
+ lea r11,[128+r8]
+ lea rax,[128+rsp]
+
+ pshufd xmm5,xmm5,0
+ movdqa xmm4,xmm1
+ movdqa xmm2,xmm1
+ paddd xmm1,xmm0
+ pcmpeqd xmm0,xmm5
+ movdqa xmm3,xmm4
+
+ paddd xmm2,xmm1
+ pcmpeqd xmm1,xmm5
+ movdqa XMMWORD[(-128)+rax],xmm0
+ movdqa xmm0,xmm4
+
+ paddd xmm3,xmm2
+ pcmpeqd xmm2,xmm5
+ movdqa XMMWORD[(-112)+rax],xmm1
+ movdqa xmm1,xmm4
+
+ paddd xmm0,xmm3
+ pcmpeqd xmm3,xmm5
+ movdqa XMMWORD[(-96)+rax],xmm2
+ movdqa xmm2,xmm4
+ paddd xmm1,xmm0
+ pcmpeqd xmm0,xmm5
+ movdqa XMMWORD[(-80)+rax],xmm3
+ movdqa xmm3,xmm4
+
+ paddd xmm2,xmm1
+ pcmpeqd xmm1,xmm5
+ movdqa XMMWORD[(-64)+rax],xmm0
+ movdqa xmm0,xmm4
+
+ paddd xmm3,xmm2
+ pcmpeqd xmm2,xmm5
+ movdqa XMMWORD[(-48)+rax],xmm1
+ movdqa xmm1,xmm4
+
+ paddd xmm0,xmm3
+ pcmpeqd xmm3,xmm5
+ movdqa XMMWORD[(-32)+rax],xmm2
+ movdqa xmm2,xmm4
+ paddd xmm1,xmm0
+ pcmpeqd xmm0,xmm5
+ movdqa XMMWORD[(-16)+rax],xmm3
+ movdqa xmm3,xmm4
+
+ paddd xmm2,xmm1
+ pcmpeqd xmm1,xmm5
+ movdqa XMMWORD[rax],xmm0
+ movdqa xmm0,xmm4
+
+ paddd xmm3,xmm2
+ pcmpeqd xmm2,xmm5
+ movdqa XMMWORD[16+rax],xmm1
+ movdqa xmm1,xmm4
+
+ paddd xmm0,xmm3
+ pcmpeqd xmm3,xmm5
+ movdqa XMMWORD[32+rax],xmm2
+ movdqa xmm2,xmm4
+ paddd xmm1,xmm0
+ pcmpeqd xmm0,xmm5
+ movdqa XMMWORD[48+rax],xmm3
+ movdqa xmm3,xmm4
+
+ paddd xmm2,xmm1
+ pcmpeqd xmm1,xmm5
+ movdqa XMMWORD[64+rax],xmm0
+ movdqa xmm0,xmm4
+
+ paddd xmm3,xmm2
+ pcmpeqd xmm2,xmm5
+ movdqa XMMWORD[80+rax],xmm1
+ movdqa xmm1,xmm4
+
+ paddd xmm0,xmm3
+ pcmpeqd xmm3,xmm5
+ movdqa XMMWORD[96+rax],xmm2
+ movdqa xmm2,xmm4
+ movdqa XMMWORD[112+rax],xmm3
jmp NEAR $L$gather
-ALIGN 16
-$L$gather:
- movq xmm0,QWORD[(((-128)))+r8]
- movq xmm1,QWORD[((-64))+r8]
- pand xmm0,xmm4
- movq xmm2,QWORD[r8]
- pand xmm1,xmm5
- movq xmm3,QWORD[64+r8]
- pand xmm2,xmm6
- por xmm0,xmm1
- pand xmm3,xmm7
-DB 0x67,0x67
- por xmm0,xmm2
- lea r8,[256+r8]
- por xmm0,xmm3
+ALIGN 32
+$L$gather:
+ pxor xmm4,xmm4
+ pxor xmm5,xmm5
+ movdqa xmm0,XMMWORD[((-128))+r11]
+ movdqa xmm1,XMMWORD[((-112))+r11]
+ movdqa xmm2,XMMWORD[((-96))+r11]
+ pand xmm0,XMMWORD[((-128))+rax]
+ movdqa xmm3,XMMWORD[((-80))+r11]
+ pand xmm1,XMMWORD[((-112))+rax]
+ por xmm4,xmm0
+ pand xmm2,XMMWORD[((-96))+rax]
+ por xmm5,xmm1
+ pand xmm3,XMMWORD[((-80))+rax]
+ por xmm4,xmm2
+ por xmm5,xmm3
+ movdqa xmm0,XMMWORD[((-64))+r11]
+ movdqa xmm1,XMMWORD[((-48))+r11]
+ movdqa xmm2,XMMWORD[((-32))+r11]
+ pand xmm0,XMMWORD[((-64))+rax]
+ movdqa xmm3,XMMWORD[((-16))+r11]
+ pand xmm1,XMMWORD[((-48))+rax]
+ por xmm4,xmm0
+ pand xmm2,XMMWORD[((-32))+rax]
+ por xmm5,xmm1
+ pand xmm3,XMMWORD[((-16))+rax]
+ por xmm4,xmm2
+ por xmm5,xmm3
+ movdqa xmm0,XMMWORD[r11]
+ movdqa xmm1,XMMWORD[16+r11]
+ movdqa xmm2,XMMWORD[32+r11]
+ pand xmm0,XMMWORD[rax]
+ movdqa xmm3,XMMWORD[48+r11]
+ pand xmm1,XMMWORD[16+rax]
+ por xmm4,xmm0
+ pand xmm2,XMMWORD[32+rax]
+ por xmm5,xmm1
+ pand xmm3,XMMWORD[48+rax]
+ por xmm4,xmm2
+ por xmm5,xmm3
+ movdqa xmm0,XMMWORD[64+r11]
+ movdqa xmm1,XMMWORD[80+r11]
+ movdqa xmm2,XMMWORD[96+r11]
+ pand xmm0,XMMWORD[64+rax]
+ movdqa xmm3,XMMWORD[112+r11]
+ pand xmm1,XMMWORD[80+rax]
+ por xmm4,xmm0
+ pand xmm2,XMMWORD[96+rax]
+ por xmm5,xmm1
+ pand xmm3,XMMWORD[112+rax]
+ por xmm4,xmm2
+ por xmm5,xmm3
+ por xmm4,xmm5
+ lea r11,[256+r11]
+ pshufd xmm0,xmm4,0x4e
+ por xmm0,xmm4
movq QWORD[rcx],xmm0
lea rcx,[8+rcx]
sub edx,1
jnz NEAR $L$gather
- movaps xmm6,XMMWORD[rsp]
- movaps xmm7,XMMWORD[16+rsp]
- lea rsp,[40+rsp]
+
+ lea rsp,[r10]
DB 0F3h,0C3h ;repret
$L$SEH_end_bn_gather5:
ALIGN 64
-$L$magic_masks:
- DD 0,0,0,0,0,0,-1,-1
- DD 0,0,0,0,0,0,0,0
+$L$inc:
+ DD 0,0,1,1
+ DD 2,2,2,2
DB 77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105
DB 112,108,105,99,97,116,105,111,110,32,119,105,116,104,32,115
DB 99,97,116,116,101,114,47,103,97,116,104,101,114,32,102,111
@@ -1946,19 +2331,16 @@ mul_handler:
lea r10,[$L$mul_epilogue]
cmp rbx,r10
- jb NEAR $L$body_40
+ ja NEAR $L$body_40
mov r10,QWORD[192+r8]
mov rax,QWORD[8+r10*8+rax]
+
jmp NEAR $L$body_proceed
$L$body_40:
mov rax,QWORD[40+rax]
$L$body_proceed:
-
- movaps xmm0,XMMWORD[((-88))+rax]
- movaps xmm1,XMMWORD[((-72))+rax]
-
mov rbx,QWORD[((-8))+rax]
mov rbp,QWORD[((-16))+rax]
mov r12,QWORD[((-24))+rax]
@@ -1971,8 +2353,6 @@ $L$body_proceed:
mov QWORD[224+r8],r13
mov QWORD[232+r8],r14
mov QWORD[240+r8],r15
- movups XMMWORD[512+r8],xmm0
- movups XMMWORD[528+r8],xmm1
$L$common_seh_tail:
mov rdi,QWORD[8+rax]
@@ -2058,8 +2438,7 @@ DB 9,0,0,0
DD $L$from_body wrt ..imagebase,$L$from_epilogue wrt ..imagebase
ALIGN 8
$L$SEH_info_bn_gather5:
-DB 0x01,0x0d,0x05,0x00
-DB 0x0d,0x78,0x01,0x00
-DB 0x08,0x68,0x00,0x00
-DB 0x04,0x42,0x00,0x00
+DB 0x01,0x0b,0x03,0x0a
+DB 0x0b,0x01,0x21,0x00
+DB 0x04,0xa3,0x00,0x00
ALIGN 8
diff --git a/win-x86_64/crypto/chacha/chacha-x86_64.asm b/win-x86_64/crypto/chacha/chacha-x86_64.asm
new file mode 100644
index 00000000..0ecbe956
--- /dev/null
+++ b/win-x86_64/crypto/chacha/chacha-x86_64.asm
@@ -0,0 +1,1689 @@
+default rel
+%define XMMWORD
+%define YMMWORD
+%define ZMMWORD
+section .text code align=64
+
+
+EXTERN OPENSSL_ia32cap_P
+
+ALIGN 64
+$L$zero:
+ DD 0,0,0,0
+$L$one:
+ DD 1,0,0,0
+$L$inc:
+ DD 0,1,2,3
+$L$four:
+ DD 4,4,4,4
+$L$incy:
+ DD 0,2,4,6,1,3,5,7
+$L$eight:
+ DD 8,8,8,8,8,8,8,8
+$L$rot16:
+DB 0x2,0x3,0x0,0x1,0x6,0x7,0x4,0x5,0xa,0xb,0x8,0x9,0xe,0xf,0xc,0xd
+$L$rot24:
+DB 0x3,0x0,0x1,0x2,0x7,0x4,0x5,0x6,0xb,0x8,0x9,0xa,0xf,0xc,0xd,0xe
+$L$sigma:
+DB 101,120,112,97,110,100,32,51,50,45,98,121,116,101,32,107
+DB 0
+DB 67,104,97,67,104,97,50,48,32,102,111,114,32,120,56,54
+DB 95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32
+DB 98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115
+DB 108,46,111,114,103,62,0
+global ChaCha20_ctr32
+
+ALIGN 64
+ChaCha20_ctr32:
+ mov QWORD[8+rsp],rdi ;WIN64 prologue
+ mov QWORD[16+rsp],rsi
+ mov rax,rsp
+$L$SEH_begin_ChaCha20_ctr32:
+ mov rdi,rcx
+ mov rsi,rdx
+ mov rdx,r8
+ mov rcx,r9
+ mov r8,QWORD[40+rsp]
+
+
+ cmp rdx,0
+ je NEAR $L$no_data
+ mov r10,QWORD[((OPENSSL_ia32cap_P+4))]
+ test r10d,512
+ jnz NEAR $L$ChaCha20_ssse3
+
+ push rbx
+ push rbp
+ push r12
+ push r13
+ push r14
+ push r15
+ sub rsp,64+24
+
+
+ movdqu xmm1,XMMWORD[rcx]
+ movdqu xmm2,XMMWORD[16+rcx]
+ movdqu xmm3,XMMWORD[r8]
+ movdqa xmm4,XMMWORD[$L$one]
+
+
+ movdqa XMMWORD[16+rsp],xmm1
+ movdqa XMMWORD[32+rsp],xmm2
+ movdqa XMMWORD[48+rsp],xmm3
+ mov rbp,rdx
+ jmp NEAR $L$oop_outer
+
+ALIGN 32
+$L$oop_outer:
+ mov eax,0x61707865
+ mov ebx,0x3320646e
+ mov ecx,0x79622d32
+ mov edx,0x6b206574
+ mov r8d,DWORD[16+rsp]
+ mov r9d,DWORD[20+rsp]
+ mov r10d,DWORD[24+rsp]
+ mov r11d,DWORD[28+rsp]
+ movd r12d,xmm3
+ mov r13d,DWORD[52+rsp]
+ mov r14d,DWORD[56+rsp]
+ mov r15d,DWORD[60+rsp]
+
+ mov QWORD[((64+0))+rsp],rbp
+ mov ebp,10
+ mov QWORD[((64+8))+rsp],rsi
+DB 102,72,15,126,214
+ mov QWORD[((64+16))+rsp],rdi
+ mov rdi,rsi
+ shr rdi,32
+ jmp NEAR $L$oop
+
+ALIGN 32
+$L$oop:
+ add eax,r8d
+ xor r12d,eax
+ rol r12d,16
+ add ebx,r9d
+ xor r13d,ebx
+ rol r13d,16
+ add esi,r12d
+ xor r8d,esi
+ rol r8d,12
+ add edi,r13d
+ xor r9d,edi
+ rol r9d,12
+ add eax,r8d
+ xor r12d,eax
+ rol r12d,8
+ add ebx,r9d
+ xor r13d,ebx
+ rol r13d,8
+ add esi,r12d
+ xor r8d,esi
+ rol r8d,7
+ add edi,r13d
+ xor r9d,edi
+ rol r9d,7
+ mov DWORD[32+rsp],esi
+ mov DWORD[36+rsp],edi
+ mov esi,DWORD[40+rsp]
+ mov edi,DWORD[44+rsp]
+ add ecx,r10d
+ xor r14d,ecx
+ rol r14d,16
+ add edx,r11d
+ xor r15d,edx
+ rol r15d,16
+ add esi,r14d
+ xor r10d,esi
+ rol r10d,12
+ add edi,r15d
+ xor r11d,edi
+ rol r11d,12
+ add ecx,r10d
+ xor r14d,ecx
+ rol r14d,8
+ add edx,r11d
+ xor r15d,edx
+ rol r15d,8
+ add esi,r14d
+ xor r10d,esi
+ rol r10d,7
+ add edi,r15d
+ xor r11d,edi
+ rol r11d,7
+ add eax,r9d
+ xor r15d,eax
+ rol r15d,16
+ add ebx,r10d
+ xor r12d,ebx
+ rol r12d,16
+ add esi,r15d
+ xor r9d,esi
+ rol r9d,12
+ add edi,r12d
+ xor r10d,edi
+ rol r10d,12
+ add eax,r9d
+ xor r15d,eax
+ rol r15d,8
+ add ebx,r10d
+ xor r12d,ebx
+ rol r12d,8
+ add esi,r15d
+ xor r9d,esi
+ rol r9d,7
+ add edi,r12d
+ xor r10d,edi
+ rol r10d,7
+ mov DWORD[40+rsp],esi
+ mov DWORD[44+rsp],edi
+ mov esi,DWORD[32+rsp]
+ mov edi,DWORD[36+rsp]
+ add ecx,r11d
+ xor r13d,ecx
+ rol r13d,16
+ add edx,r8d
+ xor r14d,edx
+ rol r14d,16
+ add esi,r13d
+ xor r11d,esi
+ rol r11d,12
+ add edi,r14d
+ xor r8d,edi
+ rol r8d,12
+ add ecx,r11d
+ xor r13d,ecx
+ rol r13d,8
+ add edx,r8d
+ xor r14d,edx
+ rol r14d,8
+ add esi,r13d
+ xor r11d,esi
+ rol r11d,7
+ add edi,r14d
+ xor r8d,edi
+ rol r8d,7
+ dec ebp
+ jnz NEAR $L$oop
+ mov DWORD[36+rsp],edi
+ mov DWORD[32+rsp],esi
+ mov rbp,QWORD[64+rsp]
+ movdqa xmm1,xmm2
+ mov rsi,QWORD[((64+8))+rsp]
+ paddd xmm3,xmm4
+ mov rdi,QWORD[((64+16))+rsp]
+
+ add eax,0x61707865
+ add ebx,0x3320646e
+ add ecx,0x79622d32
+ add edx,0x6b206574
+ add r8d,DWORD[16+rsp]
+ add r9d,DWORD[20+rsp]
+ add r10d,DWORD[24+rsp]
+ add r11d,DWORD[28+rsp]
+ add r12d,DWORD[48+rsp]
+ add r13d,DWORD[52+rsp]
+ add r14d,DWORD[56+rsp]
+ add r15d,DWORD[60+rsp]
+ paddd xmm1,XMMWORD[32+rsp]
+
+ cmp rbp,64
+ jb NEAR $L$tail
+
+ xor eax,DWORD[rsi]
+ xor ebx,DWORD[4+rsi]
+ xor ecx,DWORD[8+rsi]
+ xor edx,DWORD[12+rsi]
+ xor r8d,DWORD[16+rsi]
+ xor r9d,DWORD[20+rsi]
+ xor r10d,DWORD[24+rsi]
+ xor r11d,DWORD[28+rsi]
+ movdqu xmm0,XMMWORD[32+rsi]
+ xor r12d,DWORD[48+rsi]
+ xor r13d,DWORD[52+rsi]
+ xor r14d,DWORD[56+rsi]
+ xor r15d,DWORD[60+rsi]
+ lea rsi,[64+rsi]
+ pxor xmm0,xmm1
+
+ movdqa XMMWORD[32+rsp],xmm2
+ movd DWORD[48+rsp],xmm3
+
+ 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
+ movdqu XMMWORD[32+rdi],xmm0
+ mov DWORD[48+rdi],r12d
+ mov DWORD[52+rdi],r13d
+ mov DWORD[56+rdi],r14d
+ mov DWORD[60+rdi],r15d
+ lea rdi,[64+rdi]
+
+ sub rbp,64
+ jnz NEAR $L$oop_outer
+
+ jmp NEAR $L$done
+
+ALIGN 16
+$L$tail:
+ mov DWORD[rsp],eax
+ mov DWORD[4+rsp],ebx
+ xor rbx,rbx
+ mov DWORD[8+rsp],ecx
+ mov DWORD[12+rsp],edx
+ mov DWORD[16+rsp],r8d
+ mov DWORD[20+rsp],r9d
+ mov DWORD[24+rsp],r10d
+ mov DWORD[28+rsp],r11d
+ movdqa XMMWORD[32+rsp],xmm1
+ mov DWORD[48+rsp],r12d
+ mov DWORD[52+rsp],r13d
+ mov DWORD[56+rsp],r14d
+ mov DWORD[60+rsp],r15d
+
+$L$oop_tail:
+ movzx eax,BYTE[rbx*1+rsi]
+ movzx edx,BYTE[rbx*1+rsp]
+ lea rbx,[1+rbx]
+ xor eax,edx
+ mov BYTE[((-1))+rbx*1+rdi],al
+ dec rbp
+ jnz NEAR $L$oop_tail
+
+$L$done:
+ add rsp,64+24
+ pop r15
+ pop r14
+ pop r13
+ pop r12
+ pop rbp
+ pop rbx
+$L$no_data:
+ mov rdi,QWORD[8+rsp] ;WIN64 epilogue
+ mov rsi,QWORD[16+rsp]
+ DB 0F3h,0C3h ;repret
+$L$SEH_end_ChaCha20_ctr32:
+
+ALIGN 32
+ChaCha20_ssse3:
+ mov QWORD[8+rsp],rdi ;WIN64 prologue
+ mov QWORD[16+rsp],rsi
+ mov rax,rsp
+$L$SEH_begin_ChaCha20_ssse3:
+ mov rdi,rcx
+ mov rsi,rdx
+ mov rdx,r8
+ mov rcx,r9
+ mov r8,QWORD[40+rsp]
+
+
+$L$ChaCha20_ssse3:
+ cmp rdx,128
+ ja NEAR $L$ChaCha20_4x
+
+$L$do_sse3_after_all:
+ push rbx
+ push rbp
+ push r12
+ push r13
+ push r14
+ push r15
+
+ sub rsp,64+72
+ movaps XMMWORD[(64+32)+rsp],xmm6
+ movaps XMMWORD[(64+48)+rsp],xmm7
+ movdqa xmm0,XMMWORD[$L$sigma]
+ movdqu xmm1,XMMWORD[rcx]
+ movdqu xmm2,XMMWORD[16+rcx]
+ movdqu xmm3,XMMWORD[r8]
+ movdqa xmm6,XMMWORD[$L$rot16]
+ movdqa xmm7,XMMWORD[$L$rot24]
+
+ movdqa XMMWORD[rsp],xmm0
+ movdqa XMMWORD[16+rsp],xmm1
+ movdqa XMMWORD[32+rsp],xmm2
+ movdqa XMMWORD[48+rsp],xmm3
+ mov ebp,10
+ jmp NEAR $L$oop_ssse3
+
+ALIGN 32
+$L$oop_outer_ssse3:
+ movdqa xmm3,XMMWORD[$L$one]
+ movdqa xmm0,XMMWORD[rsp]
+ movdqa xmm1,XMMWORD[16+rsp]
+ movdqa xmm2,XMMWORD[32+rsp]
+ paddd xmm3,XMMWORD[48+rsp]
+ mov ebp,10
+ movdqa XMMWORD[48+rsp],xmm3
+ jmp NEAR $L$oop_ssse3
+
+ALIGN 32
+$L$oop_ssse3:
+ paddd xmm0,xmm1
+ pxor xmm3,xmm0
+DB 102,15,56,0,222
+ paddd xmm2,xmm3
+ pxor xmm1,xmm2
+ movdqa xmm4,xmm1
+ psrld xmm1,20
+ pslld xmm4,12
+ por xmm1,xmm4
+ paddd xmm0,xmm1
+ pxor xmm3,xmm0
+DB 102,15,56,0,223
+ paddd xmm2,xmm3
+ pxor xmm1,xmm2
+ movdqa xmm4,xmm1
+ psrld xmm1,25
+ pslld xmm4,7
+ por xmm1,xmm4
+ pshufd xmm2,xmm2,78
+ pshufd xmm1,xmm1,57
+ pshufd xmm3,xmm3,147
+ nop
+ paddd xmm0,xmm1
+ pxor xmm3,xmm0
+DB 102,15,56,0,222
+ paddd xmm2,xmm3
+ pxor xmm1,xmm2
+ movdqa xmm4,xmm1
+ psrld xmm1,20
+ pslld xmm4,12
+ por xmm1,xmm4
+ paddd xmm0,xmm1
+ pxor xmm3,xmm0
+DB 102,15,56,0,223
+ paddd xmm2,xmm3
+ pxor xmm1,xmm2
+ movdqa xmm4,xmm1
+ psrld xmm1,25
+ pslld xmm4,7
+ por xmm1,xmm4
+ pshufd xmm2,xmm2,78
+ pshufd xmm1,xmm1,147
+ pshufd xmm3,xmm3,57
+ dec ebp
+ jnz NEAR $L$oop_ssse3
+ paddd xmm0,XMMWORD[rsp]
+ paddd xmm1,XMMWORD[16+rsp]
+ paddd xmm2,XMMWORD[32+rsp]
+ paddd xmm3,XMMWORD[48+rsp]
+
+ cmp rdx,64
+ jb NEAR $L$tail_ssse3
+
+ movdqu xmm4,XMMWORD[rsi]
+ movdqu xmm5,XMMWORD[16+rsi]
+ pxor xmm0,xmm4
+ movdqu xmm4,XMMWORD[32+rsi]
+ pxor xmm1,xmm5
+ movdqu xmm5,XMMWORD[48+rsi]
+ lea rsi,[64+rsi]
+ pxor xmm2,xmm4
+ pxor xmm3,xmm5
+
+ movdqu XMMWORD[rdi],xmm0
+ movdqu XMMWORD[16+rdi],xmm1
+ movdqu XMMWORD[32+rdi],xmm2
+ movdqu XMMWORD[48+rdi],xmm3
+ lea rdi,[64+rdi]
+
+ sub rdx,64
+ jnz NEAR $L$oop_outer_ssse3
+
+ jmp NEAR $L$done_ssse3
+
+ALIGN 16
+$L$tail_ssse3:
+ movdqa XMMWORD[rsp],xmm0
+ movdqa XMMWORD[16+rsp],xmm1
+ movdqa XMMWORD[32+rsp],xmm2
+ movdqa XMMWORD[48+rsp],xmm3
+ xor rbx,rbx
+
+$L$oop_tail_ssse3:
+ movzx eax,BYTE[rbx*1+rsi]
+ movzx ecx,BYTE[rbx*1+rsp]
+ lea rbx,[1+rbx]
+ xor eax,ecx
+ mov BYTE[((-1))+rbx*1+rdi],al
+ dec rdx
+ jnz NEAR $L$oop_tail_ssse3
+
+$L$done_ssse3:
+ movaps xmm6,XMMWORD[((64+32))+rsp]
+ movaps xmm7,XMMWORD[((64+48))+rsp]
+ add rsp,64+72
+ pop r15
+ pop r14
+ pop r13
+ pop r12
+ pop rbp
+ pop rbx
+ mov rdi,QWORD[8+rsp] ;WIN64 epilogue
+ mov rsi,QWORD[16+rsp]
+ DB 0F3h,0C3h ;repret
+$L$SEH_end_ChaCha20_ssse3:
+
+ALIGN 32
+ChaCha20_4x:
+ mov QWORD[8+rsp],rdi ;WIN64 prologue
+ mov QWORD[16+rsp],rsi
+ mov rax,rsp
+$L$SEH_begin_ChaCha20_4x:
+ mov rdi,rcx
+ mov rsi,rdx
+ mov rdx,r8
+ mov rcx,r9
+ mov r8,QWORD[40+rsp]
+
+
+$L$ChaCha20_4x:
+ mov r11,r10
+ shr r10,32
+ test r10,32
+ jnz NEAR $L$ChaCha20_8x
+ cmp rdx,192
+ ja NEAR $L$proceed4x
+
+ and r11,71303168
+ cmp r11,4194304
+ je NEAR $L$do_sse3_after_all
+
+$L$proceed4x:
+ lea r11,[((-120))+rsp]
+ sub rsp,0x148+160
+ movaps XMMWORD[(-48)+r11],xmm6
+ movaps XMMWORD[(-32)+r11],xmm7
+ movaps XMMWORD[(-16)+r11],xmm8
+ movaps XMMWORD[r11],xmm9
+ movaps XMMWORD[16+r11],xmm10
+ movaps XMMWORD[32+r11],xmm11
+ movaps XMMWORD[48+r11],xmm12
+ movaps XMMWORD[64+r11],xmm13
+ movaps XMMWORD[80+r11],xmm14
+ movaps XMMWORD[96+r11],xmm15
+ movdqa xmm11,XMMWORD[$L$sigma]
+ movdqu xmm15,XMMWORD[rcx]
+ movdqu xmm7,XMMWORD[16+rcx]
+ movdqu xmm3,XMMWORD[r8]
+ lea rcx,[256+rsp]
+ lea r10,[$L$rot16]
+ lea r11,[$L$rot24]
+
+ pshufd xmm8,xmm11,0x00
+ pshufd xmm9,xmm11,0x55
+ movdqa XMMWORD[64+rsp],xmm8
+ pshufd xmm10,xmm11,0xaa
+ movdqa XMMWORD[80+rsp],xmm9
+ pshufd xmm11,xmm11,0xff
+ movdqa XMMWORD[96+rsp],xmm10
+ movdqa XMMWORD[112+rsp],xmm11
+
+ pshufd xmm12,xmm15,0x00
+ pshufd xmm13,xmm15,0x55
+ movdqa XMMWORD[(128-256)+rcx],xmm12
+ pshufd xmm14,xmm15,0xaa
+ movdqa XMMWORD[(144-256)+rcx],xmm13
+ pshufd xmm15,xmm15,0xff
+ movdqa XMMWORD[(160-256)+rcx],xmm14
+ movdqa XMMWORD[(176-256)+rcx],xmm15
+
+ pshufd xmm4,xmm7,0x00
+ pshufd xmm5,xmm7,0x55
+ movdqa XMMWORD[(192-256)+rcx],xmm4
+ pshufd xmm6,xmm7,0xaa
+ movdqa XMMWORD[(208-256)+rcx],xmm5
+ pshufd xmm7,xmm7,0xff
+ movdqa XMMWORD[(224-256)+rcx],xmm6
+ movdqa XMMWORD[(240-256)+rcx],xmm7
+
+ pshufd xmm0,xmm3,0x00
+ pshufd xmm1,xmm3,0x55
+ paddd xmm0,XMMWORD[$L$inc]
+ pshufd xmm2,xmm3,0xaa
+ movdqa XMMWORD[(272-256)+rcx],xmm1
+ pshufd xmm3,xmm3,0xff
+ movdqa XMMWORD[(288-256)+rcx],xmm2
+ movdqa XMMWORD[(304-256)+rcx],xmm3
+
+ jmp NEAR $L$oop_enter4x
+
+ALIGN 32
+$L$oop_outer4x:
+ movdqa xmm8,XMMWORD[64+rsp]
+ movdqa xmm9,XMMWORD[80+rsp]
+ movdqa xmm10,XMMWORD[96+rsp]
+ movdqa xmm11,XMMWORD[112+rsp]
+ movdqa xmm12,XMMWORD[((128-256))+rcx]
+ movdqa xmm13,XMMWORD[((144-256))+rcx]
+ movdqa xmm14,XMMWORD[((160-256))+rcx]
+ movdqa xmm15,XMMWORD[((176-256))+rcx]
+ movdqa xmm4,XMMWORD[((192-256))+rcx]
+ movdqa xmm5,XMMWORD[((208-256))+rcx]
+ movdqa xmm6,XMMWORD[((224-256))+rcx]
+ movdqa xmm7,XMMWORD[((240-256))+rcx]
+ movdqa xmm0,XMMWORD[((256-256))+rcx]
+ movdqa xmm1,XMMWORD[((272-256))+rcx]
+ movdqa xmm2,XMMWORD[((288-256))+rcx]
+ movdqa xmm3,XMMWORD[((304-256))+rcx]
+ paddd xmm0,XMMWORD[$L$four]
+
+$L$oop_enter4x:
+ movdqa XMMWORD[32+rsp],xmm6
+ movdqa XMMWORD[48+rsp],xmm7
+ movdqa xmm7,XMMWORD[r10]
+ mov eax,10
+ movdqa XMMWORD[(256-256)+rcx],xmm0
+ jmp NEAR $L$oop4x
+
+ALIGN 32
+$L$oop4x:
+ paddd xmm8,xmm12
+ paddd xmm9,xmm13
+ pxor xmm0,xmm8
+ pxor xmm1,xmm9
+DB 102,15,56,0,199
+DB 102,15,56,0,207
+ paddd xmm4,xmm0
+ paddd xmm5,xmm1
+ pxor xmm12,xmm4
+ pxor xmm13,xmm5
+ movdqa xmm6,xmm12
+ pslld xmm12,12
+ psrld xmm6,20
+ movdqa xmm7,xmm13
+ pslld xmm13,12
+ por xmm12,xmm6
+ psrld xmm7,20
+ movdqa xmm6,XMMWORD[r11]
+ por xmm13,xmm7
+ paddd xmm8,xmm12
+ paddd xmm9,xmm13
+ pxor xmm0,xmm8
+ pxor xmm1,xmm9
+DB 102,15,56,0,198
+DB 102,15,56,0,206
+ paddd xmm4,xmm0
+ paddd xmm5,xmm1
+ pxor xmm12,xmm4
+ pxor xmm13,xmm5
+ movdqa xmm7,xmm12
+ pslld xmm12,7
+ psrld xmm7,25
+ movdqa xmm6,xmm13
+ pslld xmm13,7
+ por xmm12,xmm7
+ psrld xmm6,25
+ movdqa xmm7,XMMWORD[r10]
+ por xmm13,xmm6
+ movdqa XMMWORD[rsp],xmm4
+ movdqa XMMWORD[16+rsp],xmm5
+ movdqa xmm4,XMMWORD[32+rsp]
+ movdqa xmm5,XMMWORD[48+rsp]
+ paddd xmm10,xmm14
+ paddd xmm11,xmm15
+ pxor xmm2,xmm10
+ pxor xmm3,xmm11
+DB 102,15,56,0,215
+DB 102,15,56,0,223
+ paddd xmm4,xmm2
+ paddd xmm5,xmm3
+ pxor xmm14,xmm4
+ pxor xmm15,xmm5
+ movdqa xmm6,xmm14
+ pslld xmm14,12
+ psrld xmm6,20
+ movdqa xmm7,xmm15
+ pslld xmm15,12
+ por xmm14,xmm6
+ psrld xmm7,20
+ movdqa xmm6,XMMWORD[r11]
+ por xmm15,xmm7
+ paddd xmm10,xmm14
+ paddd xmm11,xmm15
+ pxor xmm2,xmm10
+ pxor xmm3,xmm11
+DB 102,15,56,0,214
+DB 102,15,56,0,222
+ paddd xmm4,xmm2
+ paddd xmm5,xmm3
+ pxor xmm14,xmm4
+ pxor xmm15,xmm5
+ movdqa xmm7,xmm14
+ pslld xmm14,7
+ psrld xmm7,25
+ movdqa xmm6,xmm15
+ pslld xmm15,7
+ por xmm14,xmm7
+ psrld xmm6,25
+ movdqa xmm7,XMMWORD[r10]
+ por xmm15,xmm6
+ paddd xmm8,xmm13
+ paddd xmm9,xmm14
+ pxor xmm3,xmm8
+ pxor xmm0,xmm9
+DB 102,15,56,0,223
+DB 102,15,56,0,199
+ paddd xmm4,xmm3
+ paddd xmm5,xmm0
+ pxor xmm13,xmm4
+ pxor xmm14,xmm5
+ movdqa xmm6,xmm13
+ pslld xmm13,12
+ psrld xmm6,20
+ movdqa xmm7,xmm14
+ pslld xmm14,12
+ por xmm13,xmm6
+ psrld xmm7,20
+ movdqa xmm6,XMMWORD[r11]
+ por xmm14,xmm7
+ paddd xmm8,xmm13
+ paddd xmm9,xmm14
+ pxor xmm3,xmm8
+ pxor xmm0,xmm9
+DB 102,15,56,0,222
+DB 102,15,56,0,198
+ paddd xmm4,xmm3
+ paddd xmm5,xmm0
+ pxor xmm13,xmm4
+ pxor xmm14,xmm5
+ movdqa xmm7,xmm13
+ pslld xmm13,7
+ psrld xmm7,25
+ movdqa xmm6,xmm14
+ pslld xmm14,7
+ por xmm13,xmm7
+ psrld xmm6,25
+ movdqa xmm7,XMMWORD[r10]
+ por xmm14,xmm6
+ movdqa XMMWORD[32+rsp],xmm4
+ movdqa XMMWORD[48+rsp],xmm5
+ movdqa xmm4,XMMWORD[rsp]
+ movdqa xmm5,XMMWORD[16+rsp]
+ paddd xmm10,xmm15
+ paddd xmm11,xmm12
+ pxor xmm1,xmm10
+ pxor xmm2,xmm11
+DB 102,15,56,0,207
+DB 102,15,56,0,215
+ paddd xmm4,xmm1
+ paddd xmm5,xmm2
+ pxor xmm15,xmm4
+ pxor xmm12,xmm5
+ movdqa xmm6,xmm15
+ pslld xmm15,12
+ psrld xmm6,20
+ movdqa xmm7,xmm12
+ pslld xmm12,12
+ por xmm15,xmm6
+ psrld xmm7,20
+ movdqa xmm6,XMMWORD[r11]
+ por xmm12,xmm7
+ paddd xmm10,xmm15
+ paddd xmm11,xmm12
+ pxor xmm1,xmm10
+ pxor xmm2,xmm11
+DB 102,15,56,0,206
+DB 102,15,56,0,214
+ paddd xmm4,xmm1
+ paddd xmm5,xmm2
+ pxor xmm15,xmm4
+ pxor xmm12,xmm5
+ movdqa xmm7,xmm15
+ pslld xmm15,7
+ psrld xmm7,25
+ movdqa xmm6,xmm12
+ pslld xmm12,7
+ por xmm15,xmm7
+ psrld xmm6,25
+ movdqa xmm7,XMMWORD[r10]
+ por xmm12,xmm6
+ dec eax
+ jnz NEAR $L$oop4x
+
+ paddd xmm8,XMMWORD[64+rsp]
+ paddd xmm9,XMMWORD[80+rsp]
+ paddd xmm10,XMMWORD[96+rsp]
+ paddd xmm11,XMMWORD[112+rsp]
+
+ movdqa xmm6,xmm8
+ punpckldq xmm8,xmm9
+ movdqa xmm7,xmm10
+ punpckldq xmm10,xmm11
+ punpckhdq xmm6,xmm9
+ punpckhdq xmm7,xmm11
+ movdqa xmm9,xmm8
+ punpcklqdq xmm8,xmm10
+ movdqa xmm11,xmm6
+ punpcklqdq xmm6,xmm7
+ punpckhqdq xmm9,xmm10
+ punpckhqdq xmm11,xmm7
+ paddd xmm12,XMMWORD[((128-256))+rcx]
+ paddd xmm13,XMMWORD[((144-256))+rcx]
+ paddd xmm14,XMMWORD[((160-256))+rcx]
+ paddd xmm15,XMMWORD[((176-256))+rcx]
+
+ movdqa XMMWORD[rsp],xmm8
+ movdqa XMMWORD[16+rsp],xmm9
+ movdqa xmm8,XMMWORD[32+rsp]
+ movdqa xmm9,XMMWORD[48+rsp]
+
+ movdqa xmm10,xmm12
+ punpckldq xmm12,xmm13
+ movdqa xmm7,xmm14
+ punpckldq xmm14,xmm15
+ punpckhdq xmm10,xmm13
+ punpckhdq xmm7,xmm15
+ movdqa xmm13,xmm12
+ punpcklqdq xmm12,xmm14
+ movdqa xmm15,xmm10
+ punpcklqdq xmm10,xmm7
+ punpckhqdq xmm13,xmm14
+ punpckhqdq xmm15,xmm7
+ paddd xmm4,XMMWORD[((192-256))+rcx]
+ paddd xmm5,XMMWORD[((208-256))+rcx]
+ paddd xmm8,XMMWORD[((224-256))+rcx]
+ paddd xmm9,XMMWORD[((240-256))+rcx]
+
+ movdqa XMMWORD[32+rsp],xmm6
+ movdqa XMMWORD[48+rsp],xmm11
+
+ movdqa xmm14,xmm4
+ punpckldq xmm4,xmm5
+ movdqa xmm7,xmm8
+ punpckldq xmm8,xmm9
+ punpckhdq xmm14,xmm5
+ punpckhdq xmm7,xmm9
+ movdqa xmm5,xmm4
+ punpcklqdq xmm4,xmm8
+ movdqa xmm9,xmm14
+ punpcklqdq xmm14,xmm7
+ punpckhqdq xmm5,xmm8
+ punpckhqdq xmm9,xmm7
+ paddd xmm0,XMMWORD[((256-256))+rcx]
+ paddd xmm1,XMMWORD[((272-256))+rcx]
+ paddd xmm2,XMMWORD[((288-256))+rcx]
+ paddd xmm3,XMMWORD[((304-256))+rcx]
+
+ movdqa xmm8,xmm0
+ punpckldq xmm0,xmm1
+ movdqa xmm7,xmm2
+ punpckldq xmm2,xmm3
+ punpckhdq xmm8,xmm1
+ punpckhdq xmm7,xmm3
+ movdqa xmm1,xmm0
+ punpcklqdq xmm0,xmm2
+ movdqa xmm3,xmm8
+ punpcklqdq xmm8,xmm7
+ punpckhqdq xmm1,xmm2
+ punpckhqdq xmm3,xmm7
+ cmp rdx,64*4
+ jb NEAR $L$tail4x
+
+ movdqu xmm6,XMMWORD[rsi]
+ movdqu xmm11,XMMWORD[16+rsi]
+ movdqu xmm2,XMMWORD[32+rsi]
+ movdqu xmm7,XMMWORD[48+rsi]
+ pxor xmm6,XMMWORD[rsp]
+ pxor xmm11,xmm12
+ pxor xmm2,xmm4
+ pxor xmm7,xmm0
+
+ movdqu XMMWORD[rdi],xmm6
+ movdqu xmm6,XMMWORD[64+rsi]
+ movdqu XMMWORD[16+rdi],xmm11
+ movdqu xmm11,XMMWORD[80+rsi]
+ movdqu XMMWORD[32+rdi],xmm2
+ movdqu xmm2,XMMWORD[96+rsi]
+ movdqu XMMWORD[48+rdi],xmm7
+ movdqu xmm7,XMMWORD[112+rsi]
+ lea rsi,[128+rsi]
+ pxor xmm6,XMMWORD[16+rsp]
+ pxor xmm11,xmm13
+ pxor xmm2,xmm5
+ pxor xmm7,xmm1
+
+ movdqu XMMWORD[64+rdi],xmm6
+ movdqu xmm6,XMMWORD[rsi]
+ movdqu XMMWORD[80+rdi],xmm11
+ movdqu xmm11,XMMWORD[16+rsi]
+ movdqu XMMWORD[96+rdi],xmm2
+ movdqu xmm2,XMMWORD[32+rsi]
+ movdqu XMMWORD[112+rdi],xmm7
+ lea rdi,[128+rdi]
+ movdqu xmm7,XMMWORD[48+rsi]
+ pxor xmm6,XMMWORD[32+rsp]
+ pxor xmm11,xmm10
+ pxor xmm2,xmm14
+ pxor xmm7,xmm8
+
+ movdqu XMMWORD[rdi],xmm6
+ movdqu xmm6,XMMWORD[64+rsi]
+ movdqu XMMWORD[16+rdi],xmm11
+ movdqu xmm11,XMMWORD[80+rsi]
+ movdqu XMMWORD[32+rdi],xmm2
+ movdqu xmm2,XMMWORD[96+rsi]
+ movdqu XMMWORD[48+rdi],xmm7
+ movdqu xmm7,XMMWORD[112+rsi]
+ lea rsi,[128+rsi]
+ pxor xmm6,XMMWORD[48+rsp]
+ pxor xmm11,xmm15
+ pxor xmm2,xmm9
+ pxor xmm7,xmm3
+ movdqu XMMWORD[64+rdi],xmm6
+ movdqu XMMWORD[80+rdi],xmm11
+ movdqu XMMWORD[96+rdi],xmm2
+ movdqu XMMWORD[112+rdi],xmm7
+ lea rdi,[128+rdi]
+
+ sub rdx,64*4
+ jnz NEAR $L$oop_outer4x
+
+ jmp NEAR $L$done4x
+
+$L$tail4x:
+ cmp rdx,192
+ jae NEAR $L$192_or_more4x
+ cmp rdx,128
+ jae NEAR $L$128_or_more4x
+ cmp rdx,64
+ jae NEAR $L$64_or_more4x
+
+
+ xor r10,r10
+
+ movdqa XMMWORD[16+rsp],xmm12
+ movdqa XMMWORD[32+rsp],xmm4
+ movdqa XMMWORD[48+rsp],xmm0
+ jmp NEAR $L$oop_tail4x
+
+ALIGN 32
+$L$64_or_more4x:
+ movdqu xmm6,XMMWORD[rsi]
+ movdqu xmm11,XMMWORD[16+rsi]
+ movdqu xmm2,XMMWORD[32+rsi]
+ movdqu xmm7,XMMWORD[48+rsi]
+ pxor xmm6,XMMWORD[rsp]
+ pxor xmm11,xmm12
+ pxor xmm2,xmm4
+ pxor xmm7,xmm0
+ movdqu XMMWORD[rdi],xmm6
+ movdqu XMMWORD[16+rdi],xmm11
+ movdqu XMMWORD[32+rdi],xmm2
+ movdqu XMMWORD[48+rdi],xmm7
+ je NEAR $L$done4x
+
+ movdqa xmm6,XMMWORD[16+rsp]
+ lea rsi,[64+rsi]
+ xor r10,r10
+ movdqa XMMWORD[rsp],xmm6
+ movdqa XMMWORD[16+rsp],xmm13
+ lea rdi,[64+rdi]
+ movdqa XMMWORD[32+rsp],xmm5
+ sub rdx,64
+ movdqa XMMWORD[48+rsp],xmm1
+ jmp NEAR $L$oop_tail4x
+
+ALIGN 32
+$L$128_or_more4x:
+ movdqu xmm6,XMMWORD[rsi]
+ movdqu xmm11,XMMWORD[16+rsi]
+ movdqu xmm2,XMMWORD[32+rsi]
+ movdqu xmm7,XMMWORD[48+rsi]
+ pxor xmm6,XMMWORD[rsp]
+ pxor xmm11,xmm12
+ pxor xmm2,xmm4
+ pxor xmm7,xmm0
+
+ movdqu XMMWORD[rdi],xmm6
+ movdqu xmm6,XMMWORD[64+rsi]
+ movdqu XMMWORD[16+rdi],xmm11
+ movdqu xmm11,XMMWORD[80+rsi]
+ movdqu XMMWORD[32+rdi],xmm2
+ movdqu xmm2,XMMWORD[96+rsi]
+ movdqu XMMWORD[48+rdi],xmm7
+ movdqu xmm7,XMMWORD[112+rsi]
+ pxor xmm6,XMMWORD[16+rsp]
+ pxor xmm11,xmm13
+ pxor xmm2,xmm5
+ pxor xmm7,xmm1
+ movdqu XMMWORD[64+rdi],xmm6
+ movdqu XMMWORD[80+rdi],xmm11
+ movdqu XMMWORD[96+rdi],xmm2
+ movdqu XMMWORD[112+rdi],xmm7
+ je NEAR $L$done4x
+
+ movdqa xmm6,XMMWORD[32+rsp]
+ lea rsi,[128+rsi]
+ xor r10,r10
+ movdqa XMMWORD[rsp],xmm6
+ movdqa XMMWORD[16+rsp],xmm10
+ lea rdi,[128+rdi]
+ movdqa XMMWORD[32+rsp],xmm14
+ sub rdx,128
+ movdqa XMMWORD[48+rsp],xmm8
+ jmp NEAR $L$oop_tail4x
+
+ALIGN 32
+$L$192_or_more4x:
+ movdqu xmm6,XMMWORD[rsi]
+ movdqu xmm11,XMMWORD[16+rsi]
+ movdqu xmm2,XMMWORD[32+rsi]
+ movdqu xmm7,XMMWORD[48+rsi]
+ pxor xmm6,XMMWORD[rsp]
+ pxor xmm11,xmm12
+ pxor xmm2,xmm4
+ pxor xmm7,xmm0
+
+ movdqu XMMWORD[rdi],xmm6
+ movdqu xmm6,XMMWORD[64+rsi]
+ movdqu XMMWORD[16+rdi],xmm11
+ movdqu xmm11,XMMWORD[80+rsi]
+ movdqu XMMWORD[32+rdi],xmm2
+ movdqu xmm2,XMMWORD[96+rsi]
+ movdqu XMMWORD[48+rdi],xmm7
+ movdqu xmm7,XMMWORD[112+rsi]
+ lea rsi,[128+rsi]
+ pxor xmm6,XMMWORD[16+rsp]
+ pxor xmm11,xmm13
+ pxor xmm2,xmm5
+ pxor xmm7,xmm1
+
+ movdqu XMMWORD[64+rdi],xmm6
+ movdqu xmm6,XMMWORD[rsi]
+ movdqu XMMWORD[80+rdi],xmm11
+ movdqu xmm11,XMMWORD[16+rsi]
+ movdqu XMMWORD[96+rdi],xmm2
+ movdqu xmm2,XMMWORD[32+rsi]
+ movdqu XMMWORD[112+rdi],xmm7
+ lea rdi,[128+rdi]
+ movdqu xmm7,XMMWORD[48+rsi]
+ pxor xmm6,XMMWORD[32+rsp]
+ pxor xmm11,xmm10
+ pxor xmm2,xmm14
+ pxor xmm7,xmm8
+ movdqu XMMWORD[rdi],xmm6
+ movdqu XMMWORD[16+rdi],xmm11
+ movdqu XMMWORD[32+rdi],xmm2
+ movdqu XMMWORD[48+rdi],xmm7
+ je NEAR $L$done4x
+
+ movdqa xmm6,XMMWORD[48+rsp]
+ lea rsi,[64+rsi]
+ xor r10,r10
+ movdqa XMMWORD[rsp],xmm6
+ movdqa XMMWORD[16+rsp],xmm15
+ lea rdi,[64+rdi]
+ movdqa XMMWORD[32+rsp],xmm9
+ sub rdx,192
+ movdqa XMMWORD[48+rsp],xmm3
+
+$L$oop_tail4x:
+ movzx eax,BYTE[r10*1+rsi]
+ movzx ecx,BYTE[r10*1+rsp]
+ lea r10,[1+r10]
+ xor eax,ecx
+ mov BYTE[((-1))+r10*1+rdi],al
+ dec rdx
+ jnz NEAR $L$oop_tail4x
+
+$L$done4x:
+ lea r11,[((320+48))+rsp]
+ movaps xmm6,XMMWORD[((-48))+r11]
+ movaps xmm7,XMMWORD[((-32))+r11]
+ movaps xmm8,XMMWORD[((-16))+r11]
+ movaps xmm9,XMMWORD[r11]
+ movaps xmm10,XMMWORD[16+r11]
+ movaps xmm11,XMMWORD[32+r11]
+ movaps xmm12,XMMWORD[48+r11]
+ movaps xmm13,XMMWORD[64+r11]
+ movaps xmm14,XMMWORD[80+r11]
+ movaps xmm15,XMMWORD[96+r11]
+ add rsp,0x148+160
+ mov rdi,QWORD[8+rsp] ;WIN64 epilogue
+ mov rsi,QWORD[16+rsp]
+ DB 0F3h,0C3h ;repret
+$L$SEH_end_ChaCha20_4x:
+
+ALIGN 32
+ChaCha20_8x:
+ mov QWORD[8+rsp],rdi ;WIN64 prologue
+ mov QWORD[16+rsp],rsi
+ mov rax,rsp
+$L$SEH_begin_ChaCha20_8x:
+ mov rdi,rcx
+ mov rsi,rdx
+ mov rdx,r8
+ mov rcx,r9
+ mov r8,QWORD[40+rsp]
+
+
+$L$ChaCha20_8x:
+ mov r10,rsp
+ sub rsp,0x280+176
+ and rsp,-32
+ lea r11,[((656+48))+rsp]
+ movaps XMMWORD[(-48)+r11],xmm6
+ movaps XMMWORD[(-32)+r11],xmm7
+ movaps XMMWORD[(-16)+r11],xmm8
+ movaps XMMWORD[r11],xmm9
+ movaps XMMWORD[16+r11],xmm10
+ movaps XMMWORD[32+r11],xmm11
+ movaps XMMWORD[48+r11],xmm12
+ movaps XMMWORD[64+r11],xmm13
+ movaps XMMWORD[80+r11],xmm14
+ movaps XMMWORD[96+r11],xmm15
+ vzeroupper
+ mov QWORD[640+rsp],r10
+
+
+
+
+
+
+
+
+
+
+ vbroadcasti128 ymm11,YMMWORD[$L$sigma]
+ vbroadcasti128 ymm3,YMMWORD[rcx]
+ vbroadcasti128 ymm15,YMMWORD[16+rcx]
+ vbroadcasti128 ymm7,YMMWORD[r8]
+ lea rcx,[256+rsp]
+ lea rax,[512+rsp]
+ lea r10,[$L$rot16]
+ lea r11,[$L$rot24]
+
+ vpshufd ymm8,ymm11,0x00
+ vpshufd ymm9,ymm11,0x55
+ vmovdqa YMMWORD[(128-256)+rcx],ymm8
+ vpshufd ymm10,ymm11,0xaa
+ vmovdqa YMMWORD[(160-256)+rcx],ymm9
+ vpshufd ymm11,ymm11,0xff
+ vmovdqa YMMWORD[(192-256)+rcx],ymm10
+ vmovdqa YMMWORD[(224-256)+rcx],ymm11
+
+ vpshufd ymm0,ymm3,0x00
+ vpshufd ymm1,ymm3,0x55
+ vmovdqa YMMWORD[(256-256)+rcx],ymm0
+ vpshufd ymm2,ymm3,0xaa
+ vmovdqa YMMWORD[(288-256)+rcx],ymm1
+ vpshufd ymm3,ymm3,0xff
+ vmovdqa YMMWORD[(320-256)+rcx],ymm2
+ vmovdqa YMMWORD[(352-256)+rcx],ymm3
+
+ vpshufd ymm12,ymm15,0x00
+ vpshufd ymm13,ymm15,0x55
+ vmovdqa YMMWORD[(384-512)+rax],ymm12
+ vpshufd ymm14,ymm15,0xaa
+ vmovdqa YMMWORD[(416-512)+rax],ymm13
+ vpshufd ymm15,ymm15,0xff
+ vmovdqa YMMWORD[(448-512)+rax],ymm14
+ vmovdqa YMMWORD[(480-512)+rax],ymm15
+
+ vpshufd ymm4,ymm7,0x00
+ vpshufd ymm5,ymm7,0x55
+ vpaddd ymm4,ymm4,YMMWORD[$L$incy]
+ vpshufd ymm6,ymm7,0xaa
+ vmovdqa YMMWORD[(544-512)+rax],ymm5
+ vpshufd ymm7,ymm7,0xff
+ vmovdqa YMMWORD[(576-512)+rax],ymm6
+ vmovdqa YMMWORD[(608-512)+rax],ymm7
+
+ jmp NEAR $L$oop_enter8x
+
+ALIGN 32
+$L$oop_outer8x:
+ vmovdqa ymm8,YMMWORD[((128-256))+rcx]
+ vmovdqa ymm9,YMMWORD[((160-256))+rcx]
+ vmovdqa ymm10,YMMWORD[((192-256))+rcx]
+ vmovdqa ymm11,YMMWORD[((224-256))+rcx]
+ vmovdqa ymm0,YMMWORD[((256-256))+rcx]
+ vmovdqa ymm1,YMMWORD[((288-256))+rcx]
+ vmovdqa ymm2,YMMWORD[((320-256))+rcx]
+ vmovdqa ymm3,YMMWORD[((352-256))+rcx]
+ vmovdqa ymm12,YMMWORD[((384-512))+rax]
+ vmovdqa ymm13,YMMWORD[((416-512))+rax]
+ vmovdqa ymm14,YMMWORD[((448-512))+rax]
+ vmovdqa ymm15,YMMWORD[((480-512))+rax]
+ vmovdqa ymm4,YMMWORD[((512-512))+rax]
+ vmovdqa ymm5,YMMWORD[((544-512))+rax]
+ vmovdqa ymm6,YMMWORD[((576-512))+rax]
+ vmovdqa ymm7,YMMWORD[((608-512))+rax]
+ vpaddd ymm4,ymm4,YMMWORD[$L$eight]
+
+$L$oop_enter8x:
+ vmovdqa YMMWORD[64+rsp],ymm14
+ vmovdqa YMMWORD[96+rsp],ymm15
+ vbroadcasti128 ymm15,YMMWORD[r10]
+ vmovdqa YMMWORD[(512-512)+rax],ymm4
+ mov eax,10
+ jmp NEAR $L$oop8x
+
+ALIGN 32
+$L$oop8x:
+ vpaddd ymm8,ymm8,ymm0
+ vpxor ymm4,ymm8,ymm4
+ vpshufb ymm4,ymm4,ymm15
+ vpaddd ymm9,ymm9,ymm1
+ vpxor ymm5,ymm9,ymm5
+ vpshufb ymm5,ymm5,ymm15
+ vpaddd ymm12,ymm12,ymm4
+ vpxor ymm0,ymm12,ymm0
+ vpslld ymm14,ymm0,12
+ vpsrld ymm0,ymm0,20
+ vpor ymm0,ymm14,ymm0
+ vbroadcasti128 ymm14,YMMWORD[r11]
+ vpaddd ymm13,ymm13,ymm5
+ vpxor ymm1,ymm13,ymm1
+ vpslld ymm15,ymm1,12
+ vpsrld ymm1,ymm1,20
+ vpor ymm1,ymm15,ymm1
+ vpaddd ymm8,ymm8,ymm0
+ vpxor ymm4,ymm8,ymm4
+ vpshufb ymm4,ymm4,ymm14
+ vpaddd ymm9,ymm9,ymm1
+ vpxor ymm5,ymm9,ymm5
+ vpshufb ymm5,ymm5,ymm14
+ vpaddd ymm12,ymm12,ymm4
+ vpxor ymm0,ymm12,ymm0
+ vpslld ymm15,ymm0,7
+ vpsrld ymm0,ymm0,25
+ vpor ymm0,ymm15,ymm0
+ vbroadcasti128 ymm15,YMMWORD[r10]
+ vpaddd ymm13,ymm13,ymm5
+ vpxor ymm1,ymm13,ymm1
+ vpslld ymm14,ymm1,7
+ vpsrld ymm1,ymm1,25
+ vpor ymm1,ymm14,ymm1
+ vmovdqa YMMWORD[rsp],ymm12
+ vmovdqa YMMWORD[32+rsp],ymm13
+ vmovdqa ymm12,YMMWORD[64+rsp]
+ vmovdqa ymm13,YMMWORD[96+rsp]
+ vpaddd ymm10,ymm10,ymm2
+ vpxor ymm6,ymm10,ymm6
+ vpshufb ymm6,ymm6,ymm15
+ vpaddd ymm11,ymm11,ymm3
+ vpxor ymm7,ymm11,ymm7
+ vpshufb ymm7,ymm7,ymm15
+ vpaddd ymm12,ymm12,ymm6
+ vpxor ymm2,ymm12,ymm2
+ vpslld ymm14,ymm2,12
+ vpsrld ymm2,ymm2,20
+ vpor ymm2,ymm14,ymm2
+ vbroadcasti128 ymm14,YMMWORD[r11]
+ vpaddd ymm13,ymm13,ymm7
+ vpxor ymm3,ymm13,ymm3
+ vpslld ymm15,ymm3,12
+ vpsrld ymm3,ymm3,20
+ vpor ymm3,ymm15,ymm3
+ vpaddd ymm10,ymm10,ymm2
+ vpxor ymm6,ymm10,ymm6
+ vpshufb ymm6,ymm6,ymm14
+ vpaddd ymm11,ymm11,ymm3
+ vpxor ymm7,ymm11,ymm7
+ vpshufb ymm7,ymm7,ymm14
+ vpaddd ymm12,ymm12,ymm6
+ vpxor ymm2,ymm12,ymm2
+ vpslld ymm15,ymm2,7
+ vpsrld ymm2,ymm2,25
+ vpor ymm2,ymm15,ymm2
+ vbroadcasti128 ymm15,YMMWORD[r10]
+ vpaddd ymm13,ymm13,ymm7
+ vpxor ymm3,ymm13,ymm3
+ vpslld ymm14,ymm3,7
+ vpsrld ymm3,ymm3,25
+ vpor ymm3,ymm14,ymm3
+ vpaddd ymm8,ymm8,ymm1
+ vpxor ymm7,ymm8,ymm7
+ vpshufb ymm7,ymm7,ymm15
+ vpaddd ymm9,ymm9,ymm2
+ vpxor ymm4,ymm9,ymm4
+ vpshufb ymm4,ymm4,ymm15
+ vpaddd ymm12,ymm12,ymm7
+ vpxor ymm1,ymm12,ymm1
+ vpslld ymm14,ymm1,12
+ vpsrld ymm1,ymm1,20
+ vpor ymm1,ymm14,ymm1
+ vbroadcasti128 ymm14,YMMWORD[r11]
+ vpaddd ymm13,ymm13,ymm4
+ vpxor ymm2,ymm13,ymm2
+ vpslld ymm15,ymm2,12
+ vpsrld ymm2,ymm2,20
+ vpor ymm2,ymm15,ymm2
+ vpaddd ymm8,ymm8,ymm1
+ vpxor ymm7,ymm8,ymm7
+ vpshufb ymm7,ymm7,ymm14
+ vpaddd ymm9,ymm9,ymm2
+ vpxor ymm4,ymm9,ymm4
+ vpshufb ymm4,ymm4,ymm14
+ vpaddd ymm12,ymm12,ymm7
+ vpxor ymm1,ymm12,ymm1
+ vpslld ymm15,ymm1,7
+ vpsrld ymm1,ymm1,25
+ vpor ymm1,ymm15,ymm1
+ vbroadcasti128 ymm15,YMMWORD[r10]
+ vpaddd ymm13,ymm13,ymm4
+ vpxor ymm2,ymm13,ymm2
+ vpslld ymm14,ymm2,7
+ vpsrld ymm2,ymm2,25
+ vpor ymm2,ymm14,ymm2
+ vmovdqa YMMWORD[64+rsp],ymm12
+ vmovdqa YMMWORD[96+rsp],ymm13
+ vmovdqa ymm12,YMMWORD[rsp]
+ vmovdqa ymm13,YMMWORD[32+rsp]
+ vpaddd ymm10,ymm10,ymm3
+ vpxor ymm5,ymm10,ymm5
+ vpshufb ymm5,ymm5,ymm15
+ vpaddd ymm11,ymm11,ymm0
+ vpxor ymm6,ymm11,ymm6
+ vpshufb ymm6,ymm6,ymm15
+ vpaddd ymm12,ymm12,ymm5
+ vpxor ymm3,ymm12,ymm3
+ vpslld ymm14,ymm3,12
+ vpsrld ymm3,ymm3,20
+ vpor ymm3,ymm14,ymm3
+ vbroadcasti128 ymm14,YMMWORD[r11]
+ vpaddd ymm13,ymm13,ymm6
+ vpxor ymm0,ymm13,ymm0
+ vpslld ymm15,ymm0,12
+ vpsrld ymm0,ymm0,20
+ vpor ymm0,ymm15,ymm0
+ vpaddd ymm10,ymm10,ymm3
+ vpxor ymm5,ymm10,ymm5
+ vpshufb ymm5,ymm5,ymm14
+ vpaddd ymm11,ymm11,ymm0
+ vpxor ymm6,ymm11,ymm6
+ vpshufb ymm6,ymm6,ymm14
+ vpaddd ymm12,ymm12,ymm5
+ vpxor ymm3,ymm12,ymm3
+ vpslld ymm15,ymm3,7
+ vpsrld ymm3,ymm3,25
+ vpor ymm3,ymm15,ymm3
+ vbroadcasti128 ymm15,YMMWORD[r10]
+ vpaddd ymm13,ymm13,ymm6
+ vpxor ymm0,ymm13,ymm0
+ vpslld ymm14,ymm0,7
+ vpsrld ymm0,ymm0,25
+ vpor ymm0,ymm14,ymm0
+ dec eax
+ jnz NEAR $L$oop8x
+
+ lea rax,[512+rsp]
+ vpaddd ymm8,ymm8,YMMWORD[((128-256))+rcx]
+ vpaddd ymm9,ymm9,YMMWORD[((160-256))+rcx]
+ vpaddd ymm10,ymm10,YMMWORD[((192-256))+rcx]
+ vpaddd ymm11,ymm11,YMMWORD[((224-256))+rcx]
+
+ vpunpckldq ymm14,ymm8,ymm9
+ vpunpckldq ymm15,ymm10,ymm11
+ vpunpckhdq ymm8,ymm8,ymm9
+ vpunpckhdq ymm10,ymm10,ymm11
+ vpunpcklqdq ymm9,ymm14,ymm15
+ vpunpckhqdq ymm14,ymm14,ymm15
+ vpunpcklqdq ymm11,ymm8,ymm10
+ vpunpckhqdq ymm8,ymm8,ymm10
+ vpaddd ymm0,ymm0,YMMWORD[((256-256))+rcx]
+ vpaddd ymm1,ymm1,YMMWORD[((288-256))+rcx]
+ vpaddd ymm2,ymm2,YMMWORD[((320-256))+rcx]
+ vpaddd ymm3,ymm3,YMMWORD[((352-256))+rcx]
+
+ vpunpckldq ymm10,ymm0,ymm1
+ vpunpckldq ymm15,ymm2,ymm3
+ vpunpckhdq ymm0,ymm0,ymm1
+ vpunpckhdq ymm2,ymm2,ymm3
+ vpunpcklqdq ymm1,ymm10,ymm15
+ vpunpckhqdq ymm10,ymm10,ymm15
+ vpunpcklqdq ymm3,ymm0,ymm2
+ vpunpckhqdq ymm0,ymm0,ymm2
+ vperm2i128 ymm15,ymm9,ymm1,0x20
+ vperm2i128 ymm1,ymm9,ymm1,0x31
+ vperm2i128 ymm9,ymm14,ymm10,0x20
+ vperm2i128 ymm10,ymm14,ymm10,0x31
+ vperm2i128 ymm14,ymm11,ymm3,0x20
+ vperm2i128 ymm3,ymm11,ymm3,0x31
+ vperm2i128 ymm11,ymm8,ymm0,0x20
+ vperm2i128 ymm0,ymm8,ymm0,0x31
+ vmovdqa YMMWORD[rsp],ymm15
+ vmovdqa YMMWORD[32+rsp],ymm9
+ vmovdqa ymm15,YMMWORD[64+rsp]
+ vmovdqa ymm9,YMMWORD[96+rsp]
+
+ vpaddd ymm12,ymm12,YMMWORD[((384-512))+rax]
+ vpaddd ymm13,ymm13,YMMWORD[((416-512))+rax]
+ vpaddd ymm15,ymm15,YMMWORD[((448-512))+rax]
+ vpaddd ymm9,ymm9,YMMWORD[((480-512))+rax]
+
+ vpunpckldq ymm2,ymm12,ymm13
+ vpunpckldq ymm8,ymm15,ymm9
+ vpunpckhdq ymm12,ymm12,ymm13
+ vpunpckhdq ymm15,ymm15,ymm9
+ vpunpcklqdq ymm13,ymm2,ymm8
+ vpunpckhqdq ymm2,ymm2,ymm8
+ vpunpcklqdq ymm9,ymm12,ymm15
+ vpunpckhqdq ymm12,ymm12,ymm15
+ vpaddd ymm4,ymm4,YMMWORD[((512-512))+rax]
+ vpaddd ymm5,ymm5,YMMWORD[((544-512))+rax]
+ vpaddd ymm6,ymm6,YMMWORD[((576-512))+rax]
+ vpaddd ymm7,ymm7,YMMWORD[((608-512))+rax]
+
+ vpunpckldq ymm15,ymm4,ymm5
+ vpunpckldq ymm8,ymm6,ymm7
+ vpunpckhdq ymm4,ymm4,ymm5
+ vpunpckhdq ymm6,ymm6,ymm7
+ vpunpcklqdq ymm5,ymm15,ymm8
+ vpunpckhqdq ymm15,ymm15,ymm8
+ vpunpcklqdq ymm7,ymm4,ymm6
+ vpunpckhqdq ymm4,ymm4,ymm6
+ vperm2i128 ymm8,ymm13,ymm5,0x20
+ vperm2i128 ymm5,ymm13,ymm5,0x31
+ vperm2i128 ymm13,ymm2,ymm15,0x20
+ vperm2i128 ymm15,ymm2,ymm15,0x31
+ vperm2i128 ymm2,ymm9,ymm7,0x20
+ vperm2i128 ymm7,ymm9,ymm7,0x31
+ vperm2i128 ymm9,ymm12,ymm4,0x20
+ vperm2i128 ymm4,ymm12,ymm4,0x31
+ vmovdqa ymm6,YMMWORD[rsp]
+ vmovdqa ymm12,YMMWORD[32+rsp]
+
+ cmp rdx,64*8
+ jb NEAR $L$tail8x
+
+ vpxor ymm6,ymm6,YMMWORD[rsi]
+ vpxor ymm8,ymm8,YMMWORD[32+rsi]
+ vpxor ymm1,ymm1,YMMWORD[64+rsi]
+ vpxor ymm5,ymm5,YMMWORD[96+rsi]
+ lea rsi,[128+rsi]
+ vmovdqu YMMWORD[rdi],ymm6
+ vmovdqu YMMWORD[32+rdi],ymm8
+ vmovdqu YMMWORD[64+rdi],ymm1
+ vmovdqu YMMWORD[96+rdi],ymm5
+ lea rdi,[128+rdi]
+
+ vpxor ymm12,ymm12,YMMWORD[rsi]
+ vpxor ymm13,ymm13,YMMWORD[32+rsi]
+ vpxor ymm10,ymm10,YMMWORD[64+rsi]
+ vpxor ymm15,ymm15,YMMWORD[96+rsi]
+ lea rsi,[128+rsi]
+ vmovdqu YMMWORD[rdi],ymm12
+ vmovdqu YMMWORD[32+rdi],ymm13
+ vmovdqu YMMWORD[64+rdi],ymm10
+ vmovdqu YMMWORD[96+rdi],ymm15
+ lea rdi,[128+rdi]
+
+ vpxor ymm14,ymm14,YMMWORD[rsi]
+ vpxor ymm2,ymm2,YMMWORD[32+rsi]
+ vpxor ymm3,ymm3,YMMWORD[64+rsi]
+ vpxor ymm7,ymm7,YMMWORD[96+rsi]
+ lea rsi,[128+rsi]
+ vmovdqu YMMWORD[rdi],ymm14
+ vmovdqu YMMWORD[32+rdi],ymm2
+ vmovdqu YMMWORD[64+rdi],ymm3
+ vmovdqu YMMWORD[96+rdi],ymm7
+ lea rdi,[128+rdi]
+
+ vpxor ymm11,ymm11,YMMWORD[rsi]
+ vpxor ymm9,ymm9,YMMWORD[32+rsi]
+ vpxor ymm0,ymm0,YMMWORD[64+rsi]
+ vpxor ymm4,ymm4,YMMWORD[96+rsi]
+ lea rsi,[128+rsi]
+ vmovdqu YMMWORD[rdi],ymm11
+ vmovdqu YMMWORD[32+rdi],ymm9
+ vmovdqu YMMWORD[64+rdi],ymm0
+ vmovdqu YMMWORD[96+rdi],ymm4
+ lea rdi,[128+rdi]
+
+ sub rdx,64*8
+ jnz NEAR $L$oop_outer8x
+
+ jmp NEAR $L$done8x
+
+$L$tail8x:
+ cmp rdx,448
+ jae NEAR $L$448_or_more8x
+ cmp rdx,384
+ jae NEAR $L$384_or_more8x
+ cmp rdx,320
+ jae NEAR $L$320_or_more8x
+ cmp rdx,256
+ jae NEAR $L$256_or_more8x
+ cmp rdx,192
+ jae NEAR $L$192_or_more8x
+ cmp rdx,128
+ jae NEAR $L$128_or_more8x
+ cmp rdx,64
+ jae NEAR $L$64_or_more8x
+
+ xor r10,r10
+ vmovdqa YMMWORD[rsp],ymm6
+ vmovdqa YMMWORD[32+rsp],ymm8
+ jmp NEAR $L$oop_tail8x
+
+ALIGN 32
+$L$64_or_more8x:
+ vpxor ymm6,ymm6,YMMWORD[rsi]
+ vpxor ymm8,ymm8,YMMWORD[32+rsi]
+ vmovdqu YMMWORD[rdi],ymm6
+ vmovdqu YMMWORD[32+rdi],ymm8
+ je NEAR $L$done8x
+
+ lea rsi,[64+rsi]
+ xor r10,r10
+ vmovdqa YMMWORD[rsp],ymm1
+ lea rdi,[64+rdi]
+ sub rdx,64
+ vmovdqa YMMWORD[32+rsp],ymm5
+ jmp NEAR $L$oop_tail8x
+
+ALIGN 32
+$L$128_or_more8x:
+ vpxor ymm6,ymm6,YMMWORD[rsi]
+ vpxor ymm8,ymm8,YMMWORD[32+rsi]
+ vpxor ymm1,ymm1,YMMWORD[64+rsi]
+ vpxor ymm5,ymm5,YMMWORD[96+rsi]
+ vmovdqu YMMWORD[rdi],ymm6
+ vmovdqu YMMWORD[32+rdi],ymm8
+ vmovdqu YMMWORD[64+rdi],ymm1
+ vmovdqu YMMWORD[96+rdi],ymm5
+ je NEAR $L$done8x
+
+ lea rsi,[128+rsi]
+ xor r10,r10
+ vmovdqa YMMWORD[rsp],ymm12
+ lea rdi,[128+rdi]
+ sub rdx,128
+ vmovdqa YMMWORD[32+rsp],ymm13
+ jmp NEAR $L$oop_tail8x
+
+ALIGN 32
+$L$192_or_more8x:
+ vpxor ymm6,ymm6,YMMWORD[rsi]
+ vpxor ymm8,ymm8,YMMWORD[32+rsi]
+ vpxor ymm1,ymm1,YMMWORD[64+rsi]
+ vpxor ymm5,ymm5,YMMWORD[96+rsi]
+ vpxor ymm12,ymm12,YMMWORD[128+rsi]
+ vpxor ymm13,ymm13,YMMWORD[160+rsi]
+ vmovdqu YMMWORD[rdi],ymm6
+ vmovdqu YMMWORD[32+rdi],ymm8
+ vmovdqu YMMWORD[64+rdi],ymm1
+ vmovdqu YMMWORD[96+rdi],ymm5
+ vmovdqu YMMWORD[128+rdi],ymm12
+ vmovdqu YMMWORD[160+rdi],ymm13
+ je NEAR $L$done8x
+
+ lea rsi,[192+rsi]
+ xor r10,r10
+ vmovdqa YMMWORD[rsp],ymm10
+ lea rdi,[192+rdi]
+ sub rdx,192
+ vmovdqa YMMWORD[32+rsp],ymm15
+ jmp NEAR $L$oop_tail8x
+
+ALIGN 32
+$L$256_or_more8x:
+ vpxor ymm6,ymm6,YMMWORD[rsi]
+ vpxor ymm8,ymm8,YMMWORD[32+rsi]
+ vpxor ymm1,ymm1,YMMWORD[64+rsi]
+ vpxor ymm5,ymm5,YMMWORD[96+rsi]
+ vpxor ymm12,ymm12,YMMWORD[128+rsi]
+ vpxor ymm13,ymm13,YMMWORD[160+rsi]
+ vpxor ymm10,ymm10,YMMWORD[192+rsi]
+ vpxor ymm15,ymm15,YMMWORD[224+rsi]
+ vmovdqu YMMWORD[rdi],ymm6
+ vmovdqu YMMWORD[32+rdi],ymm8
+ vmovdqu YMMWORD[64+rdi],ymm1
+ vmovdqu YMMWORD[96+rdi],ymm5
+ vmovdqu YMMWORD[128+rdi],ymm12
+ vmovdqu YMMWORD[160+rdi],ymm13
+ vmovdqu YMMWORD[192+rdi],ymm10
+ vmovdqu YMMWORD[224+rdi],ymm15
+ je NEAR $L$done8x
+
+ lea rsi,[256+rsi]
+ xor r10,r10
+ vmovdqa YMMWORD[rsp],ymm14
+ lea rdi,[256+rdi]
+ sub rdx,256
+ vmovdqa YMMWORD[32+rsp],ymm2
+ jmp NEAR $L$oop_tail8x
+
+ALIGN 32
+$L$320_or_more8x:
+ vpxor ymm6,ymm6,YMMWORD[rsi]
+ vpxor ymm8,ymm8,YMMWORD[32+rsi]
+ vpxor ymm1,ymm1,YMMWORD[64+rsi]
+ vpxor ymm5,ymm5,YMMWORD[96+rsi]
+ vpxor ymm12,ymm12,YMMWORD[128+rsi]
+ vpxor ymm13,ymm13,YMMWORD[160+rsi]
+ vpxor ymm10,ymm10,YMMWORD[192+rsi]
+ vpxor ymm15,ymm15,YMMWORD[224+rsi]
+ vpxor ymm14,ymm14,YMMWORD[256+rsi]
+ vpxor ymm2,ymm2,YMMWORD[288+rsi]
+ vmovdqu YMMWORD[rdi],ymm6
+ vmovdqu YMMWORD[32+rdi],ymm8
+ vmovdqu YMMWORD[64+rdi],ymm1
+ vmovdqu YMMWORD[96+rdi],ymm5
+ vmovdqu YMMWORD[128+rdi],ymm12
+ vmovdqu YMMWORD[160+rdi],ymm13
+ vmovdqu YMMWORD[192+rdi],ymm10
+ vmovdqu YMMWORD[224+rdi],ymm15
+ vmovdqu YMMWORD[256+rdi],ymm14
+ vmovdqu YMMWORD[288+rdi],ymm2
+ je NEAR $L$done8x
+
+ lea rsi,[320+rsi]
+ xor r10,r10
+ vmovdqa YMMWORD[rsp],ymm3
+ lea rdi,[320+rdi]
+ sub rdx,320
+ vmovdqa YMMWORD[32+rsp],ymm7
+ jmp NEAR $L$oop_tail8x
+
+ALIGN 32
+$L$384_or_more8x:
+ vpxor ymm6,ymm6,YMMWORD[rsi]
+ vpxor ymm8,ymm8,YMMWORD[32+rsi]
+ vpxor ymm1,ymm1,YMMWORD[64+rsi]
+ vpxor ymm5,ymm5,YMMWORD[96+rsi]
+ vpxor ymm12,ymm12,YMMWORD[128+rsi]
+ vpxor ymm13,ymm13,YMMWORD[160+rsi]
+ vpxor ymm10,ymm10,YMMWORD[192+rsi]
+ vpxor ymm15,ymm15,YMMWORD[224+rsi]
+ vpxor ymm14,ymm14,YMMWORD[256+rsi]
+ vpxor ymm2,ymm2,YMMWORD[288+rsi]
+ vpxor ymm3,ymm3,YMMWORD[320+rsi]
+ vpxor ymm7,ymm7,YMMWORD[352+rsi]
+ vmovdqu YMMWORD[rdi],ymm6
+ vmovdqu YMMWORD[32+rdi],ymm8
+ vmovdqu YMMWORD[64+rdi],ymm1
+ vmovdqu YMMWORD[96+rdi],ymm5
+ vmovdqu YMMWORD[128+rdi],ymm12
+ vmovdqu YMMWORD[160+rdi],ymm13
+ vmovdqu YMMWORD[192+rdi],ymm10
+ vmovdqu YMMWORD[224+rdi],ymm15
+ vmovdqu YMMWORD[256+rdi],ymm14
+ vmovdqu YMMWORD[288+rdi],ymm2
+ vmovdqu YMMWORD[320+rdi],ymm3
+ vmovdqu YMMWORD[352+rdi],ymm7
+ je NEAR $L$done8x
+
+ lea rsi,[384+rsi]
+ xor r10,r10
+ vmovdqa YMMWORD[rsp],ymm11
+ lea rdi,[384+rdi]
+ sub rdx,384
+ vmovdqa YMMWORD[32+rsp],ymm9
+ jmp NEAR $L$oop_tail8x
+
+ALIGN 32
+$L$448_or_more8x:
+ vpxor ymm6,ymm6,YMMWORD[rsi]
+ vpxor ymm8,ymm8,YMMWORD[32+rsi]
+ vpxor ymm1,ymm1,YMMWORD[64+rsi]
+ vpxor ymm5,ymm5,YMMWORD[96+rsi]
+ vpxor ymm12,ymm12,YMMWORD[128+rsi]
+ vpxor ymm13,ymm13,YMMWORD[160+rsi]
+ vpxor ymm10,ymm10,YMMWORD[192+rsi]
+ vpxor ymm15,ymm15,YMMWORD[224+rsi]
+ vpxor ymm14,ymm14,YMMWORD[256+rsi]
+ vpxor ymm2,ymm2,YMMWORD[288+rsi]
+ vpxor ymm3,ymm3,YMMWORD[320+rsi]
+ vpxor ymm7,ymm7,YMMWORD[352+rsi]
+ vpxor ymm11,ymm11,YMMWORD[384+rsi]
+ vpxor ymm9,ymm9,YMMWORD[416+rsi]
+ vmovdqu YMMWORD[rdi],ymm6
+ vmovdqu YMMWORD[32+rdi],ymm8
+ vmovdqu YMMWORD[64+rdi],ymm1
+ vmovdqu YMMWORD[96+rdi],ymm5
+ vmovdqu YMMWORD[128+rdi],ymm12
+ vmovdqu YMMWORD[160+rdi],ymm13
+ vmovdqu YMMWORD[192+rdi],ymm10
+ vmovdqu YMMWORD[224+rdi],ymm15
+ vmovdqu YMMWORD[256+rdi],ymm14
+ vmovdqu YMMWORD[288+rdi],ymm2
+ vmovdqu YMMWORD[320+rdi],ymm3
+ vmovdqu YMMWORD[352+rdi],ymm7
+ vmovdqu YMMWORD[384+rdi],ymm11
+ vmovdqu YMMWORD[416+rdi],ymm9
+ je NEAR $L$done8x
+
+ lea rsi,[448+rsi]
+ xor r10,r10
+ vmovdqa YMMWORD[rsp],ymm0
+ lea rdi,[448+rdi]
+ sub rdx,448
+ vmovdqa YMMWORD[32+rsp],ymm4
+
+$L$oop_tail8x:
+ movzx eax,BYTE[r10*1+rsi]
+ movzx ecx,BYTE[r10*1+rsp]
+ lea r10,[1+r10]
+ xor eax,ecx
+ mov BYTE[((-1))+r10*1+rdi],al
+ dec rdx
+ jnz NEAR $L$oop_tail8x
+
+$L$done8x:
+ vzeroall
+ lea r11,[((656+48))+rsp]
+ movaps xmm6,XMMWORD[((-48))+r11]
+ movaps xmm7,XMMWORD[((-32))+r11]
+ movaps xmm8,XMMWORD[((-16))+r11]
+ movaps xmm9,XMMWORD[r11]
+ movaps xmm10,XMMWORD[16+r11]
+ movaps xmm11,XMMWORD[32+r11]
+ movaps xmm12,XMMWORD[48+r11]
+ movaps xmm13,XMMWORD[64+r11]
+ movaps xmm14,XMMWORD[80+r11]
+ movaps xmm15,XMMWORD[96+r11]
+ mov rsp,QWORD[640+rsp]
+ mov rdi,QWORD[8+rsp] ;WIN64 epilogue
+ mov rsi,QWORD[16+rsp]
+ DB 0F3h,0C3h ;repret
+$L$SEH_end_ChaCha20_8x:
diff --git a/win-x86_64/crypto/ec/p256-x86_64-asm.asm b/win-x86_64/crypto/ec/p256-x86_64-asm.asm
index 45ba686c..a2e40758 100644
--- a/win-x86_64/crypto/ec/p256-x86_64-asm.asm
+++ b/win-x86_64/crypto/ec/p256-x86_64-asm.asm
@@ -1009,6 +1009,7 @@ $L$SEH_begin_ecp_nistz256_point_double:
push r15
sub rsp,32*5+8
+$L$point_double_shortcutq:
movdqu xmm0,XMMWORD[rsi]
mov rbx,rsi
movdqu xmm1,XMMWORD[16+rsi]
@@ -1282,6 +1283,7 @@ DB 102,72,15,110,199
mov r14,QWORD[((64+8))+rbx]
mov r15,QWORD[((64+16))+rbx]
mov r8,QWORD[((64+24))+rbx]
+DB 102,72,15,110,203
lea rsi,[((64-0))+rbx]
lea rdi,[32+rsp]
@@ -1373,7 +1375,7 @@ DB 102,73,15,126,217
test r8,r8
jnz NEAR $L$add_proceedq
test r9,r9
- jz NEAR $L$add_proceedq
+ jz NEAR $L$add_doubleq
DB 102,72,15,126,199
pxor xmm0,xmm0
@@ -1386,6 +1388,13 @@ DB 102,72,15,126,199
jmp NEAR $L$add_doneq
ALIGN 32
+$L$add_doubleq:
+DB 102,72,15,126,206
+DB 102,72,15,126,199
+ add rsp,416
+ jmp NEAR $L$point_double_shortcutq
+
+ALIGN 32
$L$add_proceedq:
mov rax,QWORD[((0+64))+rsp]
mov r14,QWORD[((8+64))+rsp]