From 9d0d5d8798a576fbf674a823734e65e15ca5f2ec Mon Sep 17 00:00:00 2001 From: Cory Benfield Date: Thu, 13 Apr 2023 12:42:47 +0100 Subject: [PATCH] Update BoringSSL to abfd5ebc87ddca0fab9fca067c9d7edbc355eae8 (#424) * Update BoringSSL vendoring scripts for new perlasm * More patches * Update BoringSSL to abfd5ebc87ddca0fab9fca067c9d7edbc355eae8 * Fixup newly opaquified types --- Package.swift | 2 +- Package@swift-5.5.swift | 2 +- Sources/CNIOBoringSSL/crypto/asn1/a_bitstr.c | 9 +- Sources/CNIOBoringSSL/crypto/asn1/a_bool.c | 71 +- Sources/CNIOBoringSSL/crypto/asn1/a_dup.c | 1 - Sources/CNIOBoringSSL/crypto/asn1/a_gentm.c | 35 +- Sources/CNIOBoringSSL/crypto/asn1/a_i2d_fp.c | 1 - Sources/CNIOBoringSSL/crypto/asn1/a_int.c | 26 +- Sources/CNIOBoringSSL/crypto/asn1/a_mbstr.c | 59 +- Sources/CNIOBoringSSL/crypto/asn1/a_object.c | 163 +- Sources/CNIOBoringSSL/crypto/asn1/a_strex.c | 4 +- Sources/CNIOBoringSSL/crypto/asn1/a_time.c | 52 +- Sources/CNIOBoringSSL/crypto/asn1/a_type.c | 64 +- Sources/CNIOBoringSSL/crypto/asn1/a_utctm.c | 37 +- Sources/CNIOBoringSSL/crypto/asn1/asn1_lib.c | 47 +- Sources/CNIOBoringSSL/crypto/asn1/asn_pack.c | 1 - Sources/CNIOBoringSSL/crypto/asn1/internal.h | 92 +- .../CNIOBoringSSL/crypto/asn1/posix_time.c | 9 +- Sources/CNIOBoringSSL/crypto/asn1/tasn_dec.c | 138 +- Sources/CNIOBoringSSL/crypto/asn1/tasn_enc.c | 54 +- Sources/CNIOBoringSSL/crypto/asn1/tasn_fre.c | 63 +- Sources/CNIOBoringSSL/crypto/asn1/tasn_new.c | 52 +- Sources/CNIOBoringSSL/crypto/asn1/tasn_typ.c | 6 +- Sources/CNIOBoringSSL/crypto/asn1/tasn_utl.c | 67 +- Sources/CNIOBoringSSL/crypto/bio/bio.c | 28 +- Sources/CNIOBoringSSL/crypto/bio/bio_mem.c | 88 +- Sources/CNIOBoringSSL/crypto/bio/connect.c | 12 +- Sources/CNIOBoringSSL/crypto/bio/fd.c | 22 +- Sources/CNIOBoringSSL/crypto/bio/file.c | 35 +- Sources/CNIOBoringSSL/crypto/bio/pair.c | 10 +- Sources/CNIOBoringSSL/crypto/bio/printf.c | 1 - Sources/CNIOBoringSSL/crypto/bio/socket.c | 9 +- Sources/CNIOBoringSSL/crypto/blake2/blake2.c | 6 +- .../CNIOBoringSSL/crypto/bn_extra/convert.c | 33 +- Sources/CNIOBoringSSL/crypto/buf/buf.c | 8 +- Sources/CNIOBoringSSL/crypto/bytestring/ber.c | 19 +- Sources/CNIOBoringSSL/crypto/bytestring/cbb.c | 46 +- Sources/CNIOBoringSSL/crypto/bytestring/cbs.c | 97 +- .../crypto/bytestring/internal.h | 4 +- ...4.ios.arm.S => chacha-armv4-ios.ios.arm.S} | 8 +- ...x.arm.S => chacha-armv4-linux.linux.arm.S} | 9 +- ...rch64.S => chacha-armv8-ios.ios.aarch64.S} | 8 +- ...4.S => chacha-armv8-linux.linux.aarch64.S} | 9 +- ...nux.x86.S => chacha-x86-linux.linux.x86.S} | 13 +- ...4.S => chacha-x86_64-linux.linux.x86_64.S} | 9 +- ...86_64.S => chacha-x86_64-mac.mac.x86_64.S} | 8 +- ... aes128gcmsiv-x86_64-linux.linux.x86_64.S} | 9 +- ...S => aes128gcmsiv-x86_64-mac.mac.x86_64.S} | 8 +- ...chacha20_poly1305_armv8-ios.ios.aarch64.S} | 8 +- ...ha20_poly1305_armv8-linux.linux.aarch64.S} | 9 +- ...ha20_poly1305_x86_64-linux.linux.x86_64.S} | 9 +- ...chacha20_poly1305_x86_64-mac.mac.x86_64.S} | 8 +- .../crypto/cipher_extra/e_chacha20poly1305.c | 2 +- Sources/CNIOBoringSSL/crypto/conf/conf.c | 14 +- Sources/CNIOBoringSSL/crypto/conf/conf_def.h | 1 - Sources/CNIOBoringSSL/crypto/cpu_arm_linux.c | 92 +- Sources/CNIOBoringSSL/crypto/cpu_arm_linux.h | 38 - Sources/CNIOBoringSSL/crypto/cpu_ppc64le.c | 38 - Sources/CNIOBoringSSL/crypto/crypto.c | 22 +- .../crypto/curve25519/asm/x25519-asm-arm.S | 4 +- .../crypto/curve25519/curve25519.c | 4 - Sources/CNIOBoringSSL/crypto/des/des.c | 464 ++--- .../crypto/digest_extra/digest_extra.c | 3 - Sources/CNIOBoringSSL/crypto/dsa/dsa.c | 52 +- Sources/CNIOBoringSSL/crypto/dsa/dsa_asn1.c | 44 +- Sources/CNIOBoringSSL/crypto/dsa/internal.h | 6 +- .../CNIOBoringSSL/crypto/ec_extra/ec_asn1.c | 47 +- .../crypto/ec_extra/hash_to_curve.c | 322 +++- .../CNIOBoringSSL/crypto/ec_extra/internal.h | 34 +- Sources/CNIOBoringSSL/crypto/err/err.c | 139 +- Sources/CNIOBoringSSL/crypto/err/err_data.c | 174 +- Sources/CNIOBoringSSL/crypto/evp/evp.c | 58 +- Sources/CNIOBoringSSL/crypto/evp/evp_asn1.c | 6 +- Sources/CNIOBoringSSL/crypto/evp/evp_ctx.c | 1 - Sources/CNIOBoringSSL/crypto/evp/internal.h | 28 + Sources/CNIOBoringSSL/crypto/evp/p_dsa_asn1.c | 107 +- Sources/CNIOBoringSSL/crypto/evp/p_ec.c | 28 +- Sources/CNIOBoringSSL/crypto/evp/p_ec_asn1.c | 141 +- Sources/CNIOBoringSSL/crypto/evp/p_ed25519.c | 9 +- .../CNIOBoringSSL/crypto/evp/p_ed25519_asn1.c | 32 +- Sources/CNIOBoringSSL/crypto/evp/p_hkdf.c | 12 +- Sources/CNIOBoringSSL/crypto/evp/p_rsa.c | 12 +- Sources/CNIOBoringSSL/crypto/evp/p_rsa_asn1.c | 67 +- Sources/CNIOBoringSSL/crypto/evp/p_x25519.c | 9 +- .../CNIOBoringSSL/crypto/evp/p_x25519_asn1.c | 81 +- Sources/CNIOBoringSSL/crypto/evp/print.c | 381 ++-- Sources/CNIOBoringSSL/crypto/evp/scrypt.c | 1 - Sources/CNIOBoringSSL/crypto/evp/sign.c | 25 +- Sources/CNIOBoringSSL/crypto/ex_data.c | 44 +- .../crypto/fipsmodule/aes/internal.h | 6 - ... => aesni-gcm-x86_64-linux.linux.x86_64.S} | 124 +- ...64.S => aesni-gcm-x86_64-mac.mac.x86_64.S} | 87 +- ...inux.x86.S => aesni-x86-linux.linux.x86.S} | 13 +- ...64.S => aesni-x86_64-linux.linux.x86_64.S} | 9 +- ...x86_64.S => aesni-x86_64-mac.mac.x86_64.S} | 8 +- ...32.ios.arm.S => aesv8-armv7-ios.ios.arm.S} | 8 +- ...ux.arm.S => aesv8-armv7-linux.linux.arm.S} | 9 +- ...arch64.S => aesv8-armv8-ios.ios.aarch64.S} | 8 +- ...64.S => aesv8-armv8-linux.linux.aarch64.S} | 9 +- .../aesv8-gcm-armv8-ios.ios.aarch64.S | 1574 +++++++++++++++++ .../aesv8-gcm-armv8-linux.linux.aarch64.S | 1574 +++++++++++++++++ ...ont.ios.arm.S => armv4-mont-ios.ios.arm.S} | 8 +- ...nux.arm.S => armv4-mont-linux.linux.arm.S} | 9 +- ...aarch64.S => armv8-mont-ios.ios.aarch64.S} | 8 +- ...h64.S => armv8-mont-linux.linux.aarch64.S} | 9 +- ...6.linux.x86.S => bn-586-linux.linux.x86.S} | 13 +- .../fipsmodule/bn-armv8-ios.ios.aarch64.S | 108 ++ .../fipsmodule/bn-armv8-linux.linux.aarch64.S | 108 ++ .../CNIOBoringSSL/crypto/fipsmodule/bn/bn.c | 19 - .../crypto/fipsmodule/bn/bytes.c | 12 + .../CNIOBoringSSL/crypto/fipsmodule/bn/ctx.c | 2 - .../crypto/fipsmodule/bn/exponentiation.c | 112 +- .../CNIOBoringSSL/crypto/fipsmodule/bn/gcd.c | 1 - .../crypto/fipsmodule/bn/generic.c | 280 ++- .../crypto/fipsmodule/bn/internal.h | 75 +- .../crypto/fipsmodule/bn/montgomery.c | 7 + .../crypto/fipsmodule/bn/prime.c | 1 - .../crypto/fipsmodule/bn/rsaz_exp.c | 4 +- .../crypto/fipsmodule/bn/rsaz_exp.h | 13 +- .../CNIOBoringSSL/crypto/fipsmodule/bn/sqrt.c | 1 - ...v7.ios.arm.S => bsaes-armv7-ios.ios.arm.S} | 8 +- ...ux.arm.S => bsaes-armv7-linux.linux.arm.S} | 9 +- .../crypto/fipsmodule/cipher/cipher.c | 2 - .../crypto/fipsmodule/cipher/e_aes.c | 5 +- ...6.linux.x86.S => co-586-linux.linux.x86.S} | 13 +- .../CNIOBoringSSL/crypto/fipsmodule/dh/dh.c | 1 - .../crypto/fipsmodule/digest/digest.c | 3 - .../CNIOBoringSSL/crypto/fipsmodule/ec/ec.c | 5 +- .../crypto/fipsmodule/ec/ec_key.c | 77 +- .../crypto/fipsmodule/ec/ec_montgomery.c | 10 +- .../crypto/fipsmodule/ec/internal.h | 24 +- .../CNIOBoringSSL/crypto/fipsmodule/ec/oct.c | 80 +- .../crypto/fipsmodule/ec/p256-nistz.c | 4 + .../CNIOBoringSSL/crypto/fipsmodule/ec/p256.c | 8 +- .../CNIOBoringSSL/crypto/fipsmodule/ec/wnaf.c | 1 - .../crypto/fipsmodule/ecdsa/ecdsa.c | 12 + ...v4.ios.arm.S => ghash-armv4-ios.ios.arm.S} | 8 +- ...ux.arm.S => ghash-armv4-linux.linux.arm.S} | 9 +- ...4.S => ghash-neon-armv8-ios.ios.aarch64.S} | 8 +- ...=> ghash-neon-armv8-linux.linux.aarch64.S} | 9 +- ...86.S => ghash-ssse3-x86-linux.linux.x86.S} | 13 +- ...> ghash-ssse3-x86_64-linux.linux.x86_64.S} | 17 +- ....S => ghash-ssse3-x86_64-mac.mac.x86_64.S} | 16 +- ...inux.x86.S => ghash-x86-linux.linux.x86.S} | 13 +- ...64.S => ghash-x86_64-linux.linux.x86_64.S} | 15 +- ...x86_64.S => ghash-x86_64-mac.mac.x86_64.S} | 14 +- ....ios.arm.S => ghashv8-armv7-ios.ios.arm.S} | 8 +- ....arm.S => ghashv8-armv7-linux.linux.arm.S} | 9 +- ...ch64.S => ghashv8-armv8-ios.ios.aarch64.S} | 8 +- ....S => ghashv8-armv8-linux.linux.aarch64.S} | 9 +- .../crypto/fipsmodule/hmac/hmac.c | 13 +- ....linux.x86.S => md5-586-linux.linux.x86.S} | 13 +- ...6_64.S => md5-x86_64-linux.linux.x86_64.S} | 7 +- ...c.x86_64.S => md5-x86_64-mac.mac.x86_64.S} | 6 +- .../crypto/fipsmodule/modes/gcm.c | 70 +- .../crypto/fipsmodule/modes/internal.h | 25 +- ...h64.S => p256-armv8-asm-ios.ios.aarch64.S} | 82 +- ...S => p256-armv8-asm-linux.linux.aarch64.S} | 83 +- ...S => p256-x86_64-asm-linux.linux.x86_64.S} | 9 +- ..._64.S => p256-x86_64-asm-mac.mac.x86_64.S} | 8 +- ... => p256_beeu-armv8-asm-ios.ios.aarch64.S} | 8 +- ...p256_beeu-armv8-asm-linux.linux.aarch64.S} | 9 +- ...p256_beeu-x86_64-asm-linux.linux.x86_64.S} | 7 +- ... => p256_beeu-x86_64-asm-mac.mac.x86_64.S} | 6 +- .../crypto/fipsmodule/rand/fork_detect.c | 19 +- .../crypto/fipsmodule/rand/fork_detect.h | 5 +- .../crypto/fipsmodule/rand/getrandom_fillin.h | 2 - .../crypto/fipsmodule/rand/rand.c | 11 - ...4.S => rdrand-x86_64-linux.linux.x86_64.S} | 7 +- ...86_64.S => rdrand-x86_64-mac.mac.x86_64.S} | 6 +- .../crypto/fipsmodule/rsa/blinding.c | 1 - .../crypto/fipsmodule/rsa/internal.h | 30 +- .../crypto/fipsmodule/rsa/padding.c | 291 +-- .../CNIOBoringSSL/crypto/fipsmodule/rsa/rsa.c | 88 +- .../crypto/fipsmodule/rsa/rsa_impl.c | 210 +-- ...86_64.S => rsaz-avx2-linux.linux.x86_64.S} | 9 +- ...ac.x86_64.S => rsaz-avx2-mac.mac.x86_64.S} | 8 +- .../crypto/fipsmodule/self_check/self_check.c | 3 + .../service_indicator/service_indicator.c | 6 +- .../crypto/fipsmodule/sha/internal.h | 15 +- .../crypto/fipsmodule/sha/sha1-altivec.c | 361 ---- ...linux.x86.S => sha1-586-linux.linux.x86.S} | 13 +- ...s.arm.S => sha1-armv4-large-ios.ios.arm.S} | 8 +- ...m.S => sha1-armv4-large-linux.linux.arm.S} | 9 +- ...aarch64.S => sha1-armv8-ios.ios.aarch64.S} | 8 +- ...h64.S => sha1-armv8-linux.linux.aarch64.S} | 9 +- ..._64.S => sha1-x86_64-linux.linux.x86_64.S} | 10 +- ....x86_64.S => sha1-x86_64-mac.mac.x86_64.S} | 9 +- ...nux.x86.S => sha256-586-linux.linux.x86.S} | 13 +- ...4.ios.arm.S => sha256-armv4-ios.ios.arm.S} | 8 +- ...x.arm.S => sha256-armv4-linux.linux.arm.S} | 9 +- ...rch64.S => sha256-armv8-ios.ios.aarch64.S} | 8 +- ...4.S => sha256-armv8-linux.linux.aarch64.S} | 9 +- ...4.S => sha256-x86_64-linux.linux.x86_64.S} | 9 +- ...86_64.S => sha256-x86_64-mac.mac.x86_64.S} | 8 +- ...nux.x86.S => sha512-586-linux.linux.x86.S} | 13 +- ...4.ios.arm.S => sha512-armv4-ios.ios.arm.S} | 8 +- ...x.arm.S => sha512-armv4-linux.linux.arm.S} | 9 +- ...rch64.S => sha512-armv8-ios.ios.aarch64.S} | 8 +- ...4.S => sha512-armv8-linux.linux.aarch64.S} | 9 +- ...4.S => sha512-x86_64-linux.linux.x86_64.S} | 9 +- ...86_64.S => sha512-x86_64-mac.mac.x86_64.S} | 8 +- ...v7.ios.arm.S => vpaes-armv7-ios.ios.arm.S} | 8 +- ...ux.arm.S => vpaes-armv7-linux.linux.arm.S} | 9 +- ...arch64.S => vpaes-armv8-ios.ios.aarch64.S} | 8 +- ...64.S => vpaes-armv8-linux.linux.aarch64.S} | 9 +- ...inux.x86.S => vpaes-x86-linux.linux.x86.S} | 13 +- ...64.S => vpaes-x86_64-linux.linux.x86_64.S} | 9 +- ...x86_64.S => vpaes-x86_64-mac.mac.x86_64.S} | 8 +- ...linux.x86.S => x86-mont-linux.linux.x86.S} | 13 +- ..._64.S => x86_64-mont-linux.linux.x86_64.S} | 7 +- ....x86_64.S => x86_64-mont-mac.mac.x86_64.S} | 6 +- ...64.S => x86_64-mont5-linux.linux.x86_64.S} | 25 +- ...x86_64.S => x86_64-mont5-mac.mac.x86_64.S} | 24 +- Sources/CNIOBoringSSL/crypto/hpke/hpke.c | 2 - .../crypto/hrss/asm/poly_rq_mul.S | 4 +- Sources/CNIOBoringSSL/crypto/internal.h | 67 +- Sources/CNIOBoringSSL/crypto/kyber/internal.h | 91 + Sources/CNIOBoringSSL/crypto/kyber/keccak.c | 204 +++ Sources/CNIOBoringSSL/crypto/kyber/kyber.c | 826 +++++++++ Sources/CNIOBoringSSL/crypto/mem.c | 213 ++- Sources/CNIOBoringSSL/crypto/obj/obj.c | 26 +- Sources/CNIOBoringSSL/crypto/obj/obj_dat.h | 11 +- Sources/CNIOBoringSSL/crypto/pem/pem_info.c | 2 - Sources/CNIOBoringSSL/crypto/pem/pem_lib.c | 65 +- Sources/CNIOBoringSSL/crypto/pem/pem_oth.c | 1 - Sources/CNIOBoringSSL/crypto/pem/pem_pk8.c | 38 +- Sources/CNIOBoringSSL/crypto/pem/pem_x509.c | 1 - Sources/CNIOBoringSSL/crypto/pem/pem_xaux.c | 1 - .../CNIOBoringSSL/crypto/pkcs7/pkcs7_x509.c | 1 - Sources/CNIOBoringSSL/crypto/pkcs8/pkcs8.c | 3 - .../CNIOBoringSSL/crypto/pkcs8/pkcs8_x509.c | 8 +- .../CNIOBoringSSL/crypto/poly1305/poly1305.c | 25 +- .../crypto/poly1305/poly1305_arm_asm.S | 4 +- .../CNIOBoringSSL/crypto/rand_extra/passive.c | 128 +- .../{asn1/a_print.c => rsa_extra/internal.h} | 35 +- .../crypto/rsa_extra/rsa_crypt.c | 563 ++++++ Sources/CNIOBoringSSL/crypto/stack/stack.c | 21 +- Sources/CNIOBoringSSL/crypto/thread_pthread.c | 11 +- Sources/CNIOBoringSSL/crypto/thread_win.c | 11 +- .../crypto/trust_token/internal.h | 146 +- .../crypto/trust_token/pmbtoken.c | 306 +++- .../crypto/trust_token/trust_token.c | 348 +--- .../CNIOBoringSSL/crypto/trust_token/voprf.c | 221 ++- Sources/CNIOBoringSSL/crypto/x509/a_digest.c | 1 - Sources/CNIOBoringSSL/crypto/x509/a_sign.c | 46 +- Sources/CNIOBoringSSL/crypto/x509/a_verify.c | 1 - Sources/CNIOBoringSSL/crypto/x509/asn1_gen.c | 1016 +++++------ Sources/CNIOBoringSSL/crypto/x509/by_dir.c | 31 +- Sources/CNIOBoringSSL/crypto/x509/by_file.c | 1 - Sources/CNIOBoringSSL/crypto/x509/i2d_pr.c | 7 +- Sources/CNIOBoringSSL/crypto/x509/internal.h | 35 +- Sources/CNIOBoringSSL/crypto/x509/policy.c | 790 +++++++++ Sources/CNIOBoringSSL/crypto/x509/rsa_pss.c | 2 +- Sources/CNIOBoringSSL/crypto/x509/x509_att.c | 9 +- Sources/CNIOBoringSSL/crypto/x509/x509_cmp.c | 10 +- Sources/CNIOBoringSSL/crypto/x509/x509_d2.c | 1 - Sources/CNIOBoringSSL/crypto/x509/x509_def.c | 1 - Sources/CNIOBoringSSL/crypto/x509/x509_ext.c | 1 - Sources/CNIOBoringSSL/crypto/x509/x509_lu.c | 40 +- Sources/CNIOBoringSSL/crypto/x509/x509_obj.c | 7 +- Sources/CNIOBoringSSL/crypto/x509/x509_req.c | 11 +- Sources/CNIOBoringSSL/crypto/x509/x509_trs.c | 14 +- Sources/CNIOBoringSSL/crypto/x509/x509_v3.c | 12 +- Sources/CNIOBoringSSL/crypto/x509/x509_vfy.c | 206 +-- Sources/CNIOBoringSSL/crypto/x509/x509_vpm.c | 104 +- Sources/CNIOBoringSSL/crypto/x509/x509cset.c | 5 +- Sources/CNIOBoringSSL/crypto/x509/x509name.c | 1 - Sources/CNIOBoringSSL/crypto/x509/x509spki.c | 5 +- Sources/CNIOBoringSSL/crypto/x509/x_all.c | 50 +- Sources/CNIOBoringSSL/crypto/x509/x_crl.c | 10 +- Sources/CNIOBoringSSL/crypto/x509/x_info.c | 1 - Sources/CNIOBoringSSL/crypto/x509/x_name.c | 48 +- Sources/CNIOBoringSSL/crypto/x509/x_pkey.c | 1 - Sources/CNIOBoringSSL/crypto/x509/x_sig.c | 1 - Sources/CNIOBoringSSL/crypto/x509/x_spki.c | 1 - Sources/CNIOBoringSSL/crypto/x509/x_val.c | 1 - Sources/CNIOBoringSSL/crypto/x509/x_x509.c | 355 +++- Sources/CNIOBoringSSL/crypto/x509/x_x509a.c | 4 +- Sources/CNIOBoringSSL/crypto/x509v3/ext_dat.h | 3 +- .../CNIOBoringSSL/crypto/x509v3/internal.h | 227 +-- .../CNIOBoringSSL/crypto/x509v3/pcy_cache.c | 295 --- .../CNIOBoringSSL/crypto/x509v3/pcy_data.c | 134 -- Sources/CNIOBoringSSL/crypto/x509v3/pcy_map.c | 129 -- .../CNIOBoringSSL/crypto/x509v3/pcy_node.c | 187 -- .../CNIOBoringSSL/crypto/x509v3/pcy_tree.c | 829 --------- Sources/CNIOBoringSSL/crypto/x509v3/v3_akey.c | 21 +- .../CNIOBoringSSL/crypto/x509v3/v3_akeya.c | 1 - Sources/CNIOBoringSSL/crypto/x509v3/v3_alt.c | 240 ++- .../CNIOBoringSSL/crypto/x509v3/v3_bcons.c | 19 +- .../CNIOBoringSSL/crypto/x509v3/v3_bitst.c | 14 +- Sources/CNIOBoringSSL/crypto/x509v3/v3_conf.c | 261 ++- .../CNIOBoringSSL/crypto/x509v3/v3_cpols.c | 186 +- Sources/CNIOBoringSSL/crypto/x509v3/v3_crld.c | 160 +- Sources/CNIOBoringSSL/crypto/x509v3/v3_enum.c | 1 - .../CNIOBoringSSL/crypto/x509v3/v3_extku.c | 43 +- Sources/CNIOBoringSSL/crypto/x509v3/v3_genn.c | 39 +- Sources/CNIOBoringSSL/crypto/x509v3/v3_ia5.c | 5 +- Sources/CNIOBoringSSL/crypto/x509v3/v3_info.c | 23 +- Sources/CNIOBoringSSL/crypto/x509v3/v3_int.c | 3 +- Sources/CNIOBoringSSL/crypto/x509v3/v3_lib.c | 11 +- .../CNIOBoringSSL/crypto/x509v3/v3_ncons.c | 20 +- Sources/CNIOBoringSSL/crypto/x509v3/v3_ocsp.c | 8 +- Sources/CNIOBoringSSL/crypto/x509v3/v3_pci.c | 287 --- Sources/CNIOBoringSSL/crypto/x509v3/v3_pcia.c | 55 - .../CNIOBoringSSL/crypto/x509v3/v3_pcons.c | 21 +- .../CNIOBoringSSL/crypto/x509v3/v3_pmaps.c | 67 +- Sources/CNIOBoringSSL/crypto/x509v3/v3_prn.c | 1 - Sources/CNIOBoringSSL/crypto/x509v3/v3_purp.c | 40 +- Sources/CNIOBoringSSL/crypto/x509v3/v3_skey.c | 38 +- Sources/CNIOBoringSSL/crypto/x509v3/v3_utl.c | 175 +- Sources/CNIOBoringSSL/hash.txt | 2 +- Sources/CNIOBoringSSL/include/CNIOBoringSSL.h | 2 + .../include/CNIOBoringSSL_asn1.h | 300 ++-- .../include/CNIOBoringSSL_asn1t.h | 68 +- .../include/CNIOBoringSSL_base.h | 24 +- .../CNIOBoringSSL/include/CNIOBoringSSL_bio.h | 20 +- .../CNIOBoringSSL/include/CNIOBoringSSL_bn.h | 33 +- .../CNIOBoringSSL_boringssl_prefix_symbols.h | 218 ++- ...IOBoringSSL_boringssl_prefix_symbols_asm.h | 126 +- .../include/CNIOBoringSSL_bytestring.h | 48 +- .../include/CNIOBoringSSL_cipher.h | 59 +- .../include/CNIOBoringSSL_conf.h | 4 +- .../include/CNIOBoringSSL_crypto.h | 10 +- .../include/CNIOBoringSSL_ctrdrbg.h | 6 + .../CNIOBoringSSL/include/CNIOBoringSSL_dsa.h | 1 + .../CNIOBoringSSL/include/CNIOBoringSSL_ec.h | 43 +- .../include/CNIOBoringSSL_ec_key.h | 36 +- .../include/CNIOBoringSSL_ecdsa.h | 1 + .../CNIOBoringSSL/include/CNIOBoringSSL_err.h | 21 +- .../CNIOBoringSSL/include/CNIOBoringSSL_evp.h | 33 +- .../include/CNIOBoringSSL_ex_data.h | 2 +- .../include/CNIOBoringSSL_kyber.h | 128 ++ .../CNIOBoringSSL/include/CNIOBoringSSL_mem.h | 67 +- .../CNIOBoringSSL/include/CNIOBoringSSL_nid.h | 9 + .../CNIOBoringSSL/include/CNIOBoringSSL_obj.h | 9 +- .../CNIOBoringSSL/include/CNIOBoringSSL_pem.h | 25 +- .../CNIOBoringSSL/include/CNIOBoringSSL_rsa.h | 2 +- .../CNIOBoringSSL/include/CNIOBoringSSL_ssl.h | 48 +- .../include/CNIOBoringSSL_ssl3.h | 1 - .../include/CNIOBoringSSL_stack.h | 67 +- .../include/CNIOBoringSSL_time.h | 41 + .../include/CNIOBoringSSL_trust_token.h | 59 +- .../include/CNIOBoringSSL_x509.h | 67 +- .../include/CNIOBoringSSL_x509v3.h | 280 +-- .../include/boringssl_prefix_symbols_nasm.inc | 252 ++- Sources/CNIOBoringSSL/ssl/bio_ssl.cc | 4 +- Sources/CNIOBoringSSL/ssl/d1_both.cc | 8 +- .../ssl/encrypted_client_hello.cc | 28 +- Sources/CNIOBoringSSL/ssl/extensions.cc | 62 +- Sources/CNIOBoringSSL/ssl/handoff.cc | 82 +- Sources/CNIOBoringSSL/ssl/handshake_client.cc | 53 +- Sources/CNIOBoringSSL/ssl/handshake_server.cc | 14 +- Sources/CNIOBoringSSL/ssl/internal.h | 144 +- Sources/CNIOBoringSSL/ssl/s3_both.cc | 19 +- Sources/CNIOBoringSSL/ssl/s3_lib.cc | 3 +- Sources/CNIOBoringSSL/ssl/ssl_aead_ctx.cc | 1 - Sources/CNIOBoringSSL/ssl/ssl_asn1.cc | 112 +- Sources/CNIOBoringSSL/ssl/ssl_cert.cc | 14 +- Sources/CNIOBoringSSL/ssl/ssl_cipher.cc | 19 +- Sources/CNIOBoringSSL/ssl/ssl_file.cc | 4 +- Sources/CNIOBoringSSL/ssl/ssl_key_share.cc | 292 +-- Sources/CNIOBoringSSL/ssl/ssl_lib.cc | 64 +- Sources/CNIOBoringSSL/ssl/ssl_privkey.cc | 155 +- Sources/CNIOBoringSSL/ssl/ssl_session.cc | 46 +- Sources/CNIOBoringSSL/ssl/ssl_x509.cc | 11 +- Sources/CNIOBoringSSL/ssl/t1_enc.cc | 24 +- Sources/CNIOBoringSSL/ssl/tls13_both.cc | 10 +- Sources/CNIOBoringSSL/ssl/tls13_client.cc | 1 - Sources/CNIOBoringSSL/ssl/tls13_server.cc | 23 +- Sources/NIOSSL/SSLCertificate.swift | 6 +- Sources/NIOSSL/SSLContext.swift | 2 +- Sources/NIOSSL/SSLPKCS12Bundle.swift | 4 +- Sources/NIOSSL/SSLPrivateKey.swift | 26 +- Sources/NIOSSL/SSLPublicKey.swift | 12 +- Tests/NIOSSLTests/CustomPrivateKeyTests.swift | 4 +- Tests/NIOSSLTests/NIOSSLTestHelpers.swift | 8 +- scripts/build-asm.py | 53 +- scripts/patch-3-more-inttypes.patch | 13 + scripts/vendor-boringssl.sh | 3 + 380 files changed, 14028 insertions(+), 9681 deletions(-) rename Sources/CNIOBoringSSL/crypto/chacha/{chacha-armv4.ios.arm.S => chacha-armv4-ios.ios.arm.S} (99%) rename Sources/CNIOBoringSSL/crypto/chacha/{chacha-armv4.linux.arm.S => chacha-armv4-linux.linux.arm.S} (99%) rename Sources/CNIOBoringSSL/crypto/chacha/{chacha-armv8.ios.aarch64.S => chacha-armv8-ios.ios.aarch64.S} (99%) rename Sources/CNIOBoringSSL/crypto/chacha/{chacha-armv8.linux.aarch64.S => chacha-armv8-linux.linux.aarch64.S} (99%) rename Sources/CNIOBoringSSL/crypto/chacha/{chacha-x86.linux.x86.S => chacha-x86-linux.linux.x86.S} (98%) rename Sources/CNIOBoringSSL/crypto/chacha/{chacha-x86_64.linux.x86_64.S => chacha-x86_64-linux.linux.x86_64.S} (99%) rename Sources/CNIOBoringSSL/crypto/chacha/{chacha-x86_64.mac.x86_64.S => chacha-x86_64-mac.mac.x86_64.S} (99%) rename Sources/CNIOBoringSSL/crypto/cipher_extra/{aes128gcmsiv-x86_64.linux.x86_64.S => aes128gcmsiv-x86_64-linux.linux.x86_64.S} (99%) rename Sources/CNIOBoringSSL/crypto/cipher_extra/{aes128gcmsiv-x86_64.mac.x86_64.S => aes128gcmsiv-x86_64-mac.mac.x86_64.S} (99%) rename Sources/CNIOBoringSSL/crypto/cipher_extra/{chacha20_poly1305_armv8.ios.aarch64.S => chacha20_poly1305_armv8-ios.ios.aarch64.S} (99%) rename Sources/CNIOBoringSSL/crypto/cipher_extra/{chacha20_poly1305_armv8.linux.aarch64.S => chacha20_poly1305_armv8-linux.linux.aarch64.S} (99%) rename Sources/CNIOBoringSSL/crypto/cipher_extra/{chacha20_poly1305_x86_64.linux.x86_64.S => chacha20_poly1305_x86_64-linux.linux.x86_64.S} (99%) rename Sources/CNIOBoringSSL/crypto/cipher_extra/{chacha20_poly1305_x86_64.mac.x86_64.S => chacha20_poly1305_x86_64-mac.mac.x86_64.S} (99%) delete mode 100644 Sources/CNIOBoringSSL/crypto/cpu_ppc64le.c rename Sources/CNIOBoringSSL/crypto/fipsmodule/{aesni-gcm-x86_64.linux.x86_64.S => aesni-gcm-x86_64-linux.linux.x86_64.S} (93%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{aesni-gcm-x86_64.mac.x86_64.S => aesni-gcm-x86_64-mac.mac.x86_64.S} (96%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{aesni-x86.linux.x86.S => aesni-x86-linux.linux.x86.S} (99%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{aesni-x86_64.linux.x86_64.S => aesni-x86_64-linux.linux.x86_64.S} (99%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{aesni-x86_64.mac.x86_64.S => aesni-x86_64-mac.mac.x86_64.S} (99%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{aesv8-armx32.ios.arm.S => aesv8-armv7-ios.ios.arm.S} (98%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{aesv8-armx32.linux.arm.S => aesv8-armv7-linux.linux.arm.S} (98%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{aesv8-armx64.ios.aarch64.S => aesv8-armv8-ios.ios.aarch64.S} (98%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{aesv8-armx64.linux.aarch64.S => aesv8-armv8-linux.linux.aarch64.S} (98%) create mode 100644 Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-gcm-armv8-ios.ios.aarch64.S create mode 100644 Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-gcm-armv8-linux.linux.aarch64.S rename Sources/CNIOBoringSSL/crypto/fipsmodule/{armv4-mont.ios.arm.S => armv4-mont-ios.ios.arm.S} (98%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{armv4-mont.linux.arm.S => armv4-mont-linux.linux.arm.S} (98%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{armv8-mont.ios.aarch64.S => armv8-mont-ios.ios.aarch64.S} (99%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{armv8-mont.linux.aarch64.S => armv8-mont-linux.linux.aarch64.S} (99%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{bn-586.linux.x86.S => bn-586-linux.linux.x86.S} (97%) create mode 100644 Sources/CNIOBoringSSL/crypto/fipsmodule/bn-armv8-ios.ios.aarch64.S create mode 100644 Sources/CNIOBoringSSL/crypto/fipsmodule/bn-armv8-linux.linux.aarch64.S rename Sources/CNIOBoringSSL/crypto/fipsmodule/{bsaes-armv7.ios.arm.S => bsaes-armv7-ios.ios.arm.S} (99%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{bsaes-armv7.linux.arm.S => bsaes-armv7-linux.linux.arm.S} (99%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{co-586.linux.x86.S => co-586-linux.linux.x86.S} (97%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{ghash-armv4.ios.arm.S => ghash-armv4-ios.ios.arm.S} (96%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{ghash-armv4.linux.arm.S => ghash-armv4-linux.linux.arm.S} (96%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{ghash-neon-armv8.ios.aarch64.S => ghash-neon-armv8-ios.ios.aarch64.S} (97%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{ghash-neon-armv8.linux.aarch64.S => ghash-neon-armv8-linux.linux.aarch64.S} (97%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{ghash-ssse3-x86.linux.x86.S => ghash-ssse3-x86-linux.linux.x86.S} (93%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{ghash-ssse3-x86_64.linux.x86_64.S => ghash-ssse3-x86_64-linux.linux.x86_64.S} (96%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{ghash-ssse3-x86_64.mac.x86_64.S => ghash-ssse3-x86_64-mac.mac.x86_64.S} (96%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{ghash-x86.linux.x86.S => ghash-x86-linux.linux.x86.S} (94%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{ghash-x86_64.linux.x86_64.S => ghash-x86_64-linux.linux.x86_64.S} (99%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{ghash-x86_64.mac.x86_64.S => ghash-x86_64-mac.mac.x86_64.S} (99%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{ghashv8-armx32.ios.arm.S => ghashv8-armv7-ios.ios.arm.S} (96%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{ghashv8-armx32.linux.arm.S => ghashv8-armv7-linux.linux.arm.S} (96%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{ghashv8-armx64.ios.aarch64.S => ghashv8-armv8-ios.ios.aarch64.S} (98%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{ghashv8-armx64.linux.aarch64.S => ghashv8-armv8-linux.linux.aarch64.S} (98%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{md5-586.linux.x86.S => md5-586-linux.linux.x86.S} (96%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{md5-x86_64.linux.x86_64.S => md5-x86_64-linux.linux.x86_64.S} (98%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{md5-x86_64.mac.x86_64.S => md5-x86_64-mac.mac.x86_64.S} (98%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{p256-armv8-asm.ios.aarch64.S => p256-armv8-asm-ios.ios.aarch64.S} (96%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{p256-armv8-asm.linux.aarch64.S => p256-armv8-asm-linux.linux.aarch64.S} (96%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{p256-x86_64-asm.linux.x86_64.S => p256-x86_64-asm-linux.linux.x86_64.S} (99%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{p256-x86_64-asm.mac.x86_64.S => p256-x86_64-asm-mac.mac.x86_64.S} (99%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{p256_beeu-armv8-asm.ios.aarch64.S => p256_beeu-armv8-asm-ios.ios.aarch64.S} (96%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{p256_beeu-armv8-asm.linux.aarch64.S => p256_beeu-armv8-asm-linux.linux.aarch64.S} (96%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{p256_beeu-x86_64-asm.linux.x86_64.S => p256_beeu-x86_64-asm-linux.linux.x86_64.S} (96%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{p256_beeu-x86_64-asm.mac.x86_64.S => p256_beeu-x86_64-asm-mac.mac.x86_64.S} (95%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{rdrand-x86_64.linux.x86_64.S => rdrand-x86_64-linux.linux.x86_64.S} (87%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{rdrand-x86_64.mac.x86_64.S => rdrand-x86_64-mac.mac.x86_64.S} (85%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{rsaz-avx2.linux.x86_64.S => rsaz-avx2-linux.linux.x86_64.S} (99%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{rsaz-avx2.mac.x86_64.S => rsaz-avx2-mac.mac.x86_64.S} (99%) delete mode 100644 Sources/CNIOBoringSSL/crypto/fipsmodule/sha/sha1-altivec.c rename Sources/CNIOBoringSSL/crypto/fipsmodule/{sha1-586.linux.x86.S => sha1-586-linux.linux.x86.S} (99%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{sha1-armv4-large.ios.arm.S => sha1-armv4-large-ios.ios.arm.S} (99%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{sha1-armv4-large.linux.arm.S => sha1-armv4-large-linux.linux.arm.S} (99%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{sha1-armv8.ios.aarch64.S => sha1-armv8-ios.ios.aarch64.S} (99%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{sha1-armv8.linux.aarch64.S => sha1-armv8-linux.linux.aarch64.S} (99%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{sha1-x86_64.linux.x86_64.S => sha1-x86_64-linux.linux.x86_64.S} (99%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{sha1-x86_64.mac.x86_64.S => sha1-x86_64-mac.mac.x86_64.S} (99%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{sha256-586.linux.x86.S => sha256-586-linux.linux.x86.S} (99%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{sha256-armv4.ios.arm.S => sha256-armv4-ios.ios.arm.S} (99%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{sha256-armv4.linux.arm.S => sha256-armv4-linux.linux.arm.S} (99%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{sha256-armv8.ios.aarch64.S => sha256-armv8-ios.ios.aarch64.S} (99%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{sha256-armv8.linux.aarch64.S => sha256-armv8-linux.linux.aarch64.S} (99%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{sha256-x86_64.linux.x86_64.S => sha256-x86_64-linux.linux.x86_64.S} (99%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{sha256-x86_64.mac.x86_64.S => sha256-x86_64-mac.mac.x86_64.S} (99%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{sha512-586.linux.x86.S => sha512-586-linux.linux.x86.S} (99%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{sha512-armv4.ios.arm.S => sha512-armv4-ios.ios.arm.S} (99%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{sha512-armv4.linux.arm.S => sha512-armv4-linux.linux.arm.S} (99%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{sha512-armv8.ios.aarch64.S => sha512-armv8-ios.ios.aarch64.S} (99%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{sha512-armv8.linux.aarch64.S => sha512-armv8-linux.linux.aarch64.S} (99%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{sha512-x86_64.linux.x86_64.S => sha512-x86_64-linux.linux.x86_64.S} (99%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{sha512-x86_64.mac.x86_64.S => sha512-x86_64-mac.mac.x86_64.S} (99%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{vpaes-armv7.ios.arm.S => vpaes-armv7-ios.ios.arm.S} (99%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{vpaes-armv7.linux.arm.S => vpaes-armv7-linux.linux.arm.S} (99%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{vpaes-armv8.ios.aarch64.S => vpaes-armv8-ios.ios.aarch64.S} (99%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{vpaes-armv8.linux.aarch64.S => vpaes-armv8-linux.linux.aarch64.S} (99%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{vpaes-x86.linux.x86.S => vpaes-x86-linux.linux.x86.S} (97%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{vpaes-x86_64.linux.x86_64.S => vpaes-x86_64-linux.linux.x86_64.S} (98%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{vpaes-x86_64.mac.x86_64.S => vpaes-x86_64-mac.mac.x86_64.S} (98%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{x86-mont.linux.x86.S => x86-mont-linux.linux.x86.S} (95%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{x86_64-mont.linux.x86_64.S => x86_64-mont-linux.linux.x86_64.S} (99%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{x86_64-mont.mac.x86_64.S => x86_64-mont-mac.mac.x86_64.S} (99%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{x86_64-mont5.linux.x86_64.S => x86_64-mont5-linux.linux.x86_64.S} (99%) rename Sources/CNIOBoringSSL/crypto/fipsmodule/{x86_64-mont5.mac.x86_64.S => x86_64-mont5-mac.mac.x86_64.S} (99%) create mode 100644 Sources/CNIOBoringSSL/crypto/kyber/internal.h create mode 100644 Sources/CNIOBoringSSL/crypto/kyber/keccak.c create mode 100644 Sources/CNIOBoringSSL/crypto/kyber/kyber.c rename Sources/CNIOBoringSSL/crypto/{asn1/a_print.c => rsa_extra/internal.h} (84%) create mode 100644 Sources/CNIOBoringSSL/crypto/rsa_extra/rsa_crypt.c create mode 100644 Sources/CNIOBoringSSL/crypto/x509/policy.c delete mode 100644 Sources/CNIOBoringSSL/crypto/x509v3/pcy_cache.c delete mode 100644 Sources/CNIOBoringSSL/crypto/x509v3/pcy_data.c delete mode 100644 Sources/CNIOBoringSSL/crypto/x509v3/pcy_map.c delete mode 100644 Sources/CNIOBoringSSL/crypto/x509v3/pcy_node.c delete mode 100644 Sources/CNIOBoringSSL/crypto/x509v3/pcy_tree.c delete mode 100644 Sources/CNIOBoringSSL/crypto/x509v3/v3_pci.c delete mode 100644 Sources/CNIOBoringSSL/crypto/x509v3/v3_pcia.c create mode 100644 Sources/CNIOBoringSSL/include/CNIOBoringSSL_kyber.h create mode 100644 Sources/CNIOBoringSSL/include/CNIOBoringSSL_time.h create mode 100644 scripts/patch-3-more-inttypes.patch diff --git a/Package.swift b/Package.swift index fe72932d..05fd2492 100644 --- a/Package.swift +++ b/Package.swift @@ -26,7 +26,7 @@ import class Foundation.ProcessInfo // Sources/CNIOBoringSSL directory. The source repository is at // https://boringssl.googlesource.com/boringssl. // -// BoringSSL Commit: b819f7e9392d25db6705a6bd3c92be3bb91775e2 +// BoringSSL Commit: abfd5ebc87ddca0fab9fca067c9d7edbc355eae8 /// This function generates the dependencies we want to express. /// diff --git a/Package@swift-5.5.swift b/Package@swift-5.5.swift index 686b08d2..61791f0c 100644 --- a/Package@swift-5.5.swift +++ b/Package@swift-5.5.swift @@ -26,7 +26,7 @@ import class Foundation.ProcessInfo // Sources/CNIOBoringSSL directory. The source repository is at // https://boringssl.googlesource.com/boringssl. // -// BoringSSL Commit: b819f7e9392d25db6705a6bd3c92be3bb91775e2 +// BoringSSL Commit: abfd5ebc87ddca0fab9fca067c9d7edbc355eae8 /// This function generates the dependencies we want to express. /// diff --git a/Sources/CNIOBoringSSL/crypto/asn1/a_bitstr.c b/Sources/CNIOBoringSSL/crypto/asn1/a_bitstr.c index a36d4739..bc375d5b 100644 --- a/Sources/CNIOBoringSSL/crypto/asn1/a_bitstr.c +++ b/Sources/CNIOBoringSSL/crypto/asn1/a_bitstr.c @@ -66,7 +66,8 @@ #include "internal.h" -int ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, const unsigned char *d, int len) { +int ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, const unsigned char *d, + ossl_ssize_t len) { return ASN1_STRING_set(x, d, len); } @@ -115,6 +116,10 @@ int i2c_ASN1_BIT_STRING(const ASN1_BIT_STRING *a, unsigned char **pp) { uint8_t bits; int len = asn1_bit_string_length(a, &bits); + if (len > INT_MAX - 1) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_OVERFLOW); + return 0; + } int ret = 1 + len; if (pp == NULL) { return ret; @@ -179,7 +184,6 @@ ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, if (len > 0) { s = OPENSSL_memdup(p, len); if (s == NULL) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); goto err; } p += len; @@ -231,7 +235,6 @@ int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value) { c = (unsigned char *)OPENSSL_realloc(a->data, w + 1); } if (c == NULL) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); return 0; } if (w + 1 - a->length > 0) { diff --git a/Sources/CNIOBoringSSL/crypto/asn1/a_bool.c b/Sources/CNIOBoringSSL/crypto/asn1/a_bool.c index d1ba88bf..fb89c031 100644 --- a/Sources/CNIOBoringSSL/crypto/asn1/a_bool.c +++ b/Sources/CNIOBoringSSL/crypto/asn1/a_bool.c @@ -56,65 +56,40 @@ #include +#include #include -#include -int i2d_ASN1_BOOLEAN(ASN1_BOOLEAN a, unsigned char **pp) { - int r; - unsigned char *p, *allocated = NULL; +#include "../bytestring/internal.h" - r = ASN1_object_size(0, 1, V_ASN1_BOOLEAN); - if (pp == NULL) { - return r; - } - - if (*pp == NULL) { - if ((p = allocated = OPENSSL_malloc(r)) == NULL) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); - return -1; - } - } else { - p = *pp; - } - - ASN1_put_object(&p, 0, 1, V_ASN1_BOOLEAN, V_ASN1_UNIVERSAL); - *p = a ? 0xff : 0x00; - - // If a new buffer was allocated, just return it back. - // If not, return the incremented buffer pointer. - *pp = allocated != NULL ? allocated : p + 1; - return r; -} -ASN1_BOOLEAN d2i_ASN1_BOOLEAN(ASN1_BOOLEAN *a, const unsigned char **pp, - long length) { - const unsigned char *p = *pp; - long len; - int inf, tag, xclass; - inf = ASN1_get_object(&p, &len, &tag, &xclass, length); - if (inf & 0x80) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_OBJECT_HEADER); +int i2d_ASN1_BOOLEAN(ASN1_BOOLEAN a, unsigned char **outp) { + CBB cbb; + if (!CBB_init(&cbb, 3) || // + !CBB_add_asn1_bool(&cbb, a != ASN1_BOOLEAN_FALSE)) { + CBB_cleanup(&cbb); return -1; } + return CBB_finish_i2d(&cbb, outp); +} - if (inf & V_ASN1_CONSTRUCTED) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_TYPE_NOT_PRIMITIVE); - return -1; +ASN1_BOOLEAN d2i_ASN1_BOOLEAN(ASN1_BOOLEAN *out, const unsigned char **inp, + long len) { + if (len < 0) { + return ASN1_BOOLEAN_NONE; } - if (tag != V_ASN1_BOOLEAN || xclass != V_ASN1_UNIVERSAL) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_EXPECTING_A_BOOLEAN); - return -1; + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + int val; + if (!CBS_get_asn1_bool(&cbs, &val)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return ASN1_BOOLEAN_NONE; } - if (len != 1) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_BOOLEAN_IS_WRONG_LENGTH); - return -1; - } - ASN1_BOOLEAN ret = (ASN1_BOOLEAN) * (p++); - if (a != NULL) { - (*a) = ret; + ASN1_BOOLEAN ret = val ? ASN1_BOOLEAN_TRUE : ASN1_BOOLEAN_FALSE; + if (out != NULL) { + *out = ret; } - *pp = p; + *inp = CBS_data(&cbs); return ret; } diff --git a/Sources/CNIOBoringSSL/crypto/asn1/a_dup.c b/Sources/CNIOBoringSSL/crypto/asn1/a_dup.c index 8fd39d7e..3a1df92e 100644 --- a/Sources/CNIOBoringSSL/crypto/asn1/a_dup.c +++ b/Sources/CNIOBoringSSL/crypto/asn1/a_dup.c @@ -75,7 +75,6 @@ void *ASN1_item_dup(const ASN1_ITEM *it, void *x) { i = ASN1_item_i2d(x, &b, it); if (b == NULL) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); return NULL; } p = b; diff --git a/Sources/CNIOBoringSSL/crypto/asn1/a_gentm.c b/Sources/CNIOBoringSSL/crypto/asn1/a_gentm.c index c209995a..b290e695 100644 --- a/Sources/CNIOBoringSSL/crypto/asn1/a_gentm.c +++ b/Sources/CNIOBoringSSL/crypto/asn1/a_gentm.c @@ -58,6 +58,7 @@ #include #include #include +#include #include #include @@ -81,34 +82,32 @@ int ASN1_GENERALIZEDTIME_check(const ASN1_GENERALIZEDTIME *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 { + size_t len = strlen(str); + CBS cbs; + CBS_init(&cbs, (const uint8_t *)str, len); + if (!CBS_parse_generalized_time(&cbs, /*out_tm=*/NULL, + /*allow_timezone_offset=*/0)) { return 0; } + if (s != NULL) { + if (!ASN1_STRING_set(s, str, len)) { + return 0; + } + s->type = V_ASN1_GENERALIZEDTIME; + } + return 1; } ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s, - time_t t) { - return ASN1_GENERALIZEDTIME_adj(s, t, 0, 0); + int64_t posix_time) { + return ASN1_GENERALIZEDTIME_adj(s, posix_time, 0, 0); } ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s, - time_t t, int offset_day, + int64_t posix_time, int offset_day, long offset_sec) { struct tm data; - if (!OPENSSL_gmtime(&t, &data)) { + if (!OPENSSL_posix_to_tm(posix_time, &data)) { return NULL; } diff --git a/Sources/CNIOBoringSSL/crypto/asn1/a_i2d_fp.c b/Sources/CNIOBoringSSL/crypto/asn1/a_i2d_fp.c index c0557e99..53340995 100644 --- a/Sources/CNIOBoringSSL/crypto/asn1/a_i2d_fp.c +++ b/Sources/CNIOBoringSSL/crypto/asn1/a_i2d_fp.c @@ -76,7 +76,6 @@ int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x) { unsigned char *b = NULL; int n = ASN1_item_i2d(x, &b, it); if (b == NULL) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); return 0; } diff --git a/Sources/CNIOBoringSSL/crypto/asn1/a_int.c b/Sources/CNIOBoringSSL/crypto/asn1/a_int.c index fe67b409..f599e8e3 100644 --- a/Sources/CNIOBoringSSL/crypto/asn1/a_int.c +++ b/Sources/CNIOBoringSSL/crypto/asn1/a_int.c @@ -122,14 +122,17 @@ int i2c_ASN1_INTEGER(const ASN1_INTEGER *in, unsigned char **outp) { // |ASN1_INTEGER|s should be represented minimally, but it is possible to // construct invalid ones. Skip leading zeros so this does not produce an // invalid encoding or break invariants. - int start = 0; - while (start < in->length && in->data[start] == 0) { - start++; + CBS cbs; + CBS_init(&cbs, in->data, in->length); + while (CBS_len(&cbs) > 0 && CBS_data(&cbs)[0] == 0) { + CBS_skip(&cbs, 1); } int is_negative = (in->type & V_ASN1_NEG) != 0; - int pad; - if (start >= in->length) { + size_t pad; + CBS copy = cbs; + uint8_t msb; + if (!CBS_get_u8(©, &msb)) { // Zero is represented as a single byte. is_negative = 0; pad = 1; @@ -138,20 +141,19 @@ int i2c_ASN1_INTEGER(const ASN1_INTEGER *in, unsigned char **outp) { // through 0x00...01 and need an extra byte to be negative. // 0x01...00 through 0x80...00 have a two's complement of 0xfe...ff // through 0x80...00 and can be negated as-is. - pad = in->data[start] > 0x80 || - (in->data[start] == 0x80 && - !is_all_zeros(in->data + start + 1, in->length - start - 1)); + pad = msb > 0x80 || + (msb == 0x80 && !is_all_zeros(CBS_data(©), CBS_len(©))); } else { // If the high bit is set, the signed representation needs an extra // byte to be positive. - pad = (in->data[start] & 0x80) != 0; + pad = (msb & 0x80) != 0; } - if (in->length - start > INT_MAX - pad) { + if (CBS_len(&cbs) > INT_MAX - pad) { OPENSSL_PUT_ERROR(ASN1, ERR_R_OVERFLOW); return 0; } - int len = pad + in->length - start; + int len = (int)(pad + CBS_len(&cbs)); assert(len > 0); if (outp == NULL) { return len; @@ -160,7 +162,7 @@ int i2c_ASN1_INTEGER(const ASN1_INTEGER *in, unsigned char **outp) { if (pad) { (*outp)[0] = 0; } - OPENSSL_memcpy(*outp + pad, in->data + start, in->length - start); + OPENSSL_memcpy(*outp + pad, CBS_data(&cbs), CBS_len(&cbs)); if (is_negative) { negate_twos_complement(*outp, len); assert((*outp)[0] >= 0x80); diff --git a/Sources/CNIOBoringSSL/crypto/asn1/a_mbstr.c b/Sources/CNIOBoringSSL/crypto/asn1/a_mbstr.c index 5ffc21f1..3f497c50 100644 --- a/Sources/CNIOBoringSSL/crypto/asn1/a_mbstr.c +++ b/Sources/CNIOBoringSSL/crypto/asn1/a_mbstr.c @@ -85,11 +85,6 @@ OPENSSL_DECLARE_ERROR_REASON(ASN1, INVALID_UTF8STRING) int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, int inform, unsigned long mask, long minsize, long maxsize) { - int str_type; - char free_out; - ASN1_STRING *dest; - size_t nchar = 0; - char strbuf[32]; if (len == -1) { len = strlen((const char *)in); } @@ -128,7 +123,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, // Check |minsize| and |maxsize| and work out the minimal type, if any. CBS cbs; CBS_init(&cbs, in, len); - size_t utf8_len = 0; + size_t utf8_len = 0, nchar = 0; while (CBS_len(&cbs) != 0) { uint32_t c; if (!decode_func(&cbs, &c)) { @@ -167,23 +162,21 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, nchar++; utf8_len += cbb_get_utf8_len(c); + if (maxsize > 0 && nchar > (size_t)maxsize) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_LONG); + ERR_add_error_dataf("maxsize=%ld", maxsize); + return -1; + } } if (minsize > 0 && nchar < (size_t)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 > (size_t)maxsize) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_LONG); - BIO_snprintf(strbuf, sizeof strbuf, "%ld", maxsize); - ERR_add_error_data(2, "maxsize=", strbuf); + ERR_add_error_dataf("minsize=%ld", minsize); return -1; } // Now work out output format and string type + int str_type; int (*encode_func)(CBB *, uint32_t) = cbb_add_latin1; size_t size_estimate = nchar; int outform = MBSTRING_ASC; @@ -216,37 +209,31 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, if (!out) { return str_type; } + + int free_dest = 0; + ASN1_STRING *dest; 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; + free_dest = 1; dest = ASN1_STRING_type_new(str_type); if (!dest) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); return -1; } - *out = dest; } + CBB cbb; + CBB_zero(&cbb); // 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; + goto err; } + dest->type = str_type; + *out = dest; return str_type; } - - CBB cbb; if (!CBB_init(&cbb, size_estimate + 1)) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); goto err; } CBS_init(&cbs, in, len); @@ -267,12 +254,13 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, OPENSSL_free(data); goto err; } - dest->length = (int)(data_len - 1); - dest->data = data; + dest->type = str_type; + ASN1_STRING_set0(dest, data, (int)data_len - 1); + *out = dest; return str_type; err: - if (free_out) { + if (free_dest) { ASN1_STRING_free(dest); } CBB_cleanup(&cbb); @@ -283,10 +271,7 @@ int asn1_is_printable(uint32_t value) { if (value > 0x7f) { return 0; } - // Note we cannot use |isalnum| because it is locale-dependent. - return ('a' <= value && value <= 'z') || // - ('A' <= value && value <= 'Z') || // - ('0' <= value && value <= '9') || // + return OPENSSL_isalnum(value) || // value == ' ' || value == '\'' || value == '(' || value == ')' || value == '+' || value == ',' || value == '-' || value == '.' || value == '/' || value == ':' || value == '=' || value == '?'; diff --git a/Sources/CNIOBoringSSL/crypto/asn1/a_object.c b/Sources/CNIOBoringSSL/crypto/asn1/a_object.c index 37e54fab..b3811bff 100644 --- a/Sources/CNIOBoringSSL/crypto/asn1/a_object.c +++ b/Sources/CNIOBoringSSL/crypto/asn1/a_object.c @@ -59,47 +59,36 @@ #include #include +#include #include #include #include +#include "../bytestring/internal.h" #include "../internal.h" #include "internal.h" -int i2d_ASN1_OBJECT(const ASN1_OBJECT *a, unsigned char **pp) { - if (a == NULL) { +int i2d_ASN1_OBJECT(const ASN1_OBJECT *in, unsigned char **outp) { + if (in == NULL) { OPENSSL_PUT_ERROR(ASN1, ERR_R_PASSED_NULL_PARAMETER); return -1; } - if (a->length == 0) { + if (in->length <= 0) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OBJECT); return -1; } - int objsize = ASN1_object_size(0, a->length, V_ASN1_OBJECT); - if (pp == NULL || objsize == -1) { - return objsize; - } - - unsigned char *p, *allocated = NULL; - if (*pp == NULL) { - if ((p = allocated = OPENSSL_malloc(objsize)) == NULL) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); - return -1; - } - } else { - p = *pp; + CBB cbb, child; + if (!CBB_init(&cbb, (size_t)in->length + 2) || + !CBB_add_asn1(&cbb, &child, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&child, in->data, in->length)) { + CBB_cleanup(&cbb); + return -1; } - ASN1_put_object(&p, 0, a->length, V_ASN1_OBJECT, V_ASN1_UNIVERSAL); - OPENSSL_memcpy(p, a->data, a->length); - - // If a new buffer was allocated, just return it back. - // If not, return the incremented buffer pointer. - *pp = allocated != NULL ? allocated : p + a->length; - return objsize; + return CBB_finish_i2d(&cbb, outp); } int i2t_ASN1_OBJECT(char *buf, int buf_len, const ASN1_OBJECT *a) { @@ -107,8 +96,12 @@ int i2t_ASN1_OBJECT(char *buf, int buf_len, const ASN1_OBJECT *a) { } static int write_str(BIO *bp, const char *str) { - int len = strlen(str); - return BIO_write(bp, str, len) == len ? len : -1; + size_t len = strlen(str); + if (len > INT_MAX) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_OVERFLOW); + return -1; + } + return BIO_write(bp, str, (int)len) == (int)len ? (int)len : -1; } int i2a_ASN1_OBJECT(BIO *bp, const ASN1_OBJECT *a) { @@ -137,106 +130,55 @@ int i2a_ASN1_OBJECT(BIO *bp, const ASN1_OBJECT *a) { return ret; } -ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, - long length) { - long len; - int tag, xclass; - const unsigned char *p = *pp; - int inf = ASN1_get_object(&p, &len, &tag, &xclass, length); - if (inf & 0x80) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_OBJECT_HEADER); +ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **out, const unsigned char **inp, + long len) { + if (len < 0) { return NULL; } - if (inf & V_ASN1_CONSTRUCTED) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_TYPE_NOT_PRIMITIVE); + CBS cbs, child; + CBS_init(&cbs, *inp, (size_t)len); + if (!CBS_get_asn1(&cbs, &child, CBS_ASN1_OBJECT)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); return NULL; } - if (tag != V_ASN1_OBJECT || xclass != V_ASN1_UNIVERSAL) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_EXPECTING_AN_OBJECT); - return NULL; - } - ASN1_OBJECT *ret = c2i_ASN1_OBJECT(a, &p, len); - if (ret) { - *pp = p; + const uint8_t *contents = CBS_data(&child); + ASN1_OBJECT *ret = c2i_ASN1_OBJECT(out, &contents, CBS_len(&child)); + if (ret != NULL) { + // |c2i_ASN1_OBJECT| should have consumed the entire input. + assert(CBS_data(&cbs) == contents); + *inp = CBS_data(&cbs); } return ret; } -ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, +ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **out, const unsigned char **inp, 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) { + if (len < 0) { 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; - } - } - if ((a == NULL) || ((*a) == NULL) || - !((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC)) { - if ((ret = ASN1_OBJECT_new()) == NULL) { - return NULL; - } - } else { - ret = (*a); + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + if (!CBS_is_valid_asn1_oid(&cbs)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING); + return NULL; } - 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; - 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; - } - OPENSSL_memcpy(data, p, length); - // If there are dynamic strings, free them here, and clear the flag - if ((ret->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS) != 0) { - OPENSSL_free((char *)ret->sn); - OPENSSL_free((char *)ret->ln); - ret->flags &= ~ASN1_OBJECT_FLAG_DYNAMIC_STRINGS; + ASN1_OBJECT *ret = ASN1_OBJECT_create(NID_undef, *inp, (size_t)len, + /*sn=*/NULL, /*ln=*/NULL); + if (ret == NULL) { + return NULL; } - // reattach data to object, after which it remains const - ret->data = data; - ret->length = length; - ret->sn = NULL; - ret->ln = NULL; - p += length; - if (a != NULL) { - (*a) = ret; + if (out != NULL) { + ASN1_OBJECT_free(*out); + *out = ret; } - *pp = p; + *inp += len; // All bytes were consumed. 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) { @@ -244,7 +186,6 @@ ASN1_OBJECT *ASN1_OBJECT_new(void) { ret = (ASN1_OBJECT *)OPENSSL_malloc(sizeof(ASN1_OBJECT)); if (ret == NULL) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); return NULL; } ret->length = 0; @@ -275,16 +216,20 @@ void ASN1_OBJECT_free(ASN1_OBJECT *a) { } } -ASN1_OBJECT *ASN1_OBJECT_create(int nid, const unsigned char *data, int len, +ASN1_OBJECT *ASN1_OBJECT_create(int nid, const unsigned char *data, size_t len, const char *sn, const char *ln) { - ASN1_OBJECT o; + if (len > INT_MAX) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_LONG); + return NULL; + } + ASN1_OBJECT o; o.sn = sn; o.ln = ln; o.data = data; o.nid = nid; - o.length = len; + o.length = (int)len; o.flags = ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | ASN1_OBJECT_FLAG_DYNAMIC_DATA; - return (OBJ_dup(&o)); + return OBJ_dup(&o); } diff --git a/Sources/CNIOBoringSSL/crypto/asn1/a_strex.c b/Sources/CNIOBoringSSL/crypto/asn1/a_strex.c index c726b564..f862f0ba 100644 --- a/Sources/CNIOBoringSSL/crypto/asn1/a_strex.c +++ b/Sources/CNIOBoringSSL/crypto/asn1/a_strex.c @@ -59,6 +59,7 @@ #include #include #include +#include #include #include @@ -121,7 +122,8 @@ static int do_esc_char(uint32_t c, unsigned long flags, char *do_quotes, return maybe_write(out, &u8, 1) ? 1 : -1; } - int len = strlen(buf); + static_assert(sizeof(buf) < INT_MAX, "len may not fit in int"); + int len = (int)strlen(buf); return maybe_write(out, buf, len) ? len : -1; } diff --git a/Sources/CNIOBoringSSL/crypto/asn1/a_time.c b/Sources/CNIOBoringSSL/crypto/asn1/a_time.c index ed645acd..2aac8f2f 100644 --- a/Sources/CNIOBoringSSL/crypto/asn1/a_time.c +++ b/Sources/CNIOBoringSSL/crypto/asn1/a_time.c @@ -55,6 +55,7 @@ * [including the GNU Public Licence.] */ #include +#include #include #include @@ -73,29 +74,31 @@ IMPLEMENT_ASN1_MSTRING(ASN1_TIME, B_ASN1_TIME) IMPLEMENT_ASN1_FUNCTIONS_const(ASN1_TIME) -ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t) { - return ASN1_TIME_adj(s, t, 0, 0); +ASN1_TIME *ASN1_TIME_set_posix(ASN1_TIME *s, int64_t posix_time) { + return ASN1_TIME_adj(s, posix_time, 0, 0); } -ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t, int offset_day, +ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t time) { + return ASN1_TIME_adj(s, time, 0, 0); +} + +ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, int64_t posix_time, int offset_day, long offset_sec) { - struct tm *ts; - struct tm data; + struct tm tm; - ts = OPENSSL_gmtime(&t, &data); - if (ts == NULL) { + if (!OPENSSL_posix_to_tm(posix_time, &tm)) { 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)) { + if (!OPENSSL_gmtime_adj(&tm, 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); + if ((tm.tm_year >= 50) && (tm.tm_year < 150)) { + return ASN1_UTCTIME_adj(s, posix_time, offset_day, offset_sec); } - return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec); + return ASN1_GENERALIZEDTIME_adj(s, posix_time, offset_day, offset_sec); } int ASN1_TIME_check(const ASN1_TIME *t) { @@ -163,36 +166,15 @@ ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(const ASN1_TIME *t, return NULL; } - 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; + return ASN1_UTCTIME_set_string(s, str) || + ASN1_GENERALIZEDTIME_set_string(s, str); } static int asn1_time_to_tm(struct tm *tm, const ASN1_TIME *t, int allow_timezone_offset) { if (t == NULL) { - time_t now_t; - time(&now_t); - if (OPENSSL_gmtime(&now_t, tm)) { + if (OPENSSL_posix_to_tm(time(NULL), tm)) { return 1; } return 0; diff --git a/Sources/CNIOBoringSSL/crypto/asn1/a_type.c b/Sources/CNIOBoringSSL/crypto/asn1/a_type.c index d31e9c84..0fdc2a92 100644 --- a/Sources/CNIOBoringSSL/crypto/asn1/a_type.c +++ b/Sources/CNIOBoringSSL/crypto/asn1/a_type.c @@ -65,31 +65,65 @@ int ASN1_TYPE_get(const ASN1_TYPE *a) { - if (a->type == V_ASN1_BOOLEAN || a->type == V_ASN1_NULL || - a->value.ptr != NULL) { - return a->type; + switch (a->type) { + case V_ASN1_NULL: + case V_ASN1_BOOLEAN: + return a->type; + case V_ASN1_OBJECT: + return a->value.object != NULL ? a->type : 0; + default: + return a->value.asn1_string != NULL ? a->type : 0; } - return 0; } const void *asn1_type_value_as_pointer(const ASN1_TYPE *a) { - if (a->type == V_ASN1_BOOLEAN) { - return a->value.boolean ? (void *)0xff : NULL; + switch (a->type) { + case V_ASN1_NULL: + return NULL; + case V_ASN1_BOOLEAN: + return a->value.boolean ? (void *)0xff : NULL; + case V_ASN1_OBJECT: + return a->value.object; + default: + return a->value.asn1_string; } - if (a->type == V_ASN1_NULL) { - return NULL; +} + +void asn1_type_cleanup(ASN1_TYPE *a) { + switch (a->type) { + case V_ASN1_NULL: + a->value.ptr = NULL; + break; + case V_ASN1_BOOLEAN: + a->value.boolean = ASN1_BOOLEAN_NONE; + break; + case V_ASN1_OBJECT: + ASN1_OBJECT_free(a->value.object); + a->value.object = NULL; + break; + default: + ASN1_STRING_free(a->value.asn1_string); + a->value.asn1_string = NULL; + break; } - return a->value.ptr; } void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value) { - ASN1_TYPE **tmp_a = &a; - ASN1_primitive_free((ASN1_VALUE **)tmp_a, NULL); + asn1_type_cleanup(a); a->type = type; - if (type == V_ASN1_BOOLEAN) { - a->value.boolean = value ? 0xff : 0; - } else { - a->value.ptr = value; + switch (type) { + case V_ASN1_NULL: + a->value.ptr = NULL; + break; + case V_ASN1_BOOLEAN: + a->value.boolean = value ? ASN1_BOOLEAN_TRUE : ASN1_BOOLEAN_FALSE; + break; + case V_ASN1_OBJECT: + a->value.object = value; + break; + default: + a->value.asn1_string = value; + break; } } diff --git a/Sources/CNIOBoringSSL/crypto/asn1/a_utctm.c b/Sources/CNIOBoringSSL/crypto/asn1/a_utctm.c index 784657f8..c0c30817 100644 --- a/Sources/CNIOBoringSSL/crypto/asn1/a_utctm.c +++ b/Sources/CNIOBoringSSL/crypto/asn1/a_utctm.c @@ -58,6 +58,7 @@ #include #include #include +#include #include #include @@ -82,32 +83,30 @@ int ASN1_UTCTIME_check(const ASN1_UTCTIME *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 { + size_t len = strlen(str); + CBS cbs; + CBS_init(&cbs, (const uint8_t *)str, len); + if (!CBS_parse_utc_time(&cbs, /*out_tm=*/NULL, + /*allow_timezone_offset=*/1)) { return 0; } + if (s != NULL) { + if (!ASN1_STRING_set(s, str, len)) { + return 0; + } + s->type = V_ASN1_UTCTIME; + } + return 1; } -ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t) { - return ASN1_UTCTIME_adj(s, t, 0, 0); +ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, int64_t posix_time) { + return ASN1_UTCTIME_adj(s, posix_time, 0, 0); } -ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t, int offset_day, +ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, int64_t posix_time, int offset_day, long offset_sec) { struct tm data; - if (!OPENSSL_gmtime(&t, &data)) { + if (!OPENSSL_posix_to_tm(posix_time, &data)) { return NULL; } @@ -153,7 +152,7 @@ int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t) { return -2; } - if (!OPENSSL_gmtime(&t, &ttm)) { + if (!OPENSSL_posix_to_tm(t, &ttm)) { return -2; } diff --git a/Sources/CNIOBoringSSL/crypto/asn1/asn1_lib.c b/Sources/CNIOBoringSSL/crypto/asn1/asn1_lib.c index e062d34d..a92ac431 100644 --- a/Sources/CNIOBoringSSL/crypto/asn1/asn1_lib.c +++ b/Sources/CNIOBoringSSL/crypto/asn1/asn1_lib.c @@ -111,20 +111,10 @@ int ASN1_get_object(const unsigned char **inp, long *out_len, int *out_tag, return 0x80; } - // TODO(https://crbug.com/boringssl/354): This should use |CBS_get_asn1| to - // reject non-minimal lengths, which are only allowed in BER. However, - // Android sometimes needs allow a non-minimal length in certificate - // signature fields (see b/18228011). Make this only apply to that field, - // while requiring DER elsewhere. Better yet, it should be limited to an - // preprocessing step in that part of Android. - unsigned tag; - size_t header_len; - int indefinite; + CBS_ASN1_TAG tag; CBS cbs, body; CBS_init(&cbs, *inp, (size_t)in_len); - if (!CBS_get_any_ber_asn1_element(&cbs, &body, &tag, &header_len, - /*out_ber_found=*/NULL, &indefinite) || - indefinite || !CBS_skip(&body, header_len) || + if (!CBS_get_any_asn1(&cbs, &body, &tag) || // Bound the length to comfortably fit in an int. Lengths in this // module often switch between int and long without overflow checks. CBS_len(&body) > INT_MAX / 2) { @@ -271,19 +261,27 @@ ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *str) { return ret; } -int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len) { - unsigned char *c; +int ASN1_STRING_set(ASN1_STRING *str, const void *_data, ossl_ssize_t len_s) { const char *data = _data; - - if (len < 0) { + size_t len; + if (len_s < 0) { if (data == NULL) { return 0; - } else { - len = strlen(data); } + len = strlen(data); + } else { + len = (size_t)len_s; + } + + // |ASN1_STRING| cannot represent strings that exceed |int|, and we must + // reserve space for a trailing NUL below. + if (len > INT_MAX || len + 1 < len) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_OVERFLOW); + return 0; } - if ((str->length <= len) || (str->data == NULL)) { - c = str->data; + + if (str->length <= (int)len || str->data == NULL) { + unsigned char *c = str->data; if (c == NULL) { str->data = OPENSSL_malloc(len + 1); } else { @@ -291,15 +289,17 @@ int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len) { } if (str->data == NULL) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); str->data = c; return 0; } } - str->length = len; + str->length = (int)len; if (data != NULL) { OPENSSL_memcpy(str->data, data, len); - // an allowance for strings :-) + // Historically, OpenSSL would NUL-terminate most (but not all) + // |ASN1_STRING|s, in case anyone accidentally passed |str->data| into a + // function expecting a C string. We retain this behavior for compatibility, + // but code must not rely on this. See CVE-2021-3712. str->data[len] = '\0'; } return 1; @@ -320,7 +320,6 @@ ASN1_STRING *ASN1_STRING_type_new(int type) { ret = (ASN1_STRING *)OPENSSL_malloc(sizeof(ASN1_STRING)); if (ret == NULL) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); return NULL; } ret->length = 0; diff --git a/Sources/CNIOBoringSSL/crypto/asn1/asn_pack.c b/Sources/CNIOBoringSSL/crypto/asn1/asn_pack.c index b21b26c0..c6d21f95 100644 --- a/Sources/CNIOBoringSSL/crypto/asn1/asn_pack.c +++ b/Sources/CNIOBoringSSL/crypto/asn1/asn_pack.c @@ -72,7 +72,6 @@ ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_STRING **out) { if (out == NULL || *out == NULL) { ret = ASN1_STRING_new(); if (ret == NULL) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); OPENSSL_free(new_data); return NULL; } diff --git a/Sources/CNIOBoringSSL/crypto/asn1/internal.h b/Sources/CNIOBoringSSL/crypto/asn1/internal.h index 307340f3..5578aa31 100644 --- a/Sources/CNIOBoringSSL/crypto/asn1/internal.h +++ b/Sources/CNIOBoringSSL/crypto/asn1/internal.h @@ -56,8 +56,8 @@ * */ -#ifndef OPENSSL_HEADER_ASN1_ASN1_LOCL_H -#define OPENSSL_HEADER_ASN1_ASN1_LOCL_H +#ifndef OPENSSL_HEADER_ASN1_INTERNAL_H +#define OPENSSL_HEADER_ASN1_INTERNAL_H #include @@ -71,16 +71,6 @@ extern "C" { // Wrapper functions for time functions. -// OPENSSL_posix_to_tm converts a int64_t POSIX time value in |time| whuch must -// be in the range of year 0000 to 9999 to a broken out time value in |tm|. It -// returns one on success and zero on error. -OPENSSL_EXPORT int OPENSSL_posix_to_tm(int64_t time, struct tm *out_tm); - -// OPENSSL_tm_to_posix converts a time value between the years 0 and 9999 in -// |tm| to a POSIX time value in |out|. One is returned on success, zero is -// returned on failure. It is a failure if the tm contains out of range values. -OPENSSL_EXPORT int OPENSSL_tm_to_posix(const struct tm *tm, int64_t *out); - // OPENSSL_gmtime converts a time_t value in |time| which must be in the range // of year 0000 to 9999 to a broken out time value in |tm|. On success |tm| is // returned. On failure NULL is returned. @@ -96,7 +86,8 @@ OPENSSL_EXPORT int OPENSSL_timegm(const struct tm *tm, time_t *out); // |offset_day| days and |offset_sec| seconds. It returns zero on failure. |tm| // must be in the range of year 0000 to 9999 both before and after the update or // a failure will be returned. -int OPENSSL_gmtime_adj(struct tm *tm, int offset_day, long offset_sec); +OPENSSL_EXPORT int OPENSSL_gmtime_adj(struct tm *tm, int offset_day, + long offset_sec); // OPENSSL_gmtime_diff calculates the difference between |from| and |to|. It // returns one, and outputs the difference as a number of days and seconds in @@ -131,21 +122,16 @@ struct asn1_object_st { ASN1_OBJECT *ASN1_OBJECT_new(void); -// ASN1_ENCODING structure: this is used to save the received -// encoding of an ASN1 type. This is useful to get round -// problems with invalid encodings which can break signatures. +// ASN1_ENCODING is used to save the received encoding of an ASN.1 type. This +// avoids problems with invalid encodings that break signatures. typedef struct ASN1_ENCODING_st { - unsigned char *enc; // DER encoding - long len; // Length of encoding - int modified; // set to 1 if 'enc' is invalid - // alias_only is zero if |enc| owns the buffer that it points to - // (although |enc| may still be NULL). If one, |enc| points into a - // buffer that is owned elsewhere. - unsigned alias_only : 1; - // alias_only_on_next_parse is one iff the next parsing operation - // should avoid taking a copy of the input and rather set - // |alias_only|. - unsigned alias_only_on_next_parse : 1; + // enc is the saved DER encoding. Its ownership is determined by |buf|. + uint8_t *enc; + // len is the length of |enc|. If zero, there is no saved encoding. + size_t len; + // buf, if non-NULL, is the |CRYPTO_BUFFER| that |enc| points into. If NULL, + // |enc| must be released with |OPENSSL_free|. + CRYPTO_BUFFER *buf; } ASN1_ENCODING; OPENSSL_EXPORT int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d, @@ -153,16 +139,22 @@ OPENSSL_EXPORT int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d, OPENSSL_EXPORT int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d); -void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, - int combine); - int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it); void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it); void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); + +// ASN1_item_ex_d2i parses |len| bytes from |*in| as a structure of type |it| +// and writes the result to |*pval|. If |tag| is non-negative, |it| is +// implicitly tagged with the tag specified by |tag| and |aclass|. If |opt| is +// non-zero, the value is optional. If |buf| is non-NULL, |*in| must point into +// |buf|. +// +// This function returns one and advances |*in| if an object was successfully +// parsed, -1 if an optional value was successfully skipped, and zero on error. 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); + CRYPTO_BUFFER *buf); // ASN1_item_ex_i2d encodes |*pval| as a value of type |it| to |out| under the // i2d output convention. It returns a non-zero length on success and -1 on @@ -204,14 +196,24 @@ void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it); int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval, const ASN1_ITEM *it); -int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen, - const ASN1_ITEM *it); +// asn1_enc_save saves |inlen| bytes from |in| as |*pval|'s saved encoding. It +// returns one on success and zero on error. If |buf| is non-NULL, |in| must +// point into |buf|. +int asn1_enc_save(ASN1_VALUE **pval, const uint8_t *in, size_t inlen, + const ASN1_ITEM *it, CRYPTO_BUFFER *buf); + +// asn1_encoding_clear clears the cached encoding in |enc|. +void asn1_encoding_clear(ASN1_ENCODING *enc); // asn1_type_value_as_pointer returns |a|'s value in pointer form. This is // usually the value object but, for BOOLEAN values, is 0 or 0xff cast to // a pointer. const void *asn1_type_value_as_pointer(const ASN1_TYPE *a); +// asn1_type_cleanup releases memory associated with |a|'s value, without +// freeing |a| itself. +void asn1_type_cleanup(ASN1_TYPE *a); + // asn1_is_printable returns one if |value| is a valid Unicode codepoint for an // ASN.1 PrintableString, and zero otherwise. int asn1_is_printable(uint32_t value); @@ -237,9 +239,31 @@ typedef struct { OPENSSL_EXPORT void asn1_get_string_table_for_testing( const ASN1_STRING_TABLE **out_ptr, size_t *out_len); +typedef ASN1_VALUE *ASN1_new_func(void); +typedef void ASN1_free_func(ASN1_VALUE *a); +typedef ASN1_VALUE *ASN1_d2i_func(ASN1_VALUE **a, const unsigned char **in, + long length); +typedef int ASN1_i2d_func(ASN1_VALUE *a, unsigned char **in); + +typedef int ASN1_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, + const ASN1_ITEM *it, int opt, ASN1_TLC *ctx); + +typedef int ASN1_ex_i2d(ASN1_VALUE **pval, unsigned char **out, + const ASN1_ITEM *it); +typedef int ASN1_ex_new_func(ASN1_VALUE **pval, const ASN1_ITEM *it); +typedef void ASN1_ex_free_func(ASN1_VALUE **pval, const ASN1_ITEM *it); + +typedef struct ASN1_EXTERN_FUNCS_st { + ASN1_ex_new_func *asn1_ex_new; + ASN1_ex_free_func *asn1_ex_free; + ASN1_ex_free_func *asn1_ex_clear; + ASN1_ex_d2i *asn1_ex_d2i; + ASN1_ex_i2d *asn1_ex_i2d; +} ASN1_EXTERN_FUNCS; + #if defined(__cplusplus) } // extern C #endif -#endif // OPENSSL_HEADER_ASN1_ASN1_LOCL_H +#endif // OPENSSL_HEADER_ASN1_INTERNAL_H diff --git a/Sources/CNIOBoringSSL/crypto/asn1/posix_time.c b/Sources/CNIOBoringSSL/crypto/asn1/posix_time.c index 81fbe833..a553af0d 100644 --- a/Sources/CNIOBoringSSL/crypto/asn1/posix_time.c +++ b/Sources/CNIOBoringSSL/crypto/asn1/posix_time.c @@ -15,6 +15,8 @@ // Time conversion to/from POSIX time_t and struct tm, with no support // for time zones other than UTC +#include + #include #include #include @@ -191,9 +193,10 @@ int OPENSSL_gmtime_adj(struct tm *tm, int off_day, long offset_sec) { tm->tm_hour, tm->tm_min, tm->tm_sec, &posix_time)) { return 0; } - if (!utc_from_posix_time(posix_time + off_day * SECS_PER_DAY + offset_sec, - &tm->tm_year, &tm->tm_mon, &tm->tm_mday, - &tm->tm_hour, &tm->tm_min, &tm->tm_sec)) { + if (!utc_from_posix_time( + posix_time + (int64_t)off_day * SECS_PER_DAY + offset_sec, + &tm->tm_year, &tm->tm_mon, &tm->tm_mday, &tm->tm_hour, &tm->tm_min, + &tm->tm_sec)) { return 0; } tm->tm_year -= 1900; diff --git a/Sources/CNIOBoringSSL/crypto/asn1/tasn_dec.c b/Sources/CNIOBoringSSL/crypto/asn1/tasn_dec.c index f8a594c6..d1124a67 100644 --- a/Sources/CNIOBoringSSL/crypto/asn1/tasn_dec.c +++ b/Sources/CNIOBoringSSL/crypto/asn1/tasn_dec.c @@ -59,7 +59,9 @@ #include #include #include +#include +#include #include #include @@ -79,18 +81,18 @@ static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, static int asn1_template_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_TEMPLATE *tt, char opt, - int depth); + CRYPTO_BUFFER *buf, int depth); static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, long len, const ASN1_TEMPLATE *tt, char opt, - int depth); -static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, + CRYPTO_BUFFER *buf, int depth); +static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, long len, int utype, const ASN1_ITEM *it); 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); static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it, int tag, int aclass, - char opt, int depth); + char opt, CRYPTO_BUFFER *buf, int depth); // Table to convert tags to bit values, used for MSTRING type static const unsigned long tag2bit[31] = { @@ -134,6 +136,23 @@ unsigned long ASN1_tag2bit(int tag) { return tag2bit[tag]; } +static int is_supported_universal_type(int tag, int aclass) { + if (aclass != V_ASN1_UNIVERSAL) { + return 0; + } + return tag == V_ASN1_OBJECT || tag == V_ASN1_NULL || tag == V_ASN1_BOOLEAN || + tag == V_ASN1_BIT_STRING || tag == V_ASN1_INTEGER || + tag == V_ASN1_ENUMERATED || tag == V_ASN1_OCTET_STRING || + tag == V_ASN1_NUMERICSTRING || tag == V_ASN1_PRINTABLESTRING || + tag == V_ASN1_T61STRING || tag == V_ASN1_VIDEOTEXSTRING || + tag == V_ASN1_IA5STRING || tag == V_ASN1_UTCTIME || + tag == V_ASN1_GENERALIZEDTIME || tag == V_ASN1_GRAPHICSTRING || + tag == V_ASN1_VISIBLESTRING || tag == V_ASN1_GENERALSTRING || + tag == V_ASN1_UNIVERSALSTRING || tag == V_ASN1_BMPSTRING || + tag == V_ASN1_UTF8STRING || tag == V_ASN1_SET || + tag == V_ASN1_SEQUENCE; +} + // Macro to initialize and invalidate the cache // Decode an ASN1 item, this currently behaves just like a standard 'd2i' @@ -143,25 +162,40 @@ unsigned long ASN1_tag2bit(int tag) { ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it) { - ASN1_VALUE *ptmpval = NULL; - if (!pval) { - pval = &ptmpval; + ASN1_VALUE *ret = NULL; + if (asn1_item_ex_d2i(&ret, in, len, it, /*tag=*/-1, /*aclass=*/0, /*opt=*/0, + /*buf=*/NULL, /*depth=*/0) <= 0) { + // Clean up, in case the caller left a partial object. + // + // TODO(davidben): I don't think it can leave one, but the codepaths below + // are a bit inconsistent. Revisit this when rewriting this function. + ASN1_item_ex_free(&ret, it); } - if (asn1_item_ex_d2i(pval, in, len, it, -1, 0, 0, 0) > 0) { - return *pval; + // If the caller supplied an output pointer, free the old one and replace it + // with |ret|. This differs from OpenSSL slightly in that we don't support + // object reuse. We run this on both success and failure. On failure, even + // with object reuse, OpenSSL destroys the previous object. + if (pval != NULL) { + ASN1_item_ex_free(pval, it); + *pval = ret; } - return NULL; + return ret; } // Decode an item, taking care of IMPLICIT tagging, if any. If 'opt' set and // tag mismatch return -1 to handle OPTIONAL +// +// TODO(davidben): Historically, all functions in this file had to account for +// |*pval| containing an arbitrary existing value. This is no longer the case +// because |ASN1_item_d2i| now always starts from NULL. As part of rewriting +// this function, take the simplified assumptions into account. Though we must +// still account for the internal calls to |ASN1_item_ex_new|. static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it, int tag, int aclass, - char opt, int depth) { + char opt, CRYPTO_BUFFER *buf, int depth) { const ASN1_TEMPLATE *tt, *errtt = NULL; - const ASN1_EXTERN_FUNCS *ef; const unsigned char *p = NULL, *q; unsigned char oclass; char cst, isopt; @@ -169,12 +203,15 @@ static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, int otag; int ret = 0; ASN1_VALUE **pchptr; - int combine = aclass & ASN1_TFLG_COMBINE; - aclass &= ~ASN1_TFLG_COMBINE; if (!pval) { return 0; } + if (buf != NULL) { + assert(CRYPTO_BUFFER_data(buf) <= *in && + *in + len <= CRYPTO_BUFFER_data(buf) + CRYPTO_BUFFER_len(buf)); + } + // Bound |len| to comfortably fit in an int. Lengths in this module often // switch between int and long without overflow checks. if (len > INT_MAX / 2) { @@ -197,7 +234,8 @@ static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE); goto err; } - return asn1_template_ex_d2i(pval, in, len, it->templates, opt, depth); + return asn1_template_ex_d2i(pval, in, len, it->templates, opt, buf, + depth); } return asn1_d2i_ex_primitive(pval, in, len, it, tag, aclass, opt); break; @@ -238,10 +276,15 @@ static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, } return asn1_d2i_ex_primitive(pval, in, len, it, otag, 0, 0); - case ASN1_ITYPE_EXTERN: - // Use new style d2i - ef = it->funcs; - return ef->asn1_ex_d2i(pval, in, len, it, tag, aclass, opt, NULL); + case ASN1_ITYPE_EXTERN: { + // We don't support implicit tagging with external types. + if (tag != -1) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE); + goto err; + } + const ASN1_EXTERN_FUNCS *ef = it->funcs; + return ef->asn1_ex_d2i(pval, in, len, it, opt, NULL); + } case ASN1_ITYPE_CHOICE: { // It never makes sense for CHOICE types to have implicit tagging, so if @@ -275,7 +318,7 @@ static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **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, depth); + ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, buf, depth); // If field not present, try the next one if (ret == -1) { continue; @@ -377,11 +420,11 @@ static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, if (i == (it->tcount - 1)) { isopt = 0; } else { - isopt = (char)(seqtt->flags & ASN1_TFLG_OPTIONAL); + isopt = (seqtt->flags & ASN1_TFLG_OPTIONAL) != 0; } // attempt to read in field, allowing each to be OPTIONAL - ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, depth); + ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, buf, depth); if (!ret) { errtt = seqtt; goto err; @@ -420,7 +463,7 @@ static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, } } // Save encoding - if (!asn1_enc_save(pval, *in, p - *in, it)) { + if (!asn1_enc_save(pval, *in, p - *in, it, buf)) { goto auxerr; } if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL)) { @@ -436,9 +479,7 @@ static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, auxerr: OPENSSL_PUT_ERROR(ASN1, ASN1_R_AUX_ERROR); err: - if (combine == 0) { - ASN1_item_ex_free(pval, it); - } + ASN1_item_ex_free(pval, it); if (errtt) { ERR_add_error_data(4, "Field=", errtt->field_name, ", Type=", it->sname); } else { @@ -449,8 +490,9 @@ static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it, int tag, int aclass, char opt, - ASN1_TLC *ctx) { - return asn1_item_ex_d2i(pval, in, len, it, tag, aclass, opt, 0); + CRYPTO_BUFFER *buf) { + return asn1_item_ex_d2i(pval, in, len, it, tag, aclass, opt, buf, + /*depth=*/0); } // Templates are handled with two separate functions. One handles any @@ -458,15 +500,15 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, static int asn1_template_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long inlen, const ASN1_TEMPLATE *tt, char opt, - int depth) { - int flags, aclass; + CRYPTO_BUFFER *buf, int depth) { + int aclass; int ret; long len; const unsigned char *p, *q; if (!val) { return 0; } - flags = tt->flags; + uint32_t flags = tt->flags; aclass = flags & ASN1_TFLG_TAG_CLASS; p = *in; @@ -490,7 +532,7 @@ static int asn1_template_ex_d2i(ASN1_VALUE **val, const unsigned char **in, return 0; } // We've found the field so it can't be OPTIONAL now - ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, depth); + ret = asn1_template_noexp_d2i(val, &p, len, tt, /*opt=*/0, buf, depth); if (!ret) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); return 0; @@ -503,7 +545,7 @@ static int asn1_template_ex_d2i(ASN1_VALUE **val, const unsigned char **in, goto err; } } else { - return asn1_template_noexp_d2i(val, in, inlen, tt, opt, depth); + return asn1_template_noexp_d2i(val, in, inlen, tt, opt, buf, depth); } *in = p; @@ -516,14 +558,14 @@ static int asn1_template_ex_d2i(ASN1_VALUE **val, const unsigned char **in, static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, long len, const ASN1_TEMPLATE *tt, char opt, - int depth) { - int flags, aclass; + CRYPTO_BUFFER *buf, int depth) { + int aclass; int ret; const unsigned char *p; if (!val) { return 0; } - flags = tt->flags; + uint32_t flags = tt->flags; aclass = flags & ASN1_TFLG_TAG_CLASS; p = *in; @@ -565,7 +607,6 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, } if (!*val) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); goto err; } @@ -574,22 +615,21 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, ASN1_VALUE *skfield; const unsigned char *q = p; skfield = NULL; - if (!asn1_item_ex_d2i(&skfield, &p, len, ASN1_ITEM_ptr(tt->item), -1, 0, - 0, depth)) { + if (!asn1_item_ex_d2i(&skfield, &p, len, ASN1_ITEM_ptr(tt->item), + /*tag=*/-1, /*aclass=*/0, /*opt=*/0, buf, depth)) { 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)) { ASN1_item_ex_free(&skfield, ASN1_ITEM_ptr(tt->item)); - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); 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, depth); + aclass, opt, buf, depth); if (!ret) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); goto err; @@ -598,8 +638,8 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, } } else { // Nothing special - ret = asn1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), -1, - tt->flags & ASN1_TFLG_COMBINE, opt, depth); + ret = asn1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), /*tag=*/-1, + /*aclass=*/0, opt, buf, depth); if (!ret) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); goto err; @@ -654,7 +694,7 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in, OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); return 0; } - if (oclass != V_ASN1_UNIVERSAL) { + if (!is_supported_universal_type(utype, oclass)) { utype = V_ASN1_OTHER; } } @@ -709,7 +749,7 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in, // Translate ASN1 content octets into a structure -static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, +static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, long len, int utype, const ASN1_ITEM *it) { ASN1_VALUE **opval = NULL; ASN1_STRING *stmp; @@ -798,6 +838,12 @@ static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, case V_ASN1_OTHER: case V_ASN1_SET: case V_ASN1_SEQUENCE: + // TODO(crbug.com/boringssl/412): This default case should be removed, now + // that we've resolved https://crbug.com/boringssl/561. However, it is still + // needed to support some edge cases in |ASN1_PRINTABLE|. |ASN1_PRINTABLE| + // broadly doesn't tolerate unrecognized universal tags, but except for + // eight values that map to |B_ASN1_UNKNOWN| instead of zero. See the + // X509Test.NameAttributeValues test. default: { CBS cbs; CBS_init(&cbs, cont, (size_t)len); @@ -847,7 +893,6 @@ static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, if (!*pval) { stmp = ASN1_STRING_type_new(utype); if (!stmp) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); goto err; } *pval = (ASN1_VALUE *)stmp; @@ -856,7 +901,6 @@ static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, stmp->type = utype; } if (!ASN1_STRING_set(stmp, cont, len)) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); ASN1_STRING_free(stmp); *pval = NULL; goto err; diff --git a/Sources/CNIOBoringSSL/crypto/asn1/tasn_enc.c b/Sources/CNIOBoringSSL/crypto/asn1/tasn_enc.c index 942f1ec5..ec5a683d 100644 --- a/Sources/CNIOBoringSSL/crypto/asn1/tasn_enc.c +++ b/Sources/CNIOBoringSSL/crypto/asn1/tasn_enc.c @@ -78,7 +78,8 @@ static int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cont, int *out_omit, static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out, int skcontlen, const ASN1_ITEM *item, int do_sort); 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, + int optional); // Top level i2d equivalents @@ -91,12 +92,12 @@ int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it) { } buf = OPENSSL_malloc(len); if (!buf) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); return -1; } p = buf; int len2 = ASN1_item_ex_i2d(&val, &p, it, /*tag=*/-1, /*aclass=*/0); if (len2 <= 0) { + OPENSSL_free(buf); return len2; } assert(len == len2); @@ -144,11 +145,13 @@ int asn1_item_ex_i2d_opt(ASN1_VALUE **pval, unsigned char **out, switch (it->itype) { case ASN1_ITYPE_PRIMITIVE: if (it->templates) { + // This is an |ASN1_ITEM_TEMPLATE|. if (it->templates->flags & ASN1_TFLG_OPTIONAL) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE); return -1; } - return asn1_template_ex_i2d(pval, out, it->templates, tag, aclass); + return asn1_template_ex_i2d(pval, out, it->templates, tag, aclass, + optional); } return asn1_i2d_ex_primitive(pval, out, it, tag, aclass, optional); @@ -179,13 +182,17 @@ int asn1_item_ex_i2d_opt(ASN1_VALUE **pval, unsigned char **out, return -1; } ASN1_VALUE **pchval = asn1_get_field_ptr(pval, chtt); - return asn1_template_ex_i2d(pchval, out, chtt, -1, 0); + return asn1_template_ex_i2d(pchval, out, chtt, -1, 0, /*optional=*/0); } case ASN1_ITYPE_EXTERN: { - // If new style i2d it does all the work + // We don't support implicit tagging with external types. + if (tag != -1) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE); + return -1; + } const ASN1_EXTERN_FUNCS *ef = it->funcs; - int ret = ef->asn1_ex_i2d(pval, out, it, tag, aclass); + int ret = ef->asn1_ex_i2d(pval, out, it); if (ret == 0) { // |asn1_ex_i2d| should never return zero. We have already checked // for optional values generically, and |ASN1_ITYPE_EXTERN| fields @@ -223,7 +230,8 @@ int asn1_item_ex_i2d_opt(ASN1_VALUE **pval, unsigned char **out, return -1; } pseqval = asn1_get_field_ptr(pval, seqtt); - tmplen = asn1_template_ex_i2d(pseqval, NULL, seqtt, -1, 0); + tmplen = + asn1_template_ex_i2d(pseqval, NULL, seqtt, -1, 0, /*optional=*/0); if (tmplen == -1 || (tmplen > INT_MAX - seqcontlen)) { return -1; } @@ -244,7 +252,8 @@ int asn1_item_ex_i2d_opt(ASN1_VALUE **pval, unsigned char **out, return -1; } pseqval = asn1_get_field_ptr(pval, seqtt); - if (asn1_template_ex_i2d(pseqval, out, seqtt, -1, 0) < 0) { + if (asn1_template_ex_i2d(pseqval, out, seqtt, -1, 0, /*optional=*/0) < + 0) { return -1; } } @@ -259,13 +268,13 @@ int asn1_item_ex_i2d_opt(ASN1_VALUE **pval, unsigned char **out, // asn1_template_ex_i2d behaves like |asn1_item_ex_i2d_opt| but uses an // |ASN1_TEMPLATE| instead of an |ASN1_ITEM|. An |ASN1_TEMPLATE| wraps an -// |ASN1_ITEM| with modifiers such as tagging, SEQUENCE or SET, etc. Instead of -// taking an |optional| parameter, it uses the |ASN1_TFLG_OPTIONAL| flag. +// |ASN1_ITEM| with modifiers such as tagging, SEQUENCE or SET, etc. 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; + const ASN1_TEMPLATE *tt, int tag, int iclass, + int optional) { + int i, ret, ttag, tclass; size_t j; - flags = tt->flags; + uint32_t flags = tt->flags; // Historically, |iclass| was repurposed to pass additional flags into the // encoding process. @@ -294,7 +303,12 @@ static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out, tclass = 0; } - const int optional = (flags & ASN1_TFLG_OPTIONAL) != 0; + // The template may itself by marked as optional, or this may be the template + // of an |ASN1_ITEM_TEMPLATE| type which was contained inside an outer + // optional template. (They cannot both be true because the + // |ASN1_ITEM_TEMPLATE| codepath rejects optional templates.) + assert(!optional || (flags & ASN1_TFLG_OPTIONAL) == 0); + optional = optional || (flags & ASN1_TFLG_OPTIONAL) != 0; // At this point 'ttag' contains the outer tag to use, and 'tclass' is the // class. @@ -447,7 +461,6 @@ static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out, unsigned char *const buf = OPENSSL_malloc(skcontlen); DER_ENC *encoded = OPENSSL_malloc(sk_ASN1_VALUE_num(sk) * sizeof(*encoded)); if (encoded == NULL || buf == NULL) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); goto err; } @@ -631,7 +644,7 @@ static int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *out_omit, case V_ASN1_BOOLEAN: tbool = (ASN1_BOOLEAN *)pval; - if (*tbool == -1) { + if (*tbool == ASN1_BOOLEAN_NONE) { *out_omit = 1; return 0; } @@ -678,12 +691,19 @@ static int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *out_omit, case V_ASN1_UTF8STRING: case V_ASN1_SEQUENCE: case V_ASN1_SET: + // This is not a valid |ASN1_ITEM| type, but it appears in |ASN1_TYPE|. + case V_ASN1_OTHER: + // TODO(crbug.com/boringssl/412): This default case should be removed, now + // that we've resolved https://crbug.com/boringssl/561. However, it is still + // needed to support some edge cases in |ASN1_PRINTABLE|. |ASN1_PRINTABLE| + // broadly doesn't tolerate unrecognized universal tags, but except for + // eight values that map to |B_ASN1_UNKNOWN| instead of zero. See the + // X509Test.NameAttributeValues test. default: // All based on ASN1_STRING and handled the same strtmp = (ASN1_STRING *)*pval; cont = strtmp->data; len = strtmp->length; - break; } if (cout && len) { diff --git a/Sources/CNIOBoringSSL/crypto/asn1/tasn_fre.c b/Sources/CNIOBoringSSL/crypto/asn1/tasn_fre.c index bc897053..e26d3d67 100644 --- a/Sources/CNIOBoringSSL/crypto/asn1/tasn_fre.c +++ b/Sources/CNIOBoringSSL/crypto/asn1/tasn_fre.c @@ -66,15 +66,10 @@ // 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_ex_free(&val, it); } void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it) { - asn1_item_combine_free(pval, it, 0); -} - -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; int i; @@ -117,10 +112,8 @@ void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, if (asn1_cb) { asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL); } - if (!combine) { - OPENSSL_free(*pval); - *pval = NULL; - } + OPENSSL_free(*pval); + *pval = NULL; break; } @@ -160,57 +153,33 @@ void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, if (asn1_cb) { asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL); } - if (!combine) { - OPENSSL_free(*pval); - *pval = NULL; - } + 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); + for (size_t i = 0; i < sk_ASN1_VALUE_num(sk); i++) { + ASN1_VALUE *vtmp = sk_ASN1_VALUE_value(sk, i); + ASN1_item_ex_free(&vtmp, ASN1_ITEM_ptr(tt->item)); } sk_ASN1_VALUE_free(sk); *pval = NULL; } else { - asn1_item_combine_free(pval, ASN1_ITEM_ptr(tt->item), - tt->flags & ASN1_TFLG_COMBINE); + ASN1_item_ex_free(pval, ASN1_ITEM_ptr(tt->item)); } } void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it) { - int utype; // Historically, |it->funcs| for primitive types contained an // |ASN1_PRIMITIVE_FUNCS| table of calbacks. - assert(it == NULL || it->funcs == NULL); - // 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 (utype != V_ASN1_BOOLEAN && !*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; - } - } + assert(it->funcs == NULL); + int utype = it->itype == ASN1_ITYPE_MSTRING ? -1 : it->utype; switch (utype) { case V_ASN1_OBJECT: ASN1_OBJECT_free((ASN1_OBJECT *)*pval); @@ -218,9 +187,9 @@ void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it) { case V_ASN1_BOOLEAN: if (it) { - *(ASN1_BOOLEAN *)pval = it->size; + *(ASN1_BOOLEAN *)pval = (ASN1_BOOLEAN)it->size; } else { - *(ASN1_BOOLEAN *)pval = -1; + *(ASN1_BOOLEAN *)pval = ASN1_BOOLEAN_NONE; } return; @@ -228,8 +197,10 @@ void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it) { break; case V_ASN1_ANY: - ASN1_primitive_free(pval, NULL); - OPENSSL_free(*pval); + if (*pval != NULL) { + asn1_type_cleanup((ASN1_TYPE *)*pval); + OPENSSL_free(*pval); + } break; default: diff --git a/Sources/CNIOBoringSSL/crypto/asn1/tasn_new.c b/Sources/CNIOBoringSSL/crypto/asn1/tasn_new.c index edcc4c51..aa2a1cc0 100644 --- a/Sources/CNIOBoringSSL/crypto/asn1/tasn_new.c +++ b/Sources/CNIOBoringSSL/crypto/asn1/tasn_new.c @@ -67,8 +67,6 @@ #include "internal.h" -static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, - int combine); static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it); static int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); @@ -86,11 +84,6 @@ ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it) { // 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); -} - -static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, - int combine) { const ASN1_TEMPLATE *tt = NULL; const ASN1_EXTERN_FUNCS *ef; ASN1_VALUE **pseqval; @@ -134,13 +127,11 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, return 1; } } - if (!combine) { - *pval = OPENSSL_malloc(it->size); - if (!*pval) { - goto memerr; - } - OPENSSL_memset(*pval, 0, it->size); + *pval = OPENSSL_malloc(it->size); + if (!*pval) { + goto memerr; } + OPENSSL_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 auxerr2; @@ -160,15 +151,13 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, return 1; } } - if (!combine) { - *pval = OPENSSL_malloc(it->size); - if (!*pval) { - goto memerr; - } - OPENSSL_memset(*pval, 0, it->size); - asn1_refcount_set_one(pval, it); - asn1_enc_init(pval, it); + *pval = OPENSSL_malloc(it->size); + if (!*pval) { + goto memerr; } + OPENSSL_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)) { @@ -184,13 +173,12 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, return 1; memerr2: - asn1_item_combine_free(pval, it, combine); + ASN1_item_ex_free(pval, it); memerr: - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); return 0; auxerr2: - asn1_item_combine_free(pval, it, combine); + ASN1_item_ex_free(pval, it); auxerr: OPENSSL_PUT_ERROR(ASN1, ASN1_R_AUX_ERROR); return 0; @@ -246,7 +234,6 @@ static int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) { 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; } @@ -255,7 +242,7 @@ static int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) { goto done; } // Otherwise pass it back to the item routine - ret = asn1_item_ex_combine_new(pval, it, tt->flags & ASN1_TFLG_COMBINE); + ret = ASN1_item_ex_new(pval, it); done: return ret; } @@ -273,9 +260,6 @@ static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) { // all the old functions. static int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it) { - ASN1_TYPE *typ; - int utype; - if (!it) { return 0; } @@ -284,6 +268,7 @@ static int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it) { // |ASN1_PRIMITIVE_FUNCS| table of calbacks. assert(it->funcs == NULL); + int utype; if (it->itype == ASN1_ITYPE_MSTRING) { utype = -1; } else { @@ -295,15 +280,15 @@ static int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it) { return 1; case V_ASN1_BOOLEAN: - *(ASN1_BOOLEAN *)pval = it->size; + *(ASN1_BOOLEAN *)pval = (ASN1_BOOLEAN)it->size; return 1; case V_ASN1_NULL: *pval = (ASN1_VALUE *)1; return 1; - case V_ASN1_ANY: - typ = OPENSSL_malloc(sizeof(ASN1_TYPE)); + case V_ASN1_ANY: { + ASN1_TYPE *typ = OPENSSL_malloc(sizeof(ASN1_TYPE)); if (!typ) { return 0; } @@ -311,6 +296,7 @@ static int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it) { typ->type = -1; *pval = (ASN1_VALUE *)typ; break; + } default: *pval = (ASN1_VALUE *)ASN1_STRING_type_new(utype); @@ -333,7 +319,7 @@ static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) { utype = it->utype; } if (utype == V_ASN1_BOOLEAN) { - *(ASN1_BOOLEAN *)pval = it->size; + *(ASN1_BOOLEAN *)pval = (ASN1_BOOLEAN)it->size; } else { *pval = NULL; } diff --git a/Sources/CNIOBoringSSL/crypto/asn1/tasn_typ.c b/Sources/CNIOBoringSSL/crypto/asn1/tasn_typ.c index 801ec904..701a6ad3 100644 --- a/Sources/CNIOBoringSSL/crypto/asn1/tasn_typ.c +++ b/Sources/CNIOBoringSSL/crypto/asn1/tasn_typ.c @@ -107,9 +107,9 @@ IMPLEMENT_ASN1_FUNCTIONS_const_fname(ASN1_STRING, DIRECTORYSTRING, DIRECTORYSTRING) // 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) +IMPLEMENT_ASN1_TYPE_ex(ASN1_BOOLEAN, ASN1_BOOLEAN, ASN1_BOOLEAN_NONE) +IMPLEMENT_ASN1_TYPE_ex(ASN1_TBOOLEAN, ASN1_BOOLEAN, ASN1_BOOLEAN_TRUE) +IMPLEMENT_ASN1_TYPE_ex(ASN1_FBOOLEAN, ASN1_BOOLEAN, ASN1_BOOLEAN_FALSE) ASN1_ITEM_TEMPLATE(ASN1_SEQUENCE_ANY) = ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, ASN1_SEQUENCE_ANY, ASN1_ANY) diff --git a/Sources/CNIOBoringSSL/crypto/asn1/tasn_utl.c b/Sources/CNIOBoringSSL/crypto/asn1/tasn_utl.c index effee5dd..85533f70 100644 --- a/Sources/CNIOBoringSSL/crypto/asn1/tasn_utl.c +++ b/Sources/CNIOBoringSSL/crypto/asn1/tasn_utl.c @@ -63,6 +63,7 @@ #include #include #include +#include #include #include "../internal.h" @@ -131,68 +132,62 @@ static ASN1_ENCODING *asn1_get_enc_ptr(ASN1_VALUE **pval, const ASN1_ITEM *it) { } void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it) { - ASN1_ENCODING *enc; - enc = asn1_get_enc_ptr(pval, it); + ASN1_ENCODING *enc = asn1_get_enc_ptr(pval, it); if (enc) { enc->enc = NULL; enc->len = 0; - enc->alias_only = 0; - enc->alias_only_on_next_parse = 0; - enc->modified = 1; + enc->buf = NULL; } } void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it) { - ASN1_ENCODING *enc; - enc = asn1_get_enc_ptr(pval, it); + ASN1_ENCODING *enc = asn1_get_enc_ptr(pval, it); if (enc) { - if (!enc->alias_only) { - OPENSSL_free(enc->enc); - } - enc->enc = NULL; - enc->len = 0; - enc->alias_only = 0; - enc->alias_only_on_next_parse = 0; - enc->modified = 1; + asn1_encoding_clear(enc); } } -int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen, - const ASN1_ITEM *it) { +int asn1_enc_save(ASN1_VALUE **pval, const uint8_t *in, size_t in_len, + const ASN1_ITEM *it, CRYPTO_BUFFER *buf) { ASN1_ENCODING *enc; enc = asn1_get_enc_ptr(pval, it); if (!enc) { return 1; } - if (!enc->alias_only) { - OPENSSL_free(enc->enc); - } - - enc->alias_only = enc->alias_only_on_next_parse; - enc->alias_only_on_next_parse = 0; - - if (enc->alias_only) { + asn1_encoding_clear(enc); + if (buf != NULL) { + assert(CRYPTO_BUFFER_data(buf) <= in && + in + in_len <= CRYPTO_BUFFER_data(buf) + CRYPTO_BUFFER_len(buf)); + CRYPTO_BUFFER_up_ref(buf); + enc->buf = buf; enc->enc = (uint8_t *)in; } else { - enc->enc = OPENSSL_malloc(inlen); + enc->enc = OPENSSL_memdup(in, in_len); if (!enc->enc) { return 0; } - OPENSSL_memcpy(enc->enc, in, inlen); } - enc->len = inlen; - enc->modified = 0; - + enc->len = in_len; return 1; } +void asn1_encoding_clear(ASN1_ENCODING *enc) { + if (enc->buf != NULL) { + CRYPTO_BUFFER_free(enc->buf); + } else { + OPENSSL_free(enc->enc); + } + enc->enc = NULL; + enc->len = 0; + enc->buf = NULL; +} + int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval, const ASN1_ITEM *it) { - ASN1_ENCODING *enc; - enc = asn1_get_enc_ptr(pval, it); - if (!enc || enc->modified) { + ASN1_ENCODING *enc = asn1_get_enc_ptr(pval, it); + if (!enc || enc->len == 0) { return 0; } if (out) { @@ -207,11 +202,7 @@ int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval, // Given an ASN1_TEMPLATE get a pointer to a field ASN1_VALUE **asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) { - ASN1_VALUE **pvaltmp; - if (tt->flags & ASN1_TFLG_COMBINE) { - return pval; - } - pvaltmp = offset2ptr(*pval, tt->offset); + ASN1_VALUE **pvaltmp = offset2ptr(*pval, tt->offset); // NOTE for BOOLEAN types the field is just a plain int so we can't return // int **, so settle for (int *). return pvaltmp; diff --git a/Sources/CNIOBoringSSL/crypto/bio/bio.c b/Sources/CNIOBoringSSL/crypto/bio/bio.c index 7c24ff32..2b9c5e66 100644 --- a/Sources/CNIOBoringSSL/crypto/bio/bio.c +++ b/Sources/CNIOBoringSSL/crypto/bio/bio.c @@ -72,7 +72,6 @@ BIO *BIO_new(const BIO_METHOD *method) { BIO *ret = OPENSSL_malloc(sizeof(BIO)); if (ret == NULL) { - OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE); return NULL; } @@ -192,11 +191,17 @@ int BIO_write_all(BIO *bio, const void *data, size_t len) { } int BIO_puts(BIO *bio, const char *in) { - return BIO_write(bio, in, strlen(in)); + size_t len = strlen(in); + if (len > INT_MAX) { + // |BIO_write| and the return value both assume the string fits in |int|. + OPENSSL_PUT_ERROR(BIO, ERR_R_OVERFLOW); + return -1; + } + return BIO_write(bio, in, (int)len); } int BIO_flush(BIO *bio) { - return BIO_ctrl(bio, BIO_CTRL_FLUSH, 0, NULL); + return (int)BIO_ctrl(bio, BIO_CTRL_FLUSH, 0, NULL); } long BIO_ctrl(BIO *bio, int cmd, long larg, void *parg) { @@ -229,11 +234,11 @@ long BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg) { } int BIO_reset(BIO *bio) { - return BIO_ctrl(bio, BIO_CTRL_RESET, 0, NULL); + return (int)BIO_ctrl(bio, BIO_CTRL_RESET, 0, NULL); } int BIO_eof(BIO *bio) { - return BIO_ctrl(bio, BIO_CTRL_EOF, 0, NULL); + return (int)BIO_ctrl(bio, BIO_CTRL_EOF, 0, NULL); } void BIO_set_flags(BIO *bio, int flags) { @@ -333,7 +338,7 @@ size_t BIO_wpending(const BIO *bio) { } int BIO_set_close(BIO *bio, int close_flag) { - return BIO_ctrl(bio, BIO_CTRL_SET_CLOSE, close_flag, NULL); + return (int)BIO_ctrl(bio, BIO_CTRL_SET_CLOSE, close_flag, NULL); } OPENSSL_EXPORT size_t BIO_number_read(const BIO *bio) { @@ -418,7 +423,7 @@ int BIO_indent(BIO *bio, unsigned indent, unsigned max_indent) { } static int print_bio(const char *str, size_t len, void *bio) { - return BIO_write((BIO *)bio, str, len); + return BIO_write_all((BIO *)bio, str, len); } void ERR_print_errors(BIO *bio) { @@ -457,9 +462,11 @@ static int bio_read_all(BIO *bio, uint8_t **out, size_t *out_len, OPENSSL_free(*out); return 0; } - const size_t todo = len - done; - assert(todo < INT_MAX); - const int n = BIO_read(bio, *out + done, todo); + size_t todo = len - done; + if (todo > INT_MAX) { + todo = INT_MAX; + } + const int n = BIO_read(bio, *out + done, (int)todo); if (n == 0) { *out_len = done; return 1; @@ -603,7 +610,6 @@ int BIO_read_asn1(BIO *bio, uint8_t **out, size_t *out_len, size_t max_len) { *out = OPENSSL_malloc(len); if (*out == NULL) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); return 0; } OPENSSL_memcpy(*out, header, header_len); diff --git a/Sources/CNIOBoringSSL/crypto/bio/bio_mem.c b/Sources/CNIOBoringSSL/crypto/bio/bio_mem.c index f03985d9..b636531a 100644 --- a/Sources/CNIOBoringSSL/crypto/bio/bio_mem.c +++ b/Sources/CNIOBoringSSL/crypto/bio/bio_mem.c @@ -66,7 +66,7 @@ #include "../internal.h" -BIO *BIO_new_mem_buf(const void *buf, int len) { +BIO *BIO_new_mem_buf(const void *buf, ossl_ssize_t len) { BIO *ret; BUF_MEM *b; const size_t size = len < 0 ? strlen((char *)buf) : (size_t)len; @@ -130,13 +130,15 @@ static int mem_free(BIO *bio) { } static int mem_read(BIO *bio, char *out, int outl) { - int ret; - BUF_MEM *b = (BUF_MEM*) bio->ptr; - BIO_clear_retry_flags(bio); - ret = outl; - if (b->length < INT_MAX && ret > (int)b->length) { - ret = b->length; + if (outl <= 0) { + return 0; + } + + BUF_MEM *b = bio->ptr; + int ret = outl; + if ((size_t)ret > b->length) { + ret = (int)b->length; } if (ret > 0) { @@ -157,65 +159,49 @@ static int mem_read(BIO *bio, char *out, int outl) { } static int mem_write(BIO *bio, const char *in, int inl) { - int ret = -1; - int blen; - BUF_MEM *b; - - b = (BUF_MEM *)bio->ptr; + BIO_clear_retry_flags(bio); + if (inl <= 0) { + return 0; // Successfully write zero bytes. + } if (bio->flags & BIO_FLAGS_MEM_RDONLY) { OPENSSL_PUT_ERROR(BIO, BIO_R_WRITE_TO_READ_ONLY_BIO); - goto err; + return -1; } - BIO_clear_retry_flags(bio); - blen = b->length; - if (INT_MAX - blen < inl) { - goto err; + BUF_MEM *b = bio->ptr; + if (!BUF_MEM_append(b, in, inl)) { + return -1; } - if (BUF_MEM_grow_clean(b, blen + inl) != ((size_t) blen) + inl) { - goto err; - } - OPENSSL_memcpy(&b->data[blen], in, inl); - ret = inl; -err: - return ret; + return inl; } static int mem_gets(BIO *bio, char *buf, int size) { - int i, j; - char *p; - BUF_MEM *b = (BUF_MEM *)bio->ptr; - BIO_clear_retry_flags(bio); - j = b->length; - if (size - 1 < j) { - j = size - 1; - } - if (j <= 0) { - if (size > 0) { - *buf = 0; - } + if (size <= 0) { return 0; } - p = b->data; - for (i = 0; i < j; i++) { - if (p[i] == '\n') { - i++; - break; - } + // The buffer size includes space for the trailing NUL, so we can read at most + // one fewer byte. + BUF_MEM *b = bio->ptr; + int ret = size - 1; + if ((size_t)ret > b->length) { + ret = (int)b->length; } - // i is now the max num of bytes to copy, either j or up to and including the - // first newline + // Stop at the first newline. + const char *newline = OPENSSL_memchr(b->data, '\n', ret); + if (newline != NULL) { + ret = (int)(newline - b->data + 1); + } - i = mem_read(bio, buf, i); - if (i > 0) { - buf[i] = '\0'; + ret = mem_read(bio, buf, ret); + if (ret >= 0) { + buf[ret] = '\0'; } - return i; + return ret; } static long mem_ctrl(BIO *bio, int cmd, long num, void *ptr) { @@ -312,13 +298,13 @@ long BIO_get_mem_data(BIO *bio, char **contents) { } int BIO_get_mem_ptr(BIO *bio, BUF_MEM **out) { - return BIO_ctrl(bio, BIO_C_GET_BUF_MEM_PTR, 0, (char *) out); + return (int)BIO_ctrl(bio, BIO_C_GET_BUF_MEM_PTR, 0, (char *) out); } int BIO_set_mem_buf(BIO *bio, BUF_MEM *b, int take_ownership) { - return BIO_ctrl(bio, BIO_C_SET_BUF_MEM, take_ownership, (char *) b); + return (int)BIO_ctrl(bio, BIO_C_SET_BUF_MEM, take_ownership, (char *) b); } int BIO_set_mem_eof_return(BIO *bio, int eof_value) { - return BIO_ctrl(bio, BIO_C_SET_BUF_MEM_EOF_RETURN, eof_value, NULL); + return (int)BIO_ctrl(bio, BIO_C_SET_BUF_MEM_EOF_RETURN, eof_value, NULL); } diff --git a/Sources/CNIOBoringSSL/crypto/bio/connect.c b/Sources/CNIOBoringSSL/crypto/bio/connect.c index 91aa422f..2f4342de 100644 --- a/Sources/CNIOBoringSSL/crypto/bio/connect.c +++ b/Sources/CNIOBoringSSL/crypto/bio/connect.c @@ -363,7 +363,7 @@ static int conn_read(BIO *bio, char *out, int out_len) { } bio_clear_socket_error(); - ret = recv(bio->num, out, out_len, 0); + ret = (int)recv(bio->num, out, out_len, 0); BIO_clear_retry_flags(bio); if (ret <= 0) { if (bio_fd_should_retry(ret)) { @@ -387,7 +387,7 @@ static int conn_write(BIO *bio, const char *in, int in_len) { } bio_clear_socket_error(); - ret = send(bio->num, in, in_len, 0); + ret = (int)send(bio->num, in, in_len, 0); BIO_clear_retry_flags(bio); if (ret <= 0) { if (bio_fd_should_retry(ret)) { @@ -523,11 +523,11 @@ static const BIO_METHOD methods_connectp = { const BIO_METHOD *BIO_s_connect(void) { return &methods_connectp; } int BIO_set_conn_hostname(BIO *bio, const char *name) { - return BIO_ctrl(bio, BIO_C_SET_CONNECT, 0, (void*) name); + return (int)BIO_ctrl(bio, BIO_C_SET_CONNECT, 0, (void*) name); } int BIO_set_conn_port(BIO *bio, const char *port_str) { - return BIO_ctrl(bio, BIO_C_SET_CONNECT, 1, (void*) port_str); + return (int)BIO_ctrl(bio, BIO_C_SET_CONNECT, 1, (void*) port_str); } int BIO_set_conn_int_port(BIO *bio, const int *port) { @@ -537,11 +537,11 @@ int BIO_set_conn_int_port(BIO *bio, const int *port) { } int BIO_set_nbio(BIO *bio, int on) { - return BIO_ctrl(bio, BIO_C_SET_NBIO, on, NULL); + return (int)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); + return (int)BIO_ctrl(bio, BIO_C_DO_STATE_MACHINE, 0, NULL); } #endif // OPENSSL_TRUSTY diff --git a/Sources/CNIOBoringSSL/crypto/bio/fd.c b/Sources/CNIOBoringSSL/crypto/bio/fd.c index cf111766..608fdf1a 100644 --- a/Sources/CNIOBoringSSL/crypto/bio/fd.c +++ b/Sources/CNIOBoringSSL/crypto/bio/fd.c @@ -158,7 +158,7 @@ static int fd_free(BIO *bio) { static int fd_read(BIO *b, char *out, int outl) { int ret = 0; - ret = BORINGSSL_READ(b->num, out, outl); + ret = (int)BORINGSSL_READ(b->num, out, outl); BIO_clear_retry_flags(b); if (ret <= 0) { if (bio_fd_should_retry(ret)) { @@ -170,7 +170,7 @@ static int fd_read(BIO *b, char *out, int outl) { } static int fd_write(BIO *b, const char *in, int inl) { - int ret = BORINGSSL_WRITE(b->num, in, inl); + int ret = (int)BORINGSSL_WRITE(b->num, in, inl); BIO_clear_retry_flags(b); if (ret <= 0) { if (bio_fd_should_retry(ret)) { @@ -241,20 +241,24 @@ static long fd_ctrl(BIO *b, int cmd, long num, void *ptr) { } static int fd_gets(BIO *bp, char *buf, int size) { - char *ptr = buf; - char *end = buf + size - 1; - if (size <= 0) { return 0; } - while (ptr < end && fd_read(bp, ptr, 1) > 0 && ptr[0] != '\n') { + char *ptr = buf; + char *end = buf + size - 1; + while (ptr < end && fd_read(bp, ptr, 1) > 0) { + char c = ptr[0]; ptr++; + if (c == '\n') { + break; + } } ptr[0] = '\0'; - return ptr - buf; + // The output length is bounded by |size|. + return (int)(ptr - buf); } static const BIO_METHOD methods_fdp = { @@ -265,11 +269,11 @@ static const BIO_METHOD methods_fdp = { const BIO_METHOD *BIO_s_fd(void) { return &methods_fdp; } int BIO_set_fd(BIO *bio, int fd, int close_flag) { - return BIO_int_ctrl(bio, BIO_C_SET_FD, close_flag, fd); + return (int)BIO_int_ctrl(bio, BIO_C_SET_FD, close_flag, fd); } int BIO_get_fd(BIO *bio, int *out_fd) { - return BIO_ctrl(bio, BIO_C_GET_FD, 0, (char *) out_fd); + return (int)BIO_ctrl(bio, BIO_C_GET_FD, 0, (char *) out_fd); } #endif // OPENSSL_TRUSTY diff --git a/Sources/CNIOBoringSSL/crypto/bio/file.c b/Sources/CNIOBoringSSL/crypto/bio/file.c index 1f20f680..ca1edb7f 100644 --- a/Sources/CNIOBoringSSL/crypto/bio/file.c +++ b/Sources/CNIOBoringSSL/crypto/bio/file.c @@ -157,13 +157,11 @@ static int file_read(BIO *b, char *out, int outl) { } static int file_write(BIO *b, const char *in, int inl) { - int ret = 0; - if (!b->init) { return 0; } - ret = fwrite(in, inl, 1, (FILE *)b->ptr); + int ret = (int)fwrite(in, inl, 1, (FILE *)b->ptr); if (ret > 0) { ret = inl; } @@ -253,20 +251,18 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr) { } static int file_gets(BIO *bp, char *buf, int size) { - int ret = 0; - if (size == 0) { return 0; } if (!fgets(buf, size, (FILE *)bp->ptr)) { buf[0] = 0; - goto err; + // TODO(davidben): This doesn't distinguish error and EOF. This should check + // |ferror| as in |file_read|. + return 0; } - ret = strlen(buf); -err: - return ret; + return (int)strlen(buf); } static const BIO_METHOD methods_filep = { @@ -281,31 +277,32 @@ const BIO_METHOD *BIO_s_file(void) { return &methods_filep; } int BIO_get_fp(BIO *bio, FILE **out_file) { - return BIO_ctrl(bio, BIO_C_GET_FILE_PTR, 0, (char*) out_file); + return (int)BIO_ctrl(bio, BIO_C_GET_FILE_PTR, 0, (char *)out_file); } int BIO_set_fp(BIO *bio, FILE *file, int close_flag) { - return BIO_ctrl(bio, BIO_C_SET_FILE_PTR, close_flag, (char *) file); + return (int)BIO_ctrl(bio, BIO_C_SET_FILE_PTR, close_flag, (char *)file); } int BIO_read_filename(BIO *bio, const char *filename) { - return BIO_ctrl(bio, BIO_C_SET_FILENAME, BIO_CLOSE | BIO_FP_READ, - (char *)filename); + return (int)BIO_ctrl(bio, BIO_C_SET_FILENAME, BIO_CLOSE | BIO_FP_READ, + (char *)filename); } int BIO_write_filename(BIO *bio, const char *filename) { - return BIO_ctrl(bio, BIO_C_SET_FILENAME, BIO_CLOSE | BIO_FP_WRITE, - (char *)filename); + return (int)BIO_ctrl(bio, BIO_C_SET_FILENAME, BIO_CLOSE | BIO_FP_WRITE, + (char *)filename); } int BIO_append_filename(BIO *bio, const char *filename) { - return BIO_ctrl(bio, BIO_C_SET_FILENAME, BIO_CLOSE | BIO_FP_APPEND, - (char *)filename); + return (int)BIO_ctrl(bio, BIO_C_SET_FILENAME, BIO_CLOSE | BIO_FP_APPEND, + (char *)filename); } int BIO_rw_filename(BIO *bio, const char *filename) { - return BIO_ctrl(bio, BIO_C_SET_FILENAME, - BIO_CLOSE | BIO_FP_READ | BIO_FP_WRITE, (char *)filename); + return (int)BIO_ctrl(bio, BIO_C_SET_FILENAME, + BIO_CLOSE | BIO_FP_READ | BIO_FP_WRITE, + (char *)filename); } long BIO_tell(BIO *bio) { return BIO_ctrl(bio, BIO_C_FILE_TELL, 0, NULL); } diff --git a/Sources/CNIOBoringSSL/crypto/bio/pair.c b/Sources/CNIOBoringSSL/crypto/bio/pair.c index 3dabfc28..4e51d124 100644 --- a/Sources/CNIOBoringSSL/crypto/bio/pair.c +++ b/Sources/CNIOBoringSSL/crypto/bio/pair.c @@ -221,7 +221,8 @@ static int bio_read(BIO *bio, char *buf, int size_) { rest -= chunk; } while (rest); - return size; + // |size| is bounded by the buffer size, which fits in |int|. + return (int)size; } static int bio_write(BIO *bio, const char *buf, int num_) { @@ -293,7 +294,8 @@ static int bio_write(BIO *bio, const char *buf, int num_) { buf += chunk; } while (rest); - return num; + // |num| is bounded by the buffer size, which fits in |int|. + return (int)num; } static int bio_make_pair(BIO *bio1, BIO *bio2, size_t writebuf1_len, @@ -317,7 +319,6 @@ static int bio_make_pair(BIO *bio1, BIO *bio2, size_t writebuf1_len, } b1->buf = OPENSSL_malloc(b1->size); if (b1->buf == NULL) { - OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE); return 0; } b1->len = 0; @@ -330,7 +331,6 @@ static int bio_make_pair(BIO *bio1, BIO *bio2, size_t writebuf1_len, } b2->buf = OPENSSL_malloc(b2->size); if (b2->buf == NULL) { - OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE); return 0; } b2->len = 0; @@ -479,5 +479,5 @@ size_t BIO_ctrl_get_write_guarantee(BIO *bio) { } int BIO_shutdown_wr(BIO *bio) { - return BIO_ctrl(bio, BIO_C_SHUTDOWN_WR, 0, NULL); + return (int)BIO_ctrl(bio, BIO_C_SHUTDOWN_WR, 0, NULL); } diff --git a/Sources/CNIOBoringSSL/crypto/bio/printf.c b/Sources/CNIOBoringSSL/crypto/bio/printf.c index 1c118186..bfbb0c94 100644 --- a/Sources/CNIOBoringSSL/crypto/bio/printf.c +++ b/Sources/CNIOBoringSSL/crypto/bio/printf.c @@ -83,7 +83,6 @@ int BIO_printf(BIO *bio, const char *format, ...) { out = OPENSSL_malloc(requested_len + 1); out_malloced = 1; if (out == NULL) { - OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE); return -1; } va_start(args, format); diff --git a/Sources/CNIOBoringSSL/crypto/bio/socket.c b/Sources/CNIOBoringSSL/crypto/bio/socket.c index f65b3b53..466d4ecd 100644 --- a/Sources/CNIOBoringSSL/crypto/bio/socket.c +++ b/Sources/CNIOBoringSSL/crypto/bio/socket.c @@ -1,4 +1,3 @@ -/* crypto/bio/bss_sock.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -101,7 +100,7 @@ static int sock_read(BIO *b, char *out, int outl) { #if defined(OPENSSL_WINDOWS) int ret = recv(b->num, out, outl, 0); #else - int ret = read(b->num, out, outl); + int ret = (int)read(b->num, out, outl); #endif BIO_clear_retry_flags(b); if (ret <= 0) { @@ -113,13 +112,11 @@ static int sock_read(BIO *b, char *out, int outl) { } 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); + int ret = send(b->num, in, inl, 0); #else - ret = write(b->num, in, inl); + int ret = (int)write(b->num, in, inl); #endif BIO_clear_retry_flags(b); if (ret <= 0) { diff --git a/Sources/CNIOBoringSSL/crypto/blake2/blake2.c b/Sources/CNIOBoringSSL/crypto/blake2/blake2.c index c4c0dc30..91ae6820 100644 --- a/Sources/CNIOBoringSSL/crypto/blake2/blake2.c +++ b/Sources/CNIOBoringSSL/crypto/blake2/blake2.c @@ -105,8 +105,12 @@ void BLAKE2B256_Init(BLAKE2B_CTX *b2b) { } void BLAKE2B256_Update(BLAKE2B_CTX *b2b, const void *in_data, size_t len) { - const uint8_t *data = (const uint8_t *)in_data; + if (len == 0) { + // Work around a C language bug. See https://crbug.com/1019588. + return; + } + const uint8_t *data = in_data; size_t todo = sizeof(b2b->block.bytes) - b2b->block_used; if (todo > len) { todo = len; diff --git a/Sources/CNIOBoringSSL/crypto/bn_extra/convert.c b/Sources/CNIOBoringSSL/crypto/bn_extra/convert.c index 49667c61..f74e5b9f 100644 --- a/Sources/CNIOBoringSSL/crypto/bn_extra/convert.c +++ b/Sources/CNIOBoringSSL/crypto/bn_extra/convert.c @@ -81,7 +81,6 @@ char *BN_bn2hex(const BIGNUM *bn) { char *buf = OPENSSL_malloc(1 /* leading '-' */ + 1 /* zero is non-empty */ + width * BN_BYTES * 2 + 1 /* trailing NUL */); if (buf == NULL) { - OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); return NULL; } @@ -133,18 +132,9 @@ static int decode_hex(BIGNUM *bn, const char *in, int in_len) { BN_ULONG word = 0; int j; for (j = todo; j > 0; j--) { - char c = in[in_len - j]; - - BN_ULONG hex; - if (c >= '0' && c <= '9') { - hex = c - '0'; - } else if (c >= 'a' && c <= 'f') { - hex = c - 'a' + 10; - } else if (c >= 'A' && c <= 'F') { - hex = c - 'A' + 10; - } else { - hex = 0; - // This shouldn't happen. The caller checks |isxdigit|. + uint8_t hex = 0; + if (!OPENSSL_fromxdigit(&hex, in[in_len - j])) { + // This shouldn't happen. The caller checks |OPENSSL_isxdigit|. assert(0); } word = (word << 4) | hex; @@ -240,7 +230,7 @@ static int bn_x2bn(BIGNUM **outp, const char *in, decode_func decode, char_test_ } int BN_hex2bn(BIGNUM **outp, const char *in) { - return bn_x2bn(outp, in, decode_hex, isxdigit); + return bn_x2bn(outp, in, decode_hex, OPENSSL_isxdigit); } char *BN_bn2dec(const BIGNUM *a) { @@ -250,12 +240,12 @@ char *BN_bn2dec(const BIGNUM *a) { CBB cbb; if (!CBB_init(&cbb, 16) || !CBB_add_u8(&cbb, 0 /* trailing NUL */)) { - goto cbb_err; + goto err; } if (BN_is_zero(a)) { if (!CBB_add_u8(&cbb, '0')) { - goto cbb_err; + goto err; } } else { copy = BN_dup(a); @@ -272,7 +262,7 @@ char *BN_bn2dec(const BIGNUM *a) { const int add_leading_zeros = !BN_is_zero(copy); for (int i = 0; i < BN_DEC_NUM && (add_leading_zeros || word != 0); i++) { if (!CBB_add_u8(&cbb, '0' + word % 10)) { - goto cbb_err; + goto err; } word /= 10; } @@ -282,13 +272,13 @@ char *BN_bn2dec(const BIGNUM *a) { if (BN_is_negative(a) && !CBB_add_u8(&cbb, '-')) { - goto cbb_err; + goto err; } uint8_t *data; size_t len; if (!CBB_finish(&cbb, &data, &len)) { - goto cbb_err; + goto err; } // Reverse the buffer. @@ -301,8 +291,6 @@ char *BN_bn2dec(const BIGNUM *a) { BN_free(copy); return (char *)data; -cbb_err: - OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); err: BN_free(copy); CBB_cleanup(&cbb); @@ -310,7 +298,7 @@ char *BN_bn2dec(const BIGNUM *a) { } int BN_dec2bn(BIGNUM **outp, const char *in) { - return bn_x2bn(outp, in, decode_dec, isdigit); + return bn_x2bn(outp, in, decode_dec, OPENSSL_isdigit); } int BN_asc2bn(BIGNUM **outp, const char *in) { @@ -436,7 +424,6 @@ BIGNUM *BN_mpi2bn(const uint8_t *in, size_t len, BIGNUM *out) { if (out == NULL) { out = BN_new(); if (out == NULL) { - OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); return NULL; } out_is_alloced = 1; diff --git a/Sources/CNIOBoringSSL/crypto/buf/buf.c b/Sources/CNIOBoringSSL/crypto/buf/buf.c index 28ee7455..75efed75 100644 --- a/Sources/CNIOBoringSSL/crypto/buf/buf.c +++ b/Sources/CNIOBoringSSL/crypto/buf/buf.c @@ -69,7 +69,6 @@ BUF_MEM *BUF_MEM_new(void) { ret = OPENSSL_malloc(sizeof(BUF_MEM)); if (ret == NULL) { - OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE); return NULL; } @@ -93,21 +92,18 @@ int BUF_MEM_reserve(BUF_MEM *buf, size_t cap) { size_t n = cap + 3; if (n < cap) { - // overflow - OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(BUF, ERR_R_OVERFLOW); return 0; } n = n / 3; size_t alloc_size = n * 4; if (alloc_size / 4 != n) { - // overflow - OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(BUF, ERR_R_OVERFLOW); return 0; } char *new_buf = OPENSSL_realloc(buf->data, alloc_size); if (new_buf == NULL) { - OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE); return 0; } diff --git a/Sources/CNIOBoringSSL/crypto/bytestring/ber.c b/Sources/CNIOBoringSSL/crypto/bytestring/ber.c index 2033b5f8..d5db4861 100644 --- a/Sources/CNIOBoringSSL/crypto/bytestring/ber.c +++ b/Sources/CNIOBoringSSL/crypto/bytestring/ber.c @@ -24,11 +24,11 @@ // kMaxDepth is a just a sanity limit. The code should be such that the length // of the input being processes always decreases. None the less, a very large // input could otherwise cause the stack to overflow. -static const unsigned kMaxDepth = 2048; +static const uint32_t 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) { +static int is_string_type(CBS_ASN1_TAG tag) { // While BER supports constructed BIT STRINGS, OpenSSL misparses them. To // avoid acting on an ambiguous input, we do not support constructed BIT // STRINGS. See https://github.com/openssl/openssl/issues/12810. @@ -55,7 +55,7 @@ static int is_string_type(unsigned tag) { // 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, int *ber_found, unsigned depth) { +static int cbs_find_ber(const CBS *orig_in, int *ber_found, uint32_t depth) { CBS in; if (depth > kMaxDepth) { @@ -67,7 +67,7 @@ static int cbs_find_ber(const CBS *orig_in, int *ber_found, unsigned depth) { while (CBS_len(&in) > 0) { CBS contents; - unsigned tag; + CBS_ASN1_TAG tag; size_t header_len; int indefinite; if (!CBS_get_any_ber_asn1_element(&in, &contents, &tag, &header_len, @@ -110,8 +110,8 @@ static int cbs_get_eoc(CBS *cbs) { // 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) { +static int cbs_convert_ber(CBS *in, CBB *out, CBS_ASN1_TAG string_tag, + int looking_for_eoc, uint32_t depth) { assert(!(string_tag & CBS_ASN1_CONSTRUCTED)); if (depth > kMaxDepth) { @@ -124,7 +124,7 @@ static int cbs_convert_ber(CBS *in, CBB *out, unsigned string_tag, } CBS contents; - unsigned tag, child_string_tag = string_tag; + CBS_ASN1_TAG tag, child_string_tag = string_tag; size_t header_len; int indefinite; CBB *out_contents, out_contents_storage; @@ -142,7 +142,7 @@ static int cbs_convert_ber(CBS *in, CBB *out, unsigned string_tag, } out_contents = out; } else { - unsigned out_tag = tag; + CBS_ASN1_TAG 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. @@ -221,7 +221,8 @@ int CBS_asn1_ber_to_der(CBS *in, CBS *out, uint8_t **out_storage) { } int CBS_get_asn1_implicit_string(CBS *in, CBS *out, uint8_t **out_storage, - unsigned outer_tag, unsigned inner_tag) { + CBS_ASN1_TAG outer_tag, + CBS_ASN1_TAG inner_tag) { assert(!(outer_tag & CBS_ASN1_CONSTRUCTED)); assert(!(inner_tag & CBS_ASN1_CONSTRUCTED)); assert(is_string_type(inner_tag)); diff --git a/Sources/CNIOBoringSSL/crypto/bytestring/cbb.c b/Sources/CNIOBoringSSL/crypto/bytestring/cbb.c index 2da37edd..63cc9636 100644 --- a/Sources/CNIOBoringSSL/crypto/bytestring/cbb.c +++ b/Sources/CNIOBoringSSL/crypto/bytestring/cbb.c @@ -19,6 +19,7 @@ #include #include +#include #include "../internal.h" @@ -77,11 +78,13 @@ static int cbb_buffer_reserve(struct cbb_buffer_st *base, uint8_t **out, size_t newlen = base->len + len; if (newlen < base->len) { // Overflow + OPENSSL_PUT_ERROR(CRYPTO, ERR_R_OVERFLOW); goto err; } if (newlen > base->cap) { if (!base->can_resize) { + OPENSSL_PUT_ERROR(CRYPTO, ERR_R_OVERFLOW); goto err; } @@ -121,6 +124,7 @@ static int cbb_buffer_add(struct cbb_buffer_st *base, uint8_t **out, int CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len) { if (cbb->is_child) { + OPENSSL_PUT_ERROR(CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } @@ -191,6 +195,7 @@ int CBB_flush(CBB *cbb) { assert (child->pending_len_len == 1); if (len > 0xfffffffe) { + OPENSSL_PUT_ERROR(CRYPTO, ERR_R_OVERFLOW); // Too large. goto err; } else if (len > 0xffffff) { @@ -229,6 +234,7 @@ int CBB_flush(CBB *cbb) { len >>= 8; } if (len != 0) { + OPENSSL_PUT_ERROR(CRYPTO, ERR_R_OVERFLOW); goto err; } @@ -333,14 +339,14 @@ static int add_base128_integer(CBB *cbb, uint64_t v) { return 1; } -int CBB_add_asn1(CBB *cbb, CBB *out_contents, unsigned tag) { +int CBB_add_asn1(CBB *cbb, CBB *out_contents, CBS_ASN1_TAG tag) { if (!CBB_flush(cbb)) { return 0; } // Split the tag into leading bits and tag number. uint8_t tag_bits = (tag >> CBS_ASN1_TAG_SHIFT) & 0xe0; - unsigned tag_number = tag & CBS_ASN1_TAG_NUMBER_MASK; + CBS_ASN1_TAG tag_number = tag & CBS_ASN1_TAG_NUMBER_MASK; if (tag_number >= 0x1f) { // Set all the bits in the tag number to signal high tag number form. if (!CBB_add_u8(cbb, tag_bits | 0x1f) || @@ -470,7 +476,7 @@ int CBB_add_asn1_uint64(CBB *cbb, uint64_t value) { return CBB_add_asn1_uint64_with_tag(cbb, value, CBS_ASN1_INTEGER); } -int CBB_add_asn1_uint64_with_tag(CBB *cbb, uint64_t value, unsigned tag) { +int CBB_add_asn1_uint64_with_tag(CBB *cbb, uint64_t value, CBS_ASN1_TAG tag) { CBB child; if (!CBB_add_asn1(cbb, &child, tag)) { return 0; @@ -508,7 +514,7 @@ int CBB_add_asn1_int64(CBB *cbb, int64_t value) { return CBB_add_asn1_int64_with_tag(cbb, value, CBS_ASN1_INTEGER); } -int CBB_add_asn1_int64_with_tag(CBB *cbb, int64_t value, unsigned tag) { +int CBB_add_asn1_int64_with_tag(CBB *cbb, int64_t value, CBS_ASN1_TAG tag) { if (value >= 0) { return CBB_add_asn1_uint64_with_tag(cbb, (uint64_t)value, tag); } @@ -560,30 +566,15 @@ int CBB_add_asn1_bool(CBB *cbb, int value) { // component and the dot, so |cbs| may be passed into the function again for the // next value. static int parse_dotted_decimal(CBS *cbs, uint64_t *out) { - *out = 0; - int seen_digit = 0; - for (;;) { - // Valid terminators for a component are the end of the string or a - // non-terminal dot. If the string ends with a dot, this is not a valid OID - // string. - uint8_t u; - if (!CBS_get_u8(cbs, &u) || - (u == '.' && CBS_len(cbs) > 0)) { - break; - } - if (u < '0' || u > '9' || - // Forbid stray leading zeros. - (seen_digit && *out == 0) || - // Check for overflow. - *out > UINT64_MAX / 10 || - *out * 10 > UINT64_MAX - (u - '0')) { - return 0; - } - *out = *out * 10 + (u - '0'); - seen_digit = 1; + if (!CBS_get_u64_decimal(cbs, out)) { + return 0; } - // The empty string is not a legal OID component. - return seen_digit; + + // The integer must have either ended at the end of the string, or a + // non-terminal dot, which should be consumed. If the string ends with a dot, + // this is not a valid OID string. + uint8_t dot; + return !CBS_get_u8(cbs, &dot) || (dot == '.' && CBS_len(cbs) > 0); } int CBB_add_asn1_oid_from_text(CBB *cbb, const char *text, size_t len) { @@ -649,6 +640,7 @@ int CBB_flush_asn1_set_of(CBB *cbb) { CBS_init(&cbs, CBB_data(cbb), CBB_len(cbb)); while (CBS_len(&cbs) != 0) { if (!CBS_get_any_asn1_element(&cbs, NULL, NULL, NULL)) { + OPENSSL_PUT_ERROR(CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } num_children++; diff --git a/Sources/CNIOBoringSSL/crypto/bytestring/cbs.c b/Sources/CNIOBoringSSL/crypto/bytestring/cbs.c index 546b3611..a2b79e7b 100644 --- a/Sources/CNIOBoringSSL/crypto/bytestring/cbs.c +++ b/Sources/CNIOBoringSSL/crypto/bytestring/cbs.c @@ -136,7 +136,7 @@ int CBS_get_u24(CBS *cbs, uint32_t *out) { if (!cbs_get_u(cbs, &v, 3)) { return 0; } - *out = v; + *out = (uint32_t)v; return 1; } @@ -145,7 +145,7 @@ int CBS_get_u32(CBS *cbs, uint32_t *out) { if (!cbs_get_u(cbs, &v, 4)) { return 0; } - *out = v; + *out = (uint32_t)v; return 1; } @@ -227,6 +227,30 @@ int CBS_get_until_first(CBS *cbs, CBS *out, uint8_t c) { return CBS_get_bytes(cbs, out, split - CBS_data(cbs)); } +int CBS_get_u64_decimal(CBS *cbs, uint64_t *out) { + uint64_t v = 0; + int seen_digit = 0; + while (CBS_len(cbs) != 0) { + uint8_t c = CBS_data(cbs)[0]; + if (!OPENSSL_isdigit(c)) { + break; + } + CBS_skip(cbs, 1); + if (// Forbid stray leading zeros. + (v == 0 && seen_digit) || + // Check for overflow. + v > UINT64_MAX / 10 || // + v * 10 > UINT64_MAX - (c - '0')) { + return 0; + } + v = v * 10 + (c - '0'); + seen_digit = 1; + } + + *out = v; + return seen_digit; +} + // parse_base128_integer reads a big-endian base-128 integer from |cbs| and sets // |*out| to the result. This is the encoding used in DER for both high tag // number form and OID components. @@ -254,7 +278,7 @@ static int parse_base128_integer(CBS *cbs, uint64_t *out) { return 1; } -static int parse_asn1_tag(CBS *cbs, unsigned *out) { +static int parse_asn1_tag(CBS *cbs, CBS_ASN1_TAG *out) { uint8_t tag_byte; if (!CBS_get_u8(cbs, &tag_byte)) { return 0; @@ -266,8 +290,8 @@ static int parse_asn1_tag(CBS *cbs, unsigned *out) { // 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. - unsigned tag = ((unsigned)tag_byte & 0xe0) << CBS_ASN1_TAG_SHIFT; - unsigned tag_number = tag_byte & 0x1f; + CBS_ASN1_TAG tag = ((CBS_ASN1_TAG)tag_byte & 0xe0) << CBS_ASN1_TAG_SHIFT; + CBS_ASN1_TAG tag_number = tag_byte & 0x1f; if (tag_number == 0x1f) { uint64_t v; if (!parse_base128_integer(cbs, &v) || @@ -277,7 +301,7 @@ static int parse_asn1_tag(CBS *cbs, unsigned *out) { v < 0x1f) { return 0; } - tag_number = (unsigned)v; + tag_number = (CBS_ASN1_TAG)v; } tag |= tag_number; @@ -293,7 +317,7 @@ static int parse_asn1_tag(CBS *cbs, unsigned *out) { return 1; } -static int cbs_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag, +static int cbs_get_any_asn1_element(CBS *cbs, CBS *out, CBS_ASN1_TAG *out_tag, size_t *out_header_len, int *out_ber_found, int *out_indefinite, int ber_ok) { CBS header = *cbs; @@ -310,7 +334,7 @@ static int cbs_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag, assert(out_indefinite == NULL); } - unsigned tag; + CBS_ASN1_TAG tag; if (!parse_asn1_tag(&header, &tag)) { return 0; } @@ -394,7 +418,7 @@ static int cbs_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag, return CBS_get_bytes(cbs, out, len); } -int CBS_get_any_asn1(CBS *cbs, CBS *out, unsigned *out_tag) { +int CBS_get_any_asn1(CBS *cbs, CBS *out, CBS_ASN1_TAG *out_tag) { size_t header_len; if (!CBS_get_any_asn1_element(cbs, out, out_tag, &header_len)) { return 0; @@ -408,13 +432,13 @@ int CBS_get_any_asn1(CBS *cbs, CBS *out, unsigned *out_tag) { return 1; } -int CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag, +int CBS_get_any_asn1_element(CBS *cbs, CBS *out, CBS_ASN1_TAG *out_tag, size_t *out_header_len) { return cbs_get_any_asn1_element(cbs, out, out_tag, out_header_len, NULL, NULL, /*ber_ok=*/0); } -int CBS_get_any_ber_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag, +int CBS_get_any_ber_asn1_element(CBS *cbs, CBS *out, CBS_ASN1_TAG *out_tag, size_t *out_header_len, int *out_ber_found, int *out_indefinite) { int ber_found_temp; @@ -424,10 +448,10 @@ int CBS_get_any_ber_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag, /*ber_ok=*/1); } -static int cbs_get_asn1(CBS *cbs, CBS *out, unsigned tag_value, +static int cbs_get_asn1(CBS *cbs, CBS *out, CBS_ASN1_TAG tag_value, int skip_header) { size_t header_len; - unsigned tag; + CBS_ASN1_TAG tag; CBS throwaway; if (out == NULL) { @@ -447,21 +471,17 @@ static int cbs_get_asn1(CBS *cbs, CBS *out, unsigned tag_value, return 1; } -int CBS_get_asn1(CBS *cbs, CBS *out, unsigned tag_value) { +int CBS_get_asn1(CBS *cbs, CBS *out, CBS_ASN1_TAG tag_value) { return cbs_get_asn1(cbs, out, tag_value, 1 /* skip header */); } -int CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned tag_value) { +int CBS_get_asn1_element(CBS *cbs, CBS *out, CBS_ASN1_TAG tag_value) { return cbs_get_asn1(cbs, out, tag_value, 0 /* include header */); } -int CBS_peek_asn1_tag(const CBS *cbs, unsigned tag_value) { - if (CBS_len(cbs) < 1) { - return 0; - } - +int CBS_peek_asn1_tag(const CBS *cbs, CBS_ASN1_TAG tag_value) { CBS copy = *cbs; - unsigned actual_tag; + CBS_ASN1_TAG actual_tag; return parse_asn1_tag(©, &actual_tag) && tag_value == actual_tag; } @@ -524,7 +544,7 @@ int CBS_get_asn1_bool(CBS *cbs, int *out) { return 1; } -int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, unsigned tag) { +int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, CBS_ASN1_TAG tag) { int present = 0; if (CBS_peek_asn1_tag(cbs, tag)) { @@ -542,7 +562,7 @@ int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, unsigned tag) { } int CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, int *out_present, - unsigned tag) { + CBS_ASN1_TAG tag) { CBS child; int present; if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) { @@ -563,7 +583,7 @@ int CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, int *out_present, return 1; } -int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, unsigned tag, +int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, CBS_ASN1_TAG tag, uint64_t default_value) { CBS child; int present; @@ -581,7 +601,7 @@ int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, unsigned tag, return 1; } -int CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned tag, +int CBS_get_optional_asn1_bool(CBS *cbs, int *out, CBS_ASN1_TAG tag, int default_value) { CBS child, child2; int present; @@ -678,6 +698,29 @@ static int add_decimal(CBB *out, uint64_t v) { return CBB_add_bytes(out, (const uint8_t *)buf, strlen(buf)); } +int CBS_is_valid_asn1_oid(const CBS *cbs) { + if (CBS_len(cbs) == 0) { + return 0; // OID encodings cannot be empty. + } + + CBS copy = *cbs; + uint8_t v, prev = 0; + while (CBS_get_u8(©, &v)) { + // OID encodings are a sequence of minimally-encoded base-128 integers (see + // |parse_base128_integer|). If |prev|'s MSB was clear, it was the last byte + // of an integer (or |v| is the first byte). |v| is then the first byte of + // the next integer. If first byte of an integer is 0x80, it is not + // minimally-encoded. + if ((prev & 0x80) == 0 && v == 0x80) { + return 0; + } + prev = v; + } + + // The last byte should must end an integer encoding. + return (prev & 0x80) == 0; +} + char *CBS_asn1_oid_to_text(const CBS *cbs) { CBB cbb; if (!CBB_init(&cbb, 32)) { @@ -729,13 +772,13 @@ static int cbs_get_two_digits(CBS *cbs, int *out) { if (!CBS_get_u8(cbs, &first_digit)) { return 0; } - if (!isdigit(first_digit)) { + if (!OPENSSL_isdigit(first_digit)) { return 0; } if (!CBS_get_u8(cbs, &second_digit)) { return 0; } - if (!isdigit(second_digit)) { + if (!OPENSSL_isdigit(second_digit)) { return 0; } *out = (first_digit - '0') * 10 + (second_digit - '0'); diff --git a/Sources/CNIOBoringSSL/crypto/bytestring/internal.h b/Sources/CNIOBoringSSL/crypto/bytestring/internal.h index f0a0e524..4c992724 100644 --- a/Sources/CNIOBoringSSL/crypto/bytestring/internal.h +++ b/Sources/CNIOBoringSSL/crypto/bytestring/internal.h @@ -54,8 +54,8 @@ OPENSSL_EXPORT int CBS_asn1_ber_to_der(CBS *in, CBS *out, // 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); + CBS_ASN1_TAG outer_tag, + CBS_ASN1_TAG 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| diff --git a/Sources/CNIOBoringSSL/crypto/chacha/chacha-armv4.ios.arm.S b/Sources/CNIOBoringSSL/crypto/chacha/chacha-armv4-ios.ios.arm.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/chacha/chacha-armv4.ios.arm.S rename to Sources/CNIOBoringSSL/crypto/chacha/chacha-armv4-ios.ios.arm.S index 15de9034..b2ed75ff 100644 --- a/Sources/CNIOBoringSSL/crypto/chacha/chacha-armv4.ios.arm.S +++ b/Sources/CNIOBoringSSL/crypto/chacha/chacha-armv4-ios.ios.arm.S @@ -10,7 +10,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1497,7 +1497,11 @@ OPENSSL_armcap_P: .indirect_symbol _OPENSSL_armcap_P .long 0 #endif -#endif // !OPENSSL_NO_ASM +#endif // !OPENSSL_NO_ASM && defined(__ARMEL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif #endif // defined(__arm__) && defined(__APPLE__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/chacha/chacha-armv4.linux.arm.S b/Sources/CNIOBoringSSL/crypto/chacha/chacha-armv4-linux.linux.arm.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/chacha/chacha-armv4.linux.arm.S rename to Sources/CNIOBoringSSL/crypto/chacha/chacha-armv4-linux.linux.arm.S index 824ca6b6..53225d80 100644 --- a/Sources/CNIOBoringSSL/crypto/chacha/chacha-armv4.linux.arm.S +++ b/Sources/CNIOBoringSSL/crypto/chacha/chacha-armv4-linux.linux.arm.S @@ -10,8 +10,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__arm__) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1490,9 +1489,11 @@ ChaCha20_neon: .size ChaCha20_neon,.-ChaCha20_neon .comm OPENSSL_armcap_P,4,4 #endif +#endif // !OPENSSL_NO_ASM && defined(__ARMEL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM -.section .note.GNU-stack,"",%progbits #endif // defined(__arm__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/chacha/chacha-armv8.ios.aarch64.S b/Sources/CNIOBoringSSL/crypto/chacha/chacha-armv8-ios.ios.aarch64.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/chacha/chacha-armv8.ios.aarch64.S rename to Sources/CNIOBoringSSL/crypto/chacha/chacha-armv8-ios.ios.aarch64.S index 22a2fae5..7c39368a 100644 --- a/Sources/CNIOBoringSSL/crypto/chacha/chacha-armv8.ios.aarch64.S +++ b/Sources/CNIOBoringSSL/crypto/chacha/chacha-armv8-ios.ios.aarch64.S @@ -10,7 +10,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1991,7 +1991,11 @@ Ldone_512_neon: AARCH64_VALIDATE_LINK_REGISTER ret -#endif // !OPENSSL_NO_ASM +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif #endif // defined(__aarch64__) && defined(__APPLE__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/chacha/chacha-armv8.linux.aarch64.S b/Sources/CNIOBoringSSL/crypto/chacha/chacha-armv8-linux.linux.aarch64.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/chacha/chacha-armv8.linux.aarch64.S rename to Sources/CNIOBoringSSL/crypto/chacha/chacha-armv8-linux.linux.aarch64.S index f6adadcc..32496d9b 100644 --- a/Sources/CNIOBoringSSL/crypto/chacha/chacha-armv8.linux.aarch64.S +++ b/Sources/CNIOBoringSSL/crypto/chacha/chacha-armv8-linux.linux.aarch64.S @@ -10,8 +10,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__aarch64__) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1992,9 +1991,11 @@ ChaCha20_512_neon: AARCH64_VALIDATE_LINK_REGISTER ret .size ChaCha20_512_neon,.-ChaCha20_512_neon +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM -.section .note.GNU-stack,"",%progbits #endif // defined(__aarch64__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/chacha/chacha-x86.linux.x86.S b/Sources/CNIOBoringSSL/crypto/chacha/chacha-x86-linux.linux.x86.S similarity index 98% rename from Sources/CNIOBoringSSL/crypto/chacha/chacha-x86.linux.x86.S rename to Sources/CNIOBoringSSL/crypto/chacha/chacha-x86-linux.linux.x86.S index 6f261878..e6fb60c8 100644 --- a/Sources/CNIOBoringSSL/crypto/chacha/chacha-x86.linux.x86.S +++ b/Sources/CNIOBoringSSL/crypto/chacha/chacha-x86-linux.linux.x86.S @@ -3,7 +3,13 @@ // This file is generated from a similarly-named Perl script in the BoringSSL // source tree. Do not edit by hand. -#if defined(__i386__) +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -973,8 +979,11 @@ ChaCha20_ssse3: .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 // !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -.section .note.GNU-stack,"",@progbits #endif // defined(__i386__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/chacha/chacha-x86_64.linux.x86_64.S b/Sources/CNIOBoringSSL/crypto/chacha/chacha-x86_64-linux.linux.x86_64.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/chacha/chacha-x86_64.linux.x86_64.S rename to Sources/CNIOBoringSSL/crypto/chacha/chacha-x86_64-linux.linux.x86_64.S index 2853c30b..a7cfc53a 100644 --- a/Sources/CNIOBoringSSL/crypto/chacha/chacha-x86_64.linux.x86_64.S +++ b/Sources/CNIOBoringSSL/crypto/chacha/chacha-x86_64-linux.linux.x86_64.S @@ -9,7 +9,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -18,6 +18,7 @@ .extern OPENSSL_ia32cap_P .hidden OPENSSL_ia32cap_P +.section .rodata .align 64 .Lzero: .long 0,0,0,0 @@ -47,6 +48,7 @@ .Lsixteen: .long 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16 .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 +.text .globl ChaCha20_ctr32 .hidden ChaCha20_ctr32 .type ChaCha20_ctr32,@function @@ -1632,7 +1634,10 @@ ChaCha20_8x: .cfi_endproc .size ChaCha20_8x,.-ChaCha20_8x #endif -.section .note.GNU-stack,"",@progbits +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif #endif // defined(__x86_64__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/chacha/chacha-x86_64.mac.x86_64.S b/Sources/CNIOBoringSSL/crypto/chacha/chacha-x86_64-mac.mac.x86_64.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/chacha/chacha-x86_64.mac.x86_64.S rename to Sources/CNIOBoringSSL/crypto/chacha/chacha-x86_64-mac.mac.x86_64.S index ad277500..1761c07a 100644 --- a/Sources/CNIOBoringSSL/crypto/chacha/chacha-x86_64.mac.x86_64.S +++ b/Sources/CNIOBoringSSL/crypto/chacha/chacha-x86_64-mac.mac.x86_64.S @@ -9,7 +9,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -17,6 +17,7 @@ +.section __DATA,__const .p2align 6 L$zero: .long 0,0,0,0 @@ -46,6 +47,7 @@ L$incz: L$sixteen: .long 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16 .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 +.text .globl _ChaCha20_ctr32 .private_extern _ChaCha20_ctr32 @@ -1624,6 +1626,10 @@ L$8x_epilogue: .byte 0xf3,0xc3 +#endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif #endif // defined(__x86_64__) && defined(__APPLE__) #if defined(__linux__) && defined(__ELF__) diff --git a/Sources/CNIOBoringSSL/crypto/cipher_extra/aes128gcmsiv-x86_64.linux.x86_64.S b/Sources/CNIOBoringSSL/crypto/cipher_extra/aes128gcmsiv-x86_64-linux.linux.x86_64.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/cipher_extra/aes128gcmsiv-x86_64.linux.x86_64.S rename to Sources/CNIOBoringSSL/crypto/cipher_extra/aes128gcmsiv-x86_64-linux.linux.x86_64.S index 37877d7a..111e3341 100644 --- a/Sources/CNIOBoringSSL/crypto/cipher_extra/aes128gcmsiv-x86_64.linux.x86_64.S +++ b/Sources/CNIOBoringSSL/crypto/cipher_extra/aes128gcmsiv-x86_64-linux.linux.x86_64.S @@ -9,11 +9,11 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif -.data +.section .rodata .align 16 one: @@ -3078,7 +3078,10 @@ aes256gcmsiv_kdf: .cfi_endproc .size aes256gcmsiv_kdf, .-aes256gcmsiv_kdf #endif -.section .note.GNU-stack,"",@progbits +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif #endif // defined(__x86_64__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/cipher_extra/aes128gcmsiv-x86_64.mac.x86_64.S b/Sources/CNIOBoringSSL/crypto/cipher_extra/aes128gcmsiv-x86_64-mac.mac.x86_64.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/cipher_extra/aes128gcmsiv-x86_64.mac.x86_64.S rename to Sources/CNIOBoringSSL/crypto/cipher_extra/aes128gcmsiv-x86_64-mac.mac.x86_64.S index f0000f5c..26452ae2 100644 --- a/Sources/CNIOBoringSSL/crypto/cipher_extra/aes128gcmsiv-x86_64.mac.x86_64.S +++ b/Sources/CNIOBoringSSL/crypto/cipher_extra/aes128gcmsiv-x86_64-mac.mac.x86_64.S @@ -9,11 +9,11 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif -.data +.section __DATA,__const .p2align 4 one: @@ -3067,6 +3067,10 @@ _aes256gcmsiv_kdf: .byte 0xf3,0xc3 +#endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif #endif // defined(__x86_64__) && defined(__APPLE__) #if defined(__linux__) && defined(__ELF__) diff --git a/Sources/CNIOBoringSSL/crypto/cipher_extra/chacha20_poly1305_armv8.ios.aarch64.S b/Sources/CNIOBoringSSL/crypto/cipher_extra/chacha20_poly1305_armv8-ios.ios.aarch64.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/cipher_extra/chacha20_poly1305_armv8.ios.aarch64.S rename to Sources/CNIOBoringSSL/crypto/cipher_extra/chacha20_poly1305_armv8-ios.ios.aarch64.S index 2147acd8..df7622a6 100644 --- a/Sources/CNIOBoringSSL/crypto/cipher_extra/chacha20_poly1305_armv8.ios.aarch64.S +++ b/Sources/CNIOBoringSSL/crypto/cipher_extra/chacha20_poly1305_armv8-ios.ios.aarch64.S @@ -10,7 +10,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -3016,7 +3016,11 @@ Lopen_128_hash_64: b Lopen_128_hash_64 .cfi_endproc -#endif // !OPENSSL_NO_ASM +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif #endif // defined(__aarch64__) && defined(__APPLE__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/cipher_extra/chacha20_poly1305_armv8.linux.aarch64.S b/Sources/CNIOBoringSSL/crypto/cipher_extra/chacha20_poly1305_armv8-linux.linux.aarch64.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/cipher_extra/chacha20_poly1305_armv8.linux.aarch64.S rename to Sources/CNIOBoringSSL/crypto/cipher_extra/chacha20_poly1305_armv8-linux.linux.aarch64.S index 19ec669b..05dc6cfc 100644 --- a/Sources/CNIOBoringSSL/crypto/cipher_extra/chacha20_poly1305_armv8.linux.aarch64.S +++ b/Sources/CNIOBoringSSL/crypto/cipher_extra/chacha20_poly1305_armv8-linux.linux.aarch64.S @@ -10,8 +10,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__aarch64__) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -3017,9 +3016,11 @@ chacha20_poly1305_open: b .Lopen_128_hash_64 .cfi_endproc .size chacha20_poly1305_open,.-chacha20_poly1305_open +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM -.section .note.GNU-stack,"",%progbits #endif // defined(__aarch64__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/cipher_extra/chacha20_poly1305_x86_64.linux.x86_64.S b/Sources/CNIOBoringSSL/crypto/cipher_extra/chacha20_poly1305_x86_64-linux.linux.x86_64.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/cipher_extra/chacha20_poly1305_x86_64.linux.x86_64.S rename to Sources/CNIOBoringSSL/crypto/cipher_extra/chacha20_poly1305_x86_64-linux.linux.x86_64.S index eae90202..509b69e4 100644 --- a/Sources/CNIOBoringSSL/crypto/cipher_extra/chacha20_poly1305_x86_64.linux.x86_64.S +++ b/Sources/CNIOBoringSSL/crypto/cipher_extra/chacha20_poly1305_x86_64-linux.linux.x86_64.S @@ -9,7 +9,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -19,6 +19,7 @@ chacha20_poly1305_constants: +.section .rodata .align 64 .Lchacha20_consts: .byte 'e','x','p','a','n','d',' ','3','2','-','b','y','t','e',' ','k' @@ -56,6 +57,7 @@ chacha20_poly1305_constants: .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00 .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00 .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +.text .type poly_hash_ad_internal,@function .align 64 @@ -8921,7 +8923,10 @@ chacha20_poly1305_seal_avx2: .cfi_endproc .size chacha20_poly1305_seal_avx2, .-chacha20_poly1305_seal_avx2 #endif -.section .note.GNU-stack,"",@progbits +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif #endif // defined(__x86_64__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/cipher_extra/chacha20_poly1305_x86_64.mac.x86_64.S b/Sources/CNIOBoringSSL/crypto/cipher_extra/chacha20_poly1305_x86_64-mac.mac.x86_64.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/cipher_extra/chacha20_poly1305_x86_64.mac.x86_64.S rename to Sources/CNIOBoringSSL/crypto/cipher_extra/chacha20_poly1305_x86_64-mac.mac.x86_64.S index e8b57901..db98cb77 100644 --- a/Sources/CNIOBoringSSL/crypto/cipher_extra/chacha20_poly1305_x86_64.mac.x86_64.S +++ b/Sources/CNIOBoringSSL/crypto/cipher_extra/chacha20_poly1305_x86_64-mac.mac.x86_64.S @@ -9,7 +9,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -18,6 +18,7 @@ chacha20_poly1305_constants: +.section __DATA,__const .p2align 6 L$chacha20_consts: .byte 'e','x','p','a','n','d',' ','3','2','-','b','y','t','e',' ','k' @@ -55,6 +56,7 @@ L$and_masks: .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00 .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00 .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +.text .p2align 6 @@ -8877,6 +8879,10 @@ L$seal_avx2_exit: jmp L$seal_sse_tail_16 +#endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif #endif // defined(__x86_64__) && defined(__APPLE__) #if defined(__linux__) && defined(__ELF__) diff --git a/Sources/CNIOBoringSSL/crypto/cipher_extra/e_chacha20poly1305.c b/Sources/CNIOBoringSSL/crypto/cipher_extra/e_chacha20poly1305.c index 463bb222..91723c9f 100644 --- a/Sources/CNIOBoringSSL/crypto/cipher_extra/e_chacha20poly1305.c +++ b/Sources/CNIOBoringSSL/crypto/cipher_extra/e_chacha20poly1305.c @@ -145,7 +145,7 @@ static int chacha20_poly1305_seal_scatter( // encrypted byte-by-byte first. if (extra_in_len) { static const size_t kChaChaBlockSize = 64; - uint32_t block_counter = 1 + (in_len / kChaChaBlockSize); + uint32_t block_counter = (uint32_t)(1 + (in_len / kChaChaBlockSize)); size_t offset = in_len % kChaChaBlockSize; uint8_t block[64 /* kChaChaBlockSize */]; diff --git a/Sources/CNIOBoringSSL/crypto/conf/conf.c b/Sources/CNIOBoringSSL/crypto/conf/conf.c index 01b5ac4b..301ba135 100644 --- a/Sources/CNIOBoringSSL/crypto/conf/conf.c +++ b/Sources/CNIOBoringSSL/crypto/conf/conf.c @@ -132,7 +132,6 @@ CONF *NCONF_new(void *method) { CONF_VALUE *CONF_VALUE_new(void) { CONF_VALUE *v = OPENSSL_malloc(sizeof(CONF_VALUE)); if (!v) { - OPENSSL_PUT_ERROR(CONF, ERR_R_MALLOC_FAILURE); return NULL; } OPENSSL_memset(v, 0, sizeof(CONF_VALUE)); @@ -340,7 +339,6 @@ static int str_copy(CONF *conf, char *section, char **pto, char *from) { goto err; } if (!BUF_MEM_grow_clean(buf, newsize)) { - OPENSSL_PUT_ERROR(CONF, ERR_R_MALLOC_FAILURE); goto err; } while (*p) { @@ -385,8 +383,9 @@ static CONF_VALUE *get_section(const CONF *conf, const char *section) { return lh_CONF_VALUE_retrieve(conf->data, &template); } -STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf, const char *section) { - CONF_VALUE *section_value = get_section(conf, section); +const STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf, + const char *section) { + const CONF_VALUE *section_value = get_section(conf, section); if (section_value == NULL) { return NULL; } @@ -551,7 +550,6 @@ static int def_load_bio(CONF *conf, BIO *in, long *out_error_line) { section = OPENSSL_strdup(kDefaultSectionName); if (section == NULL) { - OPENSSL_PUT_ERROR(CONF, ERR_R_MALLOC_FAILURE); goto err; } @@ -686,7 +684,6 @@ static int def_load_bio(CONF *conf, BIO *in, long *out_error_line) { } v->name = OPENSSL_strdup(pname); if (v->name == NULL) { - OPENSSL_PUT_ERROR(CONF, ERR_R_MALLOC_FAILURE); goto err; } if (!str_copy(conf, psection, &(v->value), start)) { @@ -705,7 +702,6 @@ static int def_load_bio(CONF *conf, BIO *in, long *out_error_line) { tv = sv; } if (add_string(conf, tv, v) == 0) { - OPENSSL_PUT_ERROR(CONF, ERR_R_MALLOC_FAILURE); goto err; } v = NULL; @@ -779,7 +775,7 @@ int CONF_parse_list(const char *list, char sep, int remove_whitespace, lstart = list; for (;;) { if (remove_whitespace) { - while (*lstart && isspace((unsigned char)*lstart)) { + while (*lstart && OPENSSL_isspace((unsigned char)*lstart)) { lstart++; } } @@ -793,7 +789,7 @@ int CONF_parse_list(const char *list, char sep, int remove_whitespace, tmpend = lstart + strlen(lstart) - 1; } if (remove_whitespace) { - while (isspace((unsigned char)*tmpend)) { + while (OPENSSL_isspace((unsigned char)*tmpend)) { tmpend--; } } diff --git a/Sources/CNIOBoringSSL/crypto/conf/conf_def.h b/Sources/CNIOBoringSSL/crypto/conf/conf_def.h index b1e6ba63..f01a79b2 100644 --- a/Sources/CNIOBoringSSL/crypto/conf/conf_def.h +++ b/Sources/CNIOBoringSSL/crypto/conf/conf_def.h @@ -1,4 +1,3 @@ -/* crypto/conf/conf_def.h */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * diff --git a/Sources/CNIOBoringSSL/crypto/cpu_arm_linux.c b/Sources/CNIOBoringSSL/crypto/cpu_arm_linux.c index 5cf66d9f..45516a72 100644 --- a/Sources/CNIOBoringSSL/crypto/cpu_arm_linux.c +++ b/Sources/CNIOBoringSSL/crypto/cpu_arm_linux.c @@ -18,6 +18,7 @@ !defined(OPENSSL_STATIC_ARMCAP) #include #include +#include #include #include @@ -26,13 +27,6 @@ #include "cpu_arm_linux.h" -#define AT_HWCAP 16 -#define AT_HWCAP2 26 - -// |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 { @@ -49,21 +43,6 @@ static ssize_t read_eintr(int fd, void *out, size_t len) { 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. @@ -116,41 +95,14 @@ static int read_file(char **out_ptr, size_t *out_len, const char *path) { 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; -} - extern uint32_t OPENSSL_armcap_P; -static int g_has_broken_neon, g_needs_hwcap2_workaround; +static int g_needs_hwcap2_workaround; void OPENSSL_cpuid_setup(void) { // We ignore the return value of |read_file| and proceed with an empty // /proc/cpuinfo on error. If |getauxval| works, we will still detect - // capabilities. There may be a false positive due to - // |crypto_cpuinfo_has_broken_neon|, but this is now rare. + // capabilities. char *cpuinfo_data = NULL; size_t cpuinfo_len = 0; read_file(&cpuinfo_data, &cpuinfo_len, "/proc/cpuinfo"); @@ -158,37 +110,8 @@ void OPENSSL_cpuid_setup(void) { 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 = crypto_get_arm_hwcap_from_cpuinfo(&cpuinfo); - } - - // Clear NEON support if known broken. Note, if NEON is available statically, - // the non-NEON code is dropped and this workaround is a no-op. - // - // TODO(davidben): The Android NDK now builds with NEON statically available - // by default. Cronet still has some consumers that support NEON-less devices - // (b/150371744). Get metrics on whether they still see this CPU and, if not, - // remove this check entirely. - g_has_broken_neon = crypto_cpuinfo_has_broken_neon(&cpuinfo); - if (g_has_broken_neon) { - hwcap &= ~HWCAP_NEON; - } - // Matching OpenSSL, only report other features if NEON is present. + unsigned long hwcap = getauxval(AT_HWCAP); if (hwcap & HWCAP_NEON) { OPENSSL_armcap_P |= ARMV7_NEON; @@ -197,10 +120,7 @@ void OPENSSL_cpuid_setup(void) { // this is now rare (see Chrome's Net.NeedsHWCAP2Workaround metric), but AES // and PMULL extensions are very useful, so we still carry the workaround // for now. - unsigned long hwcap2 = 0; - if (getauxval != NULL) { - hwcap2 = getauxval(AT_HWCAP2); - } + unsigned long hwcap2 = getauxval(AT_HWCAP2); if (hwcap2 == 0) { hwcap2 = crypto_get_arm_hwcap2_from_cpuinfo(&cpuinfo); g_needs_hwcap2_workaround = hwcap2 != 0; @@ -223,7 +143,7 @@ void OPENSSL_cpuid_setup(void) { OPENSSL_free(cpuinfo_data); } -int CRYPTO_has_broken_NEON(void) { return g_has_broken_neon; } +int CRYPTO_has_broken_NEON(void) { return 0; } int CRYPTO_needs_hwcap2_workaround(void) { return g_needs_hwcap2_workaround; } diff --git a/Sources/CNIOBoringSSL/crypto/cpu_arm_linux.h b/Sources/CNIOBoringSSL/crypto/cpu_arm_linux.h index 35e3e9ec..5ea5f1e9 100644 --- a/Sources/CNIOBoringSSL/crypto/cpu_arm_linux.h +++ b/Sources/CNIOBoringSSL/crypto/cpu_arm_linux.h @@ -118,13 +118,6 @@ static int extract_cpuinfo_field(STRING_PIECE *out, const STRING_PIECE *in, 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) { @@ -137,27 +130,6 @@ static int has_list_item(const STRING_PIECE *list, const char *item) { return 0; } -// crypto_get_arm_hwcap_from_cpuinfo returns an equivalent ARM |AT_HWCAP| value -// from |cpuinfo|. -static unsigned long crypto_get_arm_hwcap_from_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; -} - // crypto_get_arm_hwcap2_from_cpuinfo returns an equivalent ARM |AT_HWCAP2| // value from |cpuinfo|. static unsigned long crypto_get_arm_hwcap2_from_cpuinfo( @@ -183,16 +155,6 @@ static unsigned long crypto_get_arm_hwcap2_from_cpuinfo( return ret; } -// crypto_cpuinfo_has_broken_neon returns one if |cpuinfo| matches a CPU known -// to have broken NEON unit and zero otherwise. See https://crbug.com/341598. -static int crypto_cpuinfo_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"); -} - #if defined(__cplusplus) } // extern C diff --git a/Sources/CNIOBoringSSL/crypto/cpu_ppc64le.c b/Sources/CNIOBoringSSL/crypto/cpu_ppc64le.c deleted file mode 100644 index 11a1fce4..00000000 --- a/Sources/CNIOBoringSSL/crypto/cpu_ppc64le.c +++ /dev/null @@ -1,38 +0,0 @@ -/* 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 - -#if defined(OPENSSL_PPC64LE) - -#include - -#include "internal.h" - - -#if !defined(PPC_FEATURE2_HAS_VCRYPTO) -// PPC_FEATURE2_HAS_VCRYPTO was taken from section 4.1.2.3 of the “OpenPOWER -// ABI for Linux Supplement”. -#define PPC_FEATURE2_HAS_VCRYPTO 0x02000000 -#endif - -void OPENSSL_cpuid_setup(void) { - OPENSSL_ppc64le_hwcap2 = getauxval(AT_HWCAP2); -} - -int CRYPTO_is_PPC64LE_vcrypto_capable(void) { - return (OPENSSL_ppc64le_hwcap2 & PPC_FEATURE2_HAS_VCRYPTO) != 0; -} - -#endif // OPENSSL_PPC64LE diff --git a/Sources/CNIOBoringSSL/crypto/crypto.c b/Sources/CNIOBoringSSL/crypto/crypto.c index 1b417f7a..272871a8 100644 --- a/Sources/CNIOBoringSSL/crypto/crypto.c +++ b/Sources/CNIOBoringSSL/crypto/crypto.c @@ -14,18 +14,21 @@ #include +#include + #include "fipsmodule/rand/fork_detect.h" #include "fipsmodule/rand/internal.h" #include "internal.h" +static_assert(sizeof(ossl_ssize_t) == sizeof(size_t), + "ossl_ssize_t should be the same size as size_t"); + #if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_STATIC_ARMCAP) && \ - (defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \ - defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64) || \ - defined(OPENSSL_PPC64LE)) -// x86, x86_64, the ARMs and ppc64le need to record the result of a -// cpuid/getauxval call for the asm to work correctly, unless compiled without -// asm code. + (defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \ + defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) +// x86, x86_64, and the ARMs need to record the result of a cpuid/getauxval call +// for the asm to work correctly, unless compiled without asm code. #define NEED_CPUID #else @@ -36,8 +39,7 @@ #define BORINGSSL_NO_STATIC_INITIALIZER #endif -#endif // !NO_ASM && !STATIC_ARMCAP && - // (X86 || X86_64 || ARM || AARCH64 || PPC64LE) +#endif // !NO_ASM && !STATIC_ARMCAP && (X86 || X86_64 || ARM || AARCH64) // Our assembly does not use the GOT to reference symbols, which means @@ -76,10 +78,6 @@ HIDDEN uint8_t BORINGSSL_function_hit[7] = {0}; // This value must be explicitly initialized to zero. See similar comment above. HIDDEN uint32_t OPENSSL_ia32cap_P[4] = {0}; -#elif defined(OPENSSL_PPC64LE) - -HIDDEN unsigned long OPENSSL_ppc64le_hwcap2 = 0; - #elif defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64) #include diff --git a/Sources/CNIOBoringSSL/crypto/curve25519/asm/x25519-asm-arm.S b/Sources/CNIOBoringSSL/crypto/curve25519/asm/x25519-asm-arm.S index 9e2c1ccd..874f0ffb 100644 --- a/Sources/CNIOBoringSSL/crypto/curve25519/asm/x25519-asm-arm.S +++ b/Sources/CNIOBoringSSL/crypto/curve25519/asm/x25519-asm-arm.S @@ -25,7 +25,7 @@ #endif #endif -#if !defined(OPENSSL_NO_ASM) && defined(__arm__) && !defined(__APPLE__) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include @@ -2131,7 +2131,7 @@ mov sp,r12 vpop {q4,q5,q6,q7} bx lr -#endif /* !OPENSSL_NO_ASM && __arm__ && !__APPLE__ */ +#endif /* !OPENSSL_NO_ASM && __ARMEL__ && __ELF__ */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/curve25519/curve25519.c b/Sources/CNIOBoringSSL/crypto/curve25519/curve25519.c index b3e8bad8..6dafd897 100644 --- a/Sources/CNIOBoringSSL/crypto/curve25519/curve25519.c +++ b/Sources/CNIOBoringSSL/crypto/curve25519/curve25519.c @@ -35,10 +35,6 @@ // Various pre-computed constants. #include "./curve25519_tables.h" -#if defined(OPENSSL_NO_ASM) -#define FIAT_25519_NO_ASM -#endif - #if defined(BORINGSSL_CURVE25519_64BIT) #include "../../third_party/fiat/curve25519_64.h" #else diff --git a/Sources/CNIOBoringSSL/crypto/des/des.c b/Sources/CNIOBoringSSL/crypto/des/des.c index f193a150..748d96dc 100644 --- a/Sources/CNIOBoringSSL/crypto/des/des.c +++ b/Sources/CNIOBoringSSL/crypto/des/des.c @@ -63,231 +63,231 @@ static const uint32_t des_skb[8][64] = { { // for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 - 0x00000000L, 0x00000010L, 0x20000000L, 0x20000010L, 0x00010000L, - 0x00010010L, 0x20010000L, 0x20010010L, 0x00000800L, 0x00000810L, - 0x20000800L, 0x20000810L, 0x00010800L, 0x00010810L, 0x20010800L, - 0x20010810L, 0x00000020L, 0x00000030L, 0x20000020L, 0x20000030L, - 0x00010020L, 0x00010030L, 0x20010020L, 0x20010030L, 0x00000820L, - 0x00000830L, 0x20000820L, 0x20000830L, 0x00010820L, 0x00010830L, - 0x20010820L, 0x20010830L, 0x00080000L, 0x00080010L, 0x20080000L, - 0x20080010L, 0x00090000L, 0x00090010L, 0x20090000L, 0x20090010L, - 0x00080800L, 0x00080810L, 0x20080800L, 0x20080810L, 0x00090800L, - 0x00090810L, 0x20090800L, 0x20090810L, 0x00080020L, 0x00080030L, - 0x20080020L, 0x20080030L, 0x00090020L, 0x00090030L, 0x20090020L, - 0x20090030L, 0x00080820L, 0x00080830L, 0x20080820L, 0x20080830L, - 0x00090820L, 0x00090830L, 0x20090820L, 0x20090830L, }, + 0x00000000, 0x00000010, 0x20000000, 0x20000010, 0x00010000, + 0x00010010, 0x20010000, 0x20010010, 0x00000800, 0x00000810, + 0x20000800, 0x20000810, 0x00010800, 0x00010810, 0x20010800, + 0x20010810, 0x00000020, 0x00000030, 0x20000020, 0x20000030, + 0x00010020, 0x00010030, 0x20010020, 0x20010030, 0x00000820, + 0x00000830, 0x20000820, 0x20000830, 0x00010820, 0x00010830, + 0x20010820, 0x20010830, 0x00080000, 0x00080010, 0x20080000, + 0x20080010, 0x00090000, 0x00090010, 0x20090000, 0x20090010, + 0x00080800, 0x00080810, 0x20080800, 0x20080810, 0x00090800, + 0x00090810, 0x20090800, 0x20090810, 0x00080020, 0x00080030, + 0x20080020, 0x20080030, 0x00090020, 0x00090030, 0x20090020, + 0x20090030, 0x00080820, 0x00080830, 0x20080820, 0x20080830, + 0x00090820, 0x00090830, 0x20090820, 0x20090830, }, { // for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 - 0x00000000L, 0x02000000L, 0x00002000L, 0x02002000L, 0x00200000L, - 0x02200000L, 0x00202000L, 0x02202000L, 0x00000004L, 0x02000004L, - 0x00002004L, 0x02002004L, 0x00200004L, 0x02200004L, 0x00202004L, - 0x02202004L, 0x00000400L, 0x02000400L, 0x00002400L, 0x02002400L, - 0x00200400L, 0x02200400L, 0x00202400L, 0x02202400L, 0x00000404L, - 0x02000404L, 0x00002404L, 0x02002404L, 0x00200404L, 0x02200404L, - 0x00202404L, 0x02202404L, 0x10000000L, 0x12000000L, 0x10002000L, - 0x12002000L, 0x10200000L, 0x12200000L, 0x10202000L, 0x12202000L, - 0x10000004L, 0x12000004L, 0x10002004L, 0x12002004L, 0x10200004L, - 0x12200004L, 0x10202004L, 0x12202004L, 0x10000400L, 0x12000400L, - 0x10002400L, 0x12002400L, 0x10200400L, 0x12200400L, 0x10202400L, - 0x12202400L, 0x10000404L, 0x12000404L, 0x10002404L, 0x12002404L, - 0x10200404L, 0x12200404L, 0x10202404L, 0x12202404L, }, + 0x00000000, 0x02000000, 0x00002000, 0x02002000, 0x00200000, + 0x02200000, 0x00202000, 0x02202000, 0x00000004, 0x02000004, + 0x00002004, 0x02002004, 0x00200004, 0x02200004, 0x00202004, + 0x02202004, 0x00000400, 0x02000400, 0x00002400, 0x02002400, + 0x00200400, 0x02200400, 0x00202400, 0x02202400, 0x00000404, + 0x02000404, 0x00002404, 0x02002404, 0x00200404, 0x02200404, + 0x00202404, 0x02202404, 0x10000000, 0x12000000, 0x10002000, + 0x12002000, 0x10200000, 0x12200000, 0x10202000, 0x12202000, + 0x10000004, 0x12000004, 0x10002004, 0x12002004, 0x10200004, + 0x12200004, 0x10202004, 0x12202004, 0x10000400, 0x12000400, + 0x10002400, 0x12002400, 0x10200400, 0x12200400, 0x10202400, + 0x12202400, 0x10000404, 0x12000404, 0x10002404, 0x12002404, + 0x10200404, 0x12200404, 0x10202404, 0x12202404, }, { // for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 - 0x00000000L, 0x00000001L, 0x00040000L, 0x00040001L, 0x01000000L, - 0x01000001L, 0x01040000L, 0x01040001L, 0x00000002L, 0x00000003L, - 0x00040002L, 0x00040003L, 0x01000002L, 0x01000003L, 0x01040002L, - 0x01040003L, 0x00000200L, 0x00000201L, 0x00040200L, 0x00040201L, - 0x01000200L, 0x01000201L, 0x01040200L, 0x01040201L, 0x00000202L, - 0x00000203L, 0x00040202L, 0x00040203L, 0x01000202L, 0x01000203L, - 0x01040202L, 0x01040203L, 0x08000000L, 0x08000001L, 0x08040000L, - 0x08040001L, 0x09000000L, 0x09000001L, 0x09040000L, 0x09040001L, - 0x08000002L, 0x08000003L, 0x08040002L, 0x08040003L, 0x09000002L, - 0x09000003L, 0x09040002L, 0x09040003L, 0x08000200L, 0x08000201L, - 0x08040200L, 0x08040201L, 0x09000200L, 0x09000201L, 0x09040200L, - 0x09040201L, 0x08000202L, 0x08000203L, 0x08040202L, 0x08040203L, - 0x09000202L, 0x09000203L, 0x09040202L, 0x09040203L, }, + 0x00000000, 0x00000001, 0x00040000, 0x00040001, 0x01000000, + 0x01000001, 0x01040000, 0x01040001, 0x00000002, 0x00000003, + 0x00040002, 0x00040003, 0x01000002, 0x01000003, 0x01040002, + 0x01040003, 0x00000200, 0x00000201, 0x00040200, 0x00040201, + 0x01000200, 0x01000201, 0x01040200, 0x01040201, 0x00000202, + 0x00000203, 0x00040202, 0x00040203, 0x01000202, 0x01000203, + 0x01040202, 0x01040203, 0x08000000, 0x08000001, 0x08040000, + 0x08040001, 0x09000000, 0x09000001, 0x09040000, 0x09040001, + 0x08000002, 0x08000003, 0x08040002, 0x08040003, 0x09000002, + 0x09000003, 0x09040002, 0x09040003, 0x08000200, 0x08000201, + 0x08040200, 0x08040201, 0x09000200, 0x09000201, 0x09040200, + 0x09040201, 0x08000202, 0x08000203, 0x08040202, 0x08040203, + 0x09000202, 0x09000203, 0x09040202, 0x09040203, }, { // for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 - 0x00000000L, 0x00100000L, 0x00000100L, 0x00100100L, 0x00000008L, - 0x00100008L, 0x00000108L, 0x00100108L, 0x00001000L, 0x00101000L, - 0x00001100L, 0x00101100L, 0x00001008L, 0x00101008L, 0x00001108L, - 0x00101108L, 0x04000000L, 0x04100000L, 0x04000100L, 0x04100100L, - 0x04000008L, 0x04100008L, 0x04000108L, 0x04100108L, 0x04001000L, - 0x04101000L, 0x04001100L, 0x04101100L, 0x04001008L, 0x04101008L, - 0x04001108L, 0x04101108L, 0x00020000L, 0x00120000L, 0x00020100L, - 0x00120100L, 0x00020008L, 0x00120008L, 0x00020108L, 0x00120108L, - 0x00021000L, 0x00121000L, 0x00021100L, 0x00121100L, 0x00021008L, - 0x00121008L, 0x00021108L, 0x00121108L, 0x04020000L, 0x04120000L, - 0x04020100L, 0x04120100L, 0x04020008L, 0x04120008L, 0x04020108L, - 0x04120108L, 0x04021000L, 0x04121000L, 0x04021100L, 0x04121100L, - 0x04021008L, 0x04121008L, 0x04021108L, 0x04121108L, }, + 0x00000000, 0x00100000, 0x00000100, 0x00100100, 0x00000008, + 0x00100008, 0x00000108, 0x00100108, 0x00001000, 0x00101000, + 0x00001100, 0x00101100, 0x00001008, 0x00101008, 0x00001108, + 0x00101108, 0x04000000, 0x04100000, 0x04000100, 0x04100100, + 0x04000008, 0x04100008, 0x04000108, 0x04100108, 0x04001000, + 0x04101000, 0x04001100, 0x04101100, 0x04001008, 0x04101008, + 0x04001108, 0x04101108, 0x00020000, 0x00120000, 0x00020100, + 0x00120100, 0x00020008, 0x00120008, 0x00020108, 0x00120108, + 0x00021000, 0x00121000, 0x00021100, 0x00121100, 0x00021008, + 0x00121008, 0x00021108, 0x00121108, 0x04020000, 0x04120000, + 0x04020100, 0x04120100, 0x04020008, 0x04120008, 0x04020108, + 0x04120108, 0x04021000, 0x04121000, 0x04021100, 0x04121100, + 0x04021008, 0x04121008, 0x04021108, 0x04121108, }, { // for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 - 0x00000000L, 0x10000000L, 0x00010000L, 0x10010000L, 0x00000004L, - 0x10000004L, 0x00010004L, 0x10010004L, 0x20000000L, 0x30000000L, - 0x20010000L, 0x30010000L, 0x20000004L, 0x30000004L, 0x20010004L, - 0x30010004L, 0x00100000L, 0x10100000L, 0x00110000L, 0x10110000L, - 0x00100004L, 0x10100004L, 0x00110004L, 0x10110004L, 0x20100000L, - 0x30100000L, 0x20110000L, 0x30110000L, 0x20100004L, 0x30100004L, - 0x20110004L, 0x30110004L, 0x00001000L, 0x10001000L, 0x00011000L, - 0x10011000L, 0x00001004L, 0x10001004L, 0x00011004L, 0x10011004L, - 0x20001000L, 0x30001000L, 0x20011000L, 0x30011000L, 0x20001004L, - 0x30001004L, 0x20011004L, 0x30011004L, 0x00101000L, 0x10101000L, - 0x00111000L, 0x10111000L, 0x00101004L, 0x10101004L, 0x00111004L, - 0x10111004L, 0x20101000L, 0x30101000L, 0x20111000L, 0x30111000L, - 0x20101004L, 0x30101004L, 0x20111004L, 0x30111004L, }, + 0x00000000, 0x10000000, 0x00010000, 0x10010000, 0x00000004, + 0x10000004, 0x00010004, 0x10010004, 0x20000000, 0x30000000, + 0x20010000, 0x30010000, 0x20000004, 0x30000004, 0x20010004, + 0x30010004, 0x00100000, 0x10100000, 0x00110000, 0x10110000, + 0x00100004, 0x10100004, 0x00110004, 0x10110004, 0x20100000, + 0x30100000, 0x20110000, 0x30110000, 0x20100004, 0x30100004, + 0x20110004, 0x30110004, 0x00001000, 0x10001000, 0x00011000, + 0x10011000, 0x00001004, 0x10001004, 0x00011004, 0x10011004, + 0x20001000, 0x30001000, 0x20011000, 0x30011000, 0x20001004, + 0x30001004, 0x20011004, 0x30011004, 0x00101000, 0x10101000, + 0x00111000, 0x10111000, 0x00101004, 0x10101004, 0x00111004, + 0x10111004, 0x20101000, 0x30101000, 0x20111000, 0x30111000, + 0x20101004, 0x30101004, 0x20111004, 0x30111004, }, { // for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 - 0x00000000L, 0x08000000L, 0x00000008L, 0x08000008L, 0x00000400L, - 0x08000400L, 0x00000408L, 0x08000408L, 0x00020000L, 0x08020000L, - 0x00020008L, 0x08020008L, 0x00020400L, 0x08020400L, 0x00020408L, - 0x08020408L, 0x00000001L, 0x08000001L, 0x00000009L, 0x08000009L, - 0x00000401L, 0x08000401L, 0x00000409L, 0x08000409L, 0x00020001L, - 0x08020001L, 0x00020009L, 0x08020009L, 0x00020401L, 0x08020401L, - 0x00020409L, 0x08020409L, 0x02000000L, 0x0A000000L, 0x02000008L, - 0x0A000008L, 0x02000400L, 0x0A000400L, 0x02000408L, 0x0A000408L, - 0x02020000L, 0x0A020000L, 0x02020008L, 0x0A020008L, 0x02020400L, - 0x0A020400L, 0x02020408L, 0x0A020408L, 0x02000001L, 0x0A000001L, - 0x02000009L, 0x0A000009L, 0x02000401L, 0x0A000401L, 0x02000409L, - 0x0A000409L, 0x02020001L, 0x0A020001L, 0x02020009L, 0x0A020009L, - 0x02020401L, 0x0A020401L, 0x02020409L, 0x0A020409L, }, + 0x00000000, 0x08000000, 0x00000008, 0x08000008, 0x00000400, + 0x08000400, 0x00000408, 0x08000408, 0x00020000, 0x08020000, + 0x00020008, 0x08020008, 0x00020400, 0x08020400, 0x00020408, + 0x08020408, 0x00000001, 0x08000001, 0x00000009, 0x08000009, + 0x00000401, 0x08000401, 0x00000409, 0x08000409, 0x00020001, + 0x08020001, 0x00020009, 0x08020009, 0x00020401, 0x08020401, + 0x00020409, 0x08020409, 0x02000000, 0x0A000000, 0x02000008, + 0x0A000008, 0x02000400, 0x0A000400, 0x02000408, 0x0A000408, + 0x02020000, 0x0A020000, 0x02020008, 0x0A020008, 0x02020400, + 0x0A020400, 0x02020408, 0x0A020408, 0x02000001, 0x0A000001, + 0x02000009, 0x0A000009, 0x02000401, 0x0A000401, 0x02000409, + 0x0A000409, 0x02020001, 0x0A020001, 0x02020009, 0x0A020009, + 0x02020401, 0x0A020401, 0x02020409, 0x0A020409, }, { // for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 - 0x00000000L, 0x00000100L, 0x00080000L, 0x00080100L, 0x01000000L, - 0x01000100L, 0x01080000L, 0x01080100L, 0x00000010L, 0x00000110L, - 0x00080010L, 0x00080110L, 0x01000010L, 0x01000110L, 0x01080010L, - 0x01080110L, 0x00200000L, 0x00200100L, 0x00280000L, 0x00280100L, - 0x01200000L, 0x01200100L, 0x01280000L, 0x01280100L, 0x00200010L, - 0x00200110L, 0x00280010L, 0x00280110L, 0x01200010L, 0x01200110L, - 0x01280010L, 0x01280110L, 0x00000200L, 0x00000300L, 0x00080200L, - 0x00080300L, 0x01000200L, 0x01000300L, 0x01080200L, 0x01080300L, - 0x00000210L, 0x00000310L, 0x00080210L, 0x00080310L, 0x01000210L, - 0x01000310L, 0x01080210L, 0x01080310L, 0x00200200L, 0x00200300L, - 0x00280200L, 0x00280300L, 0x01200200L, 0x01200300L, 0x01280200L, - 0x01280300L, 0x00200210L, 0x00200310L, 0x00280210L, 0x00280310L, - 0x01200210L, 0x01200310L, 0x01280210L, 0x01280310L, }, + 0x00000000, 0x00000100, 0x00080000, 0x00080100, 0x01000000, + 0x01000100, 0x01080000, 0x01080100, 0x00000010, 0x00000110, + 0x00080010, 0x00080110, 0x01000010, 0x01000110, 0x01080010, + 0x01080110, 0x00200000, 0x00200100, 0x00280000, 0x00280100, + 0x01200000, 0x01200100, 0x01280000, 0x01280100, 0x00200010, + 0x00200110, 0x00280010, 0x00280110, 0x01200010, 0x01200110, + 0x01280010, 0x01280110, 0x00000200, 0x00000300, 0x00080200, + 0x00080300, 0x01000200, 0x01000300, 0x01080200, 0x01080300, + 0x00000210, 0x00000310, 0x00080210, 0x00080310, 0x01000210, + 0x01000310, 0x01080210, 0x01080310, 0x00200200, 0x00200300, + 0x00280200, 0x00280300, 0x01200200, 0x01200300, 0x01280200, + 0x01280300, 0x00200210, 0x00200310, 0x00280210, 0x00280310, + 0x01200210, 0x01200310, 0x01280210, 0x01280310, }, { // for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 - 0x00000000L, 0x04000000L, 0x00040000L, 0x04040000L, 0x00000002L, - 0x04000002L, 0x00040002L, 0x04040002L, 0x00002000L, 0x04002000L, - 0x00042000L, 0x04042000L, 0x00002002L, 0x04002002L, 0x00042002L, - 0x04042002L, 0x00000020L, 0x04000020L, 0x00040020L, 0x04040020L, - 0x00000022L, 0x04000022L, 0x00040022L, 0x04040022L, 0x00002020L, - 0x04002020L, 0x00042020L, 0x04042020L, 0x00002022L, 0x04002022L, - 0x00042022L, 0x04042022L, 0x00000800L, 0x04000800L, 0x00040800L, - 0x04040800L, 0x00000802L, 0x04000802L, 0x00040802L, 0x04040802L, - 0x00002800L, 0x04002800L, 0x00042800L, 0x04042800L, 0x00002802L, - 0x04002802L, 0x00042802L, 0x04042802L, 0x00000820L, 0x04000820L, - 0x00040820L, 0x04040820L, 0x00000822L, 0x04000822L, 0x00040822L, - 0x04040822L, 0x00002820L, 0x04002820L, 0x00042820L, 0x04042820L, - 0x00002822L, 0x04002822L, 0x00042822L, 0x04042822L, }}; + 0x00000000, 0x04000000, 0x00040000, 0x04040000, 0x00000002, + 0x04000002, 0x00040002, 0x04040002, 0x00002000, 0x04002000, + 0x00042000, 0x04042000, 0x00002002, 0x04002002, 0x00042002, + 0x04042002, 0x00000020, 0x04000020, 0x00040020, 0x04040020, + 0x00000022, 0x04000022, 0x00040022, 0x04040022, 0x00002020, + 0x04002020, 0x00042020, 0x04042020, 0x00002022, 0x04002022, + 0x00042022, 0x04042022, 0x00000800, 0x04000800, 0x00040800, + 0x04040800, 0x00000802, 0x04000802, 0x00040802, 0x04040802, + 0x00002800, 0x04002800, 0x00042800, 0x04042800, 0x00002802, + 0x04002802, 0x00042802, 0x04042802, 0x00000820, 0x04000820, + 0x00040820, 0x04040820, 0x00000822, 0x04000822, 0x00040822, + 0x04040822, 0x00002820, 0x04002820, 0x00042820, 0x04042820, + 0x00002822, 0x04002822, 0x00042822, 0x04042822, }}; static const uint32_t DES_SPtrans[8][64] = { { // nibble 0 - 0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L, 0x02000000L, - 0x00080802L, 0x00080002L, 0x02000002L, 0x00080802L, 0x02080800L, - 0x02080000L, 0x00000802L, 0x02000802L, 0x02000000L, 0x00000000L, - 0x00080002L, 0x00080000L, 0x00000002L, 0x02000800L, 0x00080800L, - 0x02080802L, 0x02080000L, 0x00000802L, 0x02000800L, 0x00000002L, - 0x00000800L, 0x00080800L, 0x02080002L, 0x00000800L, 0x02000802L, - 0x02080002L, 0x00000000L, 0x00000000L, 0x02080802L, 0x02000800L, - 0x00080002L, 0x02080800L, 0x00080000L, 0x00000802L, 0x02000800L, - 0x02080002L, 0x00000800L, 0x00080800L, 0x02000002L, 0x00080802L, - 0x00000002L, 0x02000002L, 0x02080000L, 0x02080802L, 0x00080800L, - 0x02080000L, 0x02000802L, 0x02000000L, 0x00000802L, 0x00080002L, - 0x00000000L, 0x00080000L, 0x02000000L, 0x02000802L, 0x02080800L, - 0x00000002L, 0x02080002L, 0x00000800L, 0x00080802L, }, + 0x02080800, 0x00080000, 0x02000002, 0x02080802, 0x02000000, + 0x00080802, 0x00080002, 0x02000002, 0x00080802, 0x02080800, + 0x02080000, 0x00000802, 0x02000802, 0x02000000, 0x00000000, + 0x00080002, 0x00080000, 0x00000002, 0x02000800, 0x00080800, + 0x02080802, 0x02080000, 0x00000802, 0x02000800, 0x00000002, + 0x00000800, 0x00080800, 0x02080002, 0x00000800, 0x02000802, + 0x02080002, 0x00000000, 0x00000000, 0x02080802, 0x02000800, + 0x00080002, 0x02080800, 0x00080000, 0x00000802, 0x02000800, + 0x02080002, 0x00000800, 0x00080800, 0x02000002, 0x00080802, + 0x00000002, 0x02000002, 0x02080000, 0x02080802, 0x00080800, + 0x02080000, 0x02000802, 0x02000000, 0x00000802, 0x00080002, + 0x00000000, 0x00080000, 0x02000000, 0x02000802, 0x02080800, + 0x00000002, 0x02080002, 0x00000800, 0x00080802, }, { // nibble 1 - 0x40108010L, 0x00000000L, 0x00108000L, 0x40100000L, 0x40000010L, - 0x00008010L, 0x40008000L, 0x00108000L, 0x00008000L, 0x40100010L, - 0x00000010L, 0x40008000L, 0x00100010L, 0x40108000L, 0x40100000L, - 0x00000010L, 0x00100000L, 0x40008010L, 0x40100010L, 0x00008000L, - 0x00108010L, 0x40000000L, 0x00000000L, 0x00100010L, 0x40008010L, - 0x00108010L, 0x40108000L, 0x40000010L, 0x40000000L, 0x00100000L, - 0x00008010L, 0x40108010L, 0x00100010L, 0x40108000L, 0x40008000L, - 0x00108010L, 0x40108010L, 0x00100010L, 0x40000010L, 0x00000000L, - 0x40000000L, 0x00008010L, 0x00100000L, 0x40100010L, 0x00008000L, - 0x40000000L, 0x00108010L, 0x40008010L, 0x40108000L, 0x00008000L, - 0x00000000L, 0x40000010L, 0x00000010L, 0x40108010L, 0x00108000L, - 0x40100000L, 0x40100010L, 0x00100000L, 0x00008010L, 0x40008000L, - 0x40008010L, 0x00000010L, 0x40100000L, 0x00108000L, }, + 0x40108010, 0x00000000, 0x00108000, 0x40100000, 0x40000010, + 0x00008010, 0x40008000, 0x00108000, 0x00008000, 0x40100010, + 0x00000010, 0x40008000, 0x00100010, 0x40108000, 0x40100000, + 0x00000010, 0x00100000, 0x40008010, 0x40100010, 0x00008000, + 0x00108010, 0x40000000, 0x00000000, 0x00100010, 0x40008010, + 0x00108010, 0x40108000, 0x40000010, 0x40000000, 0x00100000, + 0x00008010, 0x40108010, 0x00100010, 0x40108000, 0x40008000, + 0x00108010, 0x40108010, 0x00100010, 0x40000010, 0x00000000, + 0x40000000, 0x00008010, 0x00100000, 0x40100010, 0x00008000, + 0x40000000, 0x00108010, 0x40008010, 0x40108000, 0x00008000, + 0x00000000, 0x40000010, 0x00000010, 0x40108010, 0x00108000, + 0x40100000, 0x40100010, 0x00100000, 0x00008010, 0x40008000, + 0x40008010, 0x00000010, 0x40100000, 0x00108000, }, { // nibble 2 - 0x04000001L, 0x04040100L, 0x00000100L, 0x04000101L, 0x00040001L, - 0x04000000L, 0x04000101L, 0x00040100L, 0x04000100L, 0x00040000L, - 0x04040000L, 0x00000001L, 0x04040101L, 0x00000101L, 0x00000001L, - 0x04040001L, 0x00000000L, 0x00040001L, 0x04040100L, 0x00000100L, - 0x00000101L, 0x04040101L, 0x00040000L, 0x04000001L, 0x04040001L, - 0x04000100L, 0x00040101L, 0x04040000L, 0x00040100L, 0x00000000L, - 0x04000000L, 0x00040101L, 0x04040100L, 0x00000100L, 0x00000001L, - 0x00040000L, 0x00000101L, 0x00040001L, 0x04040000L, 0x04000101L, - 0x00000000L, 0x04040100L, 0x00040100L, 0x04040001L, 0x00040001L, - 0x04000000L, 0x04040101L, 0x00000001L, 0x00040101L, 0x04000001L, - 0x04000000L, 0x04040101L, 0x00040000L, 0x04000100L, 0x04000101L, - 0x00040100L, 0x04000100L, 0x00000000L, 0x04040001L, 0x00000101L, - 0x04000001L, 0x00040101L, 0x00000100L, 0x04040000L, }, + 0x04000001, 0x04040100, 0x00000100, 0x04000101, 0x00040001, + 0x04000000, 0x04000101, 0x00040100, 0x04000100, 0x00040000, + 0x04040000, 0x00000001, 0x04040101, 0x00000101, 0x00000001, + 0x04040001, 0x00000000, 0x00040001, 0x04040100, 0x00000100, + 0x00000101, 0x04040101, 0x00040000, 0x04000001, 0x04040001, + 0x04000100, 0x00040101, 0x04040000, 0x00040100, 0x00000000, + 0x04000000, 0x00040101, 0x04040100, 0x00000100, 0x00000001, + 0x00040000, 0x00000101, 0x00040001, 0x04040000, 0x04000101, + 0x00000000, 0x04040100, 0x00040100, 0x04040001, 0x00040001, + 0x04000000, 0x04040101, 0x00000001, 0x00040101, 0x04000001, + 0x04000000, 0x04040101, 0x00040000, 0x04000100, 0x04000101, + 0x00040100, 0x04000100, 0x00000000, 0x04040001, 0x00000101, + 0x04000001, 0x00040101, 0x00000100, 0x04040000, }, { // nibble 3 - 0x00401008L, 0x10001000L, 0x00000008L, 0x10401008L, 0x00000000L, - 0x10400000L, 0x10001008L, 0x00400008L, 0x10401000L, 0x10000008L, - 0x10000000L, 0x00001008L, 0x10000008L, 0x00401008L, 0x00400000L, - 0x10000000L, 0x10400008L, 0x00401000L, 0x00001000L, 0x00000008L, - 0x00401000L, 0x10001008L, 0x10400000L, 0x00001000L, 0x00001008L, - 0x00000000L, 0x00400008L, 0x10401000L, 0x10001000L, 0x10400008L, - 0x10401008L, 0x00400000L, 0x10400008L, 0x00001008L, 0x00400000L, - 0x10000008L, 0x00401000L, 0x10001000L, 0x00000008L, 0x10400000L, - 0x10001008L, 0x00000000L, 0x00001000L, 0x00400008L, 0x00000000L, - 0x10400008L, 0x10401000L, 0x00001000L, 0x10000000L, 0x10401008L, - 0x00401008L, 0x00400000L, 0x10401008L, 0x00000008L, 0x10001000L, - 0x00401008L, 0x00400008L, 0x00401000L, 0x10400000L, 0x10001008L, - 0x00001008L, 0x10000000L, 0x10000008L, 0x10401000L, }, + 0x00401008, 0x10001000, 0x00000008, 0x10401008, 0x00000000, + 0x10400000, 0x10001008, 0x00400008, 0x10401000, 0x10000008, + 0x10000000, 0x00001008, 0x10000008, 0x00401008, 0x00400000, + 0x10000000, 0x10400008, 0x00401000, 0x00001000, 0x00000008, + 0x00401000, 0x10001008, 0x10400000, 0x00001000, 0x00001008, + 0x00000000, 0x00400008, 0x10401000, 0x10001000, 0x10400008, + 0x10401008, 0x00400000, 0x10400008, 0x00001008, 0x00400000, + 0x10000008, 0x00401000, 0x10001000, 0x00000008, 0x10400000, + 0x10001008, 0x00000000, 0x00001000, 0x00400008, 0x00000000, + 0x10400008, 0x10401000, 0x00001000, 0x10000000, 0x10401008, + 0x00401008, 0x00400000, 0x10401008, 0x00000008, 0x10001000, + 0x00401008, 0x00400008, 0x00401000, 0x10400000, 0x10001008, + 0x00001008, 0x10000000, 0x10000008, 0x10401000, }, { // nibble 4 - 0x08000000L, 0x00010000L, 0x00000400L, 0x08010420L, 0x08010020L, - 0x08000400L, 0x00010420L, 0x08010000L, 0x00010000L, 0x00000020L, - 0x08000020L, 0x00010400L, 0x08000420L, 0x08010020L, 0x08010400L, - 0x00000000L, 0x00010400L, 0x08000000L, 0x00010020L, 0x00000420L, - 0x08000400L, 0x00010420L, 0x00000000L, 0x08000020L, 0x00000020L, - 0x08000420L, 0x08010420L, 0x00010020L, 0x08010000L, 0x00000400L, - 0x00000420L, 0x08010400L, 0x08010400L, 0x08000420L, 0x00010020L, - 0x08010000L, 0x00010000L, 0x00000020L, 0x08000020L, 0x08000400L, - 0x08000000L, 0x00010400L, 0x08010420L, 0x00000000L, 0x00010420L, - 0x08000000L, 0x00000400L, 0x00010020L, 0x08000420L, 0x00000400L, - 0x00000000L, 0x08010420L, 0x08010020L, 0x08010400L, 0x00000420L, - 0x00010000L, 0x00010400L, 0x08010020L, 0x08000400L, 0x00000420L, - 0x00000020L, 0x00010420L, 0x08010000L, 0x08000020L, }, + 0x08000000, 0x00010000, 0x00000400, 0x08010420, 0x08010020, + 0x08000400, 0x00010420, 0x08010000, 0x00010000, 0x00000020, + 0x08000020, 0x00010400, 0x08000420, 0x08010020, 0x08010400, + 0x00000000, 0x00010400, 0x08000000, 0x00010020, 0x00000420, + 0x08000400, 0x00010420, 0x00000000, 0x08000020, 0x00000020, + 0x08000420, 0x08010420, 0x00010020, 0x08010000, 0x00000400, + 0x00000420, 0x08010400, 0x08010400, 0x08000420, 0x00010020, + 0x08010000, 0x00010000, 0x00000020, 0x08000020, 0x08000400, + 0x08000000, 0x00010400, 0x08010420, 0x00000000, 0x00010420, + 0x08000000, 0x00000400, 0x00010020, 0x08000420, 0x00000400, + 0x00000000, 0x08010420, 0x08010020, 0x08010400, 0x00000420, + 0x00010000, 0x00010400, 0x08010020, 0x08000400, 0x00000420, + 0x00000020, 0x00010420, 0x08010000, 0x08000020, }, { // nibble 5 - 0x80000040L, 0x00200040L, 0x00000000L, 0x80202000L, 0x00200040L, - 0x00002000L, 0x80002040L, 0x00200000L, 0x00002040L, 0x80202040L, - 0x00202000L, 0x80000000L, 0x80002000L, 0x80000040L, 0x80200000L, - 0x00202040L, 0x00200000L, 0x80002040L, 0x80200040L, 0x00000000L, - 0x00002000L, 0x00000040L, 0x80202000L, 0x80200040L, 0x80202040L, - 0x80200000L, 0x80000000L, 0x00002040L, 0x00000040L, 0x00202000L, - 0x00202040L, 0x80002000L, 0x00002040L, 0x80000000L, 0x80002000L, - 0x00202040L, 0x80202000L, 0x00200040L, 0x00000000L, 0x80002000L, - 0x80000000L, 0x00002000L, 0x80200040L, 0x00200000L, 0x00200040L, - 0x80202040L, 0x00202000L, 0x00000040L, 0x80202040L, 0x00202000L, - 0x00200000L, 0x80002040L, 0x80000040L, 0x80200000L, 0x00202040L, - 0x00000000L, 0x00002000L, 0x80000040L, 0x80002040L, 0x80202000L, - 0x80200000L, 0x00002040L, 0x00000040L, 0x80200040L, }, + 0x80000040, 0x00200040, 0x00000000, 0x80202000, 0x00200040, + 0x00002000, 0x80002040, 0x00200000, 0x00002040, 0x80202040, + 0x00202000, 0x80000000, 0x80002000, 0x80000040, 0x80200000, + 0x00202040, 0x00200000, 0x80002040, 0x80200040, 0x00000000, + 0x00002000, 0x00000040, 0x80202000, 0x80200040, 0x80202040, + 0x80200000, 0x80000000, 0x00002040, 0x00000040, 0x00202000, + 0x00202040, 0x80002000, 0x00002040, 0x80000000, 0x80002000, + 0x00202040, 0x80202000, 0x00200040, 0x00000000, 0x80002000, + 0x80000000, 0x00002000, 0x80200040, 0x00200000, 0x00200040, + 0x80202040, 0x00202000, 0x00000040, 0x80202040, 0x00202000, + 0x00200000, 0x80002040, 0x80000040, 0x80200000, 0x00202040, + 0x00000000, 0x00002000, 0x80000040, 0x80002040, 0x80202000, + 0x80200000, 0x00002040, 0x00000040, 0x80200040, }, { // nibble 6 - 0x00004000L, 0x00000200L, 0x01000200L, 0x01000004L, 0x01004204L, - 0x00004004L, 0x00004200L, 0x00000000L, 0x01000000L, 0x01000204L, - 0x00000204L, 0x01004000L, 0x00000004L, 0x01004200L, 0x01004000L, - 0x00000204L, 0x01000204L, 0x00004000L, 0x00004004L, 0x01004204L, - 0x00000000L, 0x01000200L, 0x01000004L, 0x00004200L, 0x01004004L, - 0x00004204L, 0x01004200L, 0x00000004L, 0x00004204L, 0x01004004L, - 0x00000200L, 0x01000000L, 0x00004204L, 0x01004000L, 0x01004004L, - 0x00000204L, 0x00004000L, 0x00000200L, 0x01000000L, 0x01004004L, - 0x01000204L, 0x00004204L, 0x00004200L, 0x00000000L, 0x00000200L, - 0x01000004L, 0x00000004L, 0x01000200L, 0x00000000L, 0x01000204L, - 0x01000200L, 0x00004200L, 0x00000204L, 0x00004000L, 0x01004204L, - 0x01000000L, 0x01004200L, 0x00000004L, 0x00004004L, 0x01004204L, - 0x01000004L, 0x01004200L, 0x01004000L, 0x00004004L, }, + 0x00004000, 0x00000200, 0x01000200, 0x01000004, 0x01004204, + 0x00004004, 0x00004200, 0x00000000, 0x01000000, 0x01000204, + 0x00000204, 0x01004000, 0x00000004, 0x01004200, 0x01004000, + 0x00000204, 0x01000204, 0x00004000, 0x00004004, 0x01004204, + 0x00000000, 0x01000200, 0x01000004, 0x00004200, 0x01004004, + 0x00004204, 0x01004200, 0x00000004, 0x00004204, 0x01004004, + 0x00000200, 0x01000000, 0x00004204, 0x01004000, 0x01004004, + 0x00000204, 0x00004000, 0x00000200, 0x01000000, 0x01004004, + 0x01000204, 0x00004204, 0x00004200, 0x00000000, 0x00000200, + 0x01000004, 0x00000004, 0x01000200, 0x00000000, 0x01000204, + 0x01000200, 0x00004200, 0x00000204, 0x00004000, 0x01004204, + 0x01000000, 0x01004200, 0x00000004, 0x00004004, 0x01004204, + 0x01000004, 0x01004200, 0x01004000, 0x00004004, }, { // nibble 7 - 0x20800080L, 0x20820000L, 0x00020080L, 0x00000000L, 0x20020000L, - 0x00800080L, 0x20800000L, 0x20820080L, 0x00000080L, 0x20000000L, - 0x00820000L, 0x00020080L, 0x00820080L, 0x20020080L, 0x20000080L, - 0x20800000L, 0x00020000L, 0x00820080L, 0x00800080L, 0x20020000L, - 0x20820080L, 0x20000080L, 0x00000000L, 0x00820000L, 0x20000000L, - 0x00800000L, 0x20020080L, 0x20800080L, 0x00800000L, 0x00020000L, - 0x20820000L, 0x00000080L, 0x00800000L, 0x00020000L, 0x20000080L, - 0x20820080L, 0x00020080L, 0x20000000L, 0x00000000L, 0x00820000L, - 0x20800080L, 0x20020080L, 0x20020000L, 0x00800080L, 0x20820000L, - 0x00000080L, 0x00800080L, 0x20020000L, 0x20820080L, 0x00800000L, - 0x20800000L, 0x20000080L, 0x00820000L, 0x00020080L, 0x20020080L, - 0x20800000L, 0x00000080L, 0x20820000L, 0x00820080L, 0x00000000L, - 0x20000000L, 0x20800080L, 0x00020000L, 0x00820080L, }}; + 0x20800080, 0x20820000, 0x00020080, 0x00000000, 0x20020000, + 0x00800080, 0x20800000, 0x20820080, 0x00000080, 0x20000000, + 0x00820000, 0x00020080, 0x00820080, 0x20020080, 0x20000080, + 0x20800000, 0x00020000, 0x00820080, 0x00800080, 0x20020000, + 0x20820080, 0x20000080, 0x00000000, 0x00820000, 0x20000000, + 0x00800000, 0x20020080, 0x20800080, 0x00800000, 0x00020000, + 0x20820000, 0x00000080, 0x00800000, 0x00020000, 0x20000080, + 0x20820080, 0x00020080, 0x20000000, 0x00000000, 0x00820000, + 0x20800080, 0x20020080, 0x20020000, 0x00800080, 0x20820000, + 0x00000080, 0x00800080, 0x20020000, 0x20820080, 0x00800000, + 0x20800000, 0x20000080, 0x00820000, 0x00020080, 0x20020080, + 0x20800000, 0x00000080, 0x20820000, 0x00820080, 0x00000000, + 0x20000000, 0x20800080, 0x00020000, 0x00820080, }}; #define HPERM_OP(a, t, n, m) \ ((t) = ((((a) << (16 - (n))) ^ (a)) & (m)), \ @@ -308,43 +308,43 @@ void DES_set_key(const DES_cblock *key, DES_key_schedule *schedule) { // do PC1 in 47 simple operations :-) // Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov) // for the inspiration. :-) - PERM_OP(d, c, t, 4, 0x0f0f0f0fL); - HPERM_OP(c, t, -2, 0xcccc0000L); - HPERM_OP(d, t, -2, 0xcccc0000L); - PERM_OP(d, c, t, 1, 0x55555555L); - PERM_OP(c, d, t, 8, 0x00ff00ffL); - PERM_OP(d, c, t, 1, 0x55555555L); - d = (((d & 0x000000ffL) << 16L) | (d & 0x0000ff00L) | - ((d & 0x00ff0000L) >> 16L) | ((c & 0xf0000000L) >> 4L)); - c &= 0x0fffffffL; + PERM_OP(d, c, t, 4, 0x0f0f0f0f); + HPERM_OP(c, t, -2, 0xcccc0000); + HPERM_OP(d, t, -2, 0xcccc0000); + PERM_OP(d, c, t, 1, 0x55555555); + PERM_OP(c, d, t, 8, 0x00ff00ff); + PERM_OP(d, c, t, 1, 0x55555555); + d = (((d & 0x000000ff) << 16) | (d & 0x0000ff00) | + ((d & 0x00ff0000) >> 16) | ((c & 0xf0000000) >> 4)); + c &= 0x0fffffff; for (i = 0; i < ITERATIONS; i++) { if (shifts2[i]) { - c = ((c >> 2L) | (c << 26L)); - d = ((d >> 2L) | (d << 26L)); + c = ((c >> 2) | (c << 26)); + d = ((d >> 2) | (d << 26)); } else { - c = ((c >> 1L) | (c << 27L)); - d = ((d >> 1L) | (d << 27L)); + c = ((c >> 1) | (c << 27)); + d = ((d >> 1) | (d << 27)); } - c &= 0x0fffffffL; - d &= 0x0fffffffL; + c &= 0x0fffffff; + d &= 0x0fffffff; // could be a few less shifts but I am to lazy at this // point in time to investigate s = des_skb[0][(c) & 0x3f] | - des_skb[1][((c >> 6L) & 0x03) | ((c >> 7L) & 0x3c)] | - des_skb[2][((c >> 13L) & 0x0f) | ((c >> 14L) & 0x30)] | - des_skb[3][((c >> 20L) & 0x01) | ((c >> 21L) & 0x06) | - ((c >> 22L) & 0x38)]; + des_skb[1][((c >> 6) & 0x03) | ((c >> 7) & 0x3c)] | + des_skb[2][((c >> 13) & 0x0f) | ((c >> 14) & 0x30)] | + des_skb[3][((c >> 20) & 0x01) | ((c >> 21) & 0x06) | + ((c >> 22) & 0x38)]; t = des_skb[4][(d) & 0x3f] | - des_skb[5][((d >> 7L) & 0x03) | ((d >> 8L) & 0x3c)] | - des_skb[6][(d >> 15L) & 0x3f] | - des_skb[7][((d >> 21L) & 0x0f) | ((d >> 22L) & 0x30)]; + des_skb[5][((d >> 7) & 0x03) | ((d >> 8) & 0x3c)] | + des_skb[6][(d >> 15) & 0x3f] | + des_skb[7][((d >> 21) & 0x0f) | ((d >> 22) & 0x30)]; // table contained 0213 4657 - t2 = ((t << 16L) | (s & 0x0000ffffL)) & 0xffffffffL; + t2 = ((t << 16) | (s & 0x0000ffff)) & 0xffffffff; schedule->subkeys[i][0] = CRYPTO_rotr_u32(t2, 30); - t2 = ((s >> 16L) | (t & 0xffff0000L)); + t2 = ((s >> 16) | (t & 0xffff0000)); schedule->subkeys[i][1] = CRYPTO_rotr_u32(t2, 26); } } diff --git a/Sources/CNIOBoringSSL/crypto/digest_extra/digest_extra.c b/Sources/CNIOBoringSSL/crypto/digest_extra/digest_extra.c index 42fddfa0..e5c44ff2 100644 --- a/Sources/CNIOBoringSSL/crypto/digest_extra/digest_extra.c +++ b/Sources/CNIOBoringSSL/crypto/digest_extra/digest_extra.c @@ -200,7 +200,6 @@ int EVP_marshal_digest_algorithm(CBB *cbb, const EVP_MD *md) { CBB algorithm, oid, null; if (!CBB_add_asn1(cbb, &algorithm, CBS_ASN1_SEQUENCE) || !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT)) { - OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE); return 0; } @@ -209,7 +208,6 @@ int EVP_marshal_digest_algorithm(CBB *cbb, const EVP_MD *md) { for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kMDOIDs); i++) { if (nid == kMDOIDs[i].nid) { if (!CBB_add_bytes(&oid, kMDOIDs[i].oid, kMDOIDs[i].oid_len)) { - OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE); return 0; } found = 1; @@ -224,7 +222,6 @@ int EVP_marshal_digest_algorithm(CBB *cbb, const EVP_MD *md) { if (!CBB_add_asn1(&algorithm, &null, CBS_ASN1_NULL) || !CBB_flush(cbb)) { - OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE); return 0; } diff --git a/Sources/CNIOBoringSSL/crypto/dsa/dsa.c b/Sources/CNIOBoringSSL/crypto/dsa/dsa.c index caab4ecb..e41a57e0 100644 --- a/Sources/CNIOBoringSSL/crypto/dsa/dsa.c +++ b/Sources/CNIOBoringSSL/crypto/dsa/dsa.c @@ -90,7 +90,6 @@ static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT; DSA *DSA_new(void) { DSA *dsa = OPENSSL_malloc(sizeof(DSA)); if (dsa == NULL) { - OPENSSL_PUT_ERROR(DSA, ERR_R_MALLOC_FAILURE); return NULL; } @@ -217,16 +216,14 @@ int DSA_generate_parameters_ex(DSA *dsa, unsigned bits, const uint8_t *seed_in, BIGNUM *g = NULL, *q = NULL, *p = NULL; BN_MONT_CTX *mont = NULL; int k, n = 0, m = 0; - unsigned i; int counter = 0; int r = 0; BN_CTX *ctx = NULL; unsigned int h = 2; - unsigned qsize; const EVP_MD *evpmd; evpmd = (bits >= 2048) ? EVP_sha256() : EVP_sha1(); - qsize = EVP_MD_size(evpmd); + size_t qsize = EVP_MD_size(evpmd); if (bits < 512) { bits = 512; @@ -235,10 +232,10 @@ int DSA_generate_parameters_ex(DSA *dsa, unsigned bits, const uint8_t *seed_in, bits = (bits + 63) / 64 * 64; if (seed_in != NULL) { - if (seed_len < (size_t)qsize) { + if (seed_len < qsize) { return 0; } - if (seed_len > (size_t)qsize) { + if (seed_len > qsize) { // Only consume as much seed as is expected. seed_len = qsize; } @@ -284,7 +281,7 @@ int DSA_generate_parameters_ex(DSA *dsa, unsigned bits, const uint8_t *seed_in, OPENSSL_memcpy(buf, seed, qsize); OPENSSL_memcpy(buf2, seed, qsize); // precompute "SEED + 1" for step 7: - for (i = qsize - 1; i < qsize; i--) { + for (size_t i = qsize - 1; i < qsize; i--) { buf[i]++; if (buf[i] != 0) { break; @@ -296,7 +293,7 @@ int DSA_generate_parameters_ex(DSA *dsa, unsigned bits, const uint8_t *seed_in, !EVP_Digest(buf, qsize, buf2, NULL, evpmd, NULL)) { goto err; } - for (i = 0; i < qsize; i++) { + for (size_t i = 0; i < qsize; i++) { md[i] ^= buf2[i]; } @@ -340,7 +337,7 @@ int DSA_generate_parameters_ex(DSA *dsa, unsigned bits, const uint8_t *seed_in, // now 'buf' contains "SEED + offset - 1" for (k = 0; k <= n; k++) { // obtain "SEED + offset + k" by incrementing: - for (i = qsize - 1; i < qsize; i--) { + for (size_t i = qsize - 1; i < qsize; i--) { buf[i]++; if (buf[i] != 0) { break; @@ -591,7 +588,12 @@ static int mod_mul_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, } DSA_SIG *DSA_do_sign(const uint8_t *digest, size_t digest_len, const DSA *dsa) { - if (!dsa_check_parameters(dsa)) { + if (!dsa_check_key(dsa)) { + return NULL; + } + + if (dsa->priv_key == NULL) { + OPENSSL_PUT_ERROR(DSA, DSA_R_MISSING_PARAMETERS); return NULL; } @@ -612,6 +614,14 @@ DSA_SIG *DSA_do_sign(const uint8_t *digest, size_t digest_len, const DSA *dsa) { goto err; } + // Cap iterations so that invalid parameters do not infinite loop. This does + // not impact valid parameters because the probability of requiring even one + // retry is negligible, let alone 32. Unfortunately, DSA was mis-specified, so + // invalid parameters are reachable from most callers handling untrusted + // private keys. (The |dsa_check_key| call above is not sufficient. Checking + // whether arbitrary paremeters form a valid DSA group is expensive.) + static const int kMaxIterations = 32; + int iters = 0; redo: if (!dsa_sign_setup(dsa, ctx, &kinv, &r)) { goto err; @@ -651,8 +661,14 @@ DSA_SIG *DSA_do_sign(const uint8_t *digest, size_t digest_len, const DSA *dsa) { // Redo if r or s is zero as required by FIPS 186-3: this is // very unlikely. if (BN_is_zero(r) || BN_is_zero(s)) { + iters++; + if (iters > kMaxIterations) { + OPENSSL_PUT_ERROR(DSA, DSA_R_TOO_MANY_ITERATIONS); + goto err; + } goto redo; } + ret = DSA_SIG_new(); if (ret == NULL) { goto err; @@ -686,7 +702,12 @@ int DSA_do_verify(const uint8_t *digest, size_t digest_len, DSA_SIG *sig, int DSA_do_check_signature(int *out_valid, const uint8_t *digest, size_t digest_len, DSA_SIG *sig, const DSA *dsa) { *out_valid = 0; - if (!dsa_check_parameters(dsa)) { + if (!dsa_check_key(dsa)) { + return 0; + } + + if (dsa->pub_key == NULL) { + OPENSSL_PUT_ERROR(DSA, DSA_R_MISSING_PARAMETERS); return 0; } @@ -845,6 +866,10 @@ static size_t der_len_len(size_t len) { } int DSA_size(const DSA *dsa) { + if (dsa->q == NULL) { + return 0; + } + 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. @@ -867,11 +892,6 @@ int DSA_size(const DSA *dsa) { static int dsa_sign_setup(const DSA *dsa, BN_CTX *ctx, BIGNUM **out_kinv, BIGNUM **out_r) { - if (!dsa->p || !dsa->q || !dsa->g) { - OPENSSL_PUT_ERROR(DSA, DSA_R_MISSING_PARAMETERS); - return 0; - } - int ret = 0; BIGNUM k; BN_init(&k); diff --git a/Sources/CNIOBoringSSL/crypto/dsa/dsa_asn1.c b/Sources/CNIOBoringSSL/crypto/dsa/dsa_asn1.c index cfc11932..f1428675 100644 --- a/Sources/CNIOBoringSSL/crypto/dsa/dsa_asn1.c +++ b/Sources/CNIOBoringSSL/crypto/dsa/dsa_asn1.c @@ -70,15 +70,25 @@ // This function is in dsa_asn1.c rather than dsa.c because it is reachable from // |EVP_PKEY| parsers. This makes it easier for the static linker to drop most // of the DSA implementation. -int dsa_check_parameters(const DSA *dsa) { +int dsa_check_key(const DSA *dsa) { if (!dsa->p || !dsa->q || !dsa->g) { OPENSSL_PUT_ERROR(DSA, DSA_R_MISSING_PARAMETERS); return 0; } - // Reject invalid parameters. In particular, signing will infinite loop if |g| - // is zero. - if (BN_is_zero(dsa->p) || BN_is_zero(dsa->q) || BN_is_zero(dsa->g)) { + // Fully checking for invalid DSA groups is expensive, so security and + // correctness of the signature scheme depend on how |dsa| was computed. I.e. + // we leave "assurance of domain parameter validity" from FIPS 186-4 to the + // caller. However, we check bounds on all values to avoid DoS vectors even + // when domain parameters are invalid. In particular, signing will infinite + // loop if |g| is zero. + if (BN_is_negative(dsa->p) || BN_is_negative(dsa->q) || BN_is_zero(dsa->p) || + BN_is_zero(dsa->q) || !BN_is_odd(dsa->p) || !BN_is_odd(dsa->q) || + // |q| must be a prime divisor of |p - 1|, which implies |q < p|. + BN_cmp(dsa->q, dsa->p) >= 0 || + // |g| is in the multiplicative group of |p|. + BN_is_negative(dsa->g) || BN_is_zero(dsa->g) || + BN_cmp(dsa->g, dsa->p) >= 0) { OPENSSL_PUT_ERROR(DSA, DSA_R_INVALID_PARAMETERS); return 0; } @@ -97,6 +107,25 @@ int dsa_check_parameters(const DSA *dsa) { return 0; } + if (dsa->pub_key != NULL) { + // The public key is also in the multiplicative group of |p|. + if (BN_is_negative(dsa->pub_key) || BN_is_zero(dsa->pub_key) || + BN_cmp(dsa->pub_key, dsa->p) >= 0) { + OPENSSL_PUT_ERROR(DSA, DSA_R_INVALID_PARAMETERS); + return 0; + } + } + + if (dsa->priv_key != NULL) { + // The private key is a non-zero element of the scalar field, determined by + // |q|. + if (BN_is_negative(dsa->priv_key) || BN_is_zero(dsa->priv_key) || + BN_cmp(dsa->priv_key, dsa->q) >= 0) { + OPENSSL_PUT_ERROR(DSA, DSA_R_INVALID_PARAMETERS); + return 0; + } + } + return 1; } @@ -162,7 +191,7 @@ DSA *DSA_parse_public_key(CBS *cbs) { OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR); goto err; } - if (!dsa_check_parameters(ret)) { + if (!dsa_check_key(ret)) { goto err; } return ret; @@ -200,7 +229,7 @@ DSA *DSA_parse_parameters(CBS *cbs) { OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR); goto err; } - if (!dsa_check_parameters(ret)) { + if (!dsa_check_key(ret)) { goto err; } return ret; @@ -251,9 +280,10 @@ DSA *DSA_parse_private_key(CBS *cbs) { OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR); goto err; } - if (!dsa_check_parameters(ret)) { + if (!dsa_check_key(ret)) { goto err; } + return ret; err: diff --git a/Sources/CNIOBoringSSL/crypto/dsa/internal.h b/Sources/CNIOBoringSSL/crypto/dsa/internal.h index 4de032ab..00b6d4bd 100644 --- a/Sources/CNIOBoringSSL/crypto/dsa/internal.h +++ b/Sources/CNIOBoringSSL/crypto/dsa/internal.h @@ -22,9 +22,9 @@ extern "C" { #endif -// dsa_check_parameters checks that |dsa|'s group is within DoS bounds. It -// returns one on success and zero on error. -int dsa_check_parameters(const DSA *dsa); +// dsa_check_key performs cheap self-checks on |dsa|, and ensures it is within +// DoS bounds. It returns one on success and zero on error. +int dsa_check_key(const DSA *dsa); #if defined(__cplusplus) diff --git a/Sources/CNIOBoringSSL/crypto/ec_extra/ec_asn1.c b/Sources/CNIOBoringSSL/crypto/ec_extra/ec_asn1.c index aaeffb9d..d8310ade 100644 --- a/Sources/CNIOBoringSSL/crypto/ec_extra/ec_asn1.c +++ b/Sources/CNIOBoringSSL/crypto/ec_extra/ec_asn1.c @@ -67,9 +67,9 @@ #include "../internal.h" -static const unsigned kParametersTag = +static const CBS_ASN1_TAG kParametersTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0; -static const unsigned kPublicKeyTag = +static const CBS_ASN1_TAG kPublicKeyTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 1; EC_KEY *EC_KEY_parse_private_key(CBS *cbs, const EC_GROUP *group) { @@ -504,7 +504,6 @@ EC_KEY *o2i_ECPublicKey(EC_KEY **keyp, const uint8_t **inp, long len) { 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 NULL; } if (!EC_POINT_oct2point(ret->group, ret->pub_key, *inp, len, NULL)) { @@ -518,42 +517,18 @@ EC_KEY *o2i_ECPublicKey(EC_KEY **keyp, const uint8_t **inp, long len) { } int i2o_ECPublicKey(const EC_KEY *key, uint8_t **outp) { - size_t buf_len = 0; - int new_buffer = 0; - if (key == NULL) { OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); return 0; } - - buf_len = EC_POINT_point2oct(key->group, key->pub_key, key->conv_form, NULL, - 0, NULL); - - if (outp == NULL || buf_len == 0) { - // out == NULL => just return the length of the octet string - return buf_len; - } - - if (*outp == NULL) { - *outp = OPENSSL_malloc(buf_len); - if (*outp == NULL) { - OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); - return 0; - } - new_buffer = 1; - } - if (!EC_POINT_point2oct(key->group, key->pub_key, key->conv_form, *outp, - buf_len, NULL)) { - OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB); - if (new_buffer) { - OPENSSL_free(*outp); - *outp = NULL; - } - return 0; - } - - if (!new_buffer) { - *outp += buf_len; + CBB cbb; + if (!CBB_init(&cbb, 0) || // + !EC_POINT_point2cbb(&cbb, key->group, key->pub_key, key->conv_form, + NULL)) { + CBB_cleanup(&cbb); + return -1; } - return buf_len; + int ret = CBB_finish_i2d(&cbb, outp); + // Historically, this function used the wrong return value on error. + return ret > 0 ? ret : 0; } diff --git a/Sources/CNIOBoringSSL/crypto/ec_extra/hash_to_curve.c b/Sources/CNIOBoringSSL/crypto/ec_extra/hash_to_curve.c index 4e22e822..46e0b0e8 100644 --- a/Sources/CNIOBoringSSL/crypto/ec_extra/hash_to_curve.c +++ b/Sources/CNIOBoringSSL/crypto/ec_extra/hash_to_curve.c @@ -27,7 +27,7 @@ // This file implements hash-to-curve, as described in -// draft-irtf-cfrg-hash-to-curve-07. +// draft-irtf-cfrg-hash-to-curve-16. // // This hash-to-curve implementation is written generically with the // expectation that we will eventually wish to support other curves. If it @@ -48,11 +48,17 @@ // templates to make specializing more convenient. // expand_message_xmd implements the operation described in section 5.3.1 of -// draft-irtf-cfrg-hash-to-curve-07. It returns one on success and zero on -// allocation failure or if |out_len| was too large. +// draft-irtf-cfrg-hash-to-curve-16. It returns one on success and zero on +// error. static int expand_message_xmd(const EVP_MD *md, uint8_t *out, size_t out_len, const uint8_t *msg, size_t msg_len, const uint8_t *dst, size_t dst_len) { + // See https://github.com/cfrg/draft-irtf-cfrg-hash-to-curve/issues/352 + if (dst_len == 0) { + OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + int ret = 0; const size_t block_size = EVP_MD_block_size(md); const size_t md_size = EVP_MD_size(md); @@ -132,7 +138,7 @@ static int expand_message_xmd(const EVP_MD *md, uint8_t *out, size_t out_len, // num_bytes_to_derive determines the number of bytes to derive when hashing to // a number modulo |modulus|. See the hash_to_field operation defined in -// section 5.2 of draft-irtf-cfrg-hash-to-curve-07. +// section 5.2 of draft-irtf-cfrg-hash-to-curve-16. static int num_bytes_to_derive(size_t *out, const BIGNUM *modulus, unsigned k) { size_t bits = BN_num_bits(modulus); size_t L = (bits + k + 7) / 8; @@ -165,7 +171,7 @@ static void big_endian_to_words(BN_ULONG *out, size_t num_words, } // hash_to_field implements the operation described in section 5.2 -// of draft-irtf-cfrg-hash-to-curve-07, with count = 2. |k| is the security +// of draft-irtf-cfrg-hash-to-curve-16, with count = 2. |k| is the security // factor. static int hash_to_field2(const EC_GROUP *group, const EVP_MD *md, EC_FELEM *out1, EC_FELEM *out2, const uint8_t *dst, @@ -214,90 +220,126 @@ static inline void mul_A(const EC_GROUP *group, EC_FELEM *out, ec_felem_sub(group, out, in, &tmp); // out = -3*in } -static inline void mul_minus_A(const EC_GROUP *group, EC_FELEM *out, - const EC_FELEM *in) { - assert(group->a_is_minus3); - EC_FELEM tmp; - ec_felem_add(group, &tmp, in, in); // tmp = 2*in - ec_felem_add(group, out, &tmp, in); // out = 3*in -} - -// sgn0_le implements the operation described in section 4.1.2 of -// draft-irtf-cfrg-hash-to-curve-07. -static BN_ULONG sgn0_le(const EC_GROUP *group, const EC_FELEM *a) { +// sgn0 implements the operation described in section 4.1.2 of +// draft-irtf-cfrg-hash-to-curve-16. +static BN_ULONG sgn0(const EC_GROUP *group, const EC_FELEM *a) { uint8_t buf[EC_MAX_BYTES]; size_t len; ec_felem_to_bytes(group, buf, &len, a); return buf[len - 1] & 1; } -// map_to_curve_simple_swu implements the operation described in section 6.6.2 -// of draft-irtf-cfrg-hash-to-curve-07, using the optimization in appendix -// D.2.1. It returns one on success and zero on error. -static int map_to_curve_simple_swu(const EC_GROUP *group, const EC_FELEM *Z, - const BN_ULONG *c1, size_t num_c1, - const EC_FELEM *c2, EC_RAW_POINT *out, - const EC_FELEM *u) { +OPENSSL_UNUSED static int is_3mod4(const EC_GROUP *group) { + return group->field.width > 0 && (group->field.d[0] & 3) == 3; +} + +// sqrt_ratio_3mod4 implements the operation described in appendix F.2.1.2 +// of draft-irtf-cfrg-hash-to-curve-16. +static BN_ULONG sqrt_ratio_3mod4(const EC_GROUP *group, const EC_FELEM *Z, + const BN_ULONG *c1, size_t num_c1, + const EC_FELEM *c2, EC_FELEM *out_y, + const EC_FELEM *u, const EC_FELEM *v) { + assert(is_3mod4(group)); + void (*const felem_mul)(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a, const EC_FELEM *b) = group->meth->felem_mul; void (*const felem_sqr)(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a) = group->meth->felem_sqr; + EC_FELEM tv1, tv2, tv3, y1, y2; + felem_sqr(group, &tv1, v); // 1. tv1 = v^2 + felem_mul(group, &tv2, u, v); // 2. tv2 = u * v + felem_mul(group, &tv1, &tv1, &tv2); // 3. tv1 = tv1 * tv2 + group->meth->felem_exp(group, &y1, &tv1, c1, num_c1); // 4. y1 = tv1^c1 + felem_mul(group, &y1, &y1, &tv2); // 5. y1 = y1 * tv2 + felem_mul(group, &y2, &y1, c2); // 6. y2 = y1 * c2 + felem_sqr(group, &tv3, &y1); // 7. tv3 = y1^2 + felem_mul(group, &tv3, &tv3, v); // 8. tv3 = tv3 * v + + // 9. isQR = tv3 == u + // 10. y = CMOV(y2, y1, isQR) + // 11. return (isQR, y) + // + // Note the specification's CMOV function and our |ec_felem_select| have the + // opposite argument order. + ec_felem_sub(group, &tv1, &tv3, u); + const BN_ULONG isQR = ~ec_felem_non_zero_mask(group, &tv1); + ec_felem_select(group, out_y, isQR, &y1, &y2); + return isQR; +} + +// map_to_curve_simple_swu implements the operation described in section 6.6.2 +// of draft-irtf-cfrg-hash-to-curve-16, using the straight-line implementation +// in appendix F.2. +static void map_to_curve_simple_swu(const EC_GROUP *group, const EC_FELEM *Z, + const BN_ULONG *c1, size_t num_c1, + const EC_FELEM *c2, EC_RAW_POINT *out, + const EC_FELEM *u) { // This function requires the prime be 3 mod 4, and that A = -3. - if (group->field.width == 0 || (group->field.d[0] & 3) != 3 || - !group->a_is_minus3) { - OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR); - return 0; - } + assert(is_3mod4(group)); + assert(group->a_is_minus3); - EC_FELEM tv1, tv2, tv3, tv4, xd, x1n, x2n, tmp, gxd, gx1, y1, y2; - felem_sqr(group, &tv1, u); // tv1 = u^2 - felem_mul(group, &tv3, Z, &tv1); // tv3 = Z * tv1 - felem_sqr(group, &tv2, &tv3); // tv2 = tv3^2 - ec_felem_add(group, &xd, &tv2, &tv3); // xd = tv2 + tv3 - ec_felem_add(group, &x1n, &xd, &group->one); // x1n = xd + 1 - felem_mul(group, &x1n, &x1n, &group->b); // x1n = x1n * B - mul_minus_A(group, &xd, &xd); // xd = -A * xd - BN_ULONG e1 = ec_felem_non_zero_mask(group, &xd); // e1 = xd == 0 [flipped] - mul_A(group, &tmp, Z); - ec_felem_select(group, &xd, e1, &xd, &tmp); // xd = CMOV(xd, Z * A, e1) - felem_sqr(group, &tv2, &xd); // tv2 = xd^2 - felem_mul(group, &gxd, &tv2, &xd); // gxd = tv2 * xd = xd^3 - mul_A(group, &tv2, &tv2); // tv2 = A * tv2 - felem_sqr(group, &gx1, &x1n); // gx1 = x1n^2 - ec_felem_add(group, &gx1, &gx1, &tv2); // gx1 = gx1 + tv2 - felem_mul(group, &gx1, &gx1, &x1n); // gx1 = gx1 * x1n - felem_mul(group, &tv2, &group->b, &gxd); // tv2 = B * gxd - ec_felem_add(group, &gx1, &gx1, &tv2); // gx1 = gx1 + tv2 - felem_sqr(group, &tv4, &gxd); // tv4 = gxd^2 - felem_mul(group, &tv2, &gx1, &gxd); // tv2 = gx1 * gxd - felem_mul(group, &tv4, &tv4, &tv2); // tv4 = tv4 * tv2 - group->meth->felem_exp(group, &y1, &tv4, c1, num_c1); // y1 = tv4^c1 - felem_mul(group, &y1, &y1, &tv2); // y1 = y1 * tv2 - felem_mul(group, &x2n, &tv3, &x1n); // x2n = tv3 * x1n - felem_mul(group, &y2, &y1, c2); // y2 = y1 * c2 - felem_mul(group, &y2, &y2, &tv1); // y2 = y2 * tv1 - felem_mul(group, &y2, &y2, u); // y2 = y2 * u - felem_sqr(group, &tv2, &y1); // tv2 = y1^2 - felem_mul(group, &tv2, &tv2, &gxd); // tv2 = tv2 * gxd - ec_felem_sub(group, &tv3, &tv2, &gx1); - BN_ULONG e2 = - ec_felem_non_zero_mask(group, &tv3); // e2 = tv2 == gx1 [flipped] - ec_felem_select(group, &x1n, e2, &x2n, &x1n); // xn = CMOV(x2n, x1n, e2) - ec_felem_select(group, &y1, e2, &y2, &y1); // y = CMOV(y2, y1, e2) - BN_ULONG sgn0_u = sgn0_le(group, u); - BN_ULONG sgn0_y = sgn0_le(group, &y1); - BN_ULONG e3 = sgn0_u ^ sgn0_y; - e3 = ((BN_ULONG)0) - e3; // e3 = sgn0(u) == sgn0(y) [flipped] - ec_felem_neg(group, &y2, &y1); - ec_felem_select(group, &y1, e3, &y2, &y1); // y = CMOV(-y, y, e3) - - // Appendix D.1 describes how to convert (x1n, xd, y1, 1) to Jacobian - // coordinates. Note yd = 1. Also note that gxd computed above is xd^3. - felem_mul(group, &out->X, &x1n, &xd); // X = xn * xd - felem_mul(group, &out->Y, &y1, &gxd); // Y = yn * gxd = yn * xd^3 - out->Z = xd; // Z = xd - return 1; + void (*const felem_mul)(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a, + const EC_FELEM *b) = group->meth->felem_mul; + void (*const felem_sqr)(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a) = + group->meth->felem_sqr; + + EC_FELEM tv1, tv2, tv3, tv4, tv5, tv6, x, y, y1; + felem_sqr(group, &tv1, u); // 1. tv1 = u^2 + felem_mul(group, &tv1, Z, &tv1); // 2. tv1 = Z * tv1 + felem_sqr(group, &tv2, &tv1); // 3. tv2 = tv1^2 + ec_felem_add(group, &tv2, &tv2, &tv1); // 4. tv2 = tv2 + tv1 + ec_felem_add(group, &tv3, &tv2, &group->one); // 5. tv3 = tv2 + 1 + felem_mul(group, &tv3, &group->b, &tv3); // 6. tv3 = B * tv3 + + // 7. tv4 = CMOV(Z, -tv2, tv2 != 0) + const BN_ULONG tv2_non_zero = ec_felem_non_zero_mask(group, &tv2); + ec_felem_neg(group, &tv4, &tv2); + ec_felem_select(group, &tv4, tv2_non_zero, &tv4, Z); + + mul_A(group, &tv4, &tv4); // 8. tv4 = A * tv4 + felem_sqr(group, &tv2, &tv3); // 9. tv2 = tv3^2 + felem_sqr(group, &tv6, &tv4); // 10. tv6 = tv4^2 + mul_A(group, &tv5, &tv6); // 11. tv5 = A * tv6 + ec_felem_add(group, &tv2, &tv2, &tv5); // 12. tv2 = tv2 + tv5 + felem_mul(group, &tv2, &tv2, &tv3); // 13. tv2 = tv2 * tv3 + felem_mul(group, &tv6, &tv6, &tv4); // 14. tv6 = tv6 * tv4 + felem_mul(group, &tv5, &group->b, &tv6); // 15. tv5 = B * tv6 + ec_felem_add(group, &tv2, &tv2, &tv5); // 16. tv2 = tv2 + tv5 + felem_mul(group, &x, &tv1, &tv3); // 17. x = tv1 * tv3 + + // 18. (is_gx1_square, y1) = sqrt_ratio(tv2, tv6) + const BN_ULONG is_gx1_square = + sqrt_ratio_3mod4(group, Z, c1, num_c1, c2, &y1, &tv2, &tv6); + + felem_mul(group, &y, &tv1, u); // 19. y = tv1 * u + felem_mul(group, &y, &y, &y1); // 20. y = y * y1 + + // 21. x = CMOV(x, tv3, is_gx1_square) + ec_felem_select(group, &x, is_gx1_square, &tv3, &x); + // 22. y = CMOV(y, y1, is_gx1_square) + ec_felem_select(group, &y, is_gx1_square, &y1, &y); + + // 23. e1 = sgn0(u) == sgn0(y) + BN_ULONG sgn0_u = sgn0(group, u); + BN_ULONG sgn0_y = sgn0(group, &y); + BN_ULONG not_e1 = sgn0_u ^ sgn0_y; + not_e1 = ((BN_ULONG)0) - not_e1; + + // 24. y = CMOV(-y, y, e1) + ec_felem_neg(group, &tv1, &y); + ec_felem_select(group, &y, not_e1, &tv1, &y); + + // 25. x = x / tv4 + // + // Our output is in projective coordinates, so rather than inverting |tv4| + // now, represent (x / tv4, y) as (x * tv4, y * tv4^3, tv4). This is much more + // efficient if the caller will do further computation on the output. (If the + // caller will immediately convert to affine coordinates, it is slightly less + // efficient, but only by a few field multiplications.) + felem_mul(group, &out->X, &x, &tv4); + felem_mul(group, &out->Y, &y, &tv6); + out->Z = tv4; } static int hash_to_curve(const EC_GROUP *group, const EVP_MD *md, @@ -318,10 +360,8 @@ static int hash_to_curve(const EC_GROUP *group, const EVP_MD *md, bn_rshift_words(c1, c1, /*shift=*/2, /*num=*/num_c1); EC_RAW_POINT Q0, Q1; - if (!map_to_curve_simple_swu(group, Z, c1, num_c1, c2, &Q0, &u0) || - !map_to_curve_simple_swu(group, Z, c1, num_c1, c2, &Q1, &u1)) { - return 0; - } + map_to_curve_simple_swu(group, Z, c1, num_c1, c2, &Q0, &u0); + map_to_curve_simple_swu(group, Z, c1, num_c1, c2, &Q1, &u1); group->meth->add(group, out, &Q0, &Q1); // R = Q0 + Q1 // All our curves have cofactor one, so |clear_cofactor| is a no-op. @@ -335,6 +375,109 @@ static int felem_from_u8(const EC_GROUP *group, EC_FELEM *out, uint8_t a) { return ec_felem_from_bytes(group, out, bytes, len); } +// kP256Sqrt10 is sqrt(10) in P-256's field. It was computed as follows in +// python3: +// +// p = 2**256 - 2**224 + 2**192 + 2**96 - 1 +// c2 = pow(10, (p+1)//4, p) +// assert pow(c2, 2, p) == 10 +// ", ".join("0x%02x" % b for b in c2.to_bytes(256//8, 'big')) +static const uint8_t kP256Sqrt10[] = { + 0xda, 0x53, 0x8e, 0x3b, 0xe1, 0xd8, 0x9b, 0x99, 0xc9, 0x78, 0xfc, + 0x67, 0x51, 0x80, 0xaa, 0xb2, 0x7b, 0x8d, 0x1f, 0xf8, 0x4c, 0x55, + 0xd5, 0xb6, 0x2c, 0xcd, 0x34, 0x27, 0xe4, 0x33, 0xc4, 0x7f}; + +// kP384Sqrt12 is sqrt(12) in P-384's field. It was computed as follows in +// python3: +// +// p = 2**384 - 2**128 - 2**96 + 2**32 - 1 +// c2 = pow(12, (p+1)//4, p) +// assert pow(c2, 2, p) == 12 +// ", ".join("0x%02x" % b for b in c2.to_bytes(384//8, 'big')) +static const uint8_t kP384Sqrt12[] = { + 0x2a, 0xcc, 0xb4, 0xa6, 0x56, 0xb0, 0x24, 0x9c, 0x71, 0xf0, 0x50, 0x0e, + 0x83, 0xda, 0x2f, 0xdd, 0x7f, 0x98, 0xe3, 0x83, 0xd6, 0x8b, 0x53, 0x87, + 0x1f, 0x87, 0x2f, 0xcb, 0x9c, 0xcb, 0x80, 0xc5, 0x3c, 0x0d, 0xe1, 0xf8, + 0xa8, 0x0f, 0x7e, 0x19, 0x14, 0xe2, 0xec, 0x69, 0xf5, 0xa6, 0x26, 0xb3}; + +int ec_hash_to_curve_p256_xmd_sha256_sswu(const EC_GROUP *group, + EC_RAW_POINT *out, const uint8_t *dst, + size_t dst_len, const uint8_t *msg, + size_t msg_len) { + // See section 8.3 of draft-irtf-cfrg-hash-to-curve-16. + if (EC_GROUP_get_curve_name(group) != NID_X9_62_prime256v1) { + OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH); + return 0; + } + + // Z = -10, c2 = sqrt(10) + EC_FELEM Z, c2; + if (!felem_from_u8(group, &Z, 10) || + !ec_felem_from_bytes(group, &c2, kP256Sqrt10, sizeof(kP256Sqrt10))) { + return 0; + } + ec_felem_neg(group, &Z, &Z); + + return hash_to_curve(group, EVP_sha256(), &Z, &c2, /*k=*/128, out, dst, + dst_len, msg, msg_len); +} + +int EC_hash_to_curve_p256_xmd_sha256_sswu(const EC_GROUP *group, EC_POINT *out, + const uint8_t *dst, size_t dst_len, + const uint8_t *msg, size_t msg_len) { + if (EC_GROUP_cmp(group, out->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return ec_hash_to_curve_p256_xmd_sha256_sswu(group, &out->raw, dst, dst_len, + msg, msg_len); +} + +int ec_hash_to_curve_p384_xmd_sha384_sswu(const EC_GROUP *group, + EC_RAW_POINT *out, const uint8_t *dst, + size_t dst_len, const uint8_t *msg, + size_t msg_len) { + // See section 8.3 of draft-irtf-cfrg-hash-to-curve-16. + if (EC_GROUP_get_curve_name(group) != NID_secp384r1) { + OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH); + return 0; + } + + // Z = -12, c2 = sqrt(12) + EC_FELEM Z, c2; + if (!felem_from_u8(group, &Z, 12) || + !ec_felem_from_bytes(group, &c2, kP384Sqrt12, sizeof(kP384Sqrt12))) { + return 0; + } + ec_felem_neg(group, &Z, &Z); + + return hash_to_curve(group, EVP_sha384(), &Z, &c2, /*k=*/192, out, dst, + dst_len, msg, msg_len); +} + +int EC_hash_to_curve_p384_xmd_sha384_sswu(const EC_GROUP *group, EC_POINT *out, + const uint8_t *dst, size_t dst_len, + const uint8_t *msg, size_t msg_len) { + if (EC_GROUP_cmp(group, out->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return ec_hash_to_curve_p384_xmd_sha384_sswu(group, &out->raw, dst, dst_len, + msg, msg_len); +} + +int ec_hash_to_scalar_p384_xmd_sha384( + const EC_GROUP *group, EC_SCALAR *out, const uint8_t *dst, size_t dst_len, + const uint8_t *msg, size_t msg_len) { + if (EC_GROUP_get_curve_name(group) != NID_secp384r1) { + OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH); + return 0; + } + + return hash_to_scalar(group, EVP_sha384(), out, dst, dst_len, /*k=*/192, msg, + msg_len); +} + int ec_hash_to_curve_p384_xmd_sha512_sswu_draft07( const EC_GROUP *group, EC_RAW_POINT *out, const uint8_t *dst, size_t dst_len, const uint8_t *msg, size_t msg_len) { @@ -344,25 +487,10 @@ int ec_hash_to_curve_p384_xmd_sha512_sswu_draft07( return 0; } - // kSqrt1728 was computed as follows in python3: - // - // p = 2**384 - 2**128 - 2**96 + 2**32 - 1 - // z3 = 12**3 - // c2 = pow(z3, (p+1)//4, p) - // assert z3 == pow(c2, 2, p) - // ", ".join("0x%02x" % b for b in c2.to_bytes(384//8, 'big') - - static const uint8_t kSqrt1728[] = { - 0x01, 0x98, 0x77, 0xcc, 0x10, 0x41, 0xb7, 0x55, 0x57, 0x43, 0xc0, 0xae, - 0x2e, 0x3a, 0x3e, 0x61, 0xfb, 0x2a, 0xaa, 0x2e, 0x0e, 0x87, 0xea, 0x55, - 0x7a, 0x56, 0x3d, 0x8b, 0x59, 0x8a, 0x09, 0x40, 0xd0, 0xa6, 0x97, 0xa9, - 0xe0, 0xb9, 0xe9, 0x2c, 0xfa, 0xa3, 0x14, 0xf5, 0x83, 0xc9, 0xd0, 0x66 - }; - - // Z = -12, c2 = sqrt(1728) + // Z = -12, c2 = sqrt(12) EC_FELEM Z, c2; if (!felem_from_u8(group, &Z, 12) || - !ec_felem_from_bytes(group, &c2, kSqrt1728, sizeof(kSqrt1728))) { + !ec_felem_from_bytes(group, &c2, kP384Sqrt12, sizeof(kP384Sqrt12))) { return 0; } ec_felem_neg(group, &Z, &Z); diff --git a/Sources/CNIOBoringSSL/crypto/ec_extra/internal.h b/Sources/CNIOBoringSSL/crypto/ec_extra/internal.h index 52bd74d2..e66400fc 100644 --- a/Sources/CNIOBoringSSL/crypto/ec_extra/internal.h +++ b/Sources/CNIOBoringSSL/crypto/ec_extra/internal.h @@ -26,16 +26,38 @@ extern "C" { // Hash-to-curve. // -// The following functions implement primitives from -// draft-irtf-cfrg-hash-to-curve. The |dst| parameter in each function is the -// domain separation tag and must be unique for each protocol and between the -// |hash_to_curve| and |hash_to_scalar| variants. See section 3.1 of the spec -// for additional guidance on this parameter. +// Internal |EC_RAW_POINT| versions of the corresponding public APIs. + +// ec_hash_to_curve_p256_xmd_sha256_sswu hashes |msg| to a point on |group| and +// writes the result to |out|, implementing the P256_XMD:SHA-256_SSWU_RO_ suite +// from draft-irtf-cfrg-hash-to-curve-16. It returns one on success and zero on +// error. +OPENSSL_EXPORT int ec_hash_to_curve_p256_xmd_sha256_sswu( + const EC_GROUP *group, EC_RAW_POINT *out, const uint8_t *dst, + size_t dst_len, const uint8_t *msg, size_t msg_len); + +// ec_hash_to_curve_p384_xmd_sha384_sswu hashes |msg| to a point on |group| and +// writes the result to |out|, implementing the P384_XMD:SHA-384_SSWU_RO_ suite +// from draft-irtf-cfrg-hash-to-curve-16. It returns one on success and zero on +// error. +OPENSSL_EXPORT int ec_hash_to_curve_p384_xmd_sha384_sswu( + const EC_GROUP *group, EC_RAW_POINT *out, const uint8_t *dst, + size_t dst_len, const uint8_t *msg, size_t msg_len); + +// ec_hash_to_scalar_p384_xmd_sha384 hashes |msg| to a scalar on |group| +// and writes the result to |out|, using the hash_to_field operation from the +// P384_XMD:SHA-384_SSWU_RO_ suite from draft-irtf-cfrg-hash-to-curve-16, but +// generating a value modulo the group order rather than a field element. +OPENSSL_EXPORT int ec_hash_to_scalar_p384_xmd_sha384( + const EC_GROUP *group, EC_SCALAR *out, const uint8_t *dst, size_t dst_len, + const uint8_t *msg, size_t msg_len); // ec_hash_to_curve_p384_xmd_sha512_sswu_draft07 hashes |msg| to a point on // |group| and writes the result to |out|, implementing the // P384_XMD:SHA-512_SSWU_RO_ suite from draft-irtf-cfrg-hash-to-curve-07. It // returns one on success and zero on error. +// +// TODO(https://crbug.com/1414562): Migrate this to the final version. OPENSSL_EXPORT int ec_hash_to_curve_p384_xmd_sha512_sswu_draft07( const EC_GROUP *group, EC_RAW_POINT *out, const uint8_t *dst, size_t dst_len, const uint8_t *msg, size_t msg_len); @@ -44,6 +66,8 @@ OPENSSL_EXPORT int ec_hash_to_curve_p384_xmd_sha512_sswu_draft07( // and writes the result to |out|, using the hash_to_field operation from the // P384_XMD:SHA-512_SSWU_RO_ suite from draft-irtf-cfrg-hash-to-curve-07, but // generating a value modulo the group order rather than a field element. +// +// TODO(https://crbug.com/1414562): Migrate this to the final version. OPENSSL_EXPORT int ec_hash_to_scalar_p384_xmd_sha512_draft07( const EC_GROUP *group, EC_SCALAR *out, const uint8_t *dst, size_t dst_len, const uint8_t *msg, size_t msg_len); diff --git a/Sources/CNIOBoringSSL/crypto/err/err.c b/Sources/CNIOBoringSSL/crypto/err/err.c index bf493b06..2314bc8c 100644 --- a/Sources/CNIOBoringSSL/crypto/err/err.c +++ b/Sources/CNIOBoringSSL/crypto/err/err.c @@ -106,11 +106,15 @@ * (eay@cryptsoft.com). This product includes software written by Tim * Hudson (tjh@cryptsoft.com). */ +// Ensure we can't call OPENSSL_malloc circularly. +#define _BORINGSSL_PROHIBIT_OPENSSL_MALLOC #include #include #include #include +#include +#include #include #if defined(OPENSSL_WINDOWS) @@ -129,8 +133,8 @@ OPENSSL_MSVC_PRAGMA(warning(pop)) struct err_error_st { // file contains the filename where the error occurred. const char *file; - // data contains a NUL-terminated string with optional data. It must be freed - // with |OPENSSL_free|. + // data contains a NUL-terminated string with optional data. It is allocated + // with system |malloc| and must be freed with |free| (not |OPENSSL_free|) char *data; // packed contains the error library and reason, as packed by ERR_PACK. uint32_t packed; @@ -162,7 +166,7 @@ extern const char kOpenSSLReasonStringData[]; // err_clear clears the given queued error. static void err_clear(struct err_error_st *error) { - OPENSSL_free(error->data); + free(error->data); OPENSSL_memset(error, 0, sizeof(struct err_error_st)); } @@ -170,12 +174,19 @@ static void err_copy(struct err_error_st *dst, const struct err_error_st *src) { err_clear(dst); dst->file = src->file; if (src->data != NULL) { - dst->data = OPENSSL_strdup(src->data); + // Disable deprecated functions on msvc so it doesn't complain about strdup. + OPENSSL_MSVC_PRAGMA(warning(push)) + OPENSSL_MSVC_PRAGMA(warning(disable : 4996)) + // We can't use OPENSSL_strdup because we don't want to call OPENSSL_malloc, + // which can affect the error stack. + dst->data = strdup(src->data); + OPENSSL_MSVC_PRAGMA(warning(pop)) } dst->packed = src->packed; dst->line = src->line; } + // global_next_library contains the next custom library value to return. static int global_next_library = ERR_NUM_LIBS; @@ -194,15 +205,15 @@ static void err_state_free(void *statep) { for (unsigned i = 0; i < ERR_NUM_ERRORS; i++) { err_clear(&state->errors[i]); } - OPENSSL_free(state->to_free); - OPENSSL_free(state); + free(state->to_free); + free(state); } // err_get_state gets the ERR_STATE object for the current thread. static ERR_STATE *err_get_state(void) { ERR_STATE *state = CRYPTO_get_thread_local(OPENSSL_THREAD_LOCAL_ERR); if (state == NULL) { - state = OPENSSL_malloc(sizeof(ERR_STATE)); + state = malloc(sizeof(ERR_STATE)); if (state == NULL) { return NULL; } @@ -258,7 +269,10 @@ static uint32_t get_error_values(int inc, int top, const char **file, int *line, } else { *data = error->data; if (flags != NULL) { - *flags = ERR_FLAG_STRING; + // Without |ERR_FLAG_MALLOCED|, rust-openssl assumes the string has a + // static lifetime. In both cases, we retain ownership of the string, + // and the caller is not expected to free it. + *flags = ERR_FLAG_STRING | ERR_FLAG_MALLOCED; } // If this error is being removed, take ownership of data from // the error. The semantics are such that the caller doesn't @@ -267,7 +281,7 @@ static uint32_t get_error_values(int inc, int top, const char **file, int *line, // error queue. if (inc) { if (error->data != NULL) { - OPENSSL_free(state->to_free); + free(state->to_free); state->to_free = error->data; } error->data = NULL; @@ -335,7 +349,7 @@ void ERR_clear_error(void) { for (i = 0; i < ERR_NUM_ERRORS; i++) { err_clear(&state->errors[i]); } - OPENSSL_free(state->to_free); + free(state->to_free); state->to_free = NULL; state->top = state->bottom = 0; @@ -629,13 +643,13 @@ static void err_set_error_data(char *data) { struct err_error_st *error; if (state == NULL || state->top == state->bottom) { - OPENSSL_free(data); + free(data); return; } error = &state->errors[state->top]; - OPENSSL_free(error->data); + free(error->data); error->data = data; } @@ -672,48 +686,42 @@ void ERR_put_error(int library, int unused, int reason, const char *file, // concatenates them and sets the result as the data on the most recent // error. static void err_add_error_vdata(unsigned num, va_list args) { - size_t alloced, new_len, len = 0, substr_len; - char *buf; + size_t total_size = 0; const char *substr; - unsigned i; + char *buf; - alloced = 80; - buf = OPENSSL_malloc(alloced + 1); - if (buf == NULL) { + va_list args_copy; + va_copy(args_copy, args); + for (size_t i = 0; i < num; i++) { + substr = va_arg(args_copy, const char *); + if (substr == NULL) { + continue; + } + size_t substr_len = strlen(substr); + if (SIZE_MAX - total_size < substr_len) { + return; // Would overflow. + } + total_size += substr_len; + } + va_end(args_copy); + if (total_size == SIZE_MAX) { + return; // Would overflow. + } + total_size += 1; // NUL terminator. + if ((buf = malloc(total_size)) == NULL) { return; } - - for (i = 0; i < num; i++) { + buf[0] = '\0'; + for (size_t i = 0; i < num; i++) { substr = va_arg(args, const char *); if (substr == NULL) { continue; } - - substr_len = strlen(substr); - new_len = len + substr_len; - if (new_len > alloced) { - char *new_buf; - - if (alloced + 20 + 1 < alloced) { - // overflow. - OPENSSL_free(buf); - return; - } - - alloced = new_len + 20; - new_buf = OPENSSL_realloc(buf, alloced + 1); - if (new_buf == NULL) { - OPENSSL_free(buf); - return; - } - buf = new_buf; + if (OPENSSL_strlcat(buf, substr, total_size) >= total_size) { + assert(0); // should not be possible. } - - OPENSSL_memcpy(buf + len, substr, substr_len); - len = new_len; } - - buf[len] = 0; + va_end(args); err_set_error_data(buf); } @@ -725,21 +733,13 @@ void ERR_add_error_data(unsigned count, ...) { } void ERR_add_error_dataf(const char *format, ...) { + char *buf = NULL; va_list ap; - char *buf; - static const unsigned buf_len = 256; - // A fixed-size buffer is used because va_copy (which would be needed in - // order to call vsnprintf twice and measure the buffer) wasn't defined until - // C99. - buf = OPENSSL_malloc(buf_len + 1); - if (buf == NULL) { + va_start(ap, format); + if (OPENSSL_vasprintf_internal(&buf, format, ap, /*system_malloc=*/1) == -1) { return; } - - va_start(ap, format); - BIO_vsnprintf(buf, buf_len, format, ap); - buf[buf_len] = 0; va_end(ap); err_set_error_data(buf); @@ -751,13 +751,20 @@ void ERR_set_error_data(char *data, int flags) { assert(0); return; } + // Disable deprecated functions on msvc so it doesn't complain about strdup. + OPENSSL_MSVC_PRAGMA(warning(push)) + OPENSSL_MSVC_PRAGMA(warning(disable : 4996)) + // We can not use OPENSSL_strdup because we don't want to call OPENSSL_malloc, + // which can affect the error stack. + char *copy = strdup(data); + OPENSSL_MSVC_PRAGMA(warning(pop)) + if (copy != NULL) { + err_set_error_data(copy); + } if (flags & ERR_FLAG_MALLOCED) { - err_set_error_data(data); - } else { - char *copy = OPENSSL_strdup(data); - if (copy != NULL) { - err_set_error_data(copy); - } + // We can not take ownership of |data| directly because it is allocated with + // |OPENSSL_malloc| and we will free it with system |free| later. + OPENSSL_free(data); } } @@ -819,8 +826,8 @@ void ERR_SAVE_STATE_free(ERR_SAVE_STATE *state) { for (size_t i = 0; i < state->num_errors; i++) { err_clear(&state->errors[i]); } - OPENSSL_free(state->errors); - OPENSSL_free(state); + free(state->errors); + free(state); } ERR_SAVE_STATE *ERR_save_state(void) { @@ -829,7 +836,7 @@ ERR_SAVE_STATE *ERR_save_state(void) { return NULL; } - ERR_SAVE_STATE *ret = OPENSSL_malloc(sizeof(ERR_SAVE_STATE)); + ERR_SAVE_STATE *ret = malloc(sizeof(ERR_SAVE_STATE)); if (ret == NULL) { return NULL; } @@ -839,9 +846,9 @@ ERR_SAVE_STATE *ERR_save_state(void) { ? state->top - state->bottom : ERR_NUM_ERRORS + state->top - state->bottom; assert(num_errors < ERR_NUM_ERRORS); - ret->errors = OPENSSL_malloc(num_errors * sizeof(struct err_error_st)); + ret->errors = malloc(num_errors * sizeof(struct err_error_st)); if (ret->errors == NULL) { - OPENSSL_free(ret); + free(ret); return NULL; } OPENSSL_memset(ret->errors, 0, num_errors * sizeof(struct err_error_st)); diff --git a/Sources/CNIOBoringSSL/crypto/err/err_data.c b/Sources/CNIOBoringSSL/crypto/err/err_data.c index a7f85ca9..15c90836 100644 --- a/Sources/CNIOBoringSSL/crypto/err/err_data.c +++ b/Sources/CNIOBoringSSL/crypto/err/err_data.c @@ -193,6 +193,7 @@ const uint32_t kOpenSSLReasonValues[] = { 0x283480b9, 0x283500f7, 0x28358cb7, + 0x2836099a, 0x2c3232bf, 0x2c329351, 0x2c3332cd, @@ -205,38 +206,39 @@ const uint32_t kOpenSSLReasonValues[] = { 0x2c36833a, 0x2c37336f, 0x2c37b39b, - 0x2c3833c0, - 0x2c38b3d7, - 0x2c3933f5, - 0x2c39b405, - 0x2c3a3417, - 0x2c3ab42b, - 0x2c3b343c, - 0x2c3bb45b, + 0x2c3833d9, + 0x2c38b3f0, + 0x2c39340e, + 0x2c39b41e, + 0x2c3a3430, + 0x2c3ab444, + 0x2c3b3455, + 0x2c3bb474, 0x2c3c1363, 0x2c3c9379, - 0x2c3d34a0, + 0x2c3d34b9, 0x2c3d9392, - 0x2c3e34ca, - 0x2c3eb4d8, - 0x2c3f34f0, - 0x2c3fb508, - 0x2c403532, + 0x2c3e34e3, + 0x2c3eb4f1, + 0x2c3f3509, + 0x2c3fb521, + 0x2c40354b, 0x2c409264, - 0x2c413543, - 0x2c41b556, + 0x2c41355c, + 0x2c41b56f, 0x2c42122a, - 0x2c42b567, + 0x2c42b580, 0x2c43076d, - 0x2c43b44d, + 0x2c43b466, 0x2c4433ae, - 0x2c44b515, + 0x2c44b52e, 0x2c453345, 0x2c45b381, - 0x2c4633e5, - 0x2c46b46f, - 0x2c473484, - 0x2c47b4bd, + 0x2c4633fe, + 0x2c46b488, + 0x2c47349d, + 0x2c47b4d6, + 0x2c4833c0, 0x30320000, 0x30328015, 0x3033001f, @@ -685,71 +687,71 @@ const uint32_t kOpenSSLReasonValues[] = { 0x4c41945b, 0x4c4215c4, 0x4c4293a3, - 0x50323579, - 0x5032b588, - 0x50333593, - 0x5033b5a3, - 0x503435bc, - 0x5034b5d6, - 0x503535e4, - 0x5035b5fa, - 0x5036360c, - 0x5036b622, - 0x5037363b, - 0x5037b64e, - 0x50383666, - 0x5038b677, - 0x5039368c, - 0x5039b6a0, - 0x503a36c0, - 0x503ab6d6, - 0x503b36ee, - 0x503bb700, - 0x503c371c, - 0x503cb733, - 0x503d374c, - 0x503db762, - 0x503e376f, - 0x503eb785, - 0x503f3797, + 0x50323592, + 0x5032b5a1, + 0x503335ac, + 0x5033b5bc, + 0x503435d5, + 0x5034b5ef, + 0x503535fd, + 0x5035b613, + 0x50363625, + 0x5036b63b, + 0x50373654, + 0x5037b667, + 0x5038367f, + 0x5038b690, + 0x503936a5, + 0x5039b6b9, + 0x503a36d9, + 0x503ab6ef, + 0x503b3707, + 0x503bb719, + 0x503c3735, + 0x503cb74c, + 0x503d3765, + 0x503db77b, + 0x503e3788, + 0x503eb79e, + 0x503f37b0, 0x503f83b3, - 0x504037aa, - 0x5040b7ba, - 0x504137d4, - 0x5041b7e3, - 0x504237fd, - 0x5042b81a, - 0x5043382a, - 0x5043b83a, - 0x50443857, + 0x504037c3, + 0x5040b7d3, + 0x504137ed, + 0x5041b7fc, + 0x50423816, + 0x5042b833, + 0x50433843, + 0x5043b853, + 0x50443870, 0x50448469, - 0x5045386b, - 0x5045b889, - 0x5046389c, - 0x5046b8b2, - 0x504738c4, - 0x5047b8d9, - 0x504838ff, - 0x5048b90d, - 0x50493920, - 0x5049b935, - 0x504a394b, - 0x504ab95b, - 0x504b397b, - 0x504bb98e, - 0x504c39b1, - 0x504cb9df, - 0x504d3a0c, - 0x504dba29, - 0x504e3a44, - 0x504eba60, - 0x504f3a72, - 0x504fba89, - 0x50503a98, + 0x50453884, + 0x5045b8a2, + 0x504638b5, + 0x5046b8cb, + 0x504738dd, + 0x5047b8f2, + 0x50483918, + 0x5048b926, + 0x50493939, + 0x5049b94e, + 0x504a3964, + 0x504ab974, + 0x504b3994, + 0x504bb9a7, + 0x504c39ca, + 0x504cb9f8, + 0x504d3a25, + 0x504dba42, + 0x504e3a5d, + 0x504eba79, + 0x504f3a8b, + 0x504fbaa2, + 0x50503ab1, 0x50508729, - 0x50513aab, - 0x5051b849, - 0x505239f1, + 0x50513ac4, + 0x5051b862, + 0x50523a0a, 0x58320fb0, 0x68320f72, 0x68328cca, @@ -757,6 +759,7 @@ const uint32_t kOpenSSLReasonValues[] = { 0x68338f80, 0x68340f90, 0x683480f7, + 0x6835099a, 0x6c320f38, 0x6c328c81, 0x6c330f43, @@ -1416,6 +1419,7 @@ const char kOpenSSLReasonStringData[] = "INVALID_FIELD_FOR_VERSION\0" "INVALID_FIELD_NAME\0" "INVALID_PARAMETER\0" + "INVALID_POLICY_EXTENSION\0" "INVALID_PSS_PARAMETERS\0" "INVALID_TRUST\0" "INVALID_VERSION\0" diff --git a/Sources/CNIOBoringSSL/crypto/evp/evp.c b/Sources/CNIOBoringSSL/crypto/evp/evp.c index a0bb7405..df113f85 100644 --- a/Sources/CNIOBoringSSL/crypto/evp/evp.c +++ b/Sources/CNIOBoringSSL/crypto/evp/evp.c @@ -85,7 +85,6 @@ EVP_PKEY *EVP_PKEY_new(void) { ret = OPENSSL_malloc(sizeof(EVP_PKEY)); if (ret == NULL) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); return NULL; } @@ -99,7 +98,7 @@ EVP_PKEY *EVP_PKEY_new(void) { static void free_it(EVP_PKEY *pkey) { if (pkey->ameth && pkey->ameth->pkey_free) { pkey->ameth->pkey_free(pkey); - pkey->pkey.ptr = NULL; + pkey->pkey = NULL; pkey->type = EVP_PKEY_NONE; } } @@ -153,21 +152,35 @@ int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { } int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) { - if (to->type != from->type) { + if (to->type == EVP_PKEY_NONE) { + if (!EVP_PKEY_set_type(to, from->type)) { + return 0; + } + } else if (to->type != from->type) { OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_KEY_TYPES); - goto err; + return 0; } if (EVP_PKEY_missing_parameters(from)) { OPENSSL_PUT_ERROR(EVP, EVP_R_MISSING_PARAMETERS); - goto err; + return 0; + } + + // Once set, parameters may not change. + if (!EVP_PKEY_missing_parameters(to)) { + if (EVP_PKEY_cmp_parameters(to, from) == 1) { + return 1; + } + OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_PARAMETERS); + return 0; } if (from->ameth && from->ameth->param_copy) { return from->ameth->param_copy(to, from); } -err: + // TODO(https://crbug.com/boringssl/536): If the algorithm takes no + // parameters, copying them should vacuously succeed. return 0; } @@ -241,7 +254,7 @@ RSA *EVP_PKEY_get0_RSA(const EVP_PKEY *pkey) { OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_AN_RSA_KEY); return NULL; } - return pkey->pkey.rsa; + return pkey->pkey; } RSA *EVP_PKEY_get1_RSA(const EVP_PKEY *pkey) { @@ -269,7 +282,7 @@ DSA *EVP_PKEY_get0_DSA(const EVP_PKEY *pkey) { OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_A_DSA_KEY); return NULL; } - return pkey->pkey.dsa; + return pkey->pkey; } DSA *EVP_PKEY_get1_DSA(const EVP_PKEY *pkey) { @@ -297,7 +310,7 @@ EC_KEY *EVP_PKEY_get0_EC_KEY(const EVP_PKEY *pkey) { OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_AN_EC_KEY_KEY); return NULL; } - return pkey->pkey.ec; + return pkey->pkey; } EC_KEY *EVP_PKEY_get1_EC_KEY(const EVP_PKEY *pkey) { @@ -315,14 +328,14 @@ int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key) { if (!EVP_PKEY_set_type(pkey, type)) { return 0; } - pkey->pkey.ptr = key; + pkey->pkey = key; return key != NULL; } int EVP_PKEY_set_type(EVP_PKEY *pkey, int type) { const EVP_PKEY_ASN1_METHOD *ameth; - if (pkey && pkey->pkey.ptr) { + if (pkey && pkey->pkey) { free_it(pkey); } @@ -416,6 +429,8 @@ int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) { if (a->ameth && a->ameth->param_cmp) { return a->ameth->param_cmp(a, b); } + // TODO(https://crbug.com/boringssl/536): If the algorithm doesn't use + // parameters, they should compare as vacuously equal. return -2; } @@ -432,7 +447,7 @@ int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **out_md) { void *EVP_PKEY_get0(const EVP_PKEY *pkey) { // Node references, but never calls this function, so for now we return NULL. // If other projects require complete support, call |EVP_PKEY_get0_RSA|, etc., - // rather than reading |pkey->pkey.ptr| directly. This avoids problems if our + // rather than reading |pkey->pkey| directly. This avoids problems if our // internal representation does not match the type the caller expects from // OpenSSL. return NULL; @@ -448,6 +463,25 @@ void OpenSSL_add_all_digests(void) {} void EVP_cleanup(void) {} +int EVP_PKEY_set1_tls_encodedpoint(EVP_PKEY *pkey, const uint8_t *in, + size_t len) { + if (pkey->ameth->set1_tls_encodedpoint == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + + return pkey->ameth->set1_tls_encodedpoint(pkey, in, len); +} + +size_t EVP_PKEY_get1_tls_encodedpoint(const EVP_PKEY *pkey, uint8_t **out_ptr) { + if (pkey->ameth->get1_tls_encodedpoint == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + + return pkey->ameth->get1_tls_encodedpoint(pkey, out_ptr); +} + int EVP_PKEY_base_id(const EVP_PKEY *pkey) { // OpenSSL has two notions of key type because it supports multiple OIDs for // the same algorithm: NID_rsa vs NID_rsaEncryption and five distinct spelling diff --git a/Sources/CNIOBoringSSL/crypto/evp/evp_asn1.c b/Sources/CNIOBoringSSL/crypto/evp/evp_asn1.c index 78e276a5..8bafb367 100644 --- a/Sources/CNIOBoringSSL/crypto/evp/evp_asn1.c +++ b/Sources/CNIOBoringSSL/crypto/evp/evp_asn1.c @@ -336,11 +336,11 @@ EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **out, const uint8_t **inp, long len) { int i2d_PublicKey(const EVP_PKEY *key, uint8_t **outp) { switch (key->type) { case EVP_PKEY_RSA: - return i2d_RSAPublicKey(key->pkey.rsa, outp); + return i2d_RSAPublicKey(EVP_PKEY_get0_RSA(key), outp); case EVP_PKEY_DSA: - return i2d_DSAPublicKey(key->pkey.dsa, outp); + return i2d_DSAPublicKey(EVP_PKEY_get0_DSA(key), outp); case EVP_PKEY_EC: - return i2o_ECPublicKey(key->pkey.ec, outp); + return i2o_ECPublicKey(EVP_PKEY_get0_EC_KEY(key), outp); default: OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE); return -1; diff --git a/Sources/CNIOBoringSSL/crypto/evp/evp_ctx.c b/Sources/CNIOBoringSSL/crypto/evp/evp_ctx.c index ec074d61..fa65d444 100644 --- a/Sources/CNIOBoringSSL/crypto/evp/evp_ctx.c +++ b/Sources/CNIOBoringSSL/crypto/evp/evp_ctx.c @@ -88,7 +88,6 @@ static EVP_PKEY_CTX *evp_pkey_ctx_new(EVP_PKEY *pkey, ENGINE *e, const EVP_PKEY_METHOD *pmeth) { EVP_PKEY_CTX *ret = OPENSSL_malloc(sizeof(EVP_PKEY_CTX)); if (!ret) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); return NULL; } OPENSSL_memset(ret, 0, sizeof(EVP_PKEY_CTX)); diff --git a/Sources/CNIOBoringSSL/crypto/evp/internal.h b/Sources/CNIOBoringSSL/crypto/evp/internal.h index 5a7ba278..1fc5e7fc 100644 --- a/Sources/CNIOBoringSSL/crypto/evp/internal.h +++ b/Sources/CNIOBoringSSL/crypto/evp/internal.h @@ -66,6 +66,9 @@ extern "C" { #endif +typedef struct evp_pkey_asn1_method_st EVP_PKEY_ASN1_METHOD; +typedef struct evp_pkey_method_st EVP_PKEY_METHOD; + struct evp_pkey_asn1_method_st { int pkey_id; uint8_t oid[9]; @@ -103,6 +106,17 @@ struct evp_pkey_asn1_method_st { int (*get_priv_raw)(const EVP_PKEY *pkey, uint8_t *out, size_t *out_len); int (*get_pub_raw)(const EVP_PKEY *pkey, uint8_t *out, size_t *out_len); + // TODO(davidben): Can these be merged with the functions above? OpenSSL does + // not implement |EVP_PKEY_get_raw_public_key|, etc., for |EVP_PKEY_EC|, but + // the distinction seems unimportant. OpenSSL 3.0 has since renamed + // |EVP_PKEY_get1_tls_encodedpoint| to |EVP_PKEY_get1_encoded_public_key|, and + // what is the difference between "raw" and an "encoded" public key. + // + // One nuisance is the notion of "raw" is slightly ambiguous for EC keys. Is + // it a DER ECPrivateKey or just the scalar? + int (*set1_tls_encodedpoint)(EVP_PKEY *pkey, const uint8_t *in, size_t len); + size_t (*get1_tls_encodedpoint)(const EVP_PKEY *pkey, uint8_t **out_ptr); + // pkey_opaque returns 1 if the |pk| is opaque. Opaque keys are backed by // custom implementations which do not expose key material and parameters. int (*pkey_opaque)(const EVP_PKEY *pk); @@ -117,6 +131,20 @@ struct evp_pkey_asn1_method_st { void (*pkey_free)(EVP_PKEY *pkey); } /* EVP_PKEY_ASN1_METHOD */; +struct evp_pkey_st { + CRYPTO_refcount_t references; + + // type contains one of the EVP_PKEY_* values or NID_undef and determines + // the type of |pkey|. + int type; + + // pkey contains a pointer to a structure dependent on |type|. + void *pkey; + + // ameth contains a pointer to a method table that contains many ASN.1 + // methods for the key type. + const EVP_PKEY_ASN1_METHOD *ameth; +} /* EVP_PKEY */; #define EVP_PKEY_OP_UNDEFINED 0 #define EVP_PKEY_OP_KEYGEN (1 << 2) diff --git a/Sources/CNIOBoringSSL/crypto/evp/p_dsa_asn1.c b/Sources/CNIOBoringSSL/crypto/evp/p_dsa_asn1.c index b12a7768..7d40547a 100644 --- a/Sources/CNIOBoringSSL/crypto/evp/p_dsa_asn1.c +++ b/Sources/CNIOBoringSSL/crypto/evp/p_dsa_asn1.c @@ -61,6 +61,7 @@ #include #include +#include "../dsa/internal.h" #include "internal.h" @@ -102,7 +103,7 @@ static int dsa_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { } static int dsa_pub_encode(CBB *out, const EVP_PKEY *key) { - const DSA *dsa = key->pkey.dsa; + const DSA *dsa = key->pkey; const int has_params = dsa->p != NULL && dsa->q != NULL && dsa->g != NULL; // See RFC 5480, section 2. @@ -136,25 +137,27 @@ static int dsa_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { } dsa->priv_key = BN_new(); - dsa->pub_key = BN_new(); - if (dsa->priv_key == NULL || dsa->pub_key == NULL) { + if (dsa->priv_key == NULL) { goto err; } - - // Decode the key. To avoid DoS attacks when importing private keys, we bound - // |dsa->priv_key| against |dsa->q|, which itself bound by - // |DSA_parse_parameters|. (We cannot call |BN_num_bits| on |dsa->priv_key|. - // That would leak a secret bit width.) if (!BN_parse_asn1_unsigned(key, dsa->priv_key) || - CBS_len(key) != 0 || - BN_cmp(dsa->priv_key, dsa->q) >= 0) { + CBS_len(key) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + goto err; + } + + // To avoid DoS attacks when importing private keys, check bounds on |dsa|. + // This bounds |dsa->priv_key| against |dsa->q| and bounds |dsa->q|'s bit + // width. + if (!dsa_check_key(dsa)) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); goto err; } // Calculate the public key. ctx = BN_CTX_new(); - if (ctx == NULL || + dsa->pub_key = BN_new(); + if (ctx == NULL || dsa->pub_key == NULL || !BN_mod_exp_mont_consttime(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx, NULL)) { goto err; @@ -171,7 +174,7 @@ static int dsa_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { } static int dsa_priv_encode(CBB *out, const EVP_PKEY *key) { - const DSA *dsa = key->pkey.dsa; + const DSA *dsa = key->pkey; if (dsa == NULL || dsa->priv_key == NULL) { OPENSSL_PUT_ERROR(EVP, EVP_R_MISSING_PARAMETERS); return 0; @@ -196,17 +199,19 @@ static int dsa_priv_encode(CBB *out, const EVP_PKEY *key) { } static int int_dsa_size(const EVP_PKEY *pkey) { - return DSA_size(pkey->pkey.dsa); + const DSA *dsa = pkey->pkey; + return DSA_size(dsa); } static int dsa_bits(const EVP_PKEY *pkey) { - return BN_num_bits(pkey->pkey.dsa->p); + const DSA *dsa = pkey->pkey; + return BN_num_bits(DSA_get0_p(dsa)); } static int dsa_missing_parameters(const EVP_PKEY *pkey) { - DSA *dsa; - dsa = pkey->pkey.dsa; - if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) { + const DSA *dsa = pkey->pkey; + if (DSA_get0_p(dsa) == NULL || DSA_get0_q(dsa) == NULL || + DSA_get0_g(dsa) == NULL) { return 1; } return 0; @@ -226,9 +231,11 @@ static int dup_bn_into(BIGNUM **out, BIGNUM *src) { } static int dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) { - if (!dup_bn_into(&to->pkey.dsa->p, from->pkey.dsa->p) || - !dup_bn_into(&to->pkey.dsa->q, from->pkey.dsa->q) || - !dup_bn_into(&to->pkey.dsa->g, from->pkey.dsa->g)) { + DSA *to_dsa = to->pkey; + const DSA *from_dsa = from->pkey; + if (!dup_bn_into(&to_dsa->p, from_dsa->p) || + !dup_bn_into(&to_dsa->q, from_dsa->q) || + !dup_bn_into(&to_dsa->g, from_dsa->g)) { return 0; } @@ -236,46 +243,56 @@ static int dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) { } static int dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) { - return BN_cmp(a->pkey.dsa->p, b->pkey.dsa->p) == 0 && - BN_cmp(a->pkey.dsa->q, b->pkey.dsa->q) == 0 && - BN_cmp(a->pkey.dsa->g, b->pkey.dsa->g) == 0; + const DSA *a_dsa = a->pkey; + const DSA *b_dsa = b->pkey; + return BN_cmp(DSA_get0_p(a_dsa), DSA_get0_p(b_dsa)) == 0 && + BN_cmp(DSA_get0_q(a_dsa), DSA_get0_q(b_dsa)) == 0 && + BN_cmp(DSA_get0_g(a_dsa), DSA_get0_g(b_dsa)) == 0; } static int dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { - return BN_cmp(b->pkey.dsa->pub_key, a->pkey.dsa->pub_key) == 0; + const DSA *a_dsa = a->pkey; + const DSA *b_dsa = b->pkey; + return BN_cmp(DSA_get0_pub_key(b_dsa), DSA_get0_pub_key(a_dsa)) == 0; } -static void int_dsa_free(EVP_PKEY *pkey) { DSA_free(pkey->pkey.dsa); } +static void int_dsa_free(EVP_PKEY *pkey) { + DSA_free(pkey->pkey); + pkey->pkey = NULL; +} const EVP_PKEY_ASN1_METHOD dsa_asn1_meth = { - EVP_PKEY_DSA, - // 1.2.840.10040.4.1 - {0x2a, 0x86, 0x48, 0xce, 0x38, 0x04, 0x01}, 7, + EVP_PKEY_DSA, + // 1.2.840.10040.4.1 + {0x2a, 0x86, 0x48, 0xce, 0x38, 0x04, 0x01}, + 7, - NULL /* pkey_method */, + /*pkey_method=*/NULL, - dsa_pub_decode, - dsa_pub_encode, - dsa_pub_cmp, + dsa_pub_decode, + dsa_pub_encode, + dsa_pub_cmp, - dsa_priv_decode, - dsa_priv_encode, + dsa_priv_decode, + dsa_priv_encode, - NULL /* set_priv_raw */, - NULL /* set_pub_raw */, - NULL /* get_priv_raw */, - NULL /* get_pub_raw */, + /*set_priv_raw=*/NULL, + /*set_pub_raw=*/NULL, + /*get_priv_raw=*/NULL, + /*get_pub_raw=*/NULL, + /*set1_tls_encodedpoint=*/NULL, + /*get1_tls_encodedpoint=*/NULL, - NULL /* pkey_opaque */, + /*pkey_opaque=*/NULL, - int_dsa_size, - dsa_bits, + int_dsa_size, + dsa_bits, - dsa_missing_parameters, - dsa_copy_parameters, - dsa_cmp_parameters, + dsa_missing_parameters, + dsa_copy_parameters, + dsa_cmp_parameters, - int_dsa_free, + int_dsa_free, }; int EVP_PKEY_CTX_set_dsa_paramgen_bits(EVP_PKEY_CTX *ctx, int nbits) { diff --git a/Sources/CNIOBoringSSL/crypto/evp/p_ec.c b/Sources/CNIOBoringSSL/crypto/evp/p_ec.c index 3dae2282..ca09331b 100644 --- a/Sources/CNIOBoringSSL/crypto/evp/p_ec.c +++ b/Sources/CNIOBoringSSL/crypto/evp/p_ec.c @@ -117,9 +117,7 @@ static void pkey_ec_cleanup(EVP_PKEY_CTX *ctx) { static int pkey_ec_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen, const uint8_t *tbs, size_t tbslen) { - unsigned int sltmp; - EC_KEY *ec = ctx->pkey->pkey.ec; - + const EC_KEY *ec = ctx->pkey->pkey; if (!sig) { *siglen = ECDSA_size(ec); return 1; @@ -128,6 +126,7 @@ static int pkey_ec_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen, return 0; } + unsigned int sltmp; if (!ECDSA_sign(0, tbs, tbslen, sig, &sltmp, ec)) { return 0; } @@ -137,37 +136,32 @@ static int pkey_ec_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen, static int pkey_ec_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig, size_t siglen, const uint8_t *tbs, size_t tbslen) { - return ECDSA_verify(0, tbs, tbslen, sig, siglen, ctx->pkey->pkey.ec); + const EC_KEY *ec_key = ctx->pkey->pkey; + return ECDSA_verify(0, tbs, tbslen, sig, siglen, ec_key); } static int pkey_ec_derive(EVP_PKEY_CTX *ctx, uint8_t *key, size_t *keylen) { - int ret; - size_t outlen; - const EC_POINT *pubkey = NULL; - EC_KEY *eckey; - if (!ctx->pkey || !ctx->peerkey) { OPENSSL_PUT_ERROR(EVP, EVP_R_KEYS_NOT_SET); return 0; } - eckey = ctx->pkey->pkey.ec; - + const EC_KEY *eckey = ctx->pkey->pkey; if (!key) { const EC_GROUP *group; group = EC_KEY_get0_group(eckey); *keylen = (EC_GROUP_get_degree(group) + 7) / 8; return 1; } - pubkey = EC_KEY_get0_public_key(ctx->peerkey->pkey.ec); + + const EC_KEY *eckey_peer = ctx->peerkey->pkey; + const EC_POINT *pubkey = EC_KEY_get0_public_key(eckey_peer); // NB: unlike PKCS#3 DH, if *outlen is less than maximum size this is // not an error, the result is truncated. - - outlen = *keylen; - - ret = ECDH_compute_key(key, outlen, pubkey, eckey, 0); + size_t outlen = *keylen; + int ret = ECDH_compute_key(key, outlen, pubkey, eckey, 0); if (ret < 0) { return 0; } @@ -224,7 +218,7 @@ static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { OPENSSL_PUT_ERROR(EVP, EVP_R_NO_PARAMETERS_SET); return 0; } - group = EC_KEY_get0_group(ctx->pkey->pkey.ec); + group = EC_KEY_get0_group(ctx->pkey->pkey); } EC_KEY *ec = EC_KEY_new(); if (ec == NULL || diff --git a/Sources/CNIOBoringSSL/crypto/evp/p_ec_asn1.c b/Sources/CNIOBoringSSL/crypto/evp/p_ec_asn1.c index ac0ea788..fadddb0d 100644 --- a/Sources/CNIOBoringSSL/crypto/evp/p_ec_asn1.c +++ b/Sources/CNIOBoringSSL/crypto/evp/p_ec_asn1.c @@ -66,7 +66,7 @@ static int eckey_pub_encode(CBB *out, const EVP_PKEY *key) { - const EC_KEY *ec_key = key->pkey.ec; + const EC_KEY *ec_key = key->pkey; const EC_GROUP *group = EC_KEY_get0_group(ec_key); const EC_POINT *public_key = EC_KEY_get0_public_key(ec_key); @@ -93,7 +93,6 @@ static int eckey_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { // See RFC 5480, section 2. // The parameters are a named curve. - EC_POINT *point = NULL; EC_KEY *eckey = NULL; EC_GROUP *group = EC_KEY_parse_curve_name(params); if (group == NULL || CBS_len(params) != 0) { @@ -102,35 +101,29 @@ static int eckey_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { } eckey = EC_KEY_new(); - if (eckey == NULL || !EC_KEY_set_group(eckey, group)) { - goto err; - } - - 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)) { + if (eckey == NULL || // + !EC_KEY_set_group(eckey, group) || + !EC_KEY_oct2key(eckey, CBS_data(key), CBS_len(key), NULL)) { goto err; } EC_GROUP_free(group); - EC_POINT_free(point); EVP_PKEY_assign_EC_KEY(out, eckey); return 1; err: EC_GROUP_free(group); - EC_POINT_free(point); EC_KEY_free(eckey); return 0; } static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { - int r; - const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec); - const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec), - *pb = EC_KEY_get0_public_key(b->pkey.ec); - r = EC_POINT_cmp(group, pa, pb, NULL); + const EC_KEY *a_ec = a->pkey; + const EC_KEY *b_ec = b->pkey; + const EC_GROUP *group = EC_KEY_get0_group(b_ec); + const EC_POINT *pa = EC_KEY_get0_public_key(a_ec), + *pb = EC_KEY_get0_public_key(b_ec); + int r = EC_POINT_cmp(group, pa, pb, NULL); if (r == 0) { return 1; } else if (r == 1) { @@ -162,7 +155,7 @@ static int eckey_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { } static int eckey_priv_encode(CBB *out, const EVP_PKEY *key) { - const EC_KEY *ec_key = key->pkey.ec; + const EC_KEY *ec_key = key->pkey; // 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 @@ -188,12 +181,36 @@ static int eckey_priv_encode(CBB *out, const EVP_PKEY *key) { return 1; } +static int eckey_set1_tls_encodedpoint(EVP_PKEY *pkey, const uint8_t *in, + size_t len) { + EC_KEY *ec_key = pkey->pkey; + if (ec_key == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_NO_KEY_SET); + return 0; + } + + return EC_KEY_oct2key(ec_key, in, len, NULL); +} + +static size_t eckey_get1_tls_encodedpoint(const EVP_PKEY *pkey, + uint8_t **out_ptr) { + const EC_KEY *ec_key = pkey->pkey; + if (ec_key == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_NO_KEY_SET); + return 0; + } + + return EC_KEY_key2buf(ec_key, POINT_CONVERSION_UNCOMPRESSED, out_ptr, NULL); +} + static int int_ec_size(const EVP_PKEY *pkey) { - return ECDSA_size(pkey->pkey.ec); + const EC_KEY *ec_key = pkey->pkey; + return ECDSA_size(ec_key); } static int ec_bits(const EVP_PKEY *pkey) { - const EC_GROUP *group = EC_KEY_get0_group(pkey->pkey.ec); + const EC_KEY *ec_key = pkey->pkey; + const EC_GROUP *group = EC_KEY_get0_group(ec_key); if (group == NULL) { ERR_clear_error(); return 0; @@ -202,16 +219,41 @@ static int ec_bits(const EVP_PKEY *pkey) { } static int ec_missing_parameters(const EVP_PKEY *pkey) { - return EC_KEY_get0_group(pkey->pkey.ec) == NULL; + const EC_KEY *ec_key = pkey->pkey; + return ec_key == NULL || EC_KEY_get0_group(ec_key) == NULL; } static int ec_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) { - return EC_KEY_set_group(to->pkey.ec, EC_KEY_get0_group(from->pkey.ec)); + const EC_KEY *from_key = from->pkey; + if (from_key == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_NO_KEY_SET); + return 0; + } + const EC_GROUP *group = EC_KEY_get0_group(from_key); + if (group == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_MISSING_PARAMETERS); + return 0; + } + if (to->pkey == NULL) { + to->pkey = EC_KEY_new(); + if (to->pkey == NULL) { + return 0; + } + } + return EC_KEY_set_group(to->pkey, group); } static int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) { - const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec), - *group_b = EC_KEY_get0_group(b->pkey.ec); + const EC_KEY *a_ec = a->pkey; + const EC_KEY *b_ec = b->pkey; + if (a_ec == NULL || b_ec == NULL) { + return -2; + } + const EC_GROUP *group_a = EC_KEY_get0_group(a_ec), + *group_b = EC_KEY_get0_group(b_ec); + if (group_a == NULL || group_b == NULL) { + return -2; + } if (EC_GROUP_cmp(group_a, group_b, NULL) != 0) { // mismatch return 0; @@ -219,39 +261,46 @@ static int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) { return 1; } -static void int_ec_free(EVP_PKEY *pkey) { EC_KEY_free(pkey->pkey.ec); } +static void int_ec_free(EVP_PKEY *pkey) { + EC_KEY_free(pkey->pkey); + pkey->pkey = NULL; +} static int eckey_opaque(const EVP_PKEY *pkey) { - return EC_KEY_is_opaque(pkey->pkey.ec); + const EC_KEY *ec_key = pkey->pkey; + return EC_KEY_is_opaque(ec_key); } const EVP_PKEY_ASN1_METHOD ec_asn1_meth = { - EVP_PKEY_EC, - // 1.2.840.10045.2.1 - {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01}, 7, + EVP_PKEY_EC, + // 1.2.840.10045.2.1 + {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01}, + 7, - &ec_pkey_meth, + &ec_pkey_meth, - eckey_pub_decode, - eckey_pub_encode, - eckey_pub_cmp, + eckey_pub_decode, + eckey_pub_encode, + eckey_pub_cmp, - eckey_priv_decode, - eckey_priv_encode, + eckey_priv_decode, + eckey_priv_encode, - NULL /* set_priv_raw */, - NULL /* set_pub_raw */, - NULL /* get_priv_raw */, - NULL /* get_pub_raw */, + /*set_priv_raw=*/NULL, + /*set_pub_raw=*/NULL, + /*get_priv_raw=*/NULL, + /*get_pub_raw=*/NULL, + eckey_set1_tls_encodedpoint, + eckey_get1_tls_encodedpoint, - eckey_opaque, + eckey_opaque, - int_ec_size, - ec_bits, + int_ec_size, + ec_bits, - ec_missing_parameters, - ec_copy_parameters, - ec_cmp_parameters, + ec_missing_parameters, + ec_copy_parameters, + ec_cmp_parameters, - int_ec_free, + int_ec_free, }; diff --git a/Sources/CNIOBoringSSL/crypto/evp/p_ed25519.c b/Sources/CNIOBoringSSL/crypto/evp/p_ed25519.c index 00fa9aab..33acd5c5 100644 --- a/Sources/CNIOBoringSSL/crypto/evp/p_ed25519.c +++ b/Sources/CNIOBoringSSL/crypto/evp/p_ed25519.c @@ -27,7 +27,6 @@ static int pkey_ed25519_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) { return 1; } static int pkey_ed25519_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { ED25519_KEY *key = OPENSSL_malloc(sizeof(ED25519_KEY)); if (key == NULL) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); return 0; } @@ -40,15 +39,15 @@ static int pkey_ed25519_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { ED25519_keypair(pubkey_unused, key->key); key->has_private = 1; - OPENSSL_free(pkey->pkey.ptr); - pkey->pkey.ptr = key; + OPENSSL_free(pkey->pkey); + pkey->pkey = key; return 1; } static int pkey_ed25519_sign_message(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen, const uint8_t *tbs, size_t tbslen) { - ED25519_KEY *key = ctx->pkey->pkey.ptr; + const ED25519_KEY *key = ctx->pkey->pkey; if (!key->has_private) { OPENSSL_PUT_ERROR(EVP, EVP_R_NOT_A_PRIVATE_KEY); return 0; @@ -75,7 +74,7 @@ static int pkey_ed25519_sign_message(EVP_PKEY_CTX *ctx, uint8_t *sig, static int pkey_ed25519_verify_message(EVP_PKEY_CTX *ctx, const uint8_t *sig, size_t siglen, const uint8_t *tbs, size_t tbslen) { - ED25519_KEY *key = ctx->pkey->pkey.ptr; + const ED25519_KEY *key = ctx->pkey->pkey; if (siglen != 64 || !ED25519_verify(tbs, tbslen, sig, key->key + ED25519_PUBLIC_KEY_OFFSET)) { OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_SIGNATURE); diff --git a/Sources/CNIOBoringSSL/crypto/evp/p_ed25519_asn1.c b/Sources/CNIOBoringSSL/crypto/evp/p_ed25519_asn1.c index d85a68f5..cecaa5f5 100644 --- a/Sources/CNIOBoringSSL/crypto/evp/p_ed25519_asn1.c +++ b/Sources/CNIOBoringSSL/crypto/evp/p_ed25519_asn1.c @@ -24,8 +24,8 @@ static void ed25519_free(EVP_PKEY *pkey) { - OPENSSL_free(pkey->pkey.ptr); - pkey->pkey.ptr = NULL; + OPENSSL_free(pkey->pkey); + pkey->pkey = NULL; } static int ed25519_set_priv_raw(EVP_PKEY *pkey, const uint8_t *in, size_t len) { @@ -36,7 +36,6 @@ static int ed25519_set_priv_raw(EVP_PKEY *pkey, const uint8_t *in, size_t len) { ED25519_KEY *key = OPENSSL_malloc(sizeof(ED25519_KEY)); if (key == NULL) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); return 0; } @@ -47,7 +46,7 @@ static int ed25519_set_priv_raw(EVP_PKEY *pkey, const uint8_t *in, size_t len) { key->has_private = 1; ed25519_free(pkey); - pkey->pkey.ptr = key; + pkey->pkey = key; return 1; } @@ -59,7 +58,6 @@ static int ed25519_set_pub_raw(EVP_PKEY *pkey, const uint8_t *in, size_t len) { ED25519_KEY *key = OPENSSL_malloc(sizeof(ED25519_KEY)); if (key == NULL) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); return 0; } @@ -67,13 +65,13 @@ static int ed25519_set_pub_raw(EVP_PKEY *pkey, const uint8_t *in, size_t len) { key->has_private = 0; ed25519_free(pkey); - pkey->pkey.ptr = key; + pkey->pkey = key; return 1; } static int ed25519_get_priv_raw(const EVP_PKEY *pkey, uint8_t *out, size_t *out_len) { - const ED25519_KEY *key = pkey->pkey.ptr; + const ED25519_KEY *key = pkey->pkey; if (!key->has_private) { OPENSSL_PUT_ERROR(EVP, EVP_R_NOT_A_PRIVATE_KEY); return 0; @@ -97,7 +95,7 @@ static int ed25519_get_priv_raw(const EVP_PKEY *pkey, uint8_t *out, static int ed25519_get_pub_raw(const EVP_PKEY *pkey, uint8_t *out, size_t *out_len) { - const ED25519_KEY *key = pkey->pkey.ptr; + const ED25519_KEY *key = pkey->pkey; if (out == NULL) { *out_len = 32; return 1; @@ -126,7 +124,7 @@ static int ed25519_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { } static int ed25519_pub_encode(CBB *out, const EVP_PKEY *pkey) { - const ED25519_KEY *key = pkey->pkey.ptr; + const ED25519_KEY *key = pkey->pkey; // See RFC 8410, section 4. CBB spki, algorithm, oid, key_bitstring; @@ -147,8 +145,8 @@ static int ed25519_pub_encode(CBB *out, const EVP_PKEY *pkey) { } static int ed25519_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { - const ED25519_KEY *a_key = a->pkey.ptr; - const ED25519_KEY *b_key = b->pkey.ptr; + const ED25519_KEY *a_key = a->pkey; + const ED25519_KEY *b_key = b->pkey; return OPENSSL_memcmp(a_key->key + ED25519_PUBLIC_KEY_OFFSET, b_key->key + ED25519_PUBLIC_KEY_OFFSET, 32) == 0; } @@ -170,7 +168,7 @@ static int ed25519_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { } static int ed25519_priv_encode(CBB *out, const EVP_PKEY *pkey) { - ED25519_KEY *key = pkey->pkey.ptr; + const ED25519_KEY *key = pkey->pkey; if (!key->has_private) { OPENSSL_PUT_ERROR(EVP, EVP_R_NOT_A_PRIVATE_KEY); return 0; @@ -214,11 +212,13 @@ const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = { ed25519_set_pub_raw, ed25519_get_priv_raw, ed25519_get_pub_raw, - NULL /* pkey_opaque */, + /*set1_tls_encodedpoint=*/NULL, + /*get1_tls_encodedpoint=*/NULL, + /*pkey_opaque=*/NULL, ed25519_size, ed25519_bits, - NULL /* param_missing */, - NULL /* param_copy */, - NULL /* param_cmp */, + /*param_missing=*/NULL, + /*param_copy=*/NULL, + /*param_cmp=*/NULL, ed25519_free, }; diff --git a/Sources/CNIOBoringSSL/crypto/evp/p_hkdf.c b/Sources/CNIOBoringSSL/crypto/evp/p_hkdf.c index 64c031cb..9ae70057 100644 --- a/Sources/CNIOBoringSSL/crypto/evp/p_hkdf.c +++ b/Sources/CNIOBoringSSL/crypto/evp/p_hkdf.c @@ -37,13 +37,11 @@ typedef struct { static int pkey_hkdf_init(EVP_PKEY_CTX *ctx) { HKDF_PKEY_CTX *hctx = OPENSSL_malloc(sizeof(HKDF_PKEY_CTX)); if (hctx == NULL) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); return 0; } OPENSSL_memset(hctx, 0, sizeof(HKDF_PKEY_CTX)); if (!CBB_init(&hctx->info, 0)) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); OPENSSL_free(hctx); return 0; } @@ -64,8 +62,7 @@ static int pkey_hkdf_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) { if (hctx_src->key_len != 0) { hctx_dst->key = OPENSSL_memdup(hctx_src->key, hctx_src->key_len); - if (hctx_src->key == NULL) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); + if (hctx_dst->key == NULL) { return 0; } hctx_dst->key_len = hctx_src->key_len; @@ -73,8 +70,7 @@ static int pkey_hkdf_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) { if (hctx_src->salt_len != 0) { hctx_dst->salt = OPENSSL_memdup(hctx_src->salt, hctx_src->salt_len); - if (hctx_src->salt == NULL) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); + if (hctx_dst->salt == NULL) { return 0; } hctx_dst->salt_len = hctx_src->salt_len; @@ -82,7 +78,6 @@ static int pkey_hkdf_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) { if (!CBB_add_bytes(&hctx_dst->info, CBB_data(&hctx_src->info), CBB_len(&hctx_src->info))) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); return 0; } @@ -159,7 +154,6 @@ static int pkey_hkdf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { case EVP_PKEY_CTRL_HKDF_KEY: { const CBS *key = p2; if (!CBS_stow(key, &hctx->key, &hctx->key_len)) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); return 0; } return 1; @@ -167,7 +161,6 @@ static int pkey_hkdf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { case EVP_PKEY_CTRL_HKDF_SALT: { const CBS *salt = p2; if (!CBS_stow(salt, &hctx->salt, &hctx->salt_len)) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); return 0; } return 1; @@ -177,7 +170,6 @@ static int pkey_hkdf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { // |EVP_PKEY_CTX_add1_hkdf_info| appends to the info string, rather than // replacing it. if (!CBB_add_bytes(&hctx->info, CBS_data(info), CBS_len(info))) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); return 0; } return 1; diff --git a/Sources/CNIOBoringSSL/crypto/evp/p_rsa.c b/Sources/CNIOBoringSSL/crypto/evp/p_rsa.c index 1c179a4e..6f10be36 100644 --- a/Sources/CNIOBoringSSL/crypto/evp/p_rsa.c +++ b/Sources/CNIOBoringSSL/crypto/evp/p_rsa.c @@ -67,7 +67,7 @@ #include #include "../internal.h" -#include "../fipsmodule/rsa/internal.h" +#include "../rsa_extra/internal.h" #include "internal.h" @@ -171,7 +171,7 @@ static int setup_tbuf(RSA_PKEY_CTX *ctx, EVP_PKEY_CTX *pk) { static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen, const uint8_t *tbs, size_t tbslen) { RSA_PKEY_CTX *rctx = ctx->data; - RSA *rsa = ctx->pkey->pkey.rsa; + RSA *rsa = ctx->pkey->pkey; const size_t key_len = EVP_PKEY_size(ctx->pkey); if (!sig) { @@ -210,7 +210,7 @@ static int pkey_rsa_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig, size_t siglen, const uint8_t *tbs, size_t tbslen) { RSA_PKEY_CTX *rctx = ctx->data; - RSA *rsa = ctx->pkey->pkey.rsa; + RSA *rsa = ctx->pkey->pkey; if (rctx->md) { switch (rctx->pad_mode) { @@ -243,7 +243,7 @@ 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; + RSA *rsa = ctx->pkey->pkey; const size_t key_len = EVP_PKEY_size(ctx->pkey); if (out == NULL) { @@ -307,7 +307,7 @@ static int pkey_rsa_verify_recover(EVP_PKEY_CTX *ctx, uint8_t *out, 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; - RSA *rsa = ctx->pkey->pkey.rsa; + RSA *rsa = ctx->pkey->pkey; const size_t key_len = EVP_PKEY_size(ctx->pkey); if (!out) { @@ -339,7 +339,7 @@ static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen, const uint8_t *in, size_t inlen) { RSA_PKEY_CTX *rctx = ctx->data; - RSA *rsa = ctx->pkey->pkey.rsa; + RSA *rsa = ctx->pkey->pkey; const size_t key_len = EVP_PKEY_size(ctx->pkey); if (!out) { diff --git a/Sources/CNIOBoringSSL/crypto/evp/p_rsa_asn1.c b/Sources/CNIOBoringSSL/crypto/evp/p_rsa_asn1.c index 138fe9b8..dfe3d9d3 100644 --- a/Sources/CNIOBoringSSL/crypto/evp/p_rsa_asn1.c +++ b/Sources/CNIOBoringSSL/crypto/evp/p_rsa_asn1.c @@ -68,6 +68,7 @@ static int rsa_pub_encode(CBB *out, const EVP_PKEY *key) { // See RFC 3279, section 2.3.1. + const RSA *rsa = key->pkey; CBB spki, algorithm, oid, null, key_bitstring; if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) || !CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) || @@ -76,7 +77,7 @@ static int rsa_pub_encode(CBB *out, const EVP_PKEY *key) { !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) || + !RSA_marshal_public_key(&key_bitstring, rsa) || !CBB_flush(out)) { OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); return 0; @@ -109,11 +110,14 @@ static int rsa_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { } static int rsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { - return BN_cmp(b->pkey.rsa->n, a->pkey.rsa->n) == 0 && - BN_cmp(b->pkey.rsa->e, a->pkey.rsa->e) == 0; + const RSA *a_rsa = a->pkey; + const RSA *b_rsa = b->pkey; + return BN_cmp(RSA_get0_n(b_rsa), RSA_get0_n(a_rsa)) == 0 && + BN_cmp(RSA_get0_e(b_rsa), RSA_get0_e(a_rsa)) == 0; } static int rsa_priv_encode(CBB *out, const EVP_PKEY *key) { + const RSA *rsa = key->pkey; CBB pkcs8, algorithm, oid, null, private_key; if (!CBB_add_asn1(out, &pkcs8, CBS_ASN1_SEQUENCE) || !CBB_add_asn1_uint64(&pkcs8, 0 /* version */) || @@ -122,7 +126,7 @@ static int rsa_priv_encode(CBB *out, const EVP_PKEY *key) { !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) || + !RSA_marshal_private_key(&private_key, rsa) || !CBB_flush(out)) { OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); return 0; @@ -153,44 +157,55 @@ static int rsa_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { } static int rsa_opaque(const EVP_PKEY *pkey) { - return RSA_is_opaque(pkey->pkey.rsa); + const RSA *rsa = pkey->pkey; + return RSA_is_opaque(rsa); } static int int_rsa_size(const EVP_PKEY *pkey) { - return RSA_size(pkey->pkey.rsa); + const RSA *rsa = pkey->pkey; + return RSA_size(rsa); } static int rsa_bits(const EVP_PKEY *pkey) { - return RSA_bits(pkey->pkey.rsa); + const RSA *rsa = pkey->pkey; + return RSA_bits(rsa); } -static void int_rsa_free(EVP_PKEY *pkey) { RSA_free(pkey->pkey.rsa); } +static void int_rsa_free(EVP_PKEY *pkey) { + RSA_free(pkey->pkey); + pkey->pkey = NULL; +} const EVP_PKEY_ASN1_METHOD rsa_asn1_meth = { - EVP_PKEY_RSA, - // 1.2.840.113549.1.1.1 - {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01}, 9, + EVP_PKEY_RSA, + // 1.2.840.113549.1.1.1 + {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01}, + 9, - &rsa_pkey_meth, + &rsa_pkey_meth, - rsa_pub_decode, - rsa_pub_encode, - rsa_pub_cmp, + rsa_pub_decode, + rsa_pub_encode, + rsa_pub_cmp, - rsa_priv_decode, - rsa_priv_encode, + rsa_priv_decode, + rsa_priv_encode, - NULL /* set_priv_raw */, - NULL /* set_pub_raw */, - NULL /* get_priv_raw */, - NULL /* get_pub_raw */, + /*set_priv_raw=*/NULL, + /*set_pub_raw=*/NULL, + /*get_priv_raw=*/NULL, + /*get_pub_raw=*/NULL, + /*set1_tls_encodedpoint=*/NULL, + /*get1_tls_encodedpoint=*/NULL, - rsa_opaque, + rsa_opaque, - int_rsa_size, - rsa_bits, + int_rsa_size, + rsa_bits, - 0,0,0, + 0, + 0, + 0, - int_rsa_free, + int_rsa_free, }; diff --git a/Sources/CNIOBoringSSL/crypto/evp/p_x25519.c b/Sources/CNIOBoringSSL/crypto/evp/p_x25519.c index ba3e9cb3..7297862b 100644 --- a/Sources/CNIOBoringSSL/crypto/evp/p_x25519.c +++ b/Sources/CNIOBoringSSL/crypto/evp/p_x25519.c @@ -27,7 +27,6 @@ static int pkey_x25519_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) { return 1; } static int pkey_x25519_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { X25519_KEY *key = OPENSSL_malloc(sizeof(X25519_KEY)); if (key == NULL) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); return 0; } @@ -39,8 +38,8 @@ static int pkey_x25519_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { X25519_keypair(key->pub, key->priv); key->has_private = 1; - OPENSSL_free(pkey->pkey.ptr); - pkey->pkey.ptr = key; + OPENSSL_free(pkey->pkey); + pkey->pkey = key; return 1; } @@ -51,8 +50,8 @@ static int pkey_x25519_derive(EVP_PKEY_CTX *ctx, uint8_t *out, return 0; } - const X25519_KEY *our_key = ctx->pkey->pkey.ptr; - const X25519_KEY *peer_key = ctx->peerkey->pkey.ptr; + const X25519_KEY *our_key = ctx->pkey->pkey; + const X25519_KEY *peer_key = ctx->peerkey->pkey; if (our_key == NULL || peer_key == NULL) { OPENSSL_PUT_ERROR(EVP, EVP_R_KEYS_NOT_SET); return 0; diff --git a/Sources/CNIOBoringSSL/crypto/evp/p_x25519_asn1.c b/Sources/CNIOBoringSSL/crypto/evp/p_x25519_asn1.c index 91b89ca8..a1a081d3 100644 --- a/Sources/CNIOBoringSSL/crypto/evp/p_x25519_asn1.c +++ b/Sources/CNIOBoringSSL/crypto/evp/p_x25519_asn1.c @@ -24,8 +24,8 @@ static void x25519_free(EVP_PKEY *pkey) { - OPENSSL_free(pkey->pkey.ptr); - pkey->pkey.ptr = NULL; + OPENSSL_free(pkey->pkey); + pkey->pkey = NULL; } static int x25519_set_priv_raw(EVP_PKEY *pkey, const uint8_t *in, size_t len) { @@ -36,7 +36,6 @@ static int x25519_set_priv_raw(EVP_PKEY *pkey, const uint8_t *in, size_t len) { X25519_KEY *key = OPENSSL_malloc(sizeof(X25519_KEY)); if (key == NULL) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); return 0; } @@ -45,7 +44,7 @@ static int x25519_set_priv_raw(EVP_PKEY *pkey, const uint8_t *in, size_t len) { key->has_private = 1; x25519_free(pkey); - pkey->pkey.ptr = key; + pkey->pkey = key; return 1; } @@ -57,7 +56,6 @@ static int x25519_set_pub_raw(EVP_PKEY *pkey, const uint8_t *in, size_t len) { X25519_KEY *key = OPENSSL_malloc(sizeof(X25519_KEY)); if (key == NULL) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); return 0; } @@ -65,13 +63,13 @@ static int x25519_set_pub_raw(EVP_PKEY *pkey, const uint8_t *in, size_t len) { key->has_private = 0; x25519_free(pkey); - pkey->pkey.ptr = key; + pkey->pkey = key; return 1; } static int x25519_get_priv_raw(const EVP_PKEY *pkey, uint8_t *out, - size_t *out_len) { - const X25519_KEY *key = pkey->pkey.ptr; + size_t *out_len) { + const X25519_KEY *key = pkey->pkey; if (!key->has_private) { OPENSSL_PUT_ERROR(EVP, EVP_R_NOT_A_PRIVATE_KEY); return 0; @@ -94,7 +92,7 @@ static int x25519_get_priv_raw(const EVP_PKEY *pkey, uint8_t *out, static int x25519_get_pub_raw(const EVP_PKEY *pkey, uint8_t *out, size_t *out_len) { - const X25519_KEY *key = pkey->pkey.ptr; + const X25519_KEY *key = pkey->pkey; if (out == NULL) { *out_len = 32; return 1; @@ -110,6 +108,23 @@ static int x25519_get_pub_raw(const EVP_PKEY *pkey, uint8_t *out, return 1; } +static int x25519_set1_tls_encodedpoint(EVP_PKEY *pkey, const uint8_t *in, + size_t len) { + return x25519_set_pub_raw(pkey, in, len); +} + +static size_t x25519_get1_tls_encodedpoint(const EVP_PKEY *pkey, + uint8_t **out_ptr) { + const X25519_KEY *key = pkey->pkey; + if (key == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_NO_KEY_SET); + return 0; + } + + *out_ptr = OPENSSL_memdup(key->pub, 32); + return *out_ptr == NULL ? 0 : 32; +} + static int x25519_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { // See RFC 8410, section 4. @@ -123,7 +138,7 @@ static int x25519_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { } static int x25519_pub_encode(CBB *out, const EVP_PKEY *pkey) { - const X25519_KEY *key = pkey->pkey.ptr; + const X25519_KEY *key = pkey->pkey; // See RFC 8410, section 4. CBB spki, algorithm, oid, key_bitstring; @@ -143,8 +158,8 @@ static int x25519_pub_encode(CBB *out, const EVP_PKEY *pkey) { } static int x25519_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { - const X25519_KEY *a_key = a->pkey.ptr; - const X25519_KEY *b_key = b->pkey.ptr; + const X25519_KEY *a_key = a->pkey; + const X25519_KEY *b_key = b->pkey; return OPENSSL_memcmp(a_key->pub, b_key->pub, 32) == 0; } @@ -165,7 +180,7 @@ static int x25519_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { } static int x25519_priv_encode(CBB *out, const EVP_PKEY *pkey) { - X25519_KEY *key = pkey->pkey.ptr; + const X25519_KEY *key = pkey->pkey; if (!key->has_private) { OPENSSL_PUT_ERROR(EVP, EVP_R_NOT_A_PRIVATE_KEY); return 0; @@ -209,41 +224,13 @@ const EVP_PKEY_ASN1_METHOD x25519_asn1_meth = { x25519_set_pub_raw, x25519_get_priv_raw, x25519_get_pub_raw, - NULL /* pkey_opaque */, + x25519_set1_tls_encodedpoint, + x25519_get1_tls_encodedpoint, + /*pkey_opaque=*/NULL, x25519_size, x25519_bits, - NULL /* param_missing */, - NULL /* param_copy */, - NULL /* param_cmp */, + /*param_missing=*/NULL, + /*param_copy=*/NULL, + /*param_cmp=*/NULL, x25519_free, }; - -int EVP_PKEY_set1_tls_encodedpoint(EVP_PKEY *pkey, const uint8_t *in, - size_t len) { - // TODO(davidben): In OpenSSL, this function also works for |EVP_PKEY_EC| - // keys. Add support if it ever comes up. - if (pkey->type != EVP_PKEY_X25519) { - OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE); - return 0; - } - - return x25519_set_pub_raw(pkey, in, len); -} - -size_t EVP_PKEY_get1_tls_encodedpoint(const EVP_PKEY *pkey, uint8_t **out_ptr) { - // TODO(davidben): In OpenSSL, this function also works for |EVP_PKEY_EC| - // keys. Add support if it ever comes up. - if (pkey->type != EVP_PKEY_X25519) { - OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE); - return 0; - } - - const X25519_KEY *key = pkey->pkey.ptr; - if (key == NULL) { - OPENSSL_PUT_ERROR(EVP, EVP_R_NO_KEY_SET); - return 0; - } - - *out_ptr = OPENSSL_memdup(key->pub, 32); - return *out_ptr == NULL ? 0 : 32; -} diff --git a/Sources/CNIOBoringSSL/crypto/evp/print.c b/Sources/CNIOBoringSSL/crypto/evp/print.c index b0cd8bb0..5e6fb2f2 100644 --- a/Sources/CNIOBoringSSL/crypto/evp/print.c +++ b/Sources/CNIOBoringSSL/crypto/evp/print.c @@ -50,6 +50,8 @@ * (eay@cryptsoft.com). This product includes software written by Tim * Hudson (tjh@cryptsoft.com). */ +#include + #include #include @@ -64,8 +66,25 @@ #include "../fipsmodule/rsa/internal.h" -static int bn_print(BIO *bp, const char *number, const BIGNUM *num, - uint8_t *buf, int off) { +static int print_hex(BIO *bp, const uint8_t *data, size_t len, int off) { + for (size_t i = 0; i < len; 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", data[i], (i + 1 == len) ? "" : ":") <= 0) { + return 0; + } + } + if (BIO_write(bp, "\n", 1) <= 0) { + return 0; + } + return 1; +} + +static int bn_print(BIO *bp, const char *name, const BIGNUM *num, int off) { if (num == NULL) { return 1; } @@ -74,287 +93,162 @@ static int bn_print(BIO *bp, const char *number, const BIGNUM *num, return 0; } if (BN_is_zero(num)) { - if (BIO_printf(bp, "%s 0\n", number) <= 0) { + if (BIO_printf(bp, "%s 0\n", name) <= 0) { return 0; } return 1; } - if (BN_num_bytes(num) <= sizeof(long)) { + uint64_t u64; + if (BN_get_u64(num, &u64)) { 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++; - } + return BIO_printf(bp, "%s %s%" PRIu64 " (%s0x%" PRIx64 ")\n", name, neg, + u64, neg, u64) > 0; + } - 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; - } + if (BIO_printf(bp, "%s%s", name, + (BN_is_negative(num)) ? " (Negative)" : "") <= 0) { + return 0; } - return 1; -} -static void update_buflen(const BIGNUM *b, size_t *pbuflen) { - if (!b) { - return; + // Print |num| in hex, adding a leading zero, as in ASN.1, if the high bit + // is set. + // + // TODO(davidben): Do we need to do this? We already print "(Negative)" above + // and negative values are never valid in keys anyway. + size_t len = BN_num_bytes(num); + uint8_t *buf = OPENSSL_malloc(len + 1); + if (buf == NULL) { + return 0; } - size_t len = BN_num_bytes(b); - if (*pbuflen < len) { - *pbuflen = len; + buf[0] = 0; + BN_bn2bin(num, buf + 1); + int ret; + if (len > 0 && (buf[1] & 0x80) != 0) { + // Print the whole buffer. + ret = print_hex(bp, buf, len + 1, off); + } else { + // Skip the leading zero. + ret = print_hex(bp, buf + 1, len, off); } + OPENSSL_free(buf); + return ret; } // 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); - } - - m = (uint8_t *)OPENSSL_malloc(buf_len + 10); - if (m == NULL) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); - goto err; - } - + int mod_len = 0; if (rsa->n != NULL) { mod_len = BN_num_bits(rsa->n); } if (!BIO_indent(out, off, 128)) { - goto err; + return 0; } + const char *s, *str; if (include_private && rsa->d) { if (BIO_printf(out, "Private-Key: (%d bit)\n", mod_len) <= 0) { - goto err; + return 0; } str = "modulus:"; s = "publicExponent:"; } else { if (BIO_printf(out, "Public-Key: (%d bit)\n", mod_len) <= 0) { - goto err; + return 0; } str = "Modulus:"; s = "Exponent:"; } - if (!bn_print(out, str, rsa->n, m, off) || - !bn_print(out, s, rsa->e, m, off)) { - goto err; + if (!bn_print(out, str, rsa->n, off) || + !bn_print(out, s, rsa->e, off)) { + return 0; } 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 (!bn_print(out, "privateExponent:", rsa->d, off) || + !bn_print(out, "prime1:", rsa->p, off) || + !bn_print(out, "prime2:", rsa->q, off) || + !bn_print(out, "exponent1:", rsa->dmp1, off) || + !bn_print(out, "exponent2:", rsa->dmq1, off) || + !bn_print(out, "coefficient:", rsa->iqmp, off)) { + return 0; } } - ret = 1; -err: - OPENSSL_free(m); - return ret; + return 1; } -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_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent) { + return do_rsa_print(bp, EVP_PKEY_get0_RSA(pkey), 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); +static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent) { + return do_rsa_print(bp, EVP_PKEY_get0_RSA(pkey), 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; + const BIGNUM *priv_key = NULL; if (ptype == 2) { priv_key = x->priv_key; } - pub_key = NULL; + const BIGNUM *pub_key = NULL; if (ptype > 0) { pub_key = x->pub_key; } - ktype = "DSA-Parameters"; + const char *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: (%u 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; + if (!BIO_indent(bp, off, 128) || + BIO_printf(bp, "%s: (%u bit)\n", ktype, BN_num_bits(x->p)) <= 0 || + // |priv_key| and |pub_key| may be NULL, in which case |bn_print| will + // silently skip them. + !bn_print(bp, "priv:", priv_key, off) || + !bn_print(bp, "pub:", pub_key, off) || + !bn_print(bp, "P:", x->p, off) || + !bn_print(bp, "Q:", x->q, off) || + !bn_print(bp, "G:", x->g, off)) { + return 0; } - ret = 1; -err: - OPENSSL_free(m); - return ret; + return 1; } -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_param_print(BIO *bp, const EVP_PKEY *pkey, int indent) { + return do_dsa_print(bp, EVP_PKEY_get0_DSA(pkey), 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_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent) { + return do_dsa_print(bp, EVP_PKEY_get0_DSA(pkey), 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 dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent) { + return do_dsa_print(bp, EVP_PKEY_get0_DSA(pkey), 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; + OPENSSL_PUT_ERROR(EVP, ERR_R_PASSED_NULL_PARAMETER); + return 0; } - if (ktype > 0) { - buf_len += 10; - if ((buffer = OPENSSL_malloc(buf_len)) == NULL) { - reason = ERR_R_MALLOC_FAILURE; - goto err; - } - } + const char *ecstr; if (ktype == 2) { ecstr = "Private-Key"; } else if (ktype == 1) { @@ -364,62 +258,61 @@ static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) { } if (!BIO_indent(bp, off, 128)) { - goto err; + return 0; } - order = BN_new(); - if (order == NULL || !EC_GROUP_get_order(group, order, NULL) || - BIO_printf(bp, "%s: (%u bit)\n", ecstr, BN_num_bits(order)) <= 0) { - goto err; + int curve_name = EC_GROUP_get_curve_name(group); + if (BIO_printf(bp, "%s: (%s)\n", ecstr, + curve_name == NID_undef + ? "unknown curve" + : EC_curve_nid2nist(curve_name)) <= 0) { + return 0; } - 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); + if (ktype == 2) { + const BIGNUM *priv_key = EC_KEY_get0_private_key(x); + if (priv_key != NULL && // + !bn_print(bp, "priv:", priv_key, off)) { + return 0; + } } - // TODO(fork): implement - /* - if (!ECPKParameters_print(bp, group, off)) - goto err; */ - ret = 1; - -err: - if (!ret) { - OPENSSL_PUT_ERROR(EVP, reason); + + if (ktype > 0 && EC_KEY_get0_public_key(x) != NULL) { + uint8_t *pub = NULL; + size_t pub_len = EC_KEY_key2buf(x, EC_KEY_get_conv_form(x), &pub, NULL); + if (pub_len == 0) { + return 0; + } + int ret = BIO_indent(bp, off, 128) && // + BIO_puts(bp, "pub:") > 0 && // + print_hex(bp, pub, pub_len, off); + OPENSSL_free(pub); + if (!ret) { + return 0; + } } - OPENSSL_free(pub_key_bytes); - BN_free(order); - BN_CTX_free(ctx); - OPENSSL_free(buffer); - return ret; + + return 1; } -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_param_print(BIO *bp, const EVP_PKEY *pkey, int indent) { + return do_EC_KEY_print(bp, EVP_PKEY_get0_EC_KEY(pkey), 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_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent) { + return do_EC_KEY_print(bp, EVP_PKEY_get0_EC_KEY(pkey), 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_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent) { + return do_EC_KEY_print(bp, EVP_PKEY_get0_EC_KEY(pkey), 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); + int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent); + int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent); + int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent); } EVP_PKEY_PRINT_METHOD; static EVP_PKEY_PRINT_METHOD kPrintMethods[] = { @@ -463,27 +356,27 @@ static int print_unsupported(BIO *out, const EVP_PKEY *pkey, int indent, 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); + EVP_PKEY_PRINT_METHOD *method = find_method(EVP_PKEY_id(pkey)); if (method != NULL && method->pub_print != NULL) { - return method->pub_print(out, pkey, indent, pctx); + return method->pub_print(out, pkey, indent); } 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); + EVP_PKEY_PRINT_METHOD *method = find_method(EVP_PKEY_id(pkey)); if (method != NULL && method->priv_print != NULL) { - return method->priv_print(out, pkey, indent, pctx); + return method->priv_print(out, pkey, indent); } 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); + EVP_PKEY_PRINT_METHOD *method = find_method(EVP_PKEY_id(pkey)); if (method != NULL && method->param_print != NULL) { - return method->param_print(out, pkey, indent, pctx); + return method->param_print(out, pkey, indent); } return print_unsupported(out, pkey, indent, "Parameters"); } diff --git a/Sources/CNIOBoringSSL/crypto/evp/scrypt.c b/Sources/CNIOBoringSSL/crypto/evp/scrypt.c index 50ac7a96..b2c87c9e 100644 --- a/Sources/CNIOBoringSSL/crypto/evp/scrypt.c +++ b/Sources/CNIOBoringSSL/crypto/evp/scrypt.c @@ -177,7 +177,6 @@ int EVP_PBE_scrypt(const char *password, size_t password_len, size_t V_blocks = N * 2 * r; block_t *B = OPENSSL_malloc((B_blocks + T_blocks + V_blocks) * sizeof(block_t)); if (B == NULL) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); return 0; } diff --git a/Sources/CNIOBoringSSL/crypto/evp/sign.c b/Sources/CNIOBoringSSL/crypto/evp/sign.c index 38b76f15..2a33a59b 100644 --- a/Sources/CNIOBoringSSL/crypto/evp/sign.c +++ b/Sources/CNIOBoringSSL/crypto/evp/sign.c @@ -56,6 +56,8 @@ #include +#include + #include #include @@ -74,15 +76,20 @@ int EVP_SignUpdate(EVP_MD_CTX *ctx, const void *data, size_t len) { return EVP_DigestUpdate(ctx, data, len); } -int EVP_SignFinal(const EVP_MD_CTX *ctx, uint8_t *sig, - unsigned int *out_sig_len, EVP_PKEY *pkey) { +int EVP_SignFinal(const EVP_MD_CTX *ctx, uint8_t *sig, unsigned *out_sig_len, + EVP_PKEY *pkey) { uint8_t m[EVP_MAX_MD_SIZE]; - unsigned int m_len; + unsigned m_len; int ret = 0; EVP_MD_CTX tmp_ctx; EVP_PKEY_CTX *pkctx = NULL; size_t sig_len = EVP_PKEY_size(pkey); + // Ensure the final result will fit in |unsigned|. + if (sig_len > UINT_MAX) { + sig_len = UINT_MAX; + } + *out_sig_len = 0; EVP_MD_CTX_init(&tmp_ctx); if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx) || @@ -92,19 +99,17 @@ int EVP_SignFinal(const EVP_MD_CTX *ctx, uint8_t *sig, EVP_MD_CTX_cleanup(&tmp_ctx); pkctx = EVP_PKEY_CTX_new(pkey, NULL); - if (!pkctx || !EVP_PKEY_sign_init(pkctx) || + if (!pkctx || // + !EVP_PKEY_sign_init(pkctx) || !EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) || !EVP_PKEY_sign(pkctx, sig, &sig_len, m, m_len)) { goto out; } - *out_sig_len = sig_len; + *out_sig_len = (unsigned)sig_len; ret = 1; out: - if (pkctx) { - EVP_PKEY_CTX_free(pkctx); - } - + EVP_PKEY_CTX_free(pkctx); return ret; } @@ -123,7 +128,7 @@ int EVP_VerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t len) { int EVP_VerifyFinal(EVP_MD_CTX *ctx, const uint8_t *sig, size_t sig_len, EVP_PKEY *pkey) { uint8_t m[EVP_MAX_MD_SIZE]; - unsigned int m_len; + unsigned m_len; int ret = 0; EVP_MD_CTX tmp_ctx; EVP_PKEY_CTX *pkctx = NULL; diff --git a/Sources/CNIOBoringSSL/crypto/ex_data.c b/Sources/CNIOBoringSSL/crypto/ex_data.c index dd311f88..266ef458 100644 --- a/Sources/CNIOBoringSSL/crypto/ex_data.c +++ b/Sources/CNIOBoringSSL/crypto/ex_data.c @@ -109,6 +109,8 @@ #include #include +#include +#include #include #include @@ -135,7 +137,6 @@ int CRYPTO_get_ex_new_index(CRYPTO_EX_DATA_CLASS *ex_data_class, int *out_index, funcs = OPENSSL_malloc(sizeof(CRYPTO_EX_DATA_FUNCS)); if (funcs == NULL) { - OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE); return 0; } @@ -149,44 +150,55 @@ int CRYPTO_get_ex_new_index(CRYPTO_EX_DATA_CLASS *ex_data_class, int *out_index, ex_data_class->meth = sk_CRYPTO_EX_DATA_FUNCS_new_null(); } - if (ex_data_class->meth == NULL || - !sk_CRYPTO_EX_DATA_FUNCS_push(ex_data_class->meth, funcs)) { - OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE); - OPENSSL_free(funcs); + if (ex_data_class->meth == NULL) { goto err; } - *out_index = sk_CRYPTO_EX_DATA_FUNCS_num(ex_data_class->meth) - 1 + + // The index must fit in |int|. + if (sk_CRYPTO_EX_DATA_FUNCS_num(ex_data_class->meth) > + (size_t)(INT_MAX - ex_data_class->num_reserved)) { + OPENSSL_PUT_ERROR(CRYPTO, ERR_R_OVERFLOW); + goto err; + } + + if (!sk_CRYPTO_EX_DATA_FUNCS_push(ex_data_class->meth, funcs)) { + goto err; + } + funcs = NULL; // |sk_CRYPTO_EX_DATA_FUNCS_push| takes ownership. + + *out_index = (int)sk_CRYPTO_EX_DATA_FUNCS_num(ex_data_class->meth) - 1 + ex_data_class->num_reserved; ret = 1; err: CRYPTO_STATIC_MUTEX_unlock_write(&ex_data_class->lock); + OPENSSL_free(funcs); return ret; } int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int index, void *val) { - int n, i; + if (index < 0) { + // A caller that can accidentally pass in an invalid index into this + // function will hit an memory error if |index| happened to be valid, and + // expected |val| to be of a different type. + abort(); + } if (ad->sk == NULL) { ad->sk = sk_void_new_null(); if (ad->sk == NULL) { - OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE); return 0; } } - n = sk_void_num(ad->sk); - // Add NULL values until the stack is long enough. - for (i = n; i <= index; i++) { + for (size_t i = sk_void_num(ad->sk); i <= (size_t)index; i++) { if (!sk_void_push(ad->sk, NULL)) { - OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE); return 0; } } - sk_void_set(ad->sk, index, val); + sk_void_set(ad->sk, (size_t)index, val); return 1; } @@ -218,7 +230,6 @@ static int get_func_pointers(STACK_OF(CRYPTO_EX_DATA_FUNCS) **out, CRYPTO_STATIC_MUTEX_unlock_read(&ex_data_class->lock); if (n > 0 && *out == NULL) { - OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE); return 0; } @@ -242,7 +253,10 @@ void CRYPTO_free_ex_data(CRYPTO_EX_DATA_CLASS *ex_data_class, void *obj, return; } - for (size_t i = 0; i < sk_CRYPTO_EX_DATA_FUNCS_num(func_pointers); i++) { + // |CRYPTO_get_ex_new_index| will not allocate indices beyond |INT_MAX|. + assert(sk_CRYPTO_EX_DATA_FUNCS_num(func_pointers) <= + (size_t)(INT_MAX - ex_data_class->num_reserved)); + for (int i = 0; i < (int)sk_CRYPTO_EX_DATA_FUNCS_num(func_pointers); i++) { CRYPTO_EX_DATA_FUNCS *func_pointer = sk_CRYPTO_EX_DATA_FUNCS_value(func_pointers, i); if (func_pointer->free_func) { diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/aes/internal.h b/Sources/CNIOBoringSSL/crypto/fipsmodule/aes/internal.h index 0685bc41..98b2a14d 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/aes/internal.h +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/aes/internal.h @@ -59,12 +59,6 @@ OPENSSL_INLINE int vpaes_capable(void) { return CRYPTO_is_NEON_capable(); } OPENSSL_INLINE int vpaes_capable(void) { return CRYPTO_is_NEON_capable(); } #endif -#elif defined(OPENSSL_PPC64LE) -#define HWAES - -OPENSSL_INLINE int hwaes_capable(void) { - return CRYPTO_is_PPC64LE_vcrypto_capable(); -} #endif #endif // !NO_ASM diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-gcm-x86_64.linux.x86_64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-gcm-x86_64-linux.linux.x86_64.S similarity index 93% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-gcm-x86_64.linux.x86_64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-gcm-x86_64-linux.linux.x86_64.S index 9cedbfb3..206d0958 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-gcm-x86_64.linux.x86_64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-gcm-x86_64-linux.linux.x86_64.S @@ -9,7 +9,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -223,7 +223,7 @@ _aesni_ctr32_ghash_6x: movbeq 0(%r14),%r12 vaesenc %xmm1,%xmm14,%xmm14 vmovups 160-128(%rcx),%xmm1 - cmpl $11,%ebp + cmpl $11,%r10d jb .Lenc_tail vaesenc %xmm15,%xmm9,%xmm9 @@ -307,6 +307,9 @@ _aesni_ctr32_ghash_6x: vpaddb %xmm2,%xmm1,%xmm0 movq %r13,112+8(%rsp) leaq 96(%rdi),%rdi + + prefetcht0 512(%rdi) + prefetcht0 576(%rdi) vaesenclast %xmm5,%xmm11,%xmm11 vpaddb %xmm2,%xmm0,%xmm5 movq %r12,120+8(%rsp) @@ -319,7 +322,7 @@ _aesni_ctr32_ghash_6x: vaesenclast %xmm3,%xmm14,%xmm14 vpaddb %xmm2,%xmm7,%xmm3 - addq $0x60,%r10 + addq $0x60,%rax subq $0x6,%rdx jc .L6x_done @@ -351,27 +354,35 @@ _aesni_ctr32_ghash_6x: .align 32 aesni_gcm_decrypt: .cfi_startproc - xorq %r10,%r10 + + xorq %rax,%rax cmpq $0x60,%rdx jb .Lgcm_dec_abort - leaq (%rsp),%rax -.cfi_def_cfa_register %rax - pushq %rbx -.cfi_offset %rbx,-16 pushq %rbp -.cfi_offset %rbp,-24 +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-16 + + movq %rsp,%rbp +.cfi_def_cfa_register %rbp + pushq %rbx +.cfi_offset %rbx,-24 + pushq %r12 .cfi_offset %r12,-32 + pushq %r13 .cfi_offset %r13,-40 + pushq %r14 .cfi_offset %r14,-48 + pushq %r15 .cfi_offset %r15,-56 + vzeroupper vmovdqu (%r8),%xmm1 @@ -385,7 +396,7 @@ aesni_gcm_decrypt: vmovdqu (%r11),%xmm0 leaq 128(%rcx),%rcx leaq 32+32(%r9),%r9 - movl 240-128(%rcx),%ebp + movl 240-128(%rcx),%r10d vpshufb %xmm0,%xmm8,%xmm8 andq %r15,%r14 @@ -398,7 +409,7 @@ aesni_gcm_decrypt: .Ldec_no_key_aliasing: vmovdqu 80(%rdi),%xmm7 - leaq (%rdi),%r14 + movq %rdi,%r14 vmovdqu 64(%rdi),%xmm4 @@ -411,7 +422,7 @@ aesni_gcm_decrypt: vmovdqu 48(%rdi),%xmm5 shrq $4,%rdx - xorq %r10,%r10 + xorq %rax,%rax vmovdqu 32(%rdi),%xmm6 vpshufb %xmm0,%xmm7,%xmm7 vmovdqu 16(%rdi),%xmm2 @@ -440,23 +451,29 @@ aesni_gcm_decrypt: vmovdqu %xmm8,-64(%r9) vzeroupper - movq -48(%rax),%r15 + leaq -40(%rbp),%rsp +.cfi_def_cfa %rsp, 0x38 + popq %r15 +.cfi_adjust_cfa_offset -8 .cfi_restore %r15 - movq -40(%rax),%r14 + popq %r14 +.cfi_adjust_cfa_offset -8 .cfi_restore %r14 - movq -32(%rax),%r13 + popq %r13 +.cfi_adjust_cfa_offset -8 .cfi_restore %r13 - movq -24(%rax),%r12 + popq %r12 +.cfi_adjust_cfa_offset -8 .cfi_restore %r12 - movq -16(%rax),%rbp -.cfi_restore %rbp - movq -8(%rax),%rbx + popq %rbx +.cfi_adjust_cfa_offset -8 .cfi_restore %rbx - leaq (%rax),%rsp -.cfi_def_cfa_register %rsp + popq %rbp +.cfi_adjust_cfa_offset -8 +.cfi_restore %rbp .Lgcm_dec_abort: - movq %r10,%rax .byte 0xf3,0xc3 + .cfi_endproc .size aesni_gcm_decrypt,.-aesni_gcm_decrypt .type _aesni_ctr32_6x,@function @@ -465,7 +482,7 @@ _aesni_ctr32_6x: .cfi_startproc vmovdqu 0-128(%rcx),%xmm4 vmovdqu 32(%r11),%xmm2 - leaq -1(%rbp),%r13 + leaq -1(%r10),%r13 vmovups 16-128(%rcx),%xmm15 leaq 32-128(%rcx),%r12 vpxor %xmm4,%xmm1,%xmm9 @@ -558,12 +575,13 @@ _aesni_ctr32_6x: .align 32 aesni_gcm_encrypt: .cfi_startproc + #ifdef BORINGSSL_DISPATCH_TEST .extern BORINGSSL_function_hit .hidden BORINGSSL_function_hit movb $1,BORINGSSL_function_hit+2(%rip) #endif - xorq %r10,%r10 + xorq %rax,%rax @@ -571,20 +589,27 @@ aesni_gcm_encrypt: cmpq $288,%rdx jb .Lgcm_enc_abort - leaq (%rsp),%rax -.cfi_def_cfa_register %rax - pushq %rbx -.cfi_offset %rbx,-16 pushq %rbp -.cfi_offset %rbp,-24 +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-16 + + movq %rsp,%rbp +.cfi_def_cfa_register %rbp + pushq %rbx +.cfi_offset %rbx,-24 + pushq %r12 .cfi_offset %r12,-32 + pushq %r13 .cfi_offset %r13,-40 + pushq %r14 .cfi_offset %r14,-48 + pushq %r15 .cfi_offset %r15,-56 + vzeroupper vmovdqu (%r8),%xmm1 @@ -596,7 +621,7 @@ aesni_gcm_encrypt: leaq 128(%rcx),%rcx vmovdqu (%r11),%xmm0 andq $-128,%rsp - movl 240-128(%rcx),%ebp + movl 240-128(%rcx),%r10d andq %r15,%r14 andq %rsp,%r15 @@ -607,7 +632,7 @@ aesni_gcm_encrypt: subq %r15,%rsp .Lenc_no_key_aliasing: - leaq (%rsi),%r14 + movq %rsi,%r14 @@ -638,7 +663,7 @@ aesni_gcm_encrypt: vmovdqu (%r9),%xmm8 leaq 32+32(%r9),%r9 subq $12,%rdx - movq $192,%r10 + movq $192,%rax vpshufb %xmm0,%xmm8,%xmm8 call _aesni_ctr32_ghash_6x @@ -818,25 +843,32 @@ aesni_gcm_encrypt: vmovdqu %xmm8,-64(%r9) vzeroupper - movq -48(%rax),%r15 + leaq -40(%rbp),%rsp +.cfi_def_cfa %rsp, 0x38 + popq %r15 +.cfi_adjust_cfa_offset -8 .cfi_restore %r15 - movq -40(%rax),%r14 + popq %r14 +.cfi_adjust_cfa_offset -8 .cfi_restore %r14 - movq -32(%rax),%r13 + popq %r13 +.cfi_adjust_cfa_offset -8 .cfi_restore %r13 - movq -24(%rax),%r12 + popq %r12 +.cfi_adjust_cfa_offset -8 .cfi_restore %r12 - movq -16(%rax),%rbp -.cfi_restore %rbp - movq -8(%rax),%rbx + popq %rbx +.cfi_adjust_cfa_offset -8 .cfi_restore %rbx - leaq (%rax),%rsp -.cfi_def_cfa_register %rsp + popq %rbp +.cfi_adjust_cfa_offset -8 +.cfi_restore %rbp .Lgcm_enc_abort: - movq %r10,%rax .byte 0xf3,0xc3 + .cfi_endproc -.size aesni_gcm_encrypt,.-aesni_gcm_encrypt +.size aesni_gcm_decrypt,.-aesni_gcm_decrypt +.section .rodata .align 64 .Lbswap_mask: .byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 @@ -850,8 +882,12 @@ aesni_gcm_encrypt: .byte 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 .byte 65,69,83,45,78,73,32,71,67,77,32,109,111,100,117,108,101,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .align 64 +.text +#endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -.section .note.GNU-stack,"",@progbits #endif // defined(__x86_64__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-gcm-x86_64.mac.x86_64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-gcm-x86_64-mac.mac.x86_64.S similarity index 96% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-gcm-x86_64.mac.x86_64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-gcm-x86_64-mac.mac.x86_64.S index 54035071..c794c6b6 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-gcm-x86_64.mac.x86_64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-gcm-x86_64-mac.mac.x86_64.S @@ -9,7 +9,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -223,7 +223,7 @@ L$resume_ctr32: movbeq 0(%r14),%r12 vaesenc %xmm1,%xmm14,%xmm14 vmovups 160-128(%rcx),%xmm1 - cmpl $11,%ebp + cmpl $11,%r10d jb L$enc_tail vaesenc %xmm15,%xmm9,%xmm9 @@ -307,6 +307,9 @@ L$enc_tail: vpaddb %xmm2,%xmm1,%xmm0 movq %r13,112+8(%rsp) leaq 96(%rdi),%rdi + + prefetcht0 512(%rdi) + prefetcht0 576(%rdi) vaesenclast %xmm5,%xmm11,%xmm11 vpaddb %xmm2,%xmm0,%xmm5 movq %r12,120+8(%rsp) @@ -319,7 +322,7 @@ L$enc_tail: vaesenclast %xmm3,%xmm14,%xmm14 vpaddb %xmm2,%xmm7,%xmm3 - addq $0x60,%r10 + addq $0x60,%rax subq $0x6,%rdx jc L$6x_done @@ -351,27 +354,34 @@ L$6x_done: .p2align 5 _aesni_gcm_decrypt: - xorq %r10,%r10 + + xorq %rax,%rax cmpq $0x60,%rdx jb L$gcm_dec_abort - leaq (%rsp),%rax + pushq %rbp + + + movq %rsp,%rbp pushq %rbx - pushq %rbp pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + vzeroupper vmovdqu (%r8),%xmm1 @@ -385,7 +395,7 @@ _aesni_gcm_decrypt: vmovdqu (%r11),%xmm0 leaq 128(%rcx),%rcx leaq 32+32(%r9),%r9 - movl 240-128(%rcx),%ebp + movl 240-128(%rcx),%r10d vpshufb %xmm0,%xmm8,%xmm8 andq %r15,%r14 @@ -398,7 +408,7 @@ _aesni_gcm_decrypt: L$dec_no_key_aliasing: vmovdqu 80(%rdi),%xmm7 - leaq (%rdi),%r14 + movq %rdi,%r14 vmovdqu 64(%rdi),%xmm4 @@ -411,7 +421,7 @@ L$dec_no_key_aliasing: vmovdqu 48(%rdi),%xmm5 shrq $4,%rdx - xorq %r10,%r10 + xorq %rax,%rax vmovdqu 32(%rdi),%xmm6 vpshufb %xmm0,%xmm7,%xmm7 vmovdqu 16(%rdi),%xmm2 @@ -440,32 +450,32 @@ L$dec_no_key_aliasing: vmovdqu %xmm8,-64(%r9) vzeroupper - movq -48(%rax),%r15 + leaq -40(%rbp),%rsp - movq -40(%rax),%r14 + popq %r15 - movq -32(%rax),%r13 + popq %r14 - movq -24(%rax),%r12 + popq %r13 - movq -16(%rax),%rbp + popq %r12 - movq -8(%rax),%rbx + popq %rbx - leaq (%rax),%rsp + popq %rbp L$gcm_dec_abort: - movq %r10,%rax .byte 0xf3,0xc3 + .p2align 5 _aesni_ctr32_6x: vmovdqu 0-128(%rcx),%xmm4 vmovdqu 32(%r11),%xmm2 - leaq -1(%rbp),%r13 + leaq -1(%r10),%r13 vmovups 16-128(%rcx),%xmm15 leaq 32-128(%rcx),%r12 vpxor %xmm4,%xmm1,%xmm9 @@ -558,11 +568,12 @@ L$handle_ctr32_2: .p2align 5 _aesni_gcm_encrypt: + #ifdef BORINGSSL_DISPATCH_TEST movb $1,_BORINGSSL_function_hit+2(%rip) #endif - xorq %r10,%r10 + xorq %rax,%rax @@ -570,20 +581,26 @@ _aesni_gcm_encrypt: cmpq $288,%rdx jb L$gcm_enc_abort - leaq (%rsp),%rax + pushq %rbp + + + movq %rsp,%rbp pushq %rbx - pushq %rbp pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + vzeroupper vmovdqu (%r8),%xmm1 @@ -595,7 +612,7 @@ _aesni_gcm_encrypt: leaq 128(%rcx),%rcx vmovdqu (%r11),%xmm0 andq $-128,%rsp - movl 240-128(%rcx),%ebp + movl 240-128(%rcx),%r10d andq %r15,%r14 andq %rsp,%r15 @@ -606,7 +623,7 @@ _aesni_gcm_encrypt: subq %r15,%rsp L$enc_no_key_aliasing: - leaq (%rsi),%r14 + movq %rsi,%r14 @@ -637,7 +654,7 @@ L$enc_no_key_aliasing: vmovdqu (%r9),%xmm8 leaq 32+32(%r9),%r9 subq $12,%rdx - movq $192,%r10 + movq $192,%rax vpshufb %xmm0,%xmm8,%xmm8 call _aesni_ctr32_ghash_6x @@ -817,25 +834,26 @@ L$enc_no_key_aliasing: vmovdqu %xmm8,-64(%r9) vzeroupper - movq -48(%rax),%r15 + leaq -40(%rbp),%rsp - movq -40(%rax),%r14 + popq %r15 - movq -32(%rax),%r13 + popq %r14 - movq -24(%rax),%r12 + popq %r13 - movq -16(%rax),%rbp + popq %r12 - movq -8(%rax),%rbx + popq %rbx - leaq (%rax),%rsp + popq %rbp L$gcm_enc_abort: - movq %r10,%rax .byte 0xf3,0xc3 + +.section __DATA,__const .p2align 6 L$bswap_mask: .byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 @@ -849,6 +867,11 @@ L$one_lsb: .byte 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 .byte 65,69,83,45,78,73,32,71,67,77,32,109,111,100,117,108,101,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .p2align 6 +.text +#endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif #endif // defined(__x86_64__) && defined(__APPLE__) #if defined(__linux__) && defined(__ELF__) diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-x86.linux.x86.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-x86-linux.linux.x86.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-x86.linux.x86.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-x86-linux.linux.x86.S index 25fabd1b..5682bf17 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-x86.linux.x86.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-x86-linux.linux.x86.S @@ -3,7 +3,13 @@ // This file is generated from a similarly-named Perl script in the BoringSSL // source tree. Do not edit by hand. -#if defined(__i386__) +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -2511,8 +2517,11 @@ aes_hw_set_decrypt_key: .byte 83,45,78,73,44,32,67,82,89,80,84,79,71,65,77,83 .byte 32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115 .byte 115,108,46,111,114,103,62,0 +#endif // !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -.section .note.GNU-stack,"",@progbits #endif // defined(__i386__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-x86_64.linux.x86_64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-x86_64-linux.linux.x86_64.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-x86_64.linux.x86_64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-x86_64-linux.linux.x86_64.S index 850b8a76..1233a749 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-x86_64.linux.x86_64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-x86_64-linux.linux.x86_64.S @@ -9,7 +9,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -2482,6 +2482,7 @@ __aesni_set_encrypt_key: .byte 0xf3,0xc3 .size aes_hw_set_encrypt_key,.-aes_hw_set_encrypt_key .size __aesni_set_encrypt_key,.-__aesni_set_encrypt_key +.section .rodata .align 64 .Lbswap_mask: .byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 @@ -2504,8 +2505,12 @@ __aesni_set_encrypt_key: .byte 65,69,83,32,102,111,114,32,73,110,116,101,108,32,65,69,83,45,78,73,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .align 64 +.text +#endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -.section .note.GNU-stack,"",@progbits #endif // defined(__x86_64__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-x86_64.mac.x86_64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-x86_64-mac.mac.x86_64.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-x86_64.mac.x86_64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-x86_64-mac.mac.x86_64.S index 47416344..fc9f1eba 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-x86_64.mac.x86_64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-x86_64-mac.mac.x86_64.S @@ -9,7 +9,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -2480,6 +2480,7 @@ L$key_expansion_256b: .byte 0xf3,0xc3 +.section __DATA,__const .p2align 6 L$bswap_mask: .byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 @@ -2502,6 +2503,11 @@ L$key_rcon1b: .byte 65,69,83,32,102,111,114,32,73,110,116,101,108,32,65,69,83,45,78,73,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .p2align 6 +.text +#endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif #endif // defined(__x86_64__) && defined(__APPLE__) #if defined(__linux__) && defined(__ELF__) diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-armx32.ios.arm.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-armv7-ios.ios.arm.S similarity index 98% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-armx32.ios.arm.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-armv7-ios.ios.arm.S index d56adf0e..d09afa2c 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-armx32.ios.arm.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-armv7-ios.ios.arm.S @@ -10,7 +10,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -808,7 +808,11 @@ Lctr32_done: ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,pc} #endif -#endif // !OPENSSL_NO_ASM +#endif // !OPENSSL_NO_ASM && defined(__ARMEL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif #endif // defined(__arm__) && defined(__APPLE__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-armx32.linux.arm.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-armv7-linux.linux.arm.S similarity index 98% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-armx32.linux.arm.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-armv7-linux.linux.arm.S index 993a9b8e..eca49be8 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-armx32.linux.arm.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-armv7-linux.linux.arm.S @@ -10,8 +10,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__arm__) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -797,9 +796,11 @@ aes_hw_ctr32_encrypt_blocks: ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,pc} .size aes_hw_ctr32_encrypt_blocks,.-aes_hw_ctr32_encrypt_blocks #endif +#endif // !OPENSSL_NO_ASM && defined(__ARMEL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM -.section .note.GNU-stack,"",%progbits #endif // defined(__arm__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-armx64.ios.aarch64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-armv8-ios.ios.aarch64.S similarity index 98% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-armx64.ios.aarch64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-armv8-ios.ios.aarch64.S index a3a27014..9182b5d3 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-armx64.ios.aarch64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-armv8-ios.ios.aarch64.S @@ -10,7 +10,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -798,7 +798,11 @@ Lctr32_done: ret #endif -#endif // !OPENSSL_NO_ASM +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif #endif // defined(__aarch64__) && defined(__APPLE__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-armx64.linux.aarch64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-armv8-linux.linux.aarch64.S similarity index 98% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-armx64.linux.aarch64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-armv8-linux.linux.aarch64.S index 41df2587..01abcdbe 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-armx64.linux.aarch64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-armv8-linux.linux.aarch64.S @@ -10,8 +10,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__aarch64__) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -799,9 +798,11 @@ aes_hw_ctr32_encrypt_blocks: ret .size aes_hw_ctr32_encrypt_blocks,.-aes_hw_ctr32_encrypt_blocks #endif +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM -.section .note.GNU-stack,"",%progbits #endif // defined(__aarch64__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-gcm-armv8-ios.ios.aarch64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-gcm-armv8-ios.ios.aarch64.S new file mode 100644 index 00000000..b314302b --- /dev/null +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-gcm-armv8-ios.ios.aarch64.S @@ -0,0 +1,1574 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__aarch64__) && defined(__APPLE__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__APPLE__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include +#if __ARM_MAX_ARCH__ >= 8 + + +.text +.globl _aes_gcm_enc_kernel +.private_extern _aes_gcm_enc_kernel + +.align 4 +_aes_gcm_enc_kernel: + AARCH64_SIGN_LINK_REGISTER + stp x29, x30, [sp, #-128]! + mov x29, sp + stp x19, x20, [sp, #16] + mov x16, x4 + mov x8, x5 + stp x21, x22, [sp, #32] + stp x23, x24, [sp, #48] + stp d8, d9, [sp, #64] + stp d10, d11, [sp, #80] + stp d12, d13, [sp, #96] + stp d14, d15, [sp, #112] + ldr w17, [x8, #240] + add x19, x8, x17, lsl #4 // borrow input_l1 for last key + ldp x13, x14, [x19] // load round N keys + ldr q31, [x19, #-16] // load round N-1 keys + add x4, x0, x1, lsr #3 // end_input_ptr + lsr x5, x1, #3 // byte_len + mov x15, x5 + ldp x10, x11, [x16] // ctr96_b64, ctr96_t32 + ld1 { v0.16b}, [x16] // special case vector load initial counter so we can start first AES block as quickly as possible + sub x5, x5, #1 // byte_len - 1 + ldr q18, [x8, #0] // load rk0 + and x5, x5, #0xffffffffffffffc0 // number of bytes to be processed in main loop (at least 1 byte must be handled by tail) + ldr q25, [x8, #112] // load rk7 + add x5, x5, x0 + lsr x12, x11, #32 + fmov d2, x10 // CTR block 2 + orr w11, w11, w11 + rev w12, w12 // rev_ctr32 + fmov d1, x10 // CTR block 1 + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b // AES block 0 - round 0 + add w12, w12, #1 // increment rev_ctr32 + rev w9, w12 // CTR block 1 + fmov d3, x10 // CTR block 3 + orr x9, x11, x9, lsl #32 // CTR block 1 + add w12, w12, #1 // CTR block 1 + ldr q19, [x8, #16] // load rk1 + fmov v1.d[1], x9 // CTR block 1 + rev w9, w12 // CTR block 2 + add w12, w12, #1 // CTR block 2 + orr x9, x11, x9, lsl #32 // CTR block 2 + ldr q20, [x8, #32] // load rk2 + fmov v2.d[1], x9 // CTR block 2 + rev w9, w12 // CTR block 3 + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b // AES block 0 - round 1 + orr x9, x11, x9, lsl #32 // CTR block 3 + fmov v3.d[1], x9 // CTR block 3 + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b // AES block 1 - round 0 + ldr q21, [x8, #48] // load rk3 + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b // AES block 0 - round 2 + ldr q24, [x8, #96] // load rk6 + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b // AES block 2 - round 0 + ldr q23, [x8, #80] // load rk5 + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b // AES block 1 - round 1 + ldr q14, [x3, #80] // load h3l | h3h + ext v14.16b, v14.16b, v14.16b, #8 + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b // AES block 3 - round 0 + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b // AES block 2 - round 1 + ldr q22, [x8, #64] // load rk4 + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b // AES block 1 - round 2 + ldr q13, [x3, #64] // load h2l | h2h + ext v13.16b, v13.16b, v13.16b, #8 + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b // AES block 3 - round 1 + ldr q30, [x8, #192] // load rk12 + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b // AES block 2 - round 2 + ldr q15, [x3, #112] // load h4l | h4h + ext v15.16b, v15.16b, v15.16b, #8 + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b // AES block 1 - round 3 + ldr q29, [x8, #176] // load rk11 + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b // AES block 3 - round 2 + ldr q26, [x8, #128] // load rk8 + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b // AES block 2 - round 3 + add w12, w12, #1 // CTR block 3 + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b // AES block 0 - round 3 + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b // AES block 3 - round 3 + ld1 { v11.16b}, [x3] + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b // AES block 2 - round 4 + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b // AES block 0 - round 4 + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b // AES block 1 - round 4 + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b // AES block 3 - round 4 + cmp x17, #12 // setup flags for AES-128/192/256 check + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b // AES block 0 - round 5 + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b // AES block 1 - round 5 + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b // AES block 3 - round 5 + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b // AES block 2 - round 5 + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b // AES block 1 - round 6 + trn2 v17.2d, v14.2d, v15.2d // h4l | h3l + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b // AES block 3 - round 6 + ldr q27, [x8, #144] // load rk9 + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b // AES block 0 - round 6 + ldr q12, [x3, #32] // load h1l | h1h + ext v12.16b, v12.16b, v12.16b, #8 + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b // AES block 2 - round 6 + ldr q28, [x8, #160] // load rk10 + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b // AES block 1 - round 7 + trn1 v9.2d, v14.2d, v15.2d // h4h | h3h + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b // AES block 0 - round 7 + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b // AES block 2 - round 7 + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b // AES block 3 - round 7 + trn2 v16.2d, v12.2d, v13.2d // h2l | h1l + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b // AES block 1 - round 8 + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b // AES block 2 - round 8 + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b // AES block 3 - round 8 + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b // AES block 0 - round 8 + b.lt Lenc_finish_first_blocks // branch if AES-128 + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b // AES block 1 - round 9 + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b // AES block 2 - round 9 + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b // AES block 3 - round 9 + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b // AES block 0 - round 9 + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b // AES block 1 - round 10 + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b // AES block 2 - round 10 + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b // AES block 3 - round 10 + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b // AES block 0 - round 10 + b.eq Lenc_finish_first_blocks // branch if AES-192 + + aese v1.16b, v29.16b + aesmc v1.16b, v1.16b // AES block 1 - round 11 + aese v2.16b, v29.16b + aesmc v2.16b, v2.16b // AES block 2 - round 11 + aese v0.16b, v29.16b + aesmc v0.16b, v0.16b // AES block 0 - round 11 + aese v3.16b, v29.16b + aesmc v3.16b, v3.16b // AES block 3 - round 11 + aese v1.16b, v30.16b + aesmc v1.16b, v1.16b // AES block 1 - round 12 + aese v2.16b, v30.16b + aesmc v2.16b, v2.16b // AES block 2 - round 12 + aese v0.16b, v30.16b + aesmc v0.16b, v0.16b // AES block 0 - round 12 + aese v3.16b, v30.16b + aesmc v3.16b, v3.16b // AES block 3 - round 12 + +Lenc_finish_first_blocks: + cmp x0, x5 // check if we have <= 4 blocks + eor v17.16b, v17.16b, v9.16b // h4k | h3k + aese v2.16b, v31.16b // AES block 2 - round N-1 + trn1 v8.2d, v12.2d, v13.2d // h2h | h1h + aese v1.16b, v31.16b // AES block 1 - round N-1 + aese v0.16b, v31.16b // AES block 0 - round N-1 + aese v3.16b, v31.16b // AES block 3 - round N-1 + eor v16.16b, v16.16b, v8.16b // h2k | h1k + b.ge Lenc_tail // handle tail + + ldp x19, x20, [x0, #16] // AES block 1 - load plaintext + rev w9, w12 // CTR block 4 + ldp x6, x7, [x0, #0] // AES block 0 - load plaintext + ldp x23, x24, [x0, #48] // AES block 3 - load plaintext + ldp x21, x22, [x0, #32] // AES block 2 - load plaintext + add x0, x0, #64 // AES input_ptr update + eor x19, x19, x13 // AES block 1 - round N low + eor x20, x20, x14 // AES block 1 - round N high + fmov d5, x19 // AES block 1 - mov low + eor x6, x6, x13 // AES block 0 - round N low + eor x7, x7, x14 // AES block 0 - round N high + eor x24, x24, x14 // AES block 3 - round N high + fmov d4, x6 // AES block 0 - mov low + cmp x0, x5 // check if we have <= 8 blocks + fmov v4.d[1], x7 // AES block 0 - mov high + eor x23, x23, x13 // AES block 3 - round N low + eor x21, x21, x13 // AES block 2 - round N low + fmov v5.d[1], x20 // AES block 1 - mov high + fmov d6, x21 // AES block 2 - mov low + add w12, w12, #1 // CTR block 4 + orr x9, x11, x9, lsl #32 // CTR block 4 + fmov d7, x23 // AES block 3 - mov low + eor x22, x22, x14 // AES block 2 - round N high + fmov v6.d[1], x22 // AES block 2 - mov high + eor v4.16b, v4.16b, v0.16b // AES block 0 - result + fmov d0, x10 // CTR block 4 + fmov v0.d[1], x9 // CTR block 4 + rev w9, w12 // CTR block 5 + add w12, w12, #1 // CTR block 5 + eor v5.16b, v5.16b, v1.16b // AES block 1 - result + fmov d1, x10 // CTR block 5 + orr x9, x11, x9, lsl #32 // CTR block 5 + fmov v1.d[1], x9 // CTR block 5 + rev w9, w12 // CTR block 6 + st1 { v4.16b}, [x2], #16 // AES block 0 - store result + fmov v7.d[1], x24 // AES block 3 - mov high + orr x9, x11, x9, lsl #32 // CTR block 6 + eor v6.16b, v6.16b, v2.16b // AES block 2 - result + st1 { v5.16b}, [x2], #16 // AES block 1 - store result + add w12, w12, #1 // CTR block 6 + fmov d2, x10 // CTR block 6 + fmov v2.d[1], x9 // CTR block 6 + st1 { v6.16b}, [x2], #16 // AES block 2 - store result + rev w9, w12 // CTR block 7 + orr x9, x11, x9, lsl #32 // CTR block 7 + eor v7.16b, v7.16b, v3.16b // AES block 3 - result + st1 { v7.16b}, [x2], #16 // AES block 3 - store result + b.ge Lenc_prepretail // do prepretail + +Lenc_main_loop: // main loop start + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 0 + rev64 v4.16b, v4.16b // GHASH block 4k (only t0 is free) + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 0 + fmov d3, x10 // CTR block 4k+3 + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 0 + ext v11.16b, v11.16b, v11.16b, #8 // PRE 0 + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 1 + fmov v3.d[1], x9 // CTR block 4k+3 + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 1 + ldp x23, x24, [x0, #48] // AES block 4k+7 - load plaintext + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 1 + ldp x21, x22, [x0, #32] // AES block 4k+6 - load plaintext + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 2 + eor v4.16b, v4.16b, v11.16b // PRE 1 + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 2 + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 0 + eor x23, x23, x13 // AES block 4k+7 - round N low + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 3 + mov d10, v17.d[1] // GHASH block 4k - mid + pmull2 v9.1q, v4.2d, v15.2d // GHASH block 4k - high + eor x22, x22, x14 // AES block 4k+6 - round N high + mov d8, v4.d[1] // GHASH block 4k - mid + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 1 + rev64 v5.16b, v5.16b // GHASH block 4k+1 (t0 and t1 free) + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 4 + pmull v11.1q, v4.1d, v15.1d // GHASH block 4k - low + eor v8.8b, v8.8b, v4.8b // GHASH block 4k - mid + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 2 + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 5 + rev64 v7.16b, v7.16b // GHASH block 4k+3 (t0, t1, t2 and t3 free) + pmull2 v4.1q, v5.2d, v14.2d // GHASH block 4k+1 - high + pmull v10.1q, v8.1d, v10.1d // GHASH block 4k - mid + rev64 v6.16b, v6.16b // GHASH block 4k+2 (t0, t1, and t2 free) + pmull v8.1q, v5.1d, v14.1d // GHASH block 4k+1 - low + eor v9.16b, v9.16b, v4.16b // GHASH block 4k+1 - high + mov d4, v5.d[1] // GHASH block 4k+1 - mid + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 3 + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 2 + eor v11.16b, v11.16b, v8.16b // GHASH block 4k+1 - low + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 3 + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 4 + mov d8, v6.d[1] // GHASH block 4k+2 - mid + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 3 + eor v4.8b, v4.8b, v5.8b // GHASH block 4k+1 - mid + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 4 + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 6 + eor v8.8b, v8.8b, v6.8b // GHASH block 4k+2 - mid + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 4 + pmull v4.1q, v4.1d, v17.1d // GHASH block 4k+1 - mid + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 7 + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 5 + ins v8.d[1], v8.d[0] // GHASH block 4k+2 - mid + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 5 + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 8 + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 5 + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 6 + eor v10.16b, v10.16b, v4.16b // GHASH block 4k+1 - mid + pmull2 v4.1q, v6.2d, v13.2d // GHASH block 4k+2 - high + pmull v5.1q, v6.1d, v13.1d // GHASH block 4k+2 - low + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 7 + pmull v6.1q, v7.1d, v12.1d // GHASH block 4k+3 - low + eor v9.16b, v9.16b, v4.16b // GHASH block 4k+2 - high + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 6 + ldp x19, x20, [x0, #16] // AES block 4k+5 - load plaintext + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 8 + mov d4, v7.d[1] // GHASH block 4k+3 - mid + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 6 + eor v11.16b, v11.16b, v5.16b // GHASH block 4k+2 - low + pmull2 v8.1q, v8.2d, v16.2d // GHASH block 4k+2 - mid + pmull2 v5.1q, v7.2d, v12.2d // GHASH block 4k+3 - high + eor v4.8b, v4.8b, v7.8b // GHASH block 4k+3 - mid + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 7 + eor x19, x19, x13 // AES block 4k+5 - round N low + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 8 + eor v10.16b, v10.16b, v8.16b // GHASH block 4k+2 - mid + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 7 + eor x21, x21, x13 // AES block 4k+6 - round N low + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 8 + movi v8.8b, #0xc2 + pmull v4.1q, v4.1d, v16.1d // GHASH block 4k+3 - mid + eor v9.16b, v9.16b, v5.16b // GHASH block 4k+3 - high + cmp x17, #12 // setup flags for AES-128/192/256 check + fmov d5, x19 // AES block 4k+5 - mov low + ldp x6, x7, [x0, #0] // AES block 4k+4 - load plaintext + b.lt Lenc_main_loop_continue // branch if AES-128 + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 9 + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 9 + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 9 + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 9 + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 10 + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 10 + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 10 + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 10 + b.eq Lenc_main_loop_continue // branch if AES-192 + + aese v0.16b, v29.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 11 + aese v1.16b, v29.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 11 + aese v2.16b, v29.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 11 + aese v3.16b, v29.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 11 + aese v1.16b, v30.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 12 + aese v0.16b, v30.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 12 + aese v2.16b, v30.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 12 + aese v3.16b, v30.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 12 + +Lenc_main_loop_continue: + shl d8, d8, #56 // mod_constant + eor v11.16b, v11.16b, v6.16b // GHASH block 4k+3 - low + eor v10.16b, v10.16b, v4.16b // GHASH block 4k+3 - mid + add w12, w12, #1 // CTR block 4k+3 + eor v4.16b, v11.16b, v9.16b // MODULO - karatsuba tidy up + add x0, x0, #64 // AES input_ptr update + pmull v7.1q, v9.1d, v8.1d // MODULO - top 64b align with mid + rev w9, w12 // CTR block 4k+8 + ext v9.16b, v9.16b, v9.16b, #8 // MODULO - other top alignment + eor x6, x6, x13 // AES block 4k+4 - round N low + eor v10.16b, v10.16b, v4.16b // MODULO - karatsuba tidy up + eor x7, x7, x14 // AES block 4k+4 - round N high + fmov d4, x6 // AES block 4k+4 - mov low + orr x9, x11, x9, lsl #32 // CTR block 4k+8 + eor v7.16b, v9.16b, v7.16b // MODULO - fold into mid + eor x20, x20, x14 // AES block 4k+5 - round N high + eor x24, x24, x14 // AES block 4k+7 - round N high + add w12, w12, #1 // CTR block 4k+8 + aese v0.16b, v31.16b // AES block 4k+4 - round N-1 + fmov v4.d[1], x7 // AES block 4k+4 - mov high + eor v10.16b, v10.16b, v7.16b // MODULO - fold into mid + fmov d7, x23 // AES block 4k+7 - mov low + aese v1.16b, v31.16b // AES block 4k+5 - round N-1 + fmov v5.d[1], x20 // AES block 4k+5 - mov high + fmov d6, x21 // AES block 4k+6 - mov low + cmp x0, x5 // LOOP CONTROL + fmov v6.d[1], x22 // AES block 4k+6 - mov high + pmull v9.1q, v10.1d, v8.1d // MODULO - mid 64b align with low + eor v4.16b, v4.16b, v0.16b // AES block 4k+4 - result + fmov d0, x10 // CTR block 4k+8 + fmov v0.d[1], x9 // CTR block 4k+8 + rev w9, w12 // CTR block 4k+9 + add w12, w12, #1 // CTR block 4k+9 + eor v5.16b, v5.16b, v1.16b // AES block 4k+5 - result + fmov d1, x10 // CTR block 4k+9 + orr x9, x11, x9, lsl #32 // CTR block 4k+9 + fmov v1.d[1], x9 // CTR block 4k+9 + aese v2.16b, v31.16b // AES block 4k+6 - round N-1 + rev w9, w12 // CTR block 4k+10 + st1 { v4.16b}, [x2], #16 // AES block 4k+4 - store result + orr x9, x11, x9, lsl #32 // CTR block 4k+10 + eor v11.16b, v11.16b, v9.16b // MODULO - fold into low + fmov v7.d[1], x24 // AES block 4k+7 - mov high + ext v10.16b, v10.16b, v10.16b, #8 // MODULO - other mid alignment + st1 { v5.16b}, [x2], #16 // AES block 4k+5 - store result + add w12, w12, #1 // CTR block 4k+10 + aese v3.16b, v31.16b // AES block 4k+7 - round N-1 + eor v6.16b, v6.16b, v2.16b // AES block 4k+6 - result + fmov d2, x10 // CTR block 4k+10 + st1 { v6.16b}, [x2], #16 // AES block 4k+6 - store result + fmov v2.d[1], x9 // CTR block 4k+10 + rev w9, w12 // CTR block 4k+11 + eor v11.16b, v11.16b, v10.16b // MODULO - fold into low + orr x9, x11, x9, lsl #32 // CTR block 4k+11 + eor v7.16b, v7.16b, v3.16b // AES block 4k+7 - result + st1 { v7.16b}, [x2], #16 // AES block 4k+7 - store result + b.lt Lenc_main_loop + +Lenc_prepretail: // PREPRETAIL + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 0 + rev64 v6.16b, v6.16b // GHASH block 4k+2 (t0, t1, and t2 free) + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 0 + fmov d3, x10 // CTR block 4k+3 + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 0 + rev64 v4.16b, v4.16b // GHASH block 4k (only t0 is free) + fmov v3.d[1], x9 // CTR block 4k+3 + ext v11.16b, v11.16b, v11.16b, #8 // PRE 0 + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 1 + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 1 + eor v4.16b, v4.16b, v11.16b // PRE 1 + rev64 v5.16b, v5.16b // GHASH block 4k+1 (t0 and t1 free) + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 2 + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 0 + mov d10, v17.d[1] // GHASH block 4k - mid + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 1 + pmull v11.1q, v4.1d, v15.1d // GHASH block 4k - low + mov d8, v4.d[1] // GHASH block 4k - mid + pmull2 v9.1q, v4.2d, v15.2d // GHASH block 4k - high + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 3 + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 2 + eor v8.8b, v8.8b, v4.8b // GHASH block 4k - mid + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 2 + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 1 + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 3 + pmull v10.1q, v8.1d, v10.1d // GHASH block 4k - mid + pmull2 v4.1q, v5.2d, v14.2d // GHASH block 4k+1 - high + pmull v8.1q, v5.1d, v14.1d // GHASH block 4k+1 - low + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 2 + eor v9.16b, v9.16b, v4.16b // GHASH block 4k+1 - high + mov d4, v5.d[1] // GHASH block 4k+1 - mid + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 3 + eor v11.16b, v11.16b, v8.16b // GHASH block 4k+1 - low + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 3 + eor v4.8b, v4.8b, v5.8b // GHASH block 4k+1 - mid + mov d8, v6.d[1] // GHASH block 4k+2 - mid + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 4 + rev64 v7.16b, v7.16b // GHASH block 4k+3 (t0, t1, t2 and t3 free) + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 4 + pmull v4.1q, v4.1d, v17.1d // GHASH block 4k+1 - mid + eor v8.8b, v8.8b, v6.8b // GHASH block 4k+2 - mid + add w12, w12, #1 // CTR block 4k+3 + pmull v5.1q, v6.1d, v13.1d // GHASH block 4k+2 - low + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 5 + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 4 + eor v10.16b, v10.16b, v4.16b // GHASH block 4k+1 - mid + pmull2 v4.1q, v6.2d, v13.2d // GHASH block 4k+2 - high + eor v11.16b, v11.16b, v5.16b // GHASH block 4k+2 - low + ins v8.d[1], v8.d[0] // GHASH block 4k+2 - mid + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 5 + eor v9.16b, v9.16b, v4.16b // GHASH block 4k+2 - high + mov d4, v7.d[1] // GHASH block 4k+3 - mid + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 4 + pmull2 v8.1q, v8.2d, v16.2d // GHASH block 4k+2 - mid + eor v4.8b, v4.8b, v7.8b // GHASH block 4k+3 - mid + pmull2 v5.1q, v7.2d, v12.2d // GHASH block 4k+3 - high + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 5 + pmull v4.1q, v4.1d, v16.1d // GHASH block 4k+3 - mid + eor v10.16b, v10.16b, v8.16b // GHASH block 4k+2 - mid + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 5 + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 6 + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 6 + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 6 + movi v8.8b, #0xc2 + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 6 + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 7 + eor v9.16b, v9.16b, v5.16b // GHASH block 4k+3 - high + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 7 + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 7 + shl d8, d8, #56 // mod_constant + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 8 + eor v10.16b, v10.16b, v4.16b // GHASH block 4k+3 - mid + pmull v6.1q, v7.1d, v12.1d // GHASH block 4k+3 - low + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 8 + cmp x17, #12 // setup flags for AES-128/192/256 check + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 8 + eor v11.16b, v11.16b, v6.16b // GHASH block 4k+3 - low + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 7 + eor v10.16b, v10.16b, v9.16b // karatsuba tidy up + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 8 + pmull v4.1q, v9.1d, v8.1d + ext v9.16b, v9.16b, v9.16b, #8 + eor v10.16b, v10.16b, v11.16b + b.lt Lenc_finish_prepretail // branch if AES-128 + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 9 + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 9 + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 9 + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 9 + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 10 + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 10 + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 10 + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 10 + b.eq Lenc_finish_prepretail // branch if AES-192 + + aese v1.16b, v29.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 11 + aese v0.16b, v29.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 11 + aese v3.16b, v29.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 11 + aese v2.16b, v29.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 11 + aese v1.16b, v30.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 12 + aese v0.16b, v30.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 12 + aese v3.16b, v30.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 12 + aese v2.16b, v30.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 12 + +Lenc_finish_prepretail: + eor v10.16b, v10.16b, v4.16b + eor v10.16b, v10.16b, v9.16b + pmull v4.1q, v10.1d, v8.1d + ext v10.16b, v10.16b, v10.16b, #8 + aese v1.16b, v31.16b // AES block 4k+5 - round N-1 + eor v11.16b, v11.16b, v4.16b + aese v3.16b, v31.16b // AES block 4k+7 - round N-1 + aese v0.16b, v31.16b // AES block 4k+4 - round N-1 + aese v2.16b, v31.16b // AES block 4k+6 - round N-1 + eor v11.16b, v11.16b, v10.16b + +Lenc_tail: // TAIL + ext v8.16b, v11.16b, v11.16b, #8 // prepare final partial tag + sub x5, x4, x0 // main_end_input_ptr is number of bytes left to process + ldp x6, x7, [x0], #16 // AES block 4k+4 - load plaintext + eor x6, x6, x13 // AES block 4k+4 - round N low + eor x7, x7, x14 // AES block 4k+4 - round N high + cmp x5, #48 + fmov d4, x6 // AES block 4k+4 - mov low + fmov v4.d[1], x7 // AES block 4k+4 - mov high + eor v5.16b, v4.16b, v0.16b // AES block 4k+4 - result + b.gt Lenc_blocks_more_than_3 + cmp x5, #32 + mov v3.16b, v2.16b + movi v11.8b, #0 + movi v9.8b, #0 + sub w12, w12, #1 + mov v2.16b, v1.16b + movi v10.8b, #0 + b.gt Lenc_blocks_more_than_2 + mov v3.16b, v1.16b + sub w12, w12, #1 + cmp x5, #16 + b.gt Lenc_blocks_more_than_1 + sub w12, w12, #1 + b Lenc_blocks_less_than_1 +Lenc_blocks_more_than_3: // blocks left > 3 + st1 { v5.16b}, [x2], #16 // AES final-3 block - store result + ldp x6, x7, [x0], #16 // AES final-2 block - load input low & high + rev64 v4.16b, v5.16b // GHASH final-3 block + eor x6, x6, x13 // AES final-2 block - round N low + eor v4.16b, v4.16b, v8.16b // feed in partial tag + eor x7, x7, x14 // AES final-2 block - round N high + mov d22, v4.d[1] // GHASH final-3 block - mid + fmov d5, x6 // AES final-2 block - mov low + fmov v5.d[1], x7 // AES final-2 block - mov high + eor v22.8b, v22.8b, v4.8b // GHASH final-3 block - mid + movi v8.8b, #0 // suppress further partial tag feed in + mov d10, v17.d[1] // GHASH final-3 block - mid + pmull v11.1q, v4.1d, v15.1d // GHASH final-3 block - low + pmull2 v9.1q, v4.2d, v15.2d // GHASH final-3 block - high + pmull v10.1q, v22.1d, v10.1d // GHASH final-3 block - mid + eor v5.16b, v5.16b, v1.16b // AES final-2 block - result +Lenc_blocks_more_than_2: // blocks left > 2 + st1 { v5.16b}, [x2], #16 // AES final-2 block - store result + ldp x6, x7, [x0], #16 // AES final-1 block - load input low & high + rev64 v4.16b, v5.16b // GHASH final-2 block + eor x6, x6, x13 // AES final-1 block - round N low + eor v4.16b, v4.16b, v8.16b // feed in partial tag + fmov d5, x6 // AES final-1 block - mov low + eor x7, x7, x14 // AES final-1 block - round N high + fmov v5.d[1], x7 // AES final-1 block - mov high + movi v8.8b, #0 // suppress further partial tag feed in + pmull2 v20.1q, v4.2d, v14.2d // GHASH final-2 block - high + mov d22, v4.d[1] // GHASH final-2 block - mid + pmull v21.1q, v4.1d, v14.1d // GHASH final-2 block - low + eor v22.8b, v22.8b, v4.8b // GHASH final-2 block - mid + eor v5.16b, v5.16b, v2.16b // AES final-1 block - result + eor v9.16b, v9.16b, v20.16b // GHASH final-2 block - high + pmull v22.1q, v22.1d, v17.1d // GHASH final-2 block - mid + eor v11.16b, v11.16b, v21.16b // GHASH final-2 block - low + eor v10.16b, v10.16b, v22.16b // GHASH final-2 block - mid +Lenc_blocks_more_than_1: // blocks left > 1 + st1 { v5.16b}, [x2], #16 // AES final-1 block - store result + rev64 v4.16b, v5.16b // GHASH final-1 block + ldp x6, x7, [x0], #16 // AES final block - load input low & high + eor v4.16b, v4.16b, v8.16b // feed in partial tag + movi v8.8b, #0 // suppress further partial tag feed in + eor x6, x6, x13 // AES final block - round N low + mov d22, v4.d[1] // GHASH final-1 block - mid + pmull2 v20.1q, v4.2d, v13.2d // GHASH final-1 block - high + eor x7, x7, x14 // AES final block - round N high + eor v22.8b, v22.8b, v4.8b // GHASH final-1 block - mid + eor v9.16b, v9.16b, v20.16b // GHASH final-1 block - high + ins v22.d[1], v22.d[0] // GHASH final-1 block - mid + fmov d5, x6 // AES final block - mov low + fmov v5.d[1], x7 // AES final block - mov high + pmull2 v22.1q, v22.2d, v16.2d // GHASH final-1 block - mid + pmull v21.1q, v4.1d, v13.1d // GHASH final-1 block - low + eor v5.16b, v5.16b, v3.16b // AES final block - result + eor v10.16b, v10.16b, v22.16b // GHASH final-1 block - mid + eor v11.16b, v11.16b, v21.16b // GHASH final-1 block - low +Lenc_blocks_less_than_1: // blocks left <= 1 + and x1, x1, #127 // bit_length %= 128 + mvn x13, xzr // rkN_l = 0xffffffffffffffff + sub x1, x1, #128 // bit_length -= 128 + neg x1, x1 // bit_length = 128 - #bits in input (in range [1,128]) + ld1 { v18.16b}, [x2] // load existing bytes where the possibly partial last block is to be stored + mvn x14, xzr // rkN_h = 0xffffffffffffffff + and x1, x1, #127 // bit_length %= 128 + lsr x14, x14, x1 // rkN_h is mask for top 64b of last block + cmp x1, #64 + csel x6, x13, x14, lt + csel x7, x14, xzr, lt + fmov d0, x6 // ctr0b is mask for last block + fmov v0.d[1], x7 + and v5.16b, v5.16b, v0.16b // possibly partial last block has zeroes in highest bits + rev64 v4.16b, v5.16b // GHASH final block + eor v4.16b, v4.16b, v8.16b // feed in partial tag + bif v5.16b, v18.16b, v0.16b // insert existing bytes in top end of result before storing + pmull2 v20.1q, v4.2d, v12.2d // GHASH final block - high + mov d8, v4.d[1] // GHASH final block - mid + rev w9, w12 + pmull v21.1q, v4.1d, v12.1d // GHASH final block - low + eor v9.16b, v9.16b, v20.16b // GHASH final block - high + eor v8.8b, v8.8b, v4.8b // GHASH final block - mid + pmull v8.1q, v8.1d, v16.1d // GHASH final block - mid + eor v11.16b, v11.16b, v21.16b // GHASH final block - low + eor v10.16b, v10.16b, v8.16b // GHASH final block - mid + movi v8.8b, #0xc2 + eor v4.16b, v11.16b, v9.16b // MODULO - karatsuba tidy up + shl d8, d8, #56 // mod_constant + eor v10.16b, v10.16b, v4.16b // MODULO - karatsuba tidy up + pmull v7.1q, v9.1d, v8.1d // MODULO - top 64b align with mid + ext v9.16b, v9.16b, v9.16b, #8 // MODULO - other top alignment + eor v10.16b, v10.16b, v7.16b // MODULO - fold into mid + eor v10.16b, v10.16b, v9.16b // MODULO - fold into mid + pmull v9.1q, v10.1d, v8.1d // MODULO - mid 64b align with low + ext v10.16b, v10.16b, v10.16b, #8 // MODULO - other mid alignment + str w9, [x16, #12] // store the updated counter + st1 { v5.16b}, [x2] // store all 16B + eor v11.16b, v11.16b, v9.16b // MODULO - fold into low + eor v11.16b, v11.16b, v10.16b // MODULO - fold into low + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + mov x0, x15 + st1 { v11.16b }, [x3] + ldp x19, x20, [sp, #16] + ldp x21, x22, [sp, #32] + ldp x23, x24, [sp, #48] + ldp d8, d9, [sp, #64] + ldp d10, d11, [sp, #80] + ldp d12, d13, [sp, #96] + ldp d14, d15, [sp, #112] + ldp x29, x30, [sp], #128 + AARCH64_VALIDATE_LINK_REGISTER + ret + +.globl _aes_gcm_dec_kernel +.private_extern _aes_gcm_dec_kernel + +.align 4 +_aes_gcm_dec_kernel: + AARCH64_SIGN_LINK_REGISTER + stp x29, x30, [sp, #-128]! + mov x29, sp + stp x19, x20, [sp, #16] + mov x16, x4 + mov x8, x5 + stp x21, x22, [sp, #32] + stp x23, x24, [sp, #48] + stp d8, d9, [sp, #64] + stp d10, d11, [sp, #80] + stp d12, d13, [sp, #96] + stp d14, d15, [sp, #112] + ldr w17, [x8, #240] + add x19, x8, x17, lsl #4 // borrow input_l1 for last key + ldp x13, x14, [x19] // load round N keys + ldr q31, [x19, #-16] // load round N-1 keys + lsr x5, x1, #3 // byte_len + mov x15, x5 + ldp x10, x11, [x16] // ctr96_b64, ctr96_t32 + ldr q26, [x8, #128] // load rk8 + sub x5, x5, #1 // byte_len - 1 + ldr q25, [x8, #112] // load rk7 + and x5, x5, #0xffffffffffffffc0 // number of bytes to be processed in main loop (at least 1 byte must be handled by tail) + add x4, x0, x1, lsr #3 // end_input_ptr + ldr q24, [x8, #96] // load rk6 + lsr x12, x11, #32 + ldr q23, [x8, #80] // load rk5 + orr w11, w11, w11 + ldr q21, [x8, #48] // load rk3 + add x5, x5, x0 + rev w12, w12 // rev_ctr32 + add w12, w12, #1 // increment rev_ctr32 + fmov d3, x10 // CTR block 3 + rev w9, w12 // CTR block 1 + add w12, w12, #1 // CTR block 1 + fmov d1, x10 // CTR block 1 + orr x9, x11, x9, lsl #32 // CTR block 1 + ld1 { v0.16b}, [x16] // special case vector load initial counter so we can start first AES block as quickly as possible + fmov v1.d[1], x9 // CTR block 1 + rev w9, w12 // CTR block 2 + add w12, w12, #1 // CTR block 2 + fmov d2, x10 // CTR block 2 + orr x9, x11, x9, lsl #32 // CTR block 2 + fmov v2.d[1], x9 // CTR block 2 + rev w9, w12 // CTR block 3 + orr x9, x11, x9, lsl #32 // CTR block 3 + ldr q18, [x8, #0] // load rk0 + fmov v3.d[1], x9 // CTR block 3 + add w12, w12, #1 // CTR block 3 + ldr q22, [x8, #64] // load rk4 + ldr q19, [x8, #16] // load rk1 + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b // AES block 0 - round 0 + ldr q14, [x3, #80] // load h3l | h3h + ext v14.16b, v14.16b, v14.16b, #8 + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b // AES block 3 - round 0 + ldr q15, [x3, #112] // load h4l | h4h + ext v15.16b, v15.16b, v15.16b, #8 + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b // AES block 1 - round 0 + ldr q13, [x3, #64] // load h2l | h2h + ext v13.16b, v13.16b, v13.16b, #8 + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b // AES block 2 - round 0 + ldr q20, [x8, #32] // load rk2 + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b // AES block 0 - round 1 + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b // AES block 1 - round 1 + ld1 { v11.16b}, [x3] + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b // AES block 2 - round 1 + ldr q27, [x8, #144] // load rk9 + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b // AES block 3 - round 1 + ldr q30, [x8, #192] // load rk12 + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b // AES block 0 - round 2 + ldr q12, [x3, #32] // load h1l | h1h + ext v12.16b, v12.16b, v12.16b, #8 + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b // AES block 2 - round 2 + ldr q28, [x8, #160] // load rk10 + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b // AES block 3 - round 2 + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b // AES block 0 - round 3 + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b // AES block 1 - round 2 + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b // AES block 3 - round 3 + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b // AES block 0 - round 4 + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b // AES block 2 - round 3 + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b // AES block 1 - round 3 + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b // AES block 3 - round 4 + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b // AES block 2 - round 4 + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b // AES block 1 - round 4 + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b // AES block 3 - round 5 + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b // AES block 0 - round 5 + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b // AES block 1 - round 5 + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b // AES block 2 - round 5 + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b // AES block 0 - round 6 + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b // AES block 3 - round 6 + cmp x17, #12 // setup flags for AES-128/192/256 check + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b // AES block 1 - round 6 + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b // AES block 2 - round 6 + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b // AES block 0 - round 7 + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b // AES block 1 - round 7 + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b // AES block 3 - round 7 + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b // AES block 0 - round 8 + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b // AES block 2 - round 7 + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b // AES block 3 - round 8 + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b // AES block 1 - round 8 + ldr q29, [x8, #176] // load rk11 + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b // AES block 2 - round 8 + b.lt Ldec_finish_first_blocks // branch if AES-128 + + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b // AES block 0 - round 9 + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b // AES block 1 - round 9 + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b // AES block 3 - round 9 + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b // AES block 2 - round 9 + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b // AES block 0 - round 10 + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b // AES block 1 - round 10 + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b // AES block 3 - round 10 + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b // AES block 2 - round 10 + b.eq Ldec_finish_first_blocks // branch if AES-192 + + aese v0.16b, v29.16b + aesmc v0.16b, v0.16b // AES block 0 - round 11 + aese v3.16b, v29.16b + aesmc v3.16b, v3.16b // AES block 3 - round 11 + aese v1.16b, v29.16b + aesmc v1.16b, v1.16b // AES block 1 - round 11 + aese v2.16b, v29.16b + aesmc v2.16b, v2.16b // AES block 2 - round 11 + aese v1.16b, v30.16b + aesmc v1.16b, v1.16b // AES block 1 - round 12 + aese v0.16b, v30.16b + aesmc v0.16b, v0.16b // AES block 0 - round 12 + aese v2.16b, v30.16b + aesmc v2.16b, v2.16b // AES block 2 - round 12 + aese v3.16b, v30.16b + aesmc v3.16b, v3.16b // AES block 3 - round 12 + +Ldec_finish_first_blocks: + cmp x0, x5 // check if we have <= 4 blocks + trn1 v9.2d, v14.2d, v15.2d // h4h | h3h + trn2 v17.2d, v14.2d, v15.2d // h4l | h3l + trn1 v8.2d, v12.2d, v13.2d // h2h | h1h + trn2 v16.2d, v12.2d, v13.2d // h2l | h1l + eor v17.16b, v17.16b, v9.16b // h4k | h3k + aese v1.16b, v31.16b // AES block 1 - round N-1 + aese v2.16b, v31.16b // AES block 2 - round N-1 + eor v16.16b, v16.16b, v8.16b // h2k | h1k + aese v3.16b, v31.16b // AES block 3 - round N-1 + aese v0.16b, v31.16b // AES block 0 - round N-1 + b.ge Ldec_tail // handle tail + + ldr q4, [x0, #0] // AES block 0 - load ciphertext + ldr q5, [x0, #16] // AES block 1 - load ciphertext + rev w9, w12 // CTR block 4 + eor v0.16b, v4.16b, v0.16b // AES block 0 - result + eor v1.16b, v5.16b, v1.16b // AES block 1 - result + rev64 v5.16b, v5.16b // GHASH block 1 + ldr q7, [x0, #48] // AES block 3 - load ciphertext + mov x7, v0.d[1] // AES block 0 - mov high + mov x6, v0.d[0] // AES block 0 - mov low + rev64 v4.16b, v4.16b // GHASH block 0 + add w12, w12, #1 // CTR block 4 + fmov d0, x10 // CTR block 4 + orr x9, x11, x9, lsl #32 // CTR block 4 + fmov v0.d[1], x9 // CTR block 4 + rev w9, w12 // CTR block 5 + add w12, w12, #1 // CTR block 5 + mov x19, v1.d[0] // AES block 1 - mov low + orr x9, x11, x9, lsl #32 // CTR block 5 + mov x20, v1.d[1] // AES block 1 - mov high + eor x7, x7, x14 // AES block 0 - round N high + eor x6, x6, x13 // AES block 0 - round N low + stp x6, x7, [x2], #16 // AES block 0 - store result + fmov d1, x10 // CTR block 5 + ldr q6, [x0, #32] // AES block 2 - load ciphertext + add x0, x0, #64 // AES input_ptr update + fmov v1.d[1], x9 // CTR block 5 + rev w9, w12 // CTR block 6 + add w12, w12, #1 // CTR block 6 + eor x19, x19, x13 // AES block 1 - round N low + orr x9, x11, x9, lsl #32 // CTR block 6 + eor x20, x20, x14 // AES block 1 - round N high + stp x19, x20, [x2], #16 // AES block 1 - store result + eor v2.16b, v6.16b, v2.16b // AES block 2 - result + cmp x0, x5 // check if we have <= 8 blocks + b.ge Ldec_prepretail // do prepretail + +Ldec_main_loop: // main loop start + mov x21, v2.d[0] // AES block 4k+2 - mov low + ext v11.16b, v11.16b, v11.16b, #8 // PRE 0 + eor v3.16b, v7.16b, v3.16b // AES block 4k+3 - result + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 0 + mov x22, v2.d[1] // AES block 4k+2 - mov high + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 0 + fmov d2, x10 // CTR block 4k+6 + fmov v2.d[1], x9 // CTR block 4k+6 + eor v4.16b, v4.16b, v11.16b // PRE 1 + rev w9, w12 // CTR block 4k+7 + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 1 + mov x24, v3.d[1] // AES block 4k+3 - mov high + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 1 + mov x23, v3.d[0] // AES block 4k+3 - mov low + pmull2 v9.1q, v4.2d, v15.2d // GHASH block 4k - high + mov d8, v4.d[1] // GHASH block 4k - mid + fmov d3, x10 // CTR block 4k+7 + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 2 + orr x9, x11, x9, lsl #32 // CTR block 4k+7 + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 0 + fmov v3.d[1], x9 // CTR block 4k+7 + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 2 + eor v8.8b, v8.8b, v4.8b // GHASH block 4k - mid + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 3 + eor x22, x22, x14 // AES block 4k+2 - round N high + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 1 + mov d10, v17.d[1] // GHASH block 4k - mid + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 3 + rev64 v6.16b, v6.16b // GHASH block 4k+2 + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 0 + eor x21, x21, x13 // AES block 4k+2 - round N low + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 2 + stp x21, x22, [x2], #16 // AES block 4k+2 - store result + pmull v11.1q, v4.1d, v15.1d // GHASH block 4k - low + pmull2 v4.1q, v5.2d, v14.2d // GHASH block 4k+1 - high + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 3 + rev64 v7.16b, v7.16b // GHASH block 4k+3 + pmull v10.1q, v8.1d, v10.1d // GHASH block 4k - mid + eor x23, x23, x13 // AES block 4k+3 - round N low + pmull v8.1q, v5.1d, v14.1d // GHASH block 4k+1 - low + eor x24, x24, x14 // AES block 4k+3 - round N high + eor v9.16b, v9.16b, v4.16b // GHASH block 4k+1 - high + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 4 + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 1 + mov d4, v5.d[1] // GHASH block 4k+1 - mid + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 4 + eor v11.16b, v11.16b, v8.16b // GHASH block 4k+1 - low + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 5 + add w12, w12, #1 // CTR block 4k+7 + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 2 + mov d8, v6.d[1] // GHASH block 4k+2 - mid + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 4 + eor v4.8b, v4.8b, v5.8b // GHASH block 4k+1 - mid + pmull v5.1q, v6.1d, v13.1d // GHASH block 4k+2 - low + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 3 + eor v8.8b, v8.8b, v6.8b // GHASH block 4k+2 - mid + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 5 + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 5 + eor v11.16b, v11.16b, v5.16b // GHASH block 4k+2 - low + pmull v4.1q, v4.1d, v17.1d // GHASH block 4k+1 - mid + rev w9, w12 // CTR block 4k+8 + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 6 + ins v8.d[1], v8.d[0] // GHASH block 4k+2 - mid + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 6 + add w12, w12, #1 // CTR block 4k+8 + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 4 + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 7 + eor v10.16b, v10.16b, v4.16b // GHASH block 4k+1 - mid + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 7 + pmull2 v4.1q, v6.2d, v13.2d // GHASH block 4k+2 - high + mov d6, v7.d[1] // GHASH block 4k+3 - mid + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 5 + pmull2 v8.1q, v8.2d, v16.2d // GHASH block 4k+2 - mid + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 8 + eor v9.16b, v9.16b, v4.16b // GHASH block 4k+2 - high + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 6 + pmull v4.1q, v7.1d, v12.1d // GHASH block 4k+3 - low + orr x9, x11, x9, lsl #32 // CTR block 4k+8 + eor v10.16b, v10.16b, v8.16b // GHASH block 4k+2 - mid + pmull2 v5.1q, v7.2d, v12.2d // GHASH block 4k+3 - high + cmp x17, #12 // setup flags for AES-128/192/256 check + eor v6.8b, v6.8b, v7.8b // GHASH block 4k+3 - mid + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 8 + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 6 + eor v9.16b, v9.16b, v5.16b // GHASH block 4k+3 - high + pmull v6.1q, v6.1d, v16.1d // GHASH block 4k+3 - mid + movi v8.8b, #0xc2 + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 7 + eor v11.16b, v11.16b, v4.16b // GHASH block 4k+3 - low + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 7 + shl d8, d8, #56 // mod_constant + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 8 + eor v10.16b, v10.16b, v6.16b // GHASH block 4k+3 - mid + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 8 + b.lt Ldec_main_loop_continue // branch if AES-128 + + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 9 + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 9 + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 9 + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 9 + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 10 + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 10 + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 10 + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 10 + b.eq Ldec_main_loop_continue // branch if AES-192 + + aese v0.16b, v29.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 11 + aese v1.16b, v29.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 11 + aese v2.16b, v29.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 11 + aese v3.16b, v29.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 11 + aese v0.16b, v30.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 12 + aese v1.16b, v30.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 12 + aese v2.16b, v30.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 12 + aese v3.16b, v30.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 12 + +Ldec_main_loop_continue: + pmull v7.1q, v9.1d, v8.1d // MODULO - top 64b align with mid + eor v6.16b, v11.16b, v9.16b // MODULO - karatsuba tidy up + ldr q4, [x0, #0] // AES block 4k+4 - load ciphertext + aese v0.16b, v31.16b // AES block 4k+4 - round N-1 + ext v9.16b, v9.16b, v9.16b, #8 // MODULO - other top alignment + eor v10.16b, v10.16b, v6.16b // MODULO - karatsuba tidy up + ldr q5, [x0, #16] // AES block 4k+5 - load ciphertext + eor v0.16b, v4.16b, v0.16b // AES block 4k+4 - result + stp x23, x24, [x2], #16 // AES block 4k+3 - store result + eor v10.16b, v10.16b, v7.16b // MODULO - fold into mid + ldr q7, [x0, #48] // AES block 4k+7 - load ciphertext + ldr q6, [x0, #32] // AES block 4k+6 - load ciphertext + mov x7, v0.d[1] // AES block 4k+4 - mov high + eor v10.16b, v10.16b, v9.16b // MODULO - fold into mid + aese v1.16b, v31.16b // AES block 4k+5 - round N-1 + add x0, x0, #64 // AES input_ptr update + mov x6, v0.d[0] // AES block 4k+4 - mov low + fmov d0, x10 // CTR block 4k+8 + fmov v0.d[1], x9 // CTR block 4k+8 + pmull v8.1q, v10.1d, v8.1d // MODULO - mid 64b align with low + eor v1.16b, v5.16b, v1.16b // AES block 4k+5 - result + rev w9, w12 // CTR block 4k+9 + aese v2.16b, v31.16b // AES block 4k+6 - round N-1 + orr x9, x11, x9, lsl #32 // CTR block 4k+9 + cmp x0, x5 // LOOP CONTROL + add w12, w12, #1 // CTR block 4k+9 + eor x6, x6, x13 // AES block 4k+4 - round N low + eor x7, x7, x14 // AES block 4k+4 - round N high + mov x20, v1.d[1] // AES block 4k+5 - mov high + eor v2.16b, v6.16b, v2.16b // AES block 4k+6 - result + eor v11.16b, v11.16b, v8.16b // MODULO - fold into low + mov x19, v1.d[0] // AES block 4k+5 - mov low + fmov d1, x10 // CTR block 4k+9 + ext v10.16b, v10.16b, v10.16b, #8 // MODULO - other mid alignment + fmov v1.d[1], x9 // CTR block 4k+9 + rev w9, w12 // CTR block 4k+10 + add w12, w12, #1 // CTR block 4k+10 + aese v3.16b, v31.16b // AES block 4k+7 - round N-1 + orr x9, x11, x9, lsl #32 // CTR block 4k+10 + rev64 v5.16b, v5.16b // GHASH block 4k+5 + eor x20, x20, x14 // AES block 4k+5 - round N high + stp x6, x7, [x2], #16 // AES block 4k+4 - store result + eor x19, x19, x13 // AES block 4k+5 - round N low + stp x19, x20, [x2], #16 // AES block 4k+5 - store result + rev64 v4.16b, v4.16b // GHASH block 4k+4 + eor v11.16b, v11.16b, v10.16b // MODULO - fold into low + b.lt Ldec_main_loop + +Ldec_prepretail: // PREPRETAIL + ext v11.16b, v11.16b, v11.16b, #8 // PRE 0 + mov x21, v2.d[0] // AES block 4k+2 - mov low + eor v3.16b, v7.16b, v3.16b // AES block 4k+3 - result + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 0 + mov x22, v2.d[1] // AES block 4k+2 - mov high + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 0 + fmov d2, x10 // CTR block 4k+6 + fmov v2.d[1], x9 // CTR block 4k+6 + rev w9, w12 // CTR block 4k+7 + eor v4.16b, v4.16b, v11.16b // PRE 1 + rev64 v6.16b, v6.16b // GHASH block 4k+2 + orr x9, x11, x9, lsl #32 // CTR block 4k+7 + mov x23, v3.d[0] // AES block 4k+3 - mov low + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 1 + mov x24, v3.d[1] // AES block 4k+3 - mov high + pmull v11.1q, v4.1d, v15.1d // GHASH block 4k - low + mov d8, v4.d[1] // GHASH block 4k - mid + fmov d3, x10 // CTR block 4k+7 + pmull2 v9.1q, v4.2d, v15.2d // GHASH block 4k - high + fmov v3.d[1], x9 // CTR block 4k+7 + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 0 + mov d10, v17.d[1] // GHASH block 4k - mid + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 1 + eor v8.8b, v8.8b, v4.8b // GHASH block 4k - mid + pmull2 v4.1q, v5.2d, v14.2d // GHASH block 4k+1 - high + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 1 + rev64 v7.16b, v7.16b // GHASH block 4k+3 + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 0 + pmull v10.1q, v8.1d, v10.1d // GHASH block 4k - mid + eor v9.16b, v9.16b, v4.16b // GHASH block 4k+1 - high + pmull v8.1q, v5.1d, v14.1d // GHASH block 4k+1 - low + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 1 + mov d4, v5.d[1] // GHASH block 4k+1 - mid + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 2 + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 2 + eor v11.16b, v11.16b, v8.16b // GHASH block 4k+1 - low + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 2 + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 3 + mov d8, v6.d[1] // GHASH block 4k+2 - mid + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 2 + eor v4.8b, v4.8b, v5.8b // GHASH block 4k+1 - mid + pmull v5.1q, v6.1d, v13.1d // GHASH block 4k+2 - low + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 4 + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 3 + eor v8.8b, v8.8b, v6.8b // GHASH block 4k+2 - mid + pmull v4.1q, v4.1d, v17.1d // GHASH block 4k+1 - mid + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 5 + eor v11.16b, v11.16b, v5.16b // GHASH block 4k+2 - low + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 4 + pmull2 v5.1q, v7.2d, v12.2d // GHASH block 4k+3 - high + eor v10.16b, v10.16b, v4.16b // GHASH block 4k+1 - mid + pmull2 v4.1q, v6.2d, v13.2d // GHASH block 4k+2 - high + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 5 + ins v8.d[1], v8.d[0] // GHASH block 4k+2 - mid + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 3 + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 3 + eor v9.16b, v9.16b, v4.16b // GHASH block 4k+2 - high + pmull v4.1q, v7.1d, v12.1d // GHASH block 4k+3 - low + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 4 + mov d6, v7.d[1] // GHASH block 4k+3 - mid + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 4 + pmull2 v8.1q, v8.2d, v16.2d // GHASH block 4k+2 - mid + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 5 + eor v6.8b, v6.8b, v7.8b // GHASH block 4k+3 - mid + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 5 + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 6 + eor v10.16b, v10.16b, v8.16b // GHASH block 4k+2 - mid + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 6 + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 6 + movi v8.8b, #0xc2 + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 6 + eor v11.16b, v11.16b, v4.16b // GHASH block 4k+3 - low + pmull v6.1q, v6.1d, v16.1d // GHASH block 4k+3 - mid + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 7 + cmp x17, #12 // setup flags for AES-128/192/256 check + eor v9.16b, v9.16b, v5.16b // GHASH block 4k+3 - high + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 7 + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 7 + eor v10.16b, v10.16b, v6.16b // GHASH block 4k+3 - mid + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 8 + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 7 + eor v6.16b, v11.16b, v9.16b // MODULO - karatsuba tidy up + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 8 + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 8 + shl d8, d8, #56 // mod_constant + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 8 + b.lt Ldec_finish_prepretail // branch if AES-128 + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 9 + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 9 + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 9 + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 9 + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 10 + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 10 + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 10 + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 10 + b.eq Ldec_finish_prepretail // branch if AES-192 + + aese v2.16b, v29.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 11 + aese v0.16b, v29.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 11 + aese v1.16b, v29.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 11 + aese v2.16b, v30.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 12 + aese v3.16b, v29.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 11 + aese v1.16b, v30.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 12 + aese v0.16b, v30.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 12 + aese v3.16b, v30.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 12 + +Ldec_finish_prepretail: + eor v10.16b, v10.16b, v6.16b // MODULO - karatsuba tidy up + pmull v7.1q, v9.1d, v8.1d // MODULO - top 64b align with mid + ext v9.16b, v9.16b, v9.16b, #8 // MODULO - other top alignment + eor v10.16b, v10.16b, v7.16b // MODULO - fold into mid + eor x22, x22, x14 // AES block 4k+2 - round N high + eor x23, x23, x13 // AES block 4k+3 - round N low + eor v10.16b, v10.16b, v9.16b // MODULO - fold into mid + add w12, w12, #1 // CTR block 4k+7 + eor x21, x21, x13 // AES block 4k+2 - round N low + pmull v8.1q, v10.1d, v8.1d // MODULO - mid 64b align with low + eor x24, x24, x14 // AES block 4k+3 - round N high + stp x21, x22, [x2], #16 // AES block 4k+2 - store result + ext v10.16b, v10.16b, v10.16b, #8 // MODULO - other mid alignment + stp x23, x24, [x2], #16 // AES block 4k+3 - store result + + eor v11.16b, v11.16b, v8.16b // MODULO - fold into low + aese v1.16b, v31.16b // AES block 4k+5 - round N-1 + aese v0.16b, v31.16b // AES block 4k+4 - round N-1 + aese v3.16b, v31.16b // AES block 4k+7 - round N-1 + aese v2.16b, v31.16b // AES block 4k+6 - round N-1 + eor v11.16b, v11.16b, v10.16b // MODULO - fold into low + +Ldec_tail: // TAIL + sub x5, x4, x0 // main_end_input_ptr is number of bytes left to process + ld1 { v5.16b}, [x0], #16 // AES block 4k+4 - load ciphertext + eor v0.16b, v5.16b, v0.16b // AES block 4k+4 - result + mov x6, v0.d[0] // AES block 4k+4 - mov low + mov x7, v0.d[1] // AES block 4k+4 - mov high + ext v8.16b, v11.16b, v11.16b, #8 // prepare final partial tag + cmp x5, #48 + eor x6, x6, x13 // AES block 4k+4 - round N low + eor x7, x7, x14 // AES block 4k+4 - round N high + b.gt Ldec_blocks_more_than_3 + sub w12, w12, #1 + mov v3.16b, v2.16b + movi v10.8b, #0 + movi v11.8b, #0 + cmp x5, #32 + movi v9.8b, #0 + mov v2.16b, v1.16b + b.gt Ldec_blocks_more_than_2 + sub w12, w12, #1 + mov v3.16b, v1.16b + cmp x5, #16 + b.gt Ldec_blocks_more_than_1 + sub w12, w12, #1 + b Ldec_blocks_less_than_1 +Ldec_blocks_more_than_3: // blocks left > 3 + rev64 v4.16b, v5.16b // GHASH final-3 block + ld1 { v5.16b}, [x0], #16 // AES final-2 block - load ciphertext + stp x6, x7, [x2], #16 // AES final-3 block - store result + mov d10, v17.d[1] // GHASH final-3 block - mid + eor v4.16b, v4.16b, v8.16b // feed in partial tag + eor v0.16b, v5.16b, v1.16b // AES final-2 block - result + mov d22, v4.d[1] // GHASH final-3 block - mid + mov x6, v0.d[0] // AES final-2 block - mov low + mov x7, v0.d[1] // AES final-2 block - mov high + eor v22.8b, v22.8b, v4.8b // GHASH final-3 block - mid + movi v8.8b, #0 // suppress further partial tag feed in + pmull2 v9.1q, v4.2d, v15.2d // GHASH final-3 block - high + pmull v10.1q, v22.1d, v10.1d // GHASH final-3 block - mid + eor x6, x6, x13 // AES final-2 block - round N low + pmull v11.1q, v4.1d, v15.1d // GHASH final-3 block - low + eor x7, x7, x14 // AES final-2 block - round N high +Ldec_blocks_more_than_2: // blocks left > 2 + rev64 v4.16b, v5.16b // GHASH final-2 block + ld1 { v5.16b}, [x0], #16 // AES final-1 block - load ciphertext + eor v4.16b, v4.16b, v8.16b // feed in partial tag + stp x6, x7, [x2], #16 // AES final-2 block - store result + eor v0.16b, v5.16b, v2.16b // AES final-1 block - result + mov d22, v4.d[1] // GHASH final-2 block - mid + pmull v21.1q, v4.1d, v14.1d // GHASH final-2 block - low + pmull2 v20.1q, v4.2d, v14.2d // GHASH final-2 block - high + eor v22.8b, v22.8b, v4.8b // GHASH final-2 block - mid + mov x6, v0.d[0] // AES final-1 block - mov low + mov x7, v0.d[1] // AES final-1 block - mov high + eor v11.16b, v11.16b, v21.16b // GHASH final-2 block - low + movi v8.8b, #0 // suppress further partial tag feed in + pmull v22.1q, v22.1d, v17.1d // GHASH final-2 block - mid + eor v9.16b, v9.16b, v20.16b // GHASH final-2 block - high + eor x6, x6, x13 // AES final-1 block - round N low + eor v10.16b, v10.16b, v22.16b // GHASH final-2 block - mid + eor x7, x7, x14 // AES final-1 block - round N high +Ldec_blocks_more_than_1: // blocks left > 1 + stp x6, x7, [x2], #16 // AES final-1 block - store result + rev64 v4.16b, v5.16b // GHASH final-1 block + ld1 { v5.16b}, [x0], #16 // AES final block - load ciphertext + eor v4.16b, v4.16b, v8.16b // feed in partial tag + movi v8.8b, #0 // suppress further partial tag feed in + mov d22, v4.d[1] // GHASH final-1 block - mid + eor v0.16b, v5.16b, v3.16b // AES final block - result + pmull2 v20.1q, v4.2d, v13.2d // GHASH final-1 block - high + eor v22.8b, v22.8b, v4.8b // GHASH final-1 block - mid + pmull v21.1q, v4.1d, v13.1d // GHASH final-1 block - low + mov x6, v0.d[0] // AES final block - mov low + ins v22.d[1], v22.d[0] // GHASH final-1 block - mid + mov x7, v0.d[1] // AES final block - mov high + pmull2 v22.1q, v22.2d, v16.2d // GHASH final-1 block - mid + eor x6, x6, x13 // AES final block - round N low + eor v11.16b, v11.16b, v21.16b // GHASH final-1 block - low + eor v9.16b, v9.16b, v20.16b // GHASH final-1 block - high + eor v10.16b, v10.16b, v22.16b // GHASH final-1 block - mid + eor x7, x7, x14 // AES final block - round N high +Ldec_blocks_less_than_1: // blocks left <= 1 + and x1, x1, #127 // bit_length %= 128 + mvn x14, xzr // rkN_h = 0xffffffffffffffff + sub x1, x1, #128 // bit_length -= 128 + mvn x13, xzr // rkN_l = 0xffffffffffffffff + ldp x4, x5, [x2] // load existing bytes we need to not overwrite + neg x1, x1 // bit_length = 128 - #bits in input (in range [1,128]) + and x1, x1, #127 // bit_length %= 128 + lsr x14, x14, x1 // rkN_h is mask for top 64b of last block + cmp x1, #64 + csel x9, x13, x14, lt + csel x10, x14, xzr, lt + fmov d0, x9 // ctr0b is mask for last block + and x6, x6, x9 + mov v0.d[1], x10 + bic x4, x4, x9 // mask out low existing bytes + rev w9, w12 + bic x5, x5, x10 // mask out high existing bytes + orr x6, x6, x4 + and x7, x7, x10 + orr x7, x7, x5 + and v5.16b, v5.16b, v0.16b // possibly partial last block has zeroes in highest bits + rev64 v4.16b, v5.16b // GHASH final block + eor v4.16b, v4.16b, v8.16b // feed in partial tag + pmull v21.1q, v4.1d, v12.1d // GHASH final block - low + mov d8, v4.d[1] // GHASH final block - mid + eor v8.8b, v8.8b, v4.8b // GHASH final block - mid + pmull2 v20.1q, v4.2d, v12.2d // GHASH final block - high + pmull v8.1q, v8.1d, v16.1d // GHASH final block - mid + eor v9.16b, v9.16b, v20.16b // GHASH final block - high + eor v11.16b, v11.16b, v21.16b // GHASH final block - low + eor v10.16b, v10.16b, v8.16b // GHASH final block - mid + movi v8.8b, #0xc2 + eor v6.16b, v11.16b, v9.16b // MODULO - karatsuba tidy up + shl d8, d8, #56 // mod_constant + eor v10.16b, v10.16b, v6.16b // MODULO - karatsuba tidy up + pmull v7.1q, v9.1d, v8.1d // MODULO - top 64b align with mid + ext v9.16b, v9.16b, v9.16b, #8 // MODULO - other top alignment + eor v10.16b, v10.16b, v7.16b // MODULO - fold into mid + eor v10.16b, v10.16b, v9.16b // MODULO - fold into mid + pmull v8.1q, v10.1d, v8.1d // MODULO - mid 64b align with low + ext v10.16b, v10.16b, v10.16b, #8 // MODULO - other mid alignment + eor v11.16b, v11.16b, v8.16b // MODULO - fold into low + stp x6, x7, [x2] + str w9, [x16, #12] // store the updated counter + eor v11.16b, v11.16b, v10.16b // MODULO - fold into low + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + mov x0, x15 + st1 { v11.16b }, [x3] + ldp x19, x20, [sp, #16] + ldp x21, x22, [sp, #32] + ldp x23, x24, [sp, #48] + ldp d8, d9, [sp, #64] + ldp d10, d11, [sp, #80] + ldp d12, d13, [sp, #96] + ldp d14, d15, [sp, #112] + ldp x29, x30, [sp], #128 + AARCH64_VALIDATE_LINK_REGISTER + ret + +#endif +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif +#endif // defined(__aarch64__) && defined(__APPLE__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-gcm-armv8-linux.linux.aarch64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-gcm-armv8-linux.linux.aarch64.S new file mode 100644 index 00000000..49113f7a --- /dev/null +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-gcm-armv8-linux.linux.aarch64.S @@ -0,0 +1,1574 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__aarch64__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__ELF__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include +#if __ARM_MAX_ARCH__ >= 8 + +.arch armv8-a+crypto +.text +.globl aes_gcm_enc_kernel +.hidden aes_gcm_enc_kernel +.type aes_gcm_enc_kernel,%function +.align 4 +aes_gcm_enc_kernel: + AARCH64_SIGN_LINK_REGISTER + stp x29, x30, [sp, #-128]! + mov x29, sp + stp x19, x20, [sp, #16] + mov x16, x4 + mov x8, x5 + stp x21, x22, [sp, #32] + stp x23, x24, [sp, #48] + stp d8, d9, [sp, #64] + stp d10, d11, [sp, #80] + stp d12, d13, [sp, #96] + stp d14, d15, [sp, #112] + ldr w17, [x8, #240] + add x19, x8, x17, lsl #4 // borrow input_l1 for last key + ldp x13, x14, [x19] // load round N keys + ldr q31, [x19, #-16] // load round N-1 keys + add x4, x0, x1, lsr #3 // end_input_ptr + lsr x5, x1, #3 // byte_len + mov x15, x5 + ldp x10, x11, [x16] // ctr96_b64, ctr96_t32 + ld1 { v0.16b}, [x16] // special case vector load initial counter so we can start first AES block as quickly as possible + sub x5, x5, #1 // byte_len - 1 + ldr q18, [x8, #0] // load rk0 + and x5, x5, #0xffffffffffffffc0 // number of bytes to be processed in main loop (at least 1 byte must be handled by tail) + ldr q25, [x8, #112] // load rk7 + add x5, x5, x0 + lsr x12, x11, #32 + fmov d2, x10 // CTR block 2 + orr w11, w11, w11 + rev w12, w12 // rev_ctr32 + fmov d1, x10 // CTR block 1 + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b // AES block 0 - round 0 + add w12, w12, #1 // increment rev_ctr32 + rev w9, w12 // CTR block 1 + fmov d3, x10 // CTR block 3 + orr x9, x11, x9, lsl #32 // CTR block 1 + add w12, w12, #1 // CTR block 1 + ldr q19, [x8, #16] // load rk1 + fmov v1.d[1], x9 // CTR block 1 + rev w9, w12 // CTR block 2 + add w12, w12, #1 // CTR block 2 + orr x9, x11, x9, lsl #32 // CTR block 2 + ldr q20, [x8, #32] // load rk2 + fmov v2.d[1], x9 // CTR block 2 + rev w9, w12 // CTR block 3 + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b // AES block 0 - round 1 + orr x9, x11, x9, lsl #32 // CTR block 3 + fmov v3.d[1], x9 // CTR block 3 + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b // AES block 1 - round 0 + ldr q21, [x8, #48] // load rk3 + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b // AES block 0 - round 2 + ldr q24, [x8, #96] // load rk6 + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b // AES block 2 - round 0 + ldr q23, [x8, #80] // load rk5 + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b // AES block 1 - round 1 + ldr q14, [x3, #80] // load h3l | h3h + ext v14.16b, v14.16b, v14.16b, #8 + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b // AES block 3 - round 0 + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b // AES block 2 - round 1 + ldr q22, [x8, #64] // load rk4 + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b // AES block 1 - round 2 + ldr q13, [x3, #64] // load h2l | h2h + ext v13.16b, v13.16b, v13.16b, #8 + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b // AES block 3 - round 1 + ldr q30, [x8, #192] // load rk12 + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b // AES block 2 - round 2 + ldr q15, [x3, #112] // load h4l | h4h + ext v15.16b, v15.16b, v15.16b, #8 + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b // AES block 1 - round 3 + ldr q29, [x8, #176] // load rk11 + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b // AES block 3 - round 2 + ldr q26, [x8, #128] // load rk8 + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b // AES block 2 - round 3 + add w12, w12, #1 // CTR block 3 + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b // AES block 0 - round 3 + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b // AES block 3 - round 3 + ld1 { v11.16b}, [x3] + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b // AES block 2 - round 4 + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b // AES block 0 - round 4 + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b // AES block 1 - round 4 + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b // AES block 3 - round 4 + cmp x17, #12 // setup flags for AES-128/192/256 check + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b // AES block 0 - round 5 + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b // AES block 1 - round 5 + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b // AES block 3 - round 5 + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b // AES block 2 - round 5 + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b // AES block 1 - round 6 + trn2 v17.2d, v14.2d, v15.2d // h4l | h3l + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b // AES block 3 - round 6 + ldr q27, [x8, #144] // load rk9 + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b // AES block 0 - round 6 + ldr q12, [x3, #32] // load h1l | h1h + ext v12.16b, v12.16b, v12.16b, #8 + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b // AES block 2 - round 6 + ldr q28, [x8, #160] // load rk10 + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b // AES block 1 - round 7 + trn1 v9.2d, v14.2d, v15.2d // h4h | h3h + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b // AES block 0 - round 7 + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b // AES block 2 - round 7 + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b // AES block 3 - round 7 + trn2 v16.2d, v12.2d, v13.2d // h2l | h1l + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b // AES block 1 - round 8 + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b // AES block 2 - round 8 + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b // AES block 3 - round 8 + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b // AES block 0 - round 8 + b.lt .Lenc_finish_first_blocks // branch if AES-128 + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b // AES block 1 - round 9 + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b // AES block 2 - round 9 + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b // AES block 3 - round 9 + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b // AES block 0 - round 9 + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b // AES block 1 - round 10 + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b // AES block 2 - round 10 + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b // AES block 3 - round 10 + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b // AES block 0 - round 10 + b.eq .Lenc_finish_first_blocks // branch if AES-192 + + aese v1.16b, v29.16b + aesmc v1.16b, v1.16b // AES block 1 - round 11 + aese v2.16b, v29.16b + aesmc v2.16b, v2.16b // AES block 2 - round 11 + aese v0.16b, v29.16b + aesmc v0.16b, v0.16b // AES block 0 - round 11 + aese v3.16b, v29.16b + aesmc v3.16b, v3.16b // AES block 3 - round 11 + aese v1.16b, v30.16b + aesmc v1.16b, v1.16b // AES block 1 - round 12 + aese v2.16b, v30.16b + aesmc v2.16b, v2.16b // AES block 2 - round 12 + aese v0.16b, v30.16b + aesmc v0.16b, v0.16b // AES block 0 - round 12 + aese v3.16b, v30.16b + aesmc v3.16b, v3.16b // AES block 3 - round 12 + +.Lenc_finish_first_blocks: + cmp x0, x5 // check if we have <= 4 blocks + eor v17.16b, v17.16b, v9.16b // h4k | h3k + aese v2.16b, v31.16b // AES block 2 - round N-1 + trn1 v8.2d, v12.2d, v13.2d // h2h | h1h + aese v1.16b, v31.16b // AES block 1 - round N-1 + aese v0.16b, v31.16b // AES block 0 - round N-1 + aese v3.16b, v31.16b // AES block 3 - round N-1 + eor v16.16b, v16.16b, v8.16b // h2k | h1k + b.ge .Lenc_tail // handle tail + + ldp x19, x20, [x0, #16] // AES block 1 - load plaintext + rev w9, w12 // CTR block 4 + ldp x6, x7, [x0, #0] // AES block 0 - load plaintext + ldp x23, x24, [x0, #48] // AES block 3 - load plaintext + ldp x21, x22, [x0, #32] // AES block 2 - load plaintext + add x0, x0, #64 // AES input_ptr update + eor x19, x19, x13 // AES block 1 - round N low + eor x20, x20, x14 // AES block 1 - round N high + fmov d5, x19 // AES block 1 - mov low + eor x6, x6, x13 // AES block 0 - round N low + eor x7, x7, x14 // AES block 0 - round N high + eor x24, x24, x14 // AES block 3 - round N high + fmov d4, x6 // AES block 0 - mov low + cmp x0, x5 // check if we have <= 8 blocks + fmov v4.d[1], x7 // AES block 0 - mov high + eor x23, x23, x13 // AES block 3 - round N low + eor x21, x21, x13 // AES block 2 - round N low + fmov v5.d[1], x20 // AES block 1 - mov high + fmov d6, x21 // AES block 2 - mov low + add w12, w12, #1 // CTR block 4 + orr x9, x11, x9, lsl #32 // CTR block 4 + fmov d7, x23 // AES block 3 - mov low + eor x22, x22, x14 // AES block 2 - round N high + fmov v6.d[1], x22 // AES block 2 - mov high + eor v4.16b, v4.16b, v0.16b // AES block 0 - result + fmov d0, x10 // CTR block 4 + fmov v0.d[1], x9 // CTR block 4 + rev w9, w12 // CTR block 5 + add w12, w12, #1 // CTR block 5 + eor v5.16b, v5.16b, v1.16b // AES block 1 - result + fmov d1, x10 // CTR block 5 + orr x9, x11, x9, lsl #32 // CTR block 5 + fmov v1.d[1], x9 // CTR block 5 + rev w9, w12 // CTR block 6 + st1 { v4.16b}, [x2], #16 // AES block 0 - store result + fmov v7.d[1], x24 // AES block 3 - mov high + orr x9, x11, x9, lsl #32 // CTR block 6 + eor v6.16b, v6.16b, v2.16b // AES block 2 - result + st1 { v5.16b}, [x2], #16 // AES block 1 - store result + add w12, w12, #1 // CTR block 6 + fmov d2, x10 // CTR block 6 + fmov v2.d[1], x9 // CTR block 6 + st1 { v6.16b}, [x2], #16 // AES block 2 - store result + rev w9, w12 // CTR block 7 + orr x9, x11, x9, lsl #32 // CTR block 7 + eor v7.16b, v7.16b, v3.16b // AES block 3 - result + st1 { v7.16b}, [x2], #16 // AES block 3 - store result + b.ge .Lenc_prepretail // do prepretail + +.Lenc_main_loop: // main loop start + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 0 + rev64 v4.16b, v4.16b // GHASH block 4k (only t0 is free) + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 0 + fmov d3, x10 // CTR block 4k+3 + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 0 + ext v11.16b, v11.16b, v11.16b, #8 // PRE 0 + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 1 + fmov v3.d[1], x9 // CTR block 4k+3 + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 1 + ldp x23, x24, [x0, #48] // AES block 4k+7 - load plaintext + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 1 + ldp x21, x22, [x0, #32] // AES block 4k+6 - load plaintext + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 2 + eor v4.16b, v4.16b, v11.16b // PRE 1 + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 2 + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 0 + eor x23, x23, x13 // AES block 4k+7 - round N low + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 3 + mov d10, v17.d[1] // GHASH block 4k - mid + pmull2 v9.1q, v4.2d, v15.2d // GHASH block 4k - high + eor x22, x22, x14 // AES block 4k+6 - round N high + mov d8, v4.d[1] // GHASH block 4k - mid + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 1 + rev64 v5.16b, v5.16b // GHASH block 4k+1 (t0 and t1 free) + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 4 + pmull v11.1q, v4.1d, v15.1d // GHASH block 4k - low + eor v8.8b, v8.8b, v4.8b // GHASH block 4k - mid + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 2 + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 5 + rev64 v7.16b, v7.16b // GHASH block 4k+3 (t0, t1, t2 and t3 free) + pmull2 v4.1q, v5.2d, v14.2d // GHASH block 4k+1 - high + pmull v10.1q, v8.1d, v10.1d // GHASH block 4k - mid + rev64 v6.16b, v6.16b // GHASH block 4k+2 (t0, t1, and t2 free) + pmull v8.1q, v5.1d, v14.1d // GHASH block 4k+1 - low + eor v9.16b, v9.16b, v4.16b // GHASH block 4k+1 - high + mov d4, v5.d[1] // GHASH block 4k+1 - mid + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 3 + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 2 + eor v11.16b, v11.16b, v8.16b // GHASH block 4k+1 - low + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 3 + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 4 + mov d8, v6.d[1] // GHASH block 4k+2 - mid + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 3 + eor v4.8b, v4.8b, v5.8b // GHASH block 4k+1 - mid + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 4 + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 6 + eor v8.8b, v8.8b, v6.8b // GHASH block 4k+2 - mid + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 4 + pmull v4.1q, v4.1d, v17.1d // GHASH block 4k+1 - mid + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 7 + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 5 + ins v8.d[1], v8.d[0] // GHASH block 4k+2 - mid + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 5 + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 8 + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 5 + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 6 + eor v10.16b, v10.16b, v4.16b // GHASH block 4k+1 - mid + pmull2 v4.1q, v6.2d, v13.2d // GHASH block 4k+2 - high + pmull v5.1q, v6.1d, v13.1d // GHASH block 4k+2 - low + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 7 + pmull v6.1q, v7.1d, v12.1d // GHASH block 4k+3 - low + eor v9.16b, v9.16b, v4.16b // GHASH block 4k+2 - high + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 6 + ldp x19, x20, [x0, #16] // AES block 4k+5 - load plaintext + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 8 + mov d4, v7.d[1] // GHASH block 4k+3 - mid + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 6 + eor v11.16b, v11.16b, v5.16b // GHASH block 4k+2 - low + pmull2 v8.1q, v8.2d, v16.2d // GHASH block 4k+2 - mid + pmull2 v5.1q, v7.2d, v12.2d // GHASH block 4k+3 - high + eor v4.8b, v4.8b, v7.8b // GHASH block 4k+3 - mid + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 7 + eor x19, x19, x13 // AES block 4k+5 - round N low + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 8 + eor v10.16b, v10.16b, v8.16b // GHASH block 4k+2 - mid + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 7 + eor x21, x21, x13 // AES block 4k+6 - round N low + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 8 + movi v8.8b, #0xc2 + pmull v4.1q, v4.1d, v16.1d // GHASH block 4k+3 - mid + eor v9.16b, v9.16b, v5.16b // GHASH block 4k+3 - high + cmp x17, #12 // setup flags for AES-128/192/256 check + fmov d5, x19 // AES block 4k+5 - mov low + ldp x6, x7, [x0, #0] // AES block 4k+4 - load plaintext + b.lt .Lenc_main_loop_continue // branch if AES-128 + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 9 + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 9 + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 9 + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 9 + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 10 + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 10 + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 10 + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 10 + b.eq .Lenc_main_loop_continue // branch if AES-192 + + aese v0.16b, v29.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 11 + aese v1.16b, v29.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 11 + aese v2.16b, v29.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 11 + aese v3.16b, v29.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 11 + aese v1.16b, v30.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 12 + aese v0.16b, v30.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 12 + aese v2.16b, v30.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 12 + aese v3.16b, v30.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 12 + +.Lenc_main_loop_continue: + shl d8, d8, #56 // mod_constant + eor v11.16b, v11.16b, v6.16b // GHASH block 4k+3 - low + eor v10.16b, v10.16b, v4.16b // GHASH block 4k+3 - mid + add w12, w12, #1 // CTR block 4k+3 + eor v4.16b, v11.16b, v9.16b // MODULO - karatsuba tidy up + add x0, x0, #64 // AES input_ptr update + pmull v7.1q, v9.1d, v8.1d // MODULO - top 64b align with mid + rev w9, w12 // CTR block 4k+8 + ext v9.16b, v9.16b, v9.16b, #8 // MODULO - other top alignment + eor x6, x6, x13 // AES block 4k+4 - round N low + eor v10.16b, v10.16b, v4.16b // MODULO - karatsuba tidy up + eor x7, x7, x14 // AES block 4k+4 - round N high + fmov d4, x6 // AES block 4k+4 - mov low + orr x9, x11, x9, lsl #32 // CTR block 4k+8 + eor v7.16b, v9.16b, v7.16b // MODULO - fold into mid + eor x20, x20, x14 // AES block 4k+5 - round N high + eor x24, x24, x14 // AES block 4k+7 - round N high + add w12, w12, #1 // CTR block 4k+8 + aese v0.16b, v31.16b // AES block 4k+4 - round N-1 + fmov v4.d[1], x7 // AES block 4k+4 - mov high + eor v10.16b, v10.16b, v7.16b // MODULO - fold into mid + fmov d7, x23 // AES block 4k+7 - mov low + aese v1.16b, v31.16b // AES block 4k+5 - round N-1 + fmov v5.d[1], x20 // AES block 4k+5 - mov high + fmov d6, x21 // AES block 4k+6 - mov low + cmp x0, x5 // .LOOP CONTROL + fmov v6.d[1], x22 // AES block 4k+6 - mov high + pmull v9.1q, v10.1d, v8.1d // MODULO - mid 64b align with low + eor v4.16b, v4.16b, v0.16b // AES block 4k+4 - result + fmov d0, x10 // CTR block 4k+8 + fmov v0.d[1], x9 // CTR block 4k+8 + rev w9, w12 // CTR block 4k+9 + add w12, w12, #1 // CTR block 4k+9 + eor v5.16b, v5.16b, v1.16b // AES block 4k+5 - result + fmov d1, x10 // CTR block 4k+9 + orr x9, x11, x9, lsl #32 // CTR block 4k+9 + fmov v1.d[1], x9 // CTR block 4k+9 + aese v2.16b, v31.16b // AES block 4k+6 - round N-1 + rev w9, w12 // CTR block 4k+10 + st1 { v4.16b}, [x2], #16 // AES block 4k+4 - store result + orr x9, x11, x9, lsl #32 // CTR block 4k+10 + eor v11.16b, v11.16b, v9.16b // MODULO - fold into low + fmov v7.d[1], x24 // AES block 4k+7 - mov high + ext v10.16b, v10.16b, v10.16b, #8 // MODULO - other mid alignment + st1 { v5.16b}, [x2], #16 // AES block 4k+5 - store result + add w12, w12, #1 // CTR block 4k+10 + aese v3.16b, v31.16b // AES block 4k+7 - round N-1 + eor v6.16b, v6.16b, v2.16b // AES block 4k+6 - result + fmov d2, x10 // CTR block 4k+10 + st1 { v6.16b}, [x2], #16 // AES block 4k+6 - store result + fmov v2.d[1], x9 // CTR block 4k+10 + rev w9, w12 // CTR block 4k+11 + eor v11.16b, v11.16b, v10.16b // MODULO - fold into low + orr x9, x11, x9, lsl #32 // CTR block 4k+11 + eor v7.16b, v7.16b, v3.16b // AES block 4k+7 - result + st1 { v7.16b}, [x2], #16 // AES block 4k+7 - store result + b.lt .Lenc_main_loop + +.Lenc_prepretail: // PREPRETAIL + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 0 + rev64 v6.16b, v6.16b // GHASH block 4k+2 (t0, t1, and t2 free) + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 0 + fmov d3, x10 // CTR block 4k+3 + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 0 + rev64 v4.16b, v4.16b // GHASH block 4k (only t0 is free) + fmov v3.d[1], x9 // CTR block 4k+3 + ext v11.16b, v11.16b, v11.16b, #8 // PRE 0 + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 1 + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 1 + eor v4.16b, v4.16b, v11.16b // PRE 1 + rev64 v5.16b, v5.16b // GHASH block 4k+1 (t0 and t1 free) + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 2 + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 0 + mov d10, v17.d[1] // GHASH block 4k - mid + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 1 + pmull v11.1q, v4.1d, v15.1d // GHASH block 4k - low + mov d8, v4.d[1] // GHASH block 4k - mid + pmull2 v9.1q, v4.2d, v15.2d // GHASH block 4k - high + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 3 + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 2 + eor v8.8b, v8.8b, v4.8b // GHASH block 4k - mid + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 2 + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 1 + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 3 + pmull v10.1q, v8.1d, v10.1d // GHASH block 4k - mid + pmull2 v4.1q, v5.2d, v14.2d // GHASH block 4k+1 - high + pmull v8.1q, v5.1d, v14.1d // GHASH block 4k+1 - low + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 2 + eor v9.16b, v9.16b, v4.16b // GHASH block 4k+1 - high + mov d4, v5.d[1] // GHASH block 4k+1 - mid + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 3 + eor v11.16b, v11.16b, v8.16b // GHASH block 4k+1 - low + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 3 + eor v4.8b, v4.8b, v5.8b // GHASH block 4k+1 - mid + mov d8, v6.d[1] // GHASH block 4k+2 - mid + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 4 + rev64 v7.16b, v7.16b // GHASH block 4k+3 (t0, t1, t2 and t3 free) + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 4 + pmull v4.1q, v4.1d, v17.1d // GHASH block 4k+1 - mid + eor v8.8b, v8.8b, v6.8b // GHASH block 4k+2 - mid + add w12, w12, #1 // CTR block 4k+3 + pmull v5.1q, v6.1d, v13.1d // GHASH block 4k+2 - low + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 5 + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 4 + eor v10.16b, v10.16b, v4.16b // GHASH block 4k+1 - mid + pmull2 v4.1q, v6.2d, v13.2d // GHASH block 4k+2 - high + eor v11.16b, v11.16b, v5.16b // GHASH block 4k+2 - low + ins v8.d[1], v8.d[0] // GHASH block 4k+2 - mid + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 5 + eor v9.16b, v9.16b, v4.16b // GHASH block 4k+2 - high + mov d4, v7.d[1] // GHASH block 4k+3 - mid + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 4 + pmull2 v8.1q, v8.2d, v16.2d // GHASH block 4k+2 - mid + eor v4.8b, v4.8b, v7.8b // GHASH block 4k+3 - mid + pmull2 v5.1q, v7.2d, v12.2d // GHASH block 4k+3 - high + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 5 + pmull v4.1q, v4.1d, v16.1d // GHASH block 4k+3 - mid + eor v10.16b, v10.16b, v8.16b // GHASH block 4k+2 - mid + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 5 + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 6 + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 6 + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 6 + movi v8.8b, #0xc2 + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 6 + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 7 + eor v9.16b, v9.16b, v5.16b // GHASH block 4k+3 - high + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 7 + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 7 + shl d8, d8, #56 // mod_constant + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 8 + eor v10.16b, v10.16b, v4.16b // GHASH block 4k+3 - mid + pmull v6.1q, v7.1d, v12.1d // GHASH block 4k+3 - low + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 8 + cmp x17, #12 // setup flags for AES-128/192/256 check + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 8 + eor v11.16b, v11.16b, v6.16b // GHASH block 4k+3 - low + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 7 + eor v10.16b, v10.16b, v9.16b // karatsuba tidy up + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 8 + pmull v4.1q, v9.1d, v8.1d + ext v9.16b, v9.16b, v9.16b, #8 + eor v10.16b, v10.16b, v11.16b + b.lt .Lenc_finish_prepretail // branch if AES-128 + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 9 + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 9 + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 9 + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 9 + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 10 + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 10 + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 10 + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 10 + b.eq .Lenc_finish_prepretail // branch if AES-192 + + aese v1.16b, v29.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 11 + aese v0.16b, v29.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 11 + aese v3.16b, v29.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 11 + aese v2.16b, v29.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 11 + aese v1.16b, v30.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 12 + aese v0.16b, v30.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 12 + aese v3.16b, v30.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 12 + aese v2.16b, v30.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 12 + +.Lenc_finish_prepretail: + eor v10.16b, v10.16b, v4.16b + eor v10.16b, v10.16b, v9.16b + pmull v4.1q, v10.1d, v8.1d + ext v10.16b, v10.16b, v10.16b, #8 + aese v1.16b, v31.16b // AES block 4k+5 - round N-1 + eor v11.16b, v11.16b, v4.16b + aese v3.16b, v31.16b // AES block 4k+7 - round N-1 + aese v0.16b, v31.16b // AES block 4k+4 - round N-1 + aese v2.16b, v31.16b // AES block 4k+6 - round N-1 + eor v11.16b, v11.16b, v10.16b + +.Lenc_tail: // TAIL + ext v8.16b, v11.16b, v11.16b, #8 // prepare final partial tag + sub x5, x4, x0 // main_end_input_ptr is number of bytes left to process + ldp x6, x7, [x0], #16 // AES block 4k+4 - load plaintext + eor x6, x6, x13 // AES block 4k+4 - round N low + eor x7, x7, x14 // AES block 4k+4 - round N high + cmp x5, #48 + fmov d4, x6 // AES block 4k+4 - mov low + fmov v4.d[1], x7 // AES block 4k+4 - mov high + eor v5.16b, v4.16b, v0.16b // AES block 4k+4 - result + b.gt .Lenc_blocks_more_than_3 + cmp x5, #32 + mov v3.16b, v2.16b + movi v11.8b, #0 + movi v9.8b, #0 + sub w12, w12, #1 + mov v2.16b, v1.16b + movi v10.8b, #0 + b.gt .Lenc_blocks_more_than_2 + mov v3.16b, v1.16b + sub w12, w12, #1 + cmp x5, #16 + b.gt .Lenc_blocks_more_than_1 + sub w12, w12, #1 + b .Lenc_blocks_less_than_1 +.Lenc_blocks_more_than_3: // blocks left > 3 + st1 { v5.16b}, [x2], #16 // AES final-3 block - store result + ldp x6, x7, [x0], #16 // AES final-2 block - load input low & high + rev64 v4.16b, v5.16b // GHASH final-3 block + eor x6, x6, x13 // AES final-2 block - round N low + eor v4.16b, v4.16b, v8.16b // feed in partial tag + eor x7, x7, x14 // AES final-2 block - round N high + mov d22, v4.d[1] // GHASH final-3 block - mid + fmov d5, x6 // AES final-2 block - mov low + fmov v5.d[1], x7 // AES final-2 block - mov high + eor v22.8b, v22.8b, v4.8b // GHASH final-3 block - mid + movi v8.8b, #0 // suppress further partial tag feed in + mov d10, v17.d[1] // GHASH final-3 block - mid + pmull v11.1q, v4.1d, v15.1d // GHASH final-3 block - low + pmull2 v9.1q, v4.2d, v15.2d // GHASH final-3 block - high + pmull v10.1q, v22.1d, v10.1d // GHASH final-3 block - mid + eor v5.16b, v5.16b, v1.16b // AES final-2 block - result +.Lenc_blocks_more_than_2: // blocks left > 2 + st1 { v5.16b}, [x2], #16 // AES final-2 block - store result + ldp x6, x7, [x0], #16 // AES final-1 block - load input low & high + rev64 v4.16b, v5.16b // GHASH final-2 block + eor x6, x6, x13 // AES final-1 block - round N low + eor v4.16b, v4.16b, v8.16b // feed in partial tag + fmov d5, x6 // AES final-1 block - mov low + eor x7, x7, x14 // AES final-1 block - round N high + fmov v5.d[1], x7 // AES final-1 block - mov high + movi v8.8b, #0 // suppress further partial tag feed in + pmull2 v20.1q, v4.2d, v14.2d // GHASH final-2 block - high + mov d22, v4.d[1] // GHASH final-2 block - mid + pmull v21.1q, v4.1d, v14.1d // GHASH final-2 block - low + eor v22.8b, v22.8b, v4.8b // GHASH final-2 block - mid + eor v5.16b, v5.16b, v2.16b // AES final-1 block - result + eor v9.16b, v9.16b, v20.16b // GHASH final-2 block - high + pmull v22.1q, v22.1d, v17.1d // GHASH final-2 block - mid + eor v11.16b, v11.16b, v21.16b // GHASH final-2 block - low + eor v10.16b, v10.16b, v22.16b // GHASH final-2 block - mid +.Lenc_blocks_more_than_1: // blocks left > 1 + st1 { v5.16b}, [x2], #16 // AES final-1 block - store result + rev64 v4.16b, v5.16b // GHASH final-1 block + ldp x6, x7, [x0], #16 // AES final block - load input low & high + eor v4.16b, v4.16b, v8.16b // feed in partial tag + movi v8.8b, #0 // suppress further partial tag feed in + eor x6, x6, x13 // AES final block - round N low + mov d22, v4.d[1] // GHASH final-1 block - mid + pmull2 v20.1q, v4.2d, v13.2d // GHASH final-1 block - high + eor x7, x7, x14 // AES final block - round N high + eor v22.8b, v22.8b, v4.8b // GHASH final-1 block - mid + eor v9.16b, v9.16b, v20.16b // GHASH final-1 block - high + ins v22.d[1], v22.d[0] // GHASH final-1 block - mid + fmov d5, x6 // AES final block - mov low + fmov v5.d[1], x7 // AES final block - mov high + pmull2 v22.1q, v22.2d, v16.2d // GHASH final-1 block - mid + pmull v21.1q, v4.1d, v13.1d // GHASH final-1 block - low + eor v5.16b, v5.16b, v3.16b // AES final block - result + eor v10.16b, v10.16b, v22.16b // GHASH final-1 block - mid + eor v11.16b, v11.16b, v21.16b // GHASH final-1 block - low +.Lenc_blocks_less_than_1: // blocks left <= 1 + and x1, x1, #127 // bit_length %= 128 + mvn x13, xzr // rkN_l = 0xffffffffffffffff + sub x1, x1, #128 // bit_length -= 128 + neg x1, x1 // bit_length = 128 - #bits in input (in range [1,128]) + ld1 { v18.16b}, [x2] // load existing bytes where the possibly partial last block is to be stored + mvn x14, xzr // rkN_h = 0xffffffffffffffff + and x1, x1, #127 // bit_length %= 128 + lsr x14, x14, x1 // rkN_h is mask for top 64b of last block + cmp x1, #64 + csel x6, x13, x14, lt + csel x7, x14, xzr, lt + fmov d0, x6 // ctr0b is mask for last block + fmov v0.d[1], x7 + and v5.16b, v5.16b, v0.16b // possibly partial last block has zeroes in highest bits + rev64 v4.16b, v5.16b // GHASH final block + eor v4.16b, v4.16b, v8.16b // feed in partial tag + bif v5.16b, v18.16b, v0.16b // insert existing bytes in top end of result before storing + pmull2 v20.1q, v4.2d, v12.2d // GHASH final block - high + mov d8, v4.d[1] // GHASH final block - mid + rev w9, w12 + pmull v21.1q, v4.1d, v12.1d // GHASH final block - low + eor v9.16b, v9.16b, v20.16b // GHASH final block - high + eor v8.8b, v8.8b, v4.8b // GHASH final block - mid + pmull v8.1q, v8.1d, v16.1d // GHASH final block - mid + eor v11.16b, v11.16b, v21.16b // GHASH final block - low + eor v10.16b, v10.16b, v8.16b // GHASH final block - mid + movi v8.8b, #0xc2 + eor v4.16b, v11.16b, v9.16b // MODULO - karatsuba tidy up + shl d8, d8, #56 // mod_constant + eor v10.16b, v10.16b, v4.16b // MODULO - karatsuba tidy up + pmull v7.1q, v9.1d, v8.1d // MODULO - top 64b align with mid + ext v9.16b, v9.16b, v9.16b, #8 // MODULO - other top alignment + eor v10.16b, v10.16b, v7.16b // MODULO - fold into mid + eor v10.16b, v10.16b, v9.16b // MODULO - fold into mid + pmull v9.1q, v10.1d, v8.1d // MODULO - mid 64b align with low + ext v10.16b, v10.16b, v10.16b, #8 // MODULO - other mid alignment + str w9, [x16, #12] // store the updated counter + st1 { v5.16b}, [x2] // store all 16B + eor v11.16b, v11.16b, v9.16b // MODULO - fold into low + eor v11.16b, v11.16b, v10.16b // MODULO - fold into low + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + mov x0, x15 + st1 { v11.16b }, [x3] + ldp x19, x20, [sp, #16] + ldp x21, x22, [sp, #32] + ldp x23, x24, [sp, #48] + ldp d8, d9, [sp, #64] + ldp d10, d11, [sp, #80] + ldp d12, d13, [sp, #96] + ldp d14, d15, [sp, #112] + ldp x29, x30, [sp], #128 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size aes_gcm_enc_kernel,.-aes_gcm_enc_kernel +.globl aes_gcm_dec_kernel +.hidden aes_gcm_dec_kernel +.type aes_gcm_dec_kernel,%function +.align 4 +aes_gcm_dec_kernel: + AARCH64_SIGN_LINK_REGISTER + stp x29, x30, [sp, #-128]! + mov x29, sp + stp x19, x20, [sp, #16] + mov x16, x4 + mov x8, x5 + stp x21, x22, [sp, #32] + stp x23, x24, [sp, #48] + stp d8, d9, [sp, #64] + stp d10, d11, [sp, #80] + stp d12, d13, [sp, #96] + stp d14, d15, [sp, #112] + ldr w17, [x8, #240] + add x19, x8, x17, lsl #4 // borrow input_l1 for last key + ldp x13, x14, [x19] // load round N keys + ldr q31, [x19, #-16] // load round N-1 keys + lsr x5, x1, #3 // byte_len + mov x15, x5 + ldp x10, x11, [x16] // ctr96_b64, ctr96_t32 + ldr q26, [x8, #128] // load rk8 + sub x5, x5, #1 // byte_len - 1 + ldr q25, [x8, #112] // load rk7 + and x5, x5, #0xffffffffffffffc0 // number of bytes to be processed in main loop (at least 1 byte must be handled by tail) + add x4, x0, x1, lsr #3 // end_input_ptr + ldr q24, [x8, #96] // load rk6 + lsr x12, x11, #32 + ldr q23, [x8, #80] // load rk5 + orr w11, w11, w11 + ldr q21, [x8, #48] // load rk3 + add x5, x5, x0 + rev w12, w12 // rev_ctr32 + add w12, w12, #1 // increment rev_ctr32 + fmov d3, x10 // CTR block 3 + rev w9, w12 // CTR block 1 + add w12, w12, #1 // CTR block 1 + fmov d1, x10 // CTR block 1 + orr x9, x11, x9, lsl #32 // CTR block 1 + ld1 { v0.16b}, [x16] // special case vector load initial counter so we can start first AES block as quickly as possible + fmov v1.d[1], x9 // CTR block 1 + rev w9, w12 // CTR block 2 + add w12, w12, #1 // CTR block 2 + fmov d2, x10 // CTR block 2 + orr x9, x11, x9, lsl #32 // CTR block 2 + fmov v2.d[1], x9 // CTR block 2 + rev w9, w12 // CTR block 3 + orr x9, x11, x9, lsl #32 // CTR block 3 + ldr q18, [x8, #0] // load rk0 + fmov v3.d[1], x9 // CTR block 3 + add w12, w12, #1 // CTR block 3 + ldr q22, [x8, #64] // load rk4 + ldr q19, [x8, #16] // load rk1 + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b // AES block 0 - round 0 + ldr q14, [x3, #80] // load h3l | h3h + ext v14.16b, v14.16b, v14.16b, #8 + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b // AES block 3 - round 0 + ldr q15, [x3, #112] // load h4l | h4h + ext v15.16b, v15.16b, v15.16b, #8 + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b // AES block 1 - round 0 + ldr q13, [x3, #64] // load h2l | h2h + ext v13.16b, v13.16b, v13.16b, #8 + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b // AES block 2 - round 0 + ldr q20, [x8, #32] // load rk2 + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b // AES block 0 - round 1 + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b // AES block 1 - round 1 + ld1 { v11.16b}, [x3] + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b // AES block 2 - round 1 + ldr q27, [x8, #144] // load rk9 + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b // AES block 3 - round 1 + ldr q30, [x8, #192] // load rk12 + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b // AES block 0 - round 2 + ldr q12, [x3, #32] // load h1l | h1h + ext v12.16b, v12.16b, v12.16b, #8 + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b // AES block 2 - round 2 + ldr q28, [x8, #160] // load rk10 + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b // AES block 3 - round 2 + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b // AES block 0 - round 3 + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b // AES block 1 - round 2 + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b // AES block 3 - round 3 + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b // AES block 0 - round 4 + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b // AES block 2 - round 3 + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b // AES block 1 - round 3 + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b // AES block 3 - round 4 + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b // AES block 2 - round 4 + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b // AES block 1 - round 4 + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b // AES block 3 - round 5 + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b // AES block 0 - round 5 + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b // AES block 1 - round 5 + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b // AES block 2 - round 5 + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b // AES block 0 - round 6 + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b // AES block 3 - round 6 + cmp x17, #12 // setup flags for AES-128/192/256 check + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b // AES block 1 - round 6 + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b // AES block 2 - round 6 + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b // AES block 0 - round 7 + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b // AES block 1 - round 7 + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b // AES block 3 - round 7 + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b // AES block 0 - round 8 + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b // AES block 2 - round 7 + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b // AES block 3 - round 8 + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b // AES block 1 - round 8 + ldr q29, [x8, #176] // load rk11 + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b // AES block 2 - round 8 + b.lt .Ldec_finish_first_blocks // branch if AES-128 + + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b // AES block 0 - round 9 + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b // AES block 1 - round 9 + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b // AES block 3 - round 9 + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b // AES block 2 - round 9 + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b // AES block 0 - round 10 + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b // AES block 1 - round 10 + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b // AES block 3 - round 10 + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b // AES block 2 - round 10 + b.eq .Ldec_finish_first_blocks // branch if AES-192 + + aese v0.16b, v29.16b + aesmc v0.16b, v0.16b // AES block 0 - round 11 + aese v3.16b, v29.16b + aesmc v3.16b, v3.16b // AES block 3 - round 11 + aese v1.16b, v29.16b + aesmc v1.16b, v1.16b // AES block 1 - round 11 + aese v2.16b, v29.16b + aesmc v2.16b, v2.16b // AES block 2 - round 11 + aese v1.16b, v30.16b + aesmc v1.16b, v1.16b // AES block 1 - round 12 + aese v0.16b, v30.16b + aesmc v0.16b, v0.16b // AES block 0 - round 12 + aese v2.16b, v30.16b + aesmc v2.16b, v2.16b // AES block 2 - round 12 + aese v3.16b, v30.16b + aesmc v3.16b, v3.16b // AES block 3 - round 12 + +.Ldec_finish_first_blocks: + cmp x0, x5 // check if we have <= 4 blocks + trn1 v9.2d, v14.2d, v15.2d // h4h | h3h + trn2 v17.2d, v14.2d, v15.2d // h4l | h3l + trn1 v8.2d, v12.2d, v13.2d // h2h | h1h + trn2 v16.2d, v12.2d, v13.2d // h2l | h1l + eor v17.16b, v17.16b, v9.16b // h4k | h3k + aese v1.16b, v31.16b // AES block 1 - round N-1 + aese v2.16b, v31.16b // AES block 2 - round N-1 + eor v16.16b, v16.16b, v8.16b // h2k | h1k + aese v3.16b, v31.16b // AES block 3 - round N-1 + aese v0.16b, v31.16b // AES block 0 - round N-1 + b.ge .Ldec_tail // handle tail + + ldr q4, [x0, #0] // AES block 0 - load ciphertext + ldr q5, [x0, #16] // AES block 1 - load ciphertext + rev w9, w12 // CTR block 4 + eor v0.16b, v4.16b, v0.16b // AES block 0 - result + eor v1.16b, v5.16b, v1.16b // AES block 1 - result + rev64 v5.16b, v5.16b // GHASH block 1 + ldr q7, [x0, #48] // AES block 3 - load ciphertext + mov x7, v0.d[1] // AES block 0 - mov high + mov x6, v0.d[0] // AES block 0 - mov low + rev64 v4.16b, v4.16b // GHASH block 0 + add w12, w12, #1 // CTR block 4 + fmov d0, x10 // CTR block 4 + orr x9, x11, x9, lsl #32 // CTR block 4 + fmov v0.d[1], x9 // CTR block 4 + rev w9, w12 // CTR block 5 + add w12, w12, #1 // CTR block 5 + mov x19, v1.d[0] // AES block 1 - mov low + orr x9, x11, x9, lsl #32 // CTR block 5 + mov x20, v1.d[1] // AES block 1 - mov high + eor x7, x7, x14 // AES block 0 - round N high + eor x6, x6, x13 // AES block 0 - round N low + stp x6, x7, [x2], #16 // AES block 0 - store result + fmov d1, x10 // CTR block 5 + ldr q6, [x0, #32] // AES block 2 - load ciphertext + add x0, x0, #64 // AES input_ptr update + fmov v1.d[1], x9 // CTR block 5 + rev w9, w12 // CTR block 6 + add w12, w12, #1 // CTR block 6 + eor x19, x19, x13 // AES block 1 - round N low + orr x9, x11, x9, lsl #32 // CTR block 6 + eor x20, x20, x14 // AES block 1 - round N high + stp x19, x20, [x2], #16 // AES block 1 - store result + eor v2.16b, v6.16b, v2.16b // AES block 2 - result + cmp x0, x5 // check if we have <= 8 blocks + b.ge .Ldec_prepretail // do prepretail + +.Ldec_main_loop: // main loop start + mov x21, v2.d[0] // AES block 4k+2 - mov low + ext v11.16b, v11.16b, v11.16b, #8 // PRE 0 + eor v3.16b, v7.16b, v3.16b // AES block 4k+3 - result + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 0 + mov x22, v2.d[1] // AES block 4k+2 - mov high + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 0 + fmov d2, x10 // CTR block 4k+6 + fmov v2.d[1], x9 // CTR block 4k+6 + eor v4.16b, v4.16b, v11.16b // PRE 1 + rev w9, w12 // CTR block 4k+7 + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 1 + mov x24, v3.d[1] // AES block 4k+3 - mov high + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 1 + mov x23, v3.d[0] // AES block 4k+3 - mov low + pmull2 v9.1q, v4.2d, v15.2d // GHASH block 4k - high + mov d8, v4.d[1] // GHASH block 4k - mid + fmov d3, x10 // CTR block 4k+7 + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 2 + orr x9, x11, x9, lsl #32 // CTR block 4k+7 + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 0 + fmov v3.d[1], x9 // CTR block 4k+7 + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 2 + eor v8.8b, v8.8b, v4.8b // GHASH block 4k - mid + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 3 + eor x22, x22, x14 // AES block 4k+2 - round N high + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 1 + mov d10, v17.d[1] // GHASH block 4k - mid + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 3 + rev64 v6.16b, v6.16b // GHASH block 4k+2 + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 0 + eor x21, x21, x13 // AES block 4k+2 - round N low + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 2 + stp x21, x22, [x2], #16 // AES block 4k+2 - store result + pmull v11.1q, v4.1d, v15.1d // GHASH block 4k - low + pmull2 v4.1q, v5.2d, v14.2d // GHASH block 4k+1 - high + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 3 + rev64 v7.16b, v7.16b // GHASH block 4k+3 + pmull v10.1q, v8.1d, v10.1d // GHASH block 4k - mid + eor x23, x23, x13 // AES block 4k+3 - round N low + pmull v8.1q, v5.1d, v14.1d // GHASH block 4k+1 - low + eor x24, x24, x14 // AES block 4k+3 - round N high + eor v9.16b, v9.16b, v4.16b // GHASH block 4k+1 - high + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 4 + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 1 + mov d4, v5.d[1] // GHASH block 4k+1 - mid + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 4 + eor v11.16b, v11.16b, v8.16b // GHASH block 4k+1 - low + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 5 + add w12, w12, #1 // CTR block 4k+7 + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 2 + mov d8, v6.d[1] // GHASH block 4k+2 - mid + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 4 + eor v4.8b, v4.8b, v5.8b // GHASH block 4k+1 - mid + pmull v5.1q, v6.1d, v13.1d // GHASH block 4k+2 - low + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 3 + eor v8.8b, v8.8b, v6.8b // GHASH block 4k+2 - mid + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 5 + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 5 + eor v11.16b, v11.16b, v5.16b // GHASH block 4k+2 - low + pmull v4.1q, v4.1d, v17.1d // GHASH block 4k+1 - mid + rev w9, w12 // CTR block 4k+8 + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 6 + ins v8.d[1], v8.d[0] // GHASH block 4k+2 - mid + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 6 + add w12, w12, #1 // CTR block 4k+8 + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 4 + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 7 + eor v10.16b, v10.16b, v4.16b // GHASH block 4k+1 - mid + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 7 + pmull2 v4.1q, v6.2d, v13.2d // GHASH block 4k+2 - high + mov d6, v7.d[1] // GHASH block 4k+3 - mid + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 5 + pmull2 v8.1q, v8.2d, v16.2d // GHASH block 4k+2 - mid + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 8 + eor v9.16b, v9.16b, v4.16b // GHASH block 4k+2 - high + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 6 + pmull v4.1q, v7.1d, v12.1d // GHASH block 4k+3 - low + orr x9, x11, x9, lsl #32 // CTR block 4k+8 + eor v10.16b, v10.16b, v8.16b // GHASH block 4k+2 - mid + pmull2 v5.1q, v7.2d, v12.2d // GHASH block 4k+3 - high + cmp x17, #12 // setup flags for AES-128/192/256 check + eor v6.8b, v6.8b, v7.8b // GHASH block 4k+3 - mid + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 8 + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 6 + eor v9.16b, v9.16b, v5.16b // GHASH block 4k+3 - high + pmull v6.1q, v6.1d, v16.1d // GHASH block 4k+3 - mid + movi v8.8b, #0xc2 + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 7 + eor v11.16b, v11.16b, v4.16b // GHASH block 4k+3 - low + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 7 + shl d8, d8, #56 // mod_constant + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 8 + eor v10.16b, v10.16b, v6.16b // GHASH block 4k+3 - mid + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 8 + b.lt .Ldec_main_loop_continue // branch if AES-128 + + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 9 + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 9 + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 9 + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 9 + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 10 + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 10 + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 10 + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 10 + b.eq .Ldec_main_loop_continue // branch if AES-192 + + aese v0.16b, v29.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 11 + aese v1.16b, v29.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 11 + aese v2.16b, v29.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 11 + aese v3.16b, v29.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 11 + aese v0.16b, v30.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 12 + aese v1.16b, v30.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 12 + aese v2.16b, v30.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 12 + aese v3.16b, v30.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 12 + +.Ldec_main_loop_continue: + pmull v7.1q, v9.1d, v8.1d // MODULO - top 64b align with mid + eor v6.16b, v11.16b, v9.16b // MODULO - karatsuba tidy up + ldr q4, [x0, #0] // AES block 4k+4 - load ciphertext + aese v0.16b, v31.16b // AES block 4k+4 - round N-1 + ext v9.16b, v9.16b, v9.16b, #8 // MODULO - other top alignment + eor v10.16b, v10.16b, v6.16b // MODULO - karatsuba tidy up + ldr q5, [x0, #16] // AES block 4k+5 - load ciphertext + eor v0.16b, v4.16b, v0.16b // AES block 4k+4 - result + stp x23, x24, [x2], #16 // AES block 4k+3 - store result + eor v10.16b, v10.16b, v7.16b // MODULO - fold into mid + ldr q7, [x0, #48] // AES block 4k+7 - load ciphertext + ldr q6, [x0, #32] // AES block 4k+6 - load ciphertext + mov x7, v0.d[1] // AES block 4k+4 - mov high + eor v10.16b, v10.16b, v9.16b // MODULO - fold into mid + aese v1.16b, v31.16b // AES block 4k+5 - round N-1 + add x0, x0, #64 // AES input_ptr update + mov x6, v0.d[0] // AES block 4k+4 - mov low + fmov d0, x10 // CTR block 4k+8 + fmov v0.d[1], x9 // CTR block 4k+8 + pmull v8.1q, v10.1d, v8.1d // MODULO - mid 64b align with low + eor v1.16b, v5.16b, v1.16b // AES block 4k+5 - result + rev w9, w12 // CTR block 4k+9 + aese v2.16b, v31.16b // AES block 4k+6 - round N-1 + orr x9, x11, x9, lsl #32 // CTR block 4k+9 + cmp x0, x5 // .LOOP CONTROL + add w12, w12, #1 // CTR block 4k+9 + eor x6, x6, x13 // AES block 4k+4 - round N low + eor x7, x7, x14 // AES block 4k+4 - round N high + mov x20, v1.d[1] // AES block 4k+5 - mov high + eor v2.16b, v6.16b, v2.16b // AES block 4k+6 - result + eor v11.16b, v11.16b, v8.16b // MODULO - fold into low + mov x19, v1.d[0] // AES block 4k+5 - mov low + fmov d1, x10 // CTR block 4k+9 + ext v10.16b, v10.16b, v10.16b, #8 // MODULO - other mid alignment + fmov v1.d[1], x9 // CTR block 4k+9 + rev w9, w12 // CTR block 4k+10 + add w12, w12, #1 // CTR block 4k+10 + aese v3.16b, v31.16b // AES block 4k+7 - round N-1 + orr x9, x11, x9, lsl #32 // CTR block 4k+10 + rev64 v5.16b, v5.16b // GHASH block 4k+5 + eor x20, x20, x14 // AES block 4k+5 - round N high + stp x6, x7, [x2], #16 // AES block 4k+4 - store result + eor x19, x19, x13 // AES block 4k+5 - round N low + stp x19, x20, [x2], #16 // AES block 4k+5 - store result + rev64 v4.16b, v4.16b // GHASH block 4k+4 + eor v11.16b, v11.16b, v10.16b // MODULO - fold into low + b.lt .Ldec_main_loop + +.Ldec_prepretail: // PREPRETAIL + ext v11.16b, v11.16b, v11.16b, #8 // PRE 0 + mov x21, v2.d[0] // AES block 4k+2 - mov low + eor v3.16b, v7.16b, v3.16b // AES block 4k+3 - result + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 0 + mov x22, v2.d[1] // AES block 4k+2 - mov high + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 0 + fmov d2, x10 // CTR block 4k+6 + fmov v2.d[1], x9 // CTR block 4k+6 + rev w9, w12 // CTR block 4k+7 + eor v4.16b, v4.16b, v11.16b // PRE 1 + rev64 v6.16b, v6.16b // GHASH block 4k+2 + orr x9, x11, x9, lsl #32 // CTR block 4k+7 + mov x23, v3.d[0] // AES block 4k+3 - mov low + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 1 + mov x24, v3.d[1] // AES block 4k+3 - mov high + pmull v11.1q, v4.1d, v15.1d // GHASH block 4k - low + mov d8, v4.d[1] // GHASH block 4k - mid + fmov d3, x10 // CTR block 4k+7 + pmull2 v9.1q, v4.2d, v15.2d // GHASH block 4k - high + fmov v3.d[1], x9 // CTR block 4k+7 + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 0 + mov d10, v17.d[1] // GHASH block 4k - mid + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 1 + eor v8.8b, v8.8b, v4.8b // GHASH block 4k - mid + pmull2 v4.1q, v5.2d, v14.2d // GHASH block 4k+1 - high + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 1 + rev64 v7.16b, v7.16b // GHASH block 4k+3 + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 0 + pmull v10.1q, v8.1d, v10.1d // GHASH block 4k - mid + eor v9.16b, v9.16b, v4.16b // GHASH block 4k+1 - high + pmull v8.1q, v5.1d, v14.1d // GHASH block 4k+1 - low + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 1 + mov d4, v5.d[1] // GHASH block 4k+1 - mid + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 2 + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 2 + eor v11.16b, v11.16b, v8.16b // GHASH block 4k+1 - low + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 2 + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 3 + mov d8, v6.d[1] // GHASH block 4k+2 - mid + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 2 + eor v4.8b, v4.8b, v5.8b // GHASH block 4k+1 - mid + pmull v5.1q, v6.1d, v13.1d // GHASH block 4k+2 - low + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 4 + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 3 + eor v8.8b, v8.8b, v6.8b // GHASH block 4k+2 - mid + pmull v4.1q, v4.1d, v17.1d // GHASH block 4k+1 - mid + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 5 + eor v11.16b, v11.16b, v5.16b // GHASH block 4k+2 - low + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 4 + pmull2 v5.1q, v7.2d, v12.2d // GHASH block 4k+3 - high + eor v10.16b, v10.16b, v4.16b // GHASH block 4k+1 - mid + pmull2 v4.1q, v6.2d, v13.2d // GHASH block 4k+2 - high + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 5 + ins v8.d[1], v8.d[0] // GHASH block 4k+2 - mid + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 3 + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 3 + eor v9.16b, v9.16b, v4.16b // GHASH block 4k+2 - high + pmull v4.1q, v7.1d, v12.1d // GHASH block 4k+3 - low + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 4 + mov d6, v7.d[1] // GHASH block 4k+3 - mid + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 4 + pmull2 v8.1q, v8.2d, v16.2d // GHASH block 4k+2 - mid + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 5 + eor v6.8b, v6.8b, v7.8b // GHASH block 4k+3 - mid + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 5 + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 6 + eor v10.16b, v10.16b, v8.16b // GHASH block 4k+2 - mid + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 6 + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 6 + movi v8.8b, #0xc2 + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 6 + eor v11.16b, v11.16b, v4.16b // GHASH block 4k+3 - low + pmull v6.1q, v6.1d, v16.1d // GHASH block 4k+3 - mid + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 7 + cmp x17, #12 // setup flags for AES-128/192/256 check + eor v9.16b, v9.16b, v5.16b // GHASH block 4k+3 - high + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 7 + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 7 + eor v10.16b, v10.16b, v6.16b // GHASH block 4k+3 - mid + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 8 + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 7 + eor v6.16b, v11.16b, v9.16b // MODULO - karatsuba tidy up + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 8 + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 8 + shl d8, d8, #56 // mod_constant + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 8 + b.lt .Ldec_finish_prepretail // branch if AES-128 + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 9 + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 9 + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 9 + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 9 + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 10 + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 10 + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 10 + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 10 + b.eq .Ldec_finish_prepretail // branch if AES-192 + + aese v2.16b, v29.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 11 + aese v0.16b, v29.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 11 + aese v1.16b, v29.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 11 + aese v2.16b, v30.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 12 + aese v3.16b, v29.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 11 + aese v1.16b, v30.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 12 + aese v0.16b, v30.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 12 + aese v3.16b, v30.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 12 + +.Ldec_finish_prepretail: + eor v10.16b, v10.16b, v6.16b // MODULO - karatsuba tidy up + pmull v7.1q, v9.1d, v8.1d // MODULO - top 64b align with mid + ext v9.16b, v9.16b, v9.16b, #8 // MODULO - other top alignment + eor v10.16b, v10.16b, v7.16b // MODULO - fold into mid + eor x22, x22, x14 // AES block 4k+2 - round N high + eor x23, x23, x13 // AES block 4k+3 - round N low + eor v10.16b, v10.16b, v9.16b // MODULO - fold into mid + add w12, w12, #1 // CTR block 4k+7 + eor x21, x21, x13 // AES block 4k+2 - round N low + pmull v8.1q, v10.1d, v8.1d // MODULO - mid 64b align with low + eor x24, x24, x14 // AES block 4k+3 - round N high + stp x21, x22, [x2], #16 // AES block 4k+2 - store result + ext v10.16b, v10.16b, v10.16b, #8 // MODULO - other mid alignment + stp x23, x24, [x2], #16 // AES block 4k+3 - store result + + eor v11.16b, v11.16b, v8.16b // MODULO - fold into low + aese v1.16b, v31.16b // AES block 4k+5 - round N-1 + aese v0.16b, v31.16b // AES block 4k+4 - round N-1 + aese v3.16b, v31.16b // AES block 4k+7 - round N-1 + aese v2.16b, v31.16b // AES block 4k+6 - round N-1 + eor v11.16b, v11.16b, v10.16b // MODULO - fold into low + +.Ldec_tail: // TAIL + sub x5, x4, x0 // main_end_input_ptr is number of bytes left to process + ld1 { v5.16b}, [x0], #16 // AES block 4k+4 - load ciphertext + eor v0.16b, v5.16b, v0.16b // AES block 4k+4 - result + mov x6, v0.d[0] // AES block 4k+4 - mov low + mov x7, v0.d[1] // AES block 4k+4 - mov high + ext v8.16b, v11.16b, v11.16b, #8 // prepare final partial tag + cmp x5, #48 + eor x6, x6, x13 // AES block 4k+4 - round N low + eor x7, x7, x14 // AES block 4k+4 - round N high + b.gt .Ldec_blocks_more_than_3 + sub w12, w12, #1 + mov v3.16b, v2.16b + movi v10.8b, #0 + movi v11.8b, #0 + cmp x5, #32 + movi v9.8b, #0 + mov v2.16b, v1.16b + b.gt .Ldec_blocks_more_than_2 + sub w12, w12, #1 + mov v3.16b, v1.16b + cmp x5, #16 + b.gt .Ldec_blocks_more_than_1 + sub w12, w12, #1 + b .Ldec_blocks_less_than_1 +.Ldec_blocks_more_than_3: // blocks left > 3 + rev64 v4.16b, v5.16b // GHASH final-3 block + ld1 { v5.16b}, [x0], #16 // AES final-2 block - load ciphertext + stp x6, x7, [x2], #16 // AES final-3 block - store result + mov d10, v17.d[1] // GHASH final-3 block - mid + eor v4.16b, v4.16b, v8.16b // feed in partial tag + eor v0.16b, v5.16b, v1.16b // AES final-2 block - result + mov d22, v4.d[1] // GHASH final-3 block - mid + mov x6, v0.d[0] // AES final-2 block - mov low + mov x7, v0.d[1] // AES final-2 block - mov high + eor v22.8b, v22.8b, v4.8b // GHASH final-3 block - mid + movi v8.8b, #0 // suppress further partial tag feed in + pmull2 v9.1q, v4.2d, v15.2d // GHASH final-3 block - high + pmull v10.1q, v22.1d, v10.1d // GHASH final-3 block - mid + eor x6, x6, x13 // AES final-2 block - round N low + pmull v11.1q, v4.1d, v15.1d // GHASH final-3 block - low + eor x7, x7, x14 // AES final-2 block - round N high +.Ldec_blocks_more_than_2: // blocks left > 2 + rev64 v4.16b, v5.16b // GHASH final-2 block + ld1 { v5.16b}, [x0], #16 // AES final-1 block - load ciphertext + eor v4.16b, v4.16b, v8.16b // feed in partial tag + stp x6, x7, [x2], #16 // AES final-2 block - store result + eor v0.16b, v5.16b, v2.16b // AES final-1 block - result + mov d22, v4.d[1] // GHASH final-2 block - mid + pmull v21.1q, v4.1d, v14.1d // GHASH final-2 block - low + pmull2 v20.1q, v4.2d, v14.2d // GHASH final-2 block - high + eor v22.8b, v22.8b, v4.8b // GHASH final-2 block - mid + mov x6, v0.d[0] // AES final-1 block - mov low + mov x7, v0.d[1] // AES final-1 block - mov high + eor v11.16b, v11.16b, v21.16b // GHASH final-2 block - low + movi v8.8b, #0 // suppress further partial tag feed in + pmull v22.1q, v22.1d, v17.1d // GHASH final-2 block - mid + eor v9.16b, v9.16b, v20.16b // GHASH final-2 block - high + eor x6, x6, x13 // AES final-1 block - round N low + eor v10.16b, v10.16b, v22.16b // GHASH final-2 block - mid + eor x7, x7, x14 // AES final-1 block - round N high +.Ldec_blocks_more_than_1: // blocks left > 1 + stp x6, x7, [x2], #16 // AES final-1 block - store result + rev64 v4.16b, v5.16b // GHASH final-1 block + ld1 { v5.16b}, [x0], #16 // AES final block - load ciphertext + eor v4.16b, v4.16b, v8.16b // feed in partial tag + movi v8.8b, #0 // suppress further partial tag feed in + mov d22, v4.d[1] // GHASH final-1 block - mid + eor v0.16b, v5.16b, v3.16b // AES final block - result + pmull2 v20.1q, v4.2d, v13.2d // GHASH final-1 block - high + eor v22.8b, v22.8b, v4.8b // GHASH final-1 block - mid + pmull v21.1q, v4.1d, v13.1d // GHASH final-1 block - low + mov x6, v0.d[0] // AES final block - mov low + ins v22.d[1], v22.d[0] // GHASH final-1 block - mid + mov x7, v0.d[1] // AES final block - mov high + pmull2 v22.1q, v22.2d, v16.2d // GHASH final-1 block - mid + eor x6, x6, x13 // AES final block - round N low + eor v11.16b, v11.16b, v21.16b // GHASH final-1 block - low + eor v9.16b, v9.16b, v20.16b // GHASH final-1 block - high + eor v10.16b, v10.16b, v22.16b // GHASH final-1 block - mid + eor x7, x7, x14 // AES final block - round N high +.Ldec_blocks_less_than_1: // blocks left <= 1 + and x1, x1, #127 // bit_length %= 128 + mvn x14, xzr // rkN_h = 0xffffffffffffffff + sub x1, x1, #128 // bit_length -= 128 + mvn x13, xzr // rkN_l = 0xffffffffffffffff + ldp x4, x5, [x2] // load existing bytes we need to not overwrite + neg x1, x1 // bit_length = 128 - #bits in input (in range [1,128]) + and x1, x1, #127 // bit_length %= 128 + lsr x14, x14, x1 // rkN_h is mask for top 64b of last block + cmp x1, #64 + csel x9, x13, x14, lt + csel x10, x14, xzr, lt + fmov d0, x9 // ctr0b is mask for last block + and x6, x6, x9 + mov v0.d[1], x10 + bic x4, x4, x9 // mask out low existing bytes + rev w9, w12 + bic x5, x5, x10 // mask out high existing bytes + orr x6, x6, x4 + and x7, x7, x10 + orr x7, x7, x5 + and v5.16b, v5.16b, v0.16b // possibly partial last block has zeroes in highest bits + rev64 v4.16b, v5.16b // GHASH final block + eor v4.16b, v4.16b, v8.16b // feed in partial tag + pmull v21.1q, v4.1d, v12.1d // GHASH final block - low + mov d8, v4.d[1] // GHASH final block - mid + eor v8.8b, v8.8b, v4.8b // GHASH final block - mid + pmull2 v20.1q, v4.2d, v12.2d // GHASH final block - high + pmull v8.1q, v8.1d, v16.1d // GHASH final block - mid + eor v9.16b, v9.16b, v20.16b // GHASH final block - high + eor v11.16b, v11.16b, v21.16b // GHASH final block - low + eor v10.16b, v10.16b, v8.16b // GHASH final block - mid + movi v8.8b, #0xc2 + eor v6.16b, v11.16b, v9.16b // MODULO - karatsuba tidy up + shl d8, d8, #56 // mod_constant + eor v10.16b, v10.16b, v6.16b // MODULO - karatsuba tidy up + pmull v7.1q, v9.1d, v8.1d // MODULO - top 64b align with mid + ext v9.16b, v9.16b, v9.16b, #8 // MODULO - other top alignment + eor v10.16b, v10.16b, v7.16b // MODULO - fold into mid + eor v10.16b, v10.16b, v9.16b // MODULO - fold into mid + pmull v8.1q, v10.1d, v8.1d // MODULO - mid 64b align with low + ext v10.16b, v10.16b, v10.16b, #8 // MODULO - other mid alignment + eor v11.16b, v11.16b, v8.16b // MODULO - fold into low + stp x6, x7, [x2] + str w9, [x16, #12] // store the updated counter + eor v11.16b, v11.16b, v10.16b // MODULO - fold into low + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + mov x0, x15 + st1 { v11.16b }, [x3] + ldp x19, x20, [sp, #16] + ldp x21, x22, [sp, #32] + ldp x23, x24, [sp, #48] + ldp d8, d9, [sp, #64] + ldp d10, d11, [sp, #80] + ldp d12, d13, [sp, #96] + ldp d14, d15, [sp, #112] + ldp x29, x30, [sp], #128 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size aes_gcm_dec_kernel,.-aes_gcm_dec_kernel +#endif +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif +#endif // defined(__aarch64__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/armv4-mont.ios.arm.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/armv4-mont-ios.ios.arm.S similarity index 98% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/armv4-mont.ios.arm.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/armv4-mont-ios.ios.arm.S index ea71ff9e..d02830a4 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/armv4-mont.ios.arm.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/armv4-mont-ios.ios.arm.S @@ -10,7 +10,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -981,7 +981,11 @@ OPENSSL_armcap_P: .long 0 .private_extern _OPENSSL_armcap_P #endif -#endif // !OPENSSL_NO_ASM +#endif // !OPENSSL_NO_ASM && defined(__ARMEL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif #endif // defined(__arm__) && defined(__APPLE__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/armv4-mont.linux.arm.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/armv4-mont-linux.linux.arm.S similarity index 98% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/armv4-mont.linux.arm.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/armv4-mont-linux.linux.arm.S index de82af55..e97bc538 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/armv4-mont.linux.arm.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/armv4-mont-linux.linux.arm.S @@ -10,8 +10,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__arm__) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -974,9 +973,11 @@ bn_mul8x_mont_neon: .comm OPENSSL_armcap_P,4,4 .hidden OPENSSL_armcap_P #endif +#endif // !OPENSSL_NO_ASM && defined(__ARMEL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM -.section .note.GNU-stack,"",%progbits #endif // defined(__arm__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/armv8-mont.ios.aarch64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/armv8-mont-ios.ios.aarch64.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/armv8-mont.ios.aarch64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/armv8-mont-ios.ios.aarch64.S index 5e3c0501..0a7e3979 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/armv8-mont.ios.aarch64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/armv8-mont-ios.ios.aarch64.S @@ -10,7 +10,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1432,7 +1432,11 @@ Lmul4x_done: .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 // !OPENSSL_NO_ASM +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif #endif // defined(__aarch64__) && defined(__APPLE__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/armv8-mont.linux.aarch64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/armv8-mont-linux.linux.aarch64.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/armv8-mont.linux.aarch64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/armv8-mont-linux.linux.aarch64.S index 9c8c8593..528dbfa5 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/armv8-mont.linux.aarch64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/armv8-mont-linux.linux.aarch64.S @@ -10,8 +10,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__aarch64__) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1433,9 +1432,11 @@ __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 // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM -.section .note.GNU-stack,"",%progbits #endif // defined(__aarch64__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/bn-586.linux.x86.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/bn-586-linux.linux.x86.S similarity index 97% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/bn-586.linux.x86.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/bn-586-linux.linux.x86.S index bd7857f7..a3e74caa 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/bn-586.linux.x86.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/bn-586-linux.linux.x86.S @@ -3,7 +3,13 @@ // This file is generated from a similarly-named Perl script in the BoringSSL // source tree. Do not edit by hand. -#if defined(__i386__) +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -995,8 +1001,11 @@ bn_sub_words: popl %ebp ret .size bn_sub_words,.-.L_bn_sub_words_begin +#endif // !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -.section .note.GNU-stack,"",@progbits #endif // defined(__i386__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/bn-armv8-ios.ios.aarch64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/bn-armv8-ios.ios.aarch64.S new file mode 100644 index 00000000..1d7a5775 --- /dev/null +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/bn-armv8-ios.ios.aarch64.S @@ -0,0 +1,108 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__aarch64__) && defined(__APPLE__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__APPLE__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include + +.text + +// BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, +// size_t num); + +.globl _bn_add_words +.private_extern _bn_add_words +.align 4 +_bn_add_words: + AARCH64_VALID_CALL_TARGET + # Clear the carry flag. + cmn xzr, xzr + + # aarch64 can load two registers at a time, so we do two loop iterations at + # at a time. Split x3 = 2 * x8 + x3. This allows loop + # operations to use CBNZ without clobbering the carry flag. + lsr x8, x3, #1 + and x3, x3, #1 + + cbz x8, Ladd_tail +Ladd_loop: + ldp x4, x5, [x1], #16 + ldp x6, x7, [x2], #16 + sub x8, x8, #1 + adcs x4, x4, x6 + adcs x5, x5, x7 + stp x4, x5, [x0], #16 + cbnz x8, Ladd_loop + +Ladd_tail: + cbz x3, Ladd_exit + ldr x4, [x1], #8 + ldr x6, [x2], #8 + adcs x4, x4, x6 + str x4, [x0], #8 + +Ladd_exit: + cset x0, cs + ret + + +// BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, +// size_t num); + +.globl _bn_sub_words +.private_extern _bn_sub_words +.align 4 +_bn_sub_words: + AARCH64_VALID_CALL_TARGET + # Set the carry flag. Arm's borrow bit is flipped from the carry flag, + # so we want C = 1 here. + cmp xzr, xzr + + # aarch64 can load two registers at a time, so we do two loop iterations at + # at a time. Split x3 = 2 * x8 + x3. This allows loop + # operations to use CBNZ without clobbering the carry flag. + lsr x8, x3, #1 + and x3, x3, #1 + + cbz x8, Lsub_tail +Lsub_loop: + ldp x4, x5, [x1], #16 + ldp x6, x7, [x2], #16 + sub x8, x8, #1 + sbcs x4, x4, x6 + sbcs x5, x5, x7 + stp x4, x5, [x0], #16 + cbnz x8, Lsub_loop + +Lsub_tail: + cbz x3, Lsub_exit + ldr x4, [x1], #8 + ldr x6, [x2], #8 + sbcs x4, x4, x6 + str x4, [x0], #8 + +Lsub_exit: + cset x0, cc + ret + +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif +#endif // defined(__aarch64__) && defined(__APPLE__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/bn-armv8-linux.linux.aarch64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/bn-armv8-linux.linux.aarch64.S new file mode 100644 index 00000000..d94a033e --- /dev/null +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/bn-armv8-linux.linux.aarch64.S @@ -0,0 +1,108 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__aarch64__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__ELF__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include + +.text + +// BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, +// size_t num); +.type bn_add_words, %function +.globl bn_add_words +.hidden bn_add_words +.align 4 +bn_add_words: + AARCH64_VALID_CALL_TARGET + # Clear the carry flag. + cmn xzr, xzr + + # aarch64 can load two registers at a time, so we do two loop iterations at + # at a time. Split x3 = 2 * x8 + x3. This allows loop + # operations to use CBNZ without clobbering the carry flag. + lsr x8, x3, #1 + and x3, x3, #1 + + cbz x8, .Ladd_tail +.Ladd_loop: + ldp x4, x5, [x1], #16 + ldp x6, x7, [x2], #16 + sub x8, x8, #1 + adcs x4, x4, x6 + adcs x5, x5, x7 + stp x4, x5, [x0], #16 + cbnz x8, .Ladd_loop + +.Ladd_tail: + cbz x3, .Ladd_exit + ldr x4, [x1], #8 + ldr x6, [x2], #8 + adcs x4, x4, x6 + str x4, [x0], #8 + +.Ladd_exit: + cset x0, cs + ret +.size bn_add_words,.-bn_add_words + +// BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, +// size_t num); +.type bn_sub_words, %function +.globl bn_sub_words +.hidden bn_sub_words +.align 4 +bn_sub_words: + AARCH64_VALID_CALL_TARGET + # Set the carry flag. Arm's borrow bit is flipped from the carry flag, + # so we want C = 1 here. + cmp xzr, xzr + + # aarch64 can load two registers at a time, so we do two loop iterations at + # at a time. Split x3 = 2 * x8 + x3. This allows loop + # operations to use CBNZ without clobbering the carry flag. + lsr x8, x3, #1 + and x3, x3, #1 + + cbz x8, .Lsub_tail +.Lsub_loop: + ldp x4, x5, [x1], #16 + ldp x6, x7, [x2], #16 + sub x8, x8, #1 + sbcs x4, x4, x6 + sbcs x5, x5, x7 + stp x4, x5, [x0], #16 + cbnz x8, .Lsub_loop + +.Lsub_tail: + cbz x3, .Lsub_exit + ldr x4, [x1], #8 + ldr x6, [x2], #8 + sbcs x4, x4, x6 + str x4, [x0], #8 + +.Lsub_exit: + cset x0, cc + ret +.size bn_sub_words,.-bn_sub_words +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif +#endif // defined(__aarch64__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/bn.c b/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/bn.c index 1dfa2afa..59d1cf5e 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/bn.c +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/bn.c @@ -76,7 +76,6 @@ BIGNUM *BN_new(void) { BIGNUM *bn = OPENSSL_malloc(sizeof(BIGNUM)); if (bn == NULL) { - OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); return NULL; } @@ -364,7 +363,6 @@ int bn_wexpand(BIGNUM *bn, size_t words) { a = OPENSSL_malloc(sizeof(BN_ULONG) * words); if (a == NULL) { - OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); return 0; } @@ -386,23 +384,6 @@ int bn_expand(BIGNUM *bn, size_t bits) { } int bn_resize_words(BIGNUM *bn, size_t words) { -#if defined(OPENSSL_PPC64LE) - // This is a workaround for a miscompilation bug in Clang 7.0.1 on POWER. - // The unittests catch the miscompilation, if it occurs, and it manifests - // as a crash in |bn_fits_in_words|. - // - // The bug only triggers if building in FIPS mode and with -O3. Clang 8.0.1 - // has the same bug but this workaround is not effective there---I've not - // been able to find a workaround for 8.0.1. - // - // At the time of writing (2019-08-08), Clang git does *not* have this bug - // and does not need this workaroud. The current git version should go on to - // be Clang 10 thus, once we can depend on that, this can be removed. - if (value_barrier_w((size_t)bn->width == words)) { - return 1; - } -#endif - if ((size_t)bn->width <= words) { if (!bn_wexpand(bn, words)) { return 0; diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/bytes.c b/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/bytes.c index 0b7f8017..f37bd694 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/bytes.c +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/bytes.c @@ -162,6 +162,18 @@ static int fits_in_bytes(const BN_ULONG *words, size_t num_words, return mask == 0; } +void bn_assert_fits_in_bytes(const BIGNUM *bn, size_t num) { + const uint8_t *bytes = (const uint8_t *)bn->d; + size_t tot_bytes = bn->width * sizeof(BN_ULONG); + if (tot_bytes > num) { + CONSTTIME_DECLASSIFY(bytes + num, tot_bytes - num); + for (size_t i = num; i < tot_bytes; i++) { + assert(bytes[i] == 0); + } + (void)bytes; + } +} + void bn_words_to_big_endian(uint8_t *out, size_t out_len, const BN_ULONG *in, size_t in_len) { // The caller should have selected an output length without truncation. diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/ctx.c b/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/ctx.c index 0c471c4e..88eecaf3 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/ctx.c +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/ctx.c @@ -108,7 +108,6 @@ struct bignum_ctx { BN_CTX *BN_CTX_new(void) { BN_CTX *ret = OPENSSL_malloc(sizeof(BN_CTX)); if (!ret) { - OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); return NULL; } @@ -162,7 +161,6 @@ BIGNUM *BN_CTX_get(BN_CTX *ctx) { if (ctx->bignums == NULL) { ctx->bignums = sk_BIGNUM_new_null(); if (ctx->bignums == NULL) { - OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); ctx->error = 1; return NULL; } diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/exponentiation.c b/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/exponentiation.c index 3ad84bfd..84f10022 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/exponentiation.c +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/exponentiation.c @@ -109,6 +109,7 @@ #include #include +#include #include #include @@ -396,7 +397,7 @@ static int BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y, // // (with draws in between). Very small exponents are often selected // with low Hamming weight, so we use w = 1 for b <= 23. -static int BN_window_bits_for_exponent_size(int b) { +static int BN_window_bits_for_exponent_size(size_t b) { if (b > 671) { return 6; } @@ -443,6 +444,7 @@ static int mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, return BN_one(r); } + BN_RECP_CTX_init(&recp); BN_CTX_start(ctx); aa = BN_CTX_get(ctx); val[0] = BN_CTX_get(ctx); @@ -450,7 +452,6 @@ static int mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, goto err; } - BN_RECP_CTX_init(&recp); if (m->neg) { // ignore sign of 'm' if (!BN_copy(aa, m)) { @@ -593,7 +594,8 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); return 0; } - if (a->neg || BN_ucmp(a, m) >= 0) { + // |a| is secret, but |a < m| is not. + if (a->neg || constant_time_declassify_int(BN_ucmp(a, m)) >= 0) { OPENSSL_PUT_ERROR(BN, BN_R_INPUT_NOT_REDUCED); return 0; } @@ -721,12 +723,14 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, void bn_mod_exp_mont_small(BN_ULONG *r, const BN_ULONG *a, size_t num, const BN_ULONG *p, size_t num_p, const BN_MONT_CTX *mont) { - if (num != (size_t)mont->N.width || num > BN_SMALL_MAX_WORDS) { + if (num != (size_t)mont->N.width || num > BN_SMALL_MAX_WORDS || + num_p > ((size_t)-1) / BN_BITS2) { abort(); } assert(BN_is_odd(&mont->N)); - // Count the number of bits in |p|. Note this function treats |p| as public. + // Count the number of bits in |p|, skipping leading zeros. Note this function + // treats |p| as public. while (num_p != 0 && p[num_p - 1] == 0) { num_p--; } @@ -734,7 +738,7 @@ void bn_mod_exp_mont_small(BN_ULONG *r, const BN_ULONG *a, size_t num, bn_from_montgomery_small(r, num, mont->RR.d, num, mont); return; } - unsigned bits = BN_num_bits_word(p[num_p - 1]) + (num_p - 1) * BN_BITS2; + size_t bits = BN_num_bits_word(p[num_p - 1]) + (num_p - 1) * BN_BITS2; assert(bits != 0); // We exponentiate by looking at sliding windows of the exponent and @@ -758,7 +762,7 @@ void bn_mod_exp_mont_small(BN_ULONG *r, const BN_ULONG *a, size_t num, // |p| is non-zero, so at least one window is non-zero. To save some // multiplications, defer initializing |r| until then. int r_is_one = 1; - unsigned wstart = bits - 1; // The top bit of the window. + size_t wstart = bits - 1; // The top bit of the window. for (;;) { if (!bn_is_bit_set_words(p, num_p, wstart)) { if (!r_is_one) { @@ -848,7 +852,11 @@ static int copy_from_prebuf(BIGNUM *b, int top, const BN_ULONG *table, int idx, OPENSSL_memset(b->d, 0, sizeof(BN_ULONG) * top); const int width = 1 << window; for (int i = 0; i < width; i++, table += top) { - BN_ULONG mask = constant_time_eq_int(i, idx); + // Use a value barrier to prevent Clang from adding a branch when |i != idx| + // and making this copy not constant time. Clang is still allowed to learn + // that |mask| is constant across the inner loop, so this won't inhibit any + // vectorization it might do. + BN_ULONG mask = value_barrier_w(constant_time_eq_int(i, idx)); for (int j = 0; j < top; j++) { b->d[j] |= table[j] & mask; } @@ -858,40 +866,15 @@ static int copy_from_prebuf(BIGNUM *b, int top, const BN_ULONG *table, int idx, return 1; } -#define MOD_EXP_CTIME_MIN_CACHE_LINE_MASK \ - (MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH - 1) - // Window sizes optimized for fixed window size modular exponentiation // algorithm (BN_mod_exp_mont_consttime). // -// To achieve the security goals of BN_mode_exp_mont_consttime, the maximum -// size of the window must not exceed -// log_2(MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH). -// -// Window size thresholds are defined for cache line sizes of 32 and 64, cache -// line sizes where log_2(32)=5 and log_2(64)=6 respectively. A window size of -// 7 should only be used on processors that have a 128 byte or greater cache -// line size. -#if MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH == 64 - +// TODO(davidben): These window sizes were originally set for 64-byte cache +// lines with a cache-line-dependent constant-time mitigation. They can probably +// be revised now that our implementation is no longer cache-time-dependent. #define BN_window_bits_for_ctime_exponent_size(b) \ ((b) > 937 ? 6 : (b) > 306 ? 5 : (b) > 89 ? 4 : (b) > 22 ? 3 : 1) -#define BN_MAX_WINDOW_BITS_FOR_CTIME_EXPONENT_SIZE (6) - -#elif MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH == 32 - -#define BN_window_bits_for_ctime_exponent_size(b) \ - ((b) > 306 ? 5 : (b) > 89 ? 4 : (b) > 22 ? 3 : 1) -#define BN_MAX_WINDOW_BITS_FOR_CTIME_EXPONENT_SIZE (5) - -#endif - -// Given a pointer value, compute the next address that is a cache line -// multiple. -#define MOD_EXP_CTIME_ALIGN(x_) \ - ((unsigned char *)(x_) + \ - (MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH - \ - (((size_t)(x_)) & (MOD_EXP_CTIME_MIN_CACHE_LINE_MASK)))) +#define BN_MAX_MOD_EXP_CTIME_WINDOW (6) // This variant of |BN_mod_exp_mont| uses fixed windows and fixed memory access // patterns to protect secret exponents (cf. the hyper-threading timing attacks @@ -900,14 +883,12 @@ static int copy_from_prebuf(BIGNUM *b, int top, const BN_ULONG *table, int idx, int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, const BN_MONT_CTX *mont) { - int i, ret = 0, window, wvalue; + int i, ret = 0, wvalue; BN_MONT_CTX *new_mont = NULL; - int numPowers; - unsigned char *powerbufFree = NULL; - int powerbufLen = 0; + unsigned char *powerbuf_free = NULL; + size_t powerbuf_len = 0; BN_ULONG *powerbuf = NULL; - BIGNUM tmp, am; if (!BN_is_odd(m)) { OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS); @@ -953,8 +934,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, // paths. If we were to use separate static buffers for each then there is // some chance that both large buffers would be allocated on the stack, // causing the stack space requirement to be truly huge (~10KB). - alignas(MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH) BN_ULONG - storage[MOD_EXP_CTIME_STORAGE_LEN]; + alignas(MOD_EXP_CTIME_ALIGN) BN_ULONG storage[MOD_EXP_CTIME_STORAGE_LEN]; #endif #if defined(RSAZ_ENABLED) // If the size of the operands allow it, perform the optimized RSAZ @@ -975,41 +955,49 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, #endif // Get the window size to use with size of p. - window = BN_window_bits_for_ctime_exponent_size(bits); + int window = BN_window_bits_for_ctime_exponent_size(bits); + assert(window <= BN_MAX_MOD_EXP_CTIME_WINDOW); + + // Calculating |powerbuf_len| below cannot overflow because of the bound on + // Montgomery reduction. + assert((size_t)top <= BN_MONTGOMERY_MAX_WORDS); + static_assert( + BN_MONTGOMERY_MAX_WORDS <= + INT_MAX / sizeof(BN_ULONG) / ((1 << BN_MAX_MOD_EXP_CTIME_WINDOW) + 3), + "powerbuf_len may overflow"); + #if defined(OPENSSL_BN_ASM_MONT5) if (window >= 5) { window = 5; // ~5% improvement for RSA2048 sign, and even for RSA4096 // Reserve space for the |mont->N| copy. - powerbufLen += top * sizeof(mont->N.d[0]); + powerbuf_len += top * sizeof(mont->N.d[0]); } #endif // Allocate a buffer large enough to hold all of the pre-computed // powers of |am|, |am| itself, and |tmp|. - numPowers = 1 << window; - powerbufLen += - sizeof(m->d[0]) * - (top * numPowers + ((2 * top) > numPowers ? (2 * top) : numPowers)); + int num_powers = 1 << window; + powerbuf_len += sizeof(m->d[0]) * top * (num_powers + 2); #if defined(OPENSSL_BN_ASM_MONT5) - if ((size_t)powerbufLen <= sizeof(storage)) { + if (powerbuf_len <= sizeof(storage)) { powerbuf = storage; } // |storage| is more than large enough to handle 1024-bit inputs. assert(powerbuf != NULL || top * BN_BITS2 > 1024); #endif if (powerbuf == NULL) { - powerbufFree = - OPENSSL_malloc(powerbufLen + MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH); - if (powerbufFree == NULL) { + powerbuf_free = OPENSSL_malloc(powerbuf_len + MOD_EXP_CTIME_ALIGN); + if (powerbuf_free == NULL) { goto err; } - powerbuf = (BN_ULONG *)MOD_EXP_CTIME_ALIGN(powerbufFree); + powerbuf = align_pointer(powerbuf_free, MOD_EXP_CTIME_ALIGN); } - OPENSSL_memset(powerbuf, 0, powerbufLen); + OPENSSL_memset(powerbuf, 0, powerbuf_len); // Place |tmp| and |am| right after powers table. - tmp.d = powerbuf + top * numPowers; + BIGNUM tmp, am; + tmp.d = powerbuf + top * num_powers; am.d = tmp.d + top; tmp.width = am.width = 0; tmp.dmax = am.dmax = top; @@ -1158,7 +1146,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, copy_to_prebuf(&tmp, top, powerbuf, 2, window); - for (i = 3; i < numPowers; i++) { + for (i = 3; i < num_powers; i++) { // Calculate a^i = a^(i-1) * a if (!BN_mod_mul_montgomery(&tmp, &am, &tmp, mont, ctx)) { goto err; @@ -1213,11 +1201,11 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, err: BN_MONT_CTX_free(new_mont); - if (powerbuf != NULL && powerbufFree == NULL) { - OPENSSL_cleanse(powerbuf, powerbufLen); + if (powerbuf != NULL && powerbuf_free == NULL) { + OPENSSL_cleanse(powerbuf, powerbuf_len); } - OPENSSL_free(powerbufFree); - return (ret); + OPENSSL_free(powerbuf_free); + return ret; } int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p, diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/gcd.c b/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/gcd.c index 8bc397c4..afa2f433 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/gcd.c +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/gcd.c @@ -286,7 +286,6 @@ BIGNUM *BN_mod_inverse(BIGNUM *out, const BIGNUM *a, const BIGNUM *n, if (out == NULL) { new_out = BN_new(); if (new_out == NULL) { - OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); return NULL; } out = new_out; diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/generic.c b/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/generic.c index 5b186f53..21451612 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/generic.c +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/generic.c @@ -61,11 +61,25 @@ #include "internal.h" -// 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) || \ - (defined(OPENSSL_X86_64) && (defined(__GNUC__) || defined(__clang__)))) +#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86) +// See asm/bn-586.pl. +#define BN_ADD_ASM +#define BN_MUL_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \ + (defined(__GNUC__) || defined(__clang__)) +// See asm/x86_64-gcc.c +#define BN_ADD_ASM +#define BN_MUL_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_AARCH64) +// See asm/bn-armv8.pl. +#define BN_ADD_ASM +#endif + +#if !defined(BN_MUL_ASM) #ifdef BN_ULLONG #define mul_add(r, a, w, c) \ @@ -201,157 +215,6 @@ void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, size_t n) { } } -#ifdef BN_ULLONG -BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, - size_t n) { - BN_ULLONG ll = 0; - - if (n == 0) { - return 0; - } - - while (n & ~3) { - ll += (BN_ULLONG)a[0] + b[0]; - r[0] = (BN_ULONG)ll; - ll >>= BN_BITS2; - ll += (BN_ULLONG)a[1] + b[1]; - r[1] = (BN_ULONG)ll; - ll >>= BN_BITS2; - ll += (BN_ULLONG)a[2] + b[2]; - r[2] = (BN_ULONG)ll; - ll >>= BN_BITS2; - ll += (BN_ULLONG)a[3] + b[3]; - r[3] = (BN_ULONG)ll; - ll >>= BN_BITS2; - a += 4; - b += 4; - r += 4; - n -= 4; - } - while (n) { - ll += (BN_ULLONG)a[0] + b[0]; - r[0] = (BN_ULONG)ll; - ll >>= BN_BITS2; - a++; - b++; - r++; - n--; - } - return (BN_ULONG)ll; -} - -#else // !BN_ULLONG - -BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, - size_t n) { - BN_ULONG c, l, t; - - if (n == 0) { - return (BN_ULONG)0; - } - - c = 0; - while (n & ~3) { - t = a[0]; - t += c; - c = (t < c); - l = t + b[0]; - c += (l < t); - r[0] = l; - t = a[1]; - t += c; - c = (t < c); - l = t + b[1]; - c += (l < t); - r[1] = l; - t = a[2]; - t += c; - c = (t < c); - l = t + b[2]; - c += (l < t); - r[2] = l; - t = a[3]; - t += c; - c = (t < c); - l = t + b[3]; - c += (l < t); - r[3] = l; - a += 4; - b += 4; - r += 4; - n -= 4; - } - while (n) { - t = a[0]; - t += c; - c = (t < c); - l = t + b[0]; - c += (l < t); - r[0] = l; - a++; - b++; - r++; - n--; - } - return (BN_ULONG)c; -} - -#endif // !BN_ULLONG - -BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, - size_t n) { - BN_ULONG t1, t2; - int c = 0; - - if (n == 0) { - return (BN_ULONG)0; - } - - while (n & ~3) { - t1 = a[0]; - t2 = b[0]; - r[0] = t1 - t2 - c; - if (t1 != t2) { - c = (t1 < t2); - } - t1 = a[1]; - t2 = b[1]; - r[1] = t1 - t2 - c; - if (t1 != t2) { - c = (t1 < t2); - } - t1 = a[2]; - t2 = b[2]; - r[2] = t1 - t2 - c; - if (t1 != t2) { - c = (t1 < t2); - } - t1 = a[3]; - t2 = b[3]; - r[3] = t1 - t2 - c; - if (t1 != t2) { - c = (t1 < t2); - } - a += 4; - b += 4; - r += 4; - n -= 4; - } - while (n) { - t1 = a[0]; - t2 = b[0]; - r[0] = t1 - t2 - c; - if (t1 != t2) { - c = (t1 < t2); - } - a++; - b++; - r++; - n--; - } - return c; -} - // 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) // sqr_add_c(a,i,c0,c1,c2) -- c+=a[i]^2 for three word number c=(c2,c1,c0) @@ -369,9 +232,7 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, (c0) = (BN_ULONG)Lw(t); \ hi = (BN_ULONG)Hw(t); \ (c1) += (hi); \ - if ((c1) < hi) { \ - (c2)++; \ - } \ + (c2) += (c1) < hi; \ } while (0) #define mul_add_c2(a, b, c0, c1, c2) \ @@ -382,16 +243,12 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, (c0) = (BN_ULONG)Lw(tt); \ hi = (BN_ULONG)Hw(tt); \ (c1) += hi; \ - if ((c1) < hi) { \ - (c2)++; \ - } \ + (c2) += (c1) < hi; \ t += (c0); /* no carry */ \ (c0) = (BN_ULONG)Lw(t); \ hi = (BN_ULONG)Hw(t); \ (c1) += hi; \ - if ((c1) < hi) { \ - (c2)++; \ - } \ + (c2) += (c1) < hi; \ } while (0) #define sqr_add_c(a, i, c0, c1, c2) \ @@ -402,9 +259,7 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, (c0) = (BN_ULONG)Lw(t); \ hi = (BN_ULONG)Hw(t); \ (c1) += hi; \ - if ((c1) < hi) { \ - (c2)++; \ - } \ + (c2) += (c1) < hi; \ } while (0) #define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2) @@ -708,4 +563,93 @@ void bn_sqr_comba4(BN_ULONG r[8], const BN_ULONG a[4]) { #undef sqr_add_c #undef sqr_add_c2 +#endif // !BN_MUL_ASM + +#if !defined(BN_ADD_ASM) + +// bn_add_with_carry returns |x + y + carry|, and sets |*out_carry| to the +// carry bit. |carry| must be zero or one. +static inline BN_ULONG bn_add_with_carry(BN_ULONG x, BN_ULONG y, BN_ULONG carry, + BN_ULONG *out_carry) { + assert(carry == 0 || carry == 1); +#if defined(BN_ULLONG) + BN_ULLONG ret = carry; + ret += (BN_ULLONG)x + y; + *out_carry = (BN_ULONG)(ret >> BN_BITS2); + return (BN_ULONG)ret; +#else + x += carry; + carry = x < carry; + BN_ULONG ret = x + y; + carry += ret < x; + *out_carry = carry; + return ret; #endif +} + +// bn_sub_with_borrow returns |x - y - borrow|, and sets |*out_borrow| to the +// borrow bit. |borrow| must be zero or one. +static inline BN_ULONG bn_sub_with_borrow(BN_ULONG x, BN_ULONG y, + BN_ULONG borrow, + BN_ULONG *out_borrow) { + assert(borrow == 0 || borrow == 1); + BN_ULONG ret = x - y - borrow; + *out_borrow = (x < y) | ((x == y) & borrow); + return ret; +} + +BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, + size_t n) { + if (n == 0) { + return 0; + } + + BN_ULONG carry = 0; + while (n & ~3) { + r[0] = bn_add_with_carry(a[0], b[0], carry, &carry); + r[1] = bn_add_with_carry(a[1], b[1], carry, &carry); + r[2] = bn_add_with_carry(a[2], b[2], carry, &carry); + r[3] = bn_add_with_carry(a[3], b[3], carry, &carry); + a += 4; + b += 4; + r += 4; + n -= 4; + } + while (n) { + r[0] = bn_add_with_carry(a[0], b[0], carry, &carry); + a++; + b++; + r++; + n--; + } + return carry; +} + +BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, + size_t n) { + if (n == 0) { + return (BN_ULONG)0; + } + + BN_ULONG borrow = 0; + while (n & ~3) { + r[0] = bn_sub_with_borrow(a[0], b[0], borrow, &borrow); + r[1] = bn_sub_with_borrow(a[1], b[1], borrow, &borrow); + r[2] = bn_sub_with_borrow(a[2], b[2], borrow, &borrow); + r[3] = bn_sub_with_borrow(a[3], b[3], borrow, &borrow); + a += 4; + b += 4; + r += 4; + n -= 4; + } + while (n) { + r[0] = bn_sub_with_borrow(a[0], b[0], borrow, &borrow); + a++; + b++; + r++; + n--; + } + return borrow; +} + +#endif // !BN_ADD_ASM diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/internal.h b/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/internal.h index c6ca9f9e..fe7732b0 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/internal.h +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/internal.h @@ -189,14 +189,20 @@ extern "C" { #define BN_CAN_USE_INLINE_ASM #endif -// |BN_mod_exp_mont_consttime| is based on the assumption that the L1 data -// cache line width of the target processor is at least the following value. -#define MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH 64 - -// The number of |BN_ULONG|s needed for the |BN_mod_exp_mont_consttime| stack- -// allocated storage buffer. The buffer is just the right size for the RSAZ -// and is about ~1KB larger than what's necessary (4480 bytes) for 1024-bit -// inputs. +// MOD_EXP_CTIME_ALIGN is the alignment needed for |BN_mod_exp_mont_consttime|'s +// tables. +// +// TODO(davidben): Historically, this alignment came from cache line +// assumptions, which we've since removed. Is 64-byte alignment still necessary +// or ideal? The true alignment requirement seems to now be 32 bytes, coming +// from RSAZ's use of VMOVDQA to a YMM register. Non-x86_64 has even fewer +// requirements. +#define MOD_EXP_CTIME_ALIGN 64 + +// MOD_EXP_CTIME_STORAGE_LEN is the number of |BN_ULONG|s needed for the +// |BN_mod_exp_mont_consttime| stack-allocated storage buffer. The buffer is +// just the right size for the RSAZ and is about ~1KB larger than what's +// necessary (4480 bytes) for 1024-bit inputs. #define MOD_EXP_CTIME_STORAGE_LEN \ (((320u * 3u) + (32u * 9u * 16u)) / sizeof(BN_ULONG)) @@ -211,8 +217,8 @@ extern "C" { #define Hw(t) ((BN_ULONG)((t) >> BN_BITS2)) #endif -// bn_minimal_width returns the minimal value of |bn->top| which fits the -// value of |bn|. +// bn_minimal_width returns the minimal number of words needed to represent +// |bn|. int bn_minimal_width(const BIGNUM *bn); // bn_set_minimal_width sets |bn->width| to |bn_minimal_width(bn)|. If |bn| is @@ -228,7 +234,7 @@ int bn_wexpand(BIGNUM *bn, size_t words); // than a number of words. int bn_expand(BIGNUM *bn, size_t bits); -// bn_resize_words adjusts |bn->top| to be |words|. It returns one on success +// bn_resize_words adjusts |bn->width| to be |words|. It returns one on success // and zero on allocation error or if |bn|'s value is too large. OPENSSL_EXPORT int bn_resize_words(BIGNUM *bn, size_t words); @@ -257,6 +263,12 @@ int bn_fits_in_words(const BIGNUM *bn, size_t num); // is representable in |num| words. Otherwise, it returns zero. int bn_copy_words(BN_ULONG *out, size_t num, const BIGNUM *bn); +// bn_assert_fits_in_bytes asserts that |bn| fits in |num| bytes. This is a +// no-op in release builds, but triggers an assert in debug builds, and +// declassifies all bytes which are therefore known to be zero in constant-time +// validation. +void bn_assert_fits_in_bytes(const BIGNUM *bn, size_t num); + // bn_mul_add_words multiples |ap| by |w|, adds the result to |rp|, and places // the result in |rp|. |ap| and |rp| must both be |num| words long. It returns // the carry word of the operation. |ap| and |rp| may be equal but otherwise may @@ -344,6 +356,12 @@ int bn_rand_range_words(BN_ULONG *out, BN_ULONG min_inclusive, int bn_rand_secret_range(BIGNUM *r, int *out_is_uniform, BN_ULONG min_inclusive, const BIGNUM *max_exclusive); +// BN_MONTGOMERY_MAX_WORDS is the maximum numer of words allowed in a |BIGNUM| +// used with Montgomery reduction. Ideally this limit would be applied to all +// |BIGNUM|s, in |bn_wexpand|, but the exactfloat library needs to create 8 MiB +// values for other operations. +#define BN_MONTGOMERY_MAX_WORDS (8 * 1024 / sizeof(BN_ULONG)) + #if !defined(OPENSSL_NO_ASM) && \ (defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \ defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) @@ -356,11 +374,13 @@ int bn_rand_secret_range(BIGNUM *r, int *out_is_uniform, BN_ULONG min_inclusive, // If at least one of |ap| or |bp| is fully reduced, |rp| will be fully reduced. // If neither is fully-reduced, the output may not be either. // +// This function allocates |num| words on the stack, so |num| should be at most +// |BN_MONTGOMERY_MAX_WORDS|. +// // TODO(davidben): The x86_64 implementation expects a 32-bit input and masks // off upper bits. The aarch64 implementation expects a 64-bit input and does // not. |size_t| is the safer option but not strictly correct for x86_64. But -// this function implicitly already has a bound on the size of |num| because it -// internally creates |num|-sized stack allocation. +// the |BN_MONTGOMERY_MAX_WORDS| bound makes this moot. // // See also discussion in |ToWord| in abi_test.h for notes on smaller-than-word // inputs. @@ -374,7 +394,8 @@ int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, // bn_mul_mont_gather5 multiples loads index |power| of |table|, multiplies it // by |ap| modulo |np|, and stores the result in |rp|. The values are |num| // words long and represented in Montgomery form. |n0| is a pointer to the -// corresponding field in |BN_MONT_CTX|. +// corresponding field in |BN_MONT_CTX|. |table| must be aligned to at least +// 16 bytes. |power| must be less than 32 and is treated as secret. // // WARNING: This function implements Almost Montgomery Multiplication from // https://eprint.iacr.org/2011/239. The inputs do not need to be fully reduced. @@ -384,20 +405,22 @@ void bn_mul_mont_gather5(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *n0, int num, int power); // bn_scatter5 stores |inp| to index |power| of |table|. |inp| and each entry of -// |table| are |num| words long. |power| must be less than 32. |table| must be -// 32*|num| words long. +// |table| are |num| words long. |power| must be less than 32 and is treated as +// public. |table| must be 32*|num| words long. |table| must be aligned to at +// least 16 bytes. void bn_scatter5(const BN_ULONG *inp, size_t num, BN_ULONG *table, size_t power); // bn_gather5 loads index |power| of |table| and stores it in |out|. |out| and -// each entry of |table| are |num| words long. |power| must be less than 32. +// each entry of |table| are |num| words long. |power| must be less than 32 and +// is treated as secret. |table| must be aligned to at least 16 bytes. void bn_gather5(BN_ULONG *out, size_t num, const BN_ULONG *table, size_t power); // bn_power5 squares |ap| five times and multiplies it by the value stored at // index |power| of |table|, modulo |np|. It stores the result in |rp|. The // values are |num| words long and represented in Montgomery form. |n0| is a // pointer to the corresponding field in |BN_MONT_CTX|. |num| must be divisible -// by 8. +// by 8. |power| must be less than 32 and is treated as secret. // // WARNING: This function implements Almost Montgomery Multiplication from // https://eprint.iacr.org/2011/239. The inputs do not need to be fully reduced. @@ -635,6 +658,15 @@ int bn_mod_inverse_prime(BIGNUM *out, const BIGNUM *a, const BIGNUM *p, int bn_mod_inverse_secret_prime(BIGNUM *out, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx, const BN_MONT_CTX *mont_p); +// 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|. It returns one on success and zero on error. Note +// this function assumes |mod| is public. +// +// 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); + // Low-level operations for small numbers. // @@ -690,9 +722,10 @@ void bn_mod_mul_montgomery_small(BN_ULONG *r, const BN_ULONG *a, // bn_mod_exp_mont_small sets |r| to |a|^|p| mod |mont->N|. It returns one on // success and zero on programmer or internal error. Both inputs and outputs are // in the Montgomery domain. |r| and |a| are |num| words long, which must be -// |mont->N.width| and at most |BN_SMALL_MAX_WORDS|. |a| must be fully-reduced. -// This function runs in time independent of |a|, but |p| and |mont->N| are -// public values. |a| must be fully-reduced and may alias with |r|. +// |mont->N.width| and at most |BN_SMALL_MAX_WORDS|. |num_p|, measured in bits, +// must fit in |size_t|. |a| must be fully-reduced. This function runs in time +// independent of |a|, but |p| and |mont->N| are public values. |a| must be +// fully-reduced and may alias with |r|. // // Note this function differs from |BN_mod_exp_mont| which uses Montgomery // reduction but takes input and output outside the Montgomery domain. Combine diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/montgomery.c b/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/montgomery.c index c77af161..96c6583e 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/montgomery.c +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/montgomery.c @@ -172,6 +172,10 @@ static int bn_mont_ctx_set_N_and_n0(BN_MONT_CTX *mont, const BIGNUM *mod) { OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); return 0; } + if (!bn_fits_in_words(mod, BN_MONTGOMERY_MAX_WORDS)) { + OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG); + return 0; + } // Save the modulus. if (!BN_copy(&mont->N, mod)) { @@ -428,6 +432,9 @@ int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, if (!bn_wexpand(r, num)) { return 0; } + // This bound is implied by |bn_mont_ctx_set_N_and_n0|. |bn_mul_mont| + // allocates |num| words on the stack, so |num| cannot be too large. + assert((size_t)num <= BN_MONTGOMERY_MAX_WORDS); if (!bn_mul_mont(r->d, a->d, b->d, mont->N.d, mont->n0, num)) { // The check above ensures this won't happen. assert(0); diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/prime.c b/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/prime.c index 0947c02c..6b377eb2 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/prime.c +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/prime.c @@ -362,7 +362,6 @@ static int probable_prime_dh_safe(BIGNUM *rnd, int bits, const BIGNUM *add, BN_GENCB *BN_GENCB_new(void) { BN_GENCB *callback = OPENSSL_malloc(sizeof(BN_GENCB)); if (callback == NULL) { - OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); return NULL; } OPENSSL_memset(callback, 0, sizeof(BN_GENCB)); diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/rsaz_exp.c b/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/rsaz_exp.c index ab379f18..f9c6c4c6 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/rsaz_exp.c +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/rsaz_exp.c @@ -40,8 +40,8 @@ void RSAZ_1024_mod_exp_avx2(BN_ULONG result_norm[16], const BN_ULONG m_norm[16], const BN_ULONG RR[16], BN_ULONG k0, BN_ULONG storage[MOD_EXP_CTIME_STORAGE_LEN]) { - static_assert(MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH % 64 == 0, - "MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH is too small"); + static_assert(MOD_EXP_CTIME_ALIGN % 64 == 0, + "MOD_EXP_CTIME_ALIGN is too small"); assert((uintptr_t)storage % 64 == 0); BN_ULONG *a_inv, *m, *result, *table_s = storage + 40 * 3, *R2 = table_s; diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/rsaz_exp.h b/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/rsaz_exp.h index abe8b351..6ed350ba 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/rsaz_exp.h +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/rsaz_exp.h @@ -32,8 +32,7 @@ extern "C" { // modulo |m_norm|. |base_norm| must be fully-reduced and |exponent| must have // the high bit set (it is 1024 bits wide). |RR| and |k0| must be |RR| and |n0|, // respectively, extracted from |m_norm|'s |BN_MONT_CTX|. |storage_words| is a -// temporary buffer that must be aligned to |MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH| -// bytes. +// temporary buffer that must be aligned to |MOD_EXP_CTIME_ALIGN| bytes. void RSAZ_1024_mod_exp_avx2(BN_ULONG result[16], const BN_ULONG base_norm[16], const BN_ULONG exponent[16], const BN_ULONG m_norm[16], const BN_ULONG RR[16], @@ -79,13 +78,15 @@ void rsaz_1024_sqr_avx2(BN_ULONG ret[40], const BN_ULONG a[40], const BN_ULONG n[40], BN_ULONG k, int count); // rsaz_1024_scatter5_avx2 stores |val| at index |i| of |tbl|. |i| must be -// positive and at most 31. Note the table only uses 18 |BN_ULONG|s per entry -// instead of 40. It packs two 29-bit limbs into each |BN_ULONG| and only stores -// 36 limbs rather than the padded 40. +// positive and at most 31. It is treated as public. Note the table only uses 18 +// |BN_ULONG|s per entry instead of 40. It packs two 29-bit limbs into each +// |BN_ULONG| and only stores 36 limbs rather than the padded 40. void rsaz_1024_scatter5_avx2(BN_ULONG tbl[32 * 18], const BN_ULONG val[40], int i); -// rsaz_1024_gather5_avx2 loads index |i| of |tbl| and writes it to |val|. +// rsaz_1024_gather5_avx2 loads index |i| of |tbl| and writes it to |val|. |i| +// must be positive and at most 31. It is treated as secret. |tbl| must be +// aligned to 32 bytes. void rsaz_1024_gather5_avx2(BN_ULONG val[40], const BN_ULONG tbl[32 * 18], int i); diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/sqrt.c b/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/sqrt.c index b8322d0a..f9ebade2 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/sqrt.c +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/sqrt.c @@ -445,7 +445,6 @@ int BN_sqrt(BIGNUM *out_sqrt, const BIGNUM *in, BN_CTX *ctx) { last_delta = BN_CTX_get(ctx); delta = BN_CTX_get(ctx); if (estimate == NULL || tmp == NULL || last_delta == NULL || delta == NULL) { - OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); goto err; } diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/bsaes-armv7.ios.arm.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/bsaes-armv7-ios.ios.arm.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/bsaes-armv7.ios.arm.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/bsaes-armv7-ios.ios.arm.S index 3d9be856..4375ae3e 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/bsaes-armv7.ios.arm.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/bsaes-armv7-ios.ios.arm.S @@ -10,7 +10,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1535,7 +1535,11 @@ Lctr_enc_bzero:@ wipe key schedule [if any] @ out to retain a constant-time implementation. #endif -#endif // !OPENSSL_NO_ASM +#endif // !OPENSSL_NO_ASM && defined(__ARMEL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif #endif // defined(__arm__) && defined(__APPLE__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/bsaes-armv7.linux.arm.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/bsaes-armv7-linux.linux.arm.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/bsaes-armv7.linux.arm.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/bsaes-armv7-linux.linux.arm.S index 52bef0c2..042d72d3 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/bsaes-armv7.linux.arm.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/bsaes-armv7-linux.linux.arm.S @@ -10,8 +10,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__arm__) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1526,9 +1525,11 @@ bsaes_ctr32_encrypt_blocks: @ out to retain a constant-time implementation. .size bsaes_ctr32_encrypt_blocks,.-bsaes_ctr32_encrypt_blocks #endif +#endif // !OPENSSL_NO_ASM && defined(__ARMEL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM -.section .note.GNU-stack,"",%progbits #endif // defined(__arm__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/cipher/cipher.c b/Sources/CNIOBoringSSL/crypto/fipsmodule/cipher/cipher.c index 0cc61781..644bee66 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/cipher/cipher.c +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/cipher/cipher.c @@ -116,7 +116,6 @@ int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in) { out->cipher_data = OPENSSL_malloc(in->cipher->ctx_size); if (!out->cipher_data) { out->cipher = NULL; - OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE); return 0; } OPENSSL_memcpy(out->cipher_data, in->cipher_data, in->cipher->ctx_size); @@ -165,7 +164,6 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ctx->cipher_data = OPENSSL_malloc(ctx->cipher->ctx_size); if (!ctx->cipher_data) { ctx->cipher = NULL; - OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE); return 0; } } else { diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/cipher/e_aes.c b/Sources/CNIOBoringSSL/crypto/fipsmodule/cipher/e_aes.c index 03c11e21..6709d074 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/cipher/e_aes.c +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/cipher/e_aes.c @@ -529,11 +529,10 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) { if (gctx->iv == c->iv) { gctx_out->iv = out->iv; } else { - gctx_out->iv = OPENSSL_malloc(gctx->ivlen); + gctx_out->iv = OPENSSL_memdup(gctx->iv, gctx->ivlen); if (!gctx_out->iv) { return 0; } - OPENSSL_memcpy(gctx_out->iv, gctx->iv, gctx->ivlen); } return 1; } @@ -1469,8 +1468,6 @@ int EVP_has_aes_hardware(void) { return hwaes_capable() && crypto_gcm_clmul_enabled(); #elif defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64) return hwaes_capable() && CRYPTO_is_ARMv8_PMULL_capable(); -#elif defined(OPENSSL_PPC64LE) - return CRYPTO_is_PPC64LE_vcrypto_capable(); #else return 0; #endif diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/co-586.linux.x86.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/co-586-linux.linux.x86.S similarity index 97% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/co-586.linux.x86.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/co-586-linux.linux.x86.S index 5bfa33ab..c95fc5ee 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/co-586.linux.x86.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/co-586-linux.linux.x86.S @@ -3,7 +3,13 @@ // This file is generated from a similarly-named Perl script in the BoringSSL // source tree. Do not edit by hand. -#if defined(__i386__) +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1264,8 +1270,11 @@ bn_sqr_comba4: popl %esi ret .size bn_sqr_comba4,.-.L_bn_sqr_comba4_begin +#endif // !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -.section .note.GNU-stack,"",@progbits #endif // defined(__i386__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/dh/dh.c b/Sources/CNIOBoringSSL/crypto/fipsmodule/dh/dh.c index e08fa2c3..0aea3856 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/dh/dh.c +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/dh/dh.c @@ -75,7 +75,6 @@ DH *DH_new(void) { DH *dh = OPENSSL_malloc(sizeof(DH)); if (dh == NULL) { - OPENSSL_PUT_ERROR(DH, ERR_R_MALLOC_FAILURE); return NULL; } diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/digest/digest.c b/Sources/CNIOBoringSSL/crypto/fipsmodule/digest/digest.c index 70104172..14a118c4 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/digest/digest.c +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/digest/digest.c @@ -144,7 +144,6 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) { if (in->pctx) { pctx = in->pctx_ops->dup(in->pctx); if (!pctx) { - OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE); return 0; } } @@ -158,7 +157,6 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) { if (pctx) { in->pctx_ops->free(pctx); } - OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE); return 0; } } else { @@ -207,7 +205,6 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *engine) { assert(type->ctx_size != 0); uint8_t *md_data = OPENSSL_malloc(type->ctx_size); if (md_data == NULL) { - OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE); return 0; } diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/ec.c b/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/ec.c index 07be46d2..d0f9dc08 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/ec.c +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/ec.c @@ -285,7 +285,6 @@ EC_GROUP *ec_group_new(const EC_METHOD *meth) { ret = OPENSSL_malloc(sizeof(EC_GROUP)); if (ret == NULL) { - OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); return NULL; } OPENSSL_memset(ret, 0, sizeof(EC_GROUP)); @@ -447,7 +446,6 @@ static EC_GROUP *ec_group_new_from_data(const struct built_in_curve *curve) { BN_CTX *ctx = BN_CTX_new(); if (ctx == NULL) { - OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); goto err; } @@ -686,7 +684,6 @@ EC_POINT *EC_POINT_new(const EC_GROUP *group) { EC_POINT *ret = OPENSSL_malloc(sizeof *ret); if (ret == NULL) { - OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); return NULL; } @@ -1195,7 +1192,7 @@ int ec_get_x_coordinate_as_scalar(const EC_GROUP *group, EC_SCALAR *out, // Additionally, one can manually check this property for built-in curves. It // is enforced for legacy custom curves in |EC_GROUP_set_generator|. const BIGNUM *order = &group->order; - BN_ULONG words[EC_MAX_WORDS + 1]; + BN_ULONG words[EC_MAX_WORDS + 1] = {0}; bn_big_endian_to_words(words, order->width + 1, bytes, len); bn_reduce_once(out->words, words, /*carry=*/words[order->width], order->d, order->width); diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/ec_key.c b/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/ec_key.c index 57c150ea..87db728a 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/ec_key.c +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/ec_key.c @@ -88,7 +88,6 @@ DEFINE_STATIC_EX_DATA_CLASS(g_ec_ex_data_class) static EC_WRAPPED_SCALAR *ec_wrapped_scalar_new(const EC_GROUP *group) { EC_WRAPPED_SCALAR *wrapped = OPENSSL_malloc(sizeof(EC_WRAPPED_SCALAR)); if (wrapped == NULL) { - OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); return NULL; } @@ -109,7 +108,6 @@ EC_KEY *EC_KEY_new(void) { return EC_KEY_new_method(NULL); } EC_KEY *EC_KEY_new_method(const ENGINE *engine) { EC_KEY *ret = OPENSSL_malloc(sizeof(EC_KEY)); if (ret == NULL) { - OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); return NULL; } @@ -142,7 +140,6 @@ EC_KEY *EC_KEY_new_method(const ENGINE *engine) { EC_KEY *EC_KEY_new_by_curve_name(int nid) { EC_KEY *ret = EC_KEY_new(); if (ret == NULL) { - OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); return NULL; } ret->group = EC_GROUP_new_by_curve_name(nid); @@ -247,8 +244,9 @@ int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key) { if (scalar == NULL) { return 0; } - if (!ec_bignum_to_scalar(key->group, &scalar->scalar, priv_key)) { - OPENSSL_PUT_ERROR(EC, EC_R_WRONG_ORDER); + if (!ec_bignum_to_scalar(key->group, &scalar->scalar, priv_key) || + ec_scalar_is_zero(key->group, &scalar->scalar)) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_PRIVATE_KEY); ec_wrapped_scalar_free(scalar); return 0; } @@ -394,14 +392,73 @@ int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, const BIGNUM *x, return ok; } +int EC_KEY_oct2key(EC_KEY *key, const uint8_t *in, size_t len, BN_CTX *ctx) { + if (key->group == NULL) { + OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PARAMETERS); + return 0; + } + + EC_POINT *point = EC_POINT_new(key->group); + int ok = point != NULL && + EC_POINT_oct2point(key->group, point, in, len, ctx) && + EC_KEY_set_public_key(key, point); + EC_POINT_free(point); + return ok; +} + size_t EC_KEY_key2buf(const EC_KEY *key, point_conversion_form_t form, - unsigned char **out_buf, BN_CTX *ctx) { + uint8_t **out_buf, BN_CTX *ctx) { if (key == NULL || key->pub_key == NULL || key->group == NULL) { + OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PARAMETERS); + return 0; + } + + return EC_POINT_point2buf(key->group, key->pub_key, form, out_buf, ctx); +} + +int EC_KEY_oct2priv(EC_KEY *key, const uint8_t *in, size_t len) { + if (key->group == NULL) { + OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PARAMETERS); + return 0; + } + + if (len != BN_num_bytes(EC_GROUP_get0_order(key->group))) { + OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR); + return 0; + } + + BIGNUM *priv_key = BN_bin2bn(in, len, NULL); + int ok = priv_key != NULL && // + EC_KEY_set_private_key(key, priv_key); + BN_free(priv_key); + return ok; +} + +size_t EC_KEY_priv2oct(const EC_KEY *key, uint8_t *out, size_t max_out) { + if (key->group == NULL || key->priv_key == NULL) { + OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PARAMETERS); return 0; } - const size_t len = - EC_POINT_point2oct(key->group, key->pub_key, form, NULL, 0, ctx); + size_t len = BN_num_bytes(EC_GROUP_get0_order(key->group)); + if (out == NULL) { + return len; + } + + if (max_out < len) { + OPENSSL_PUT_ERROR(EC, EC_R_BUFFER_TOO_SMALL); + return 0; + } + + size_t bytes_written; + ec_scalar_to_bytes(key->group, out, &bytes_written, &key->priv_key->scalar); + assert(bytes_written == len); + return len; +} + +size_t EC_KEY_priv2buf(const EC_KEY *key, uint8_t **out_buf) { + *out_buf = NULL; + size_t len = EC_KEY_priv2oct(key, NULL, 0); if (len == 0) { return 0; } @@ -411,8 +468,8 @@ size_t EC_KEY_key2buf(const EC_KEY *key, point_conversion_form_t form, return 0; } - if (EC_POINT_point2oct(key->group, key->pub_key, form, buf, len, ctx) != - len) { + len = EC_KEY_priv2oct(key, buf, len); + if (len == 0) { OPENSSL_free(buf); return 0; } diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/ec_montgomery.c b/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/ec_montgomery.c index a0b2e944..aacc4855 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/ec_montgomery.c +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/ec_montgomery.c @@ -156,8 +156,8 @@ int ec_GFp_mont_felem_from_bytes(const EC_GROUP *group, EC_FELEM *out, return 1; } -static void ec_GFp_mont_felem_reduce(const EC_GROUP *group, EC_FELEM *out, - const BN_ULONG *words, size_t num) { +void ec_GFp_mont_felem_reduce(const EC_GROUP *group, EC_FELEM *out, + const BN_ULONG *words, size_t num) { // Convert "from" Montgomery form so the value is reduced mod p. bn_from_montgomery_small(out->words, group->field.width, words, num, group->mont); @@ -167,9 +167,9 @@ static void ec_GFp_mont_felem_reduce(const EC_GROUP *group, EC_FELEM *out, ec_GFp_mont_felem_to_montgomery(group, out, out); } -static void ec_GFp_mont_felem_exp(const EC_GROUP *group, EC_FELEM *out, - const EC_FELEM *a, const BN_ULONG *exp, - size_t num_exp) { +void ec_GFp_mont_felem_exp(const EC_GROUP *group, EC_FELEM *out, + const EC_FELEM *a, const BN_ULONG *exp, + size_t num_exp) { bn_mod_exp_mont_small(out->words, a->words, group->field.width, exp, num_exp, group->mont); } diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/internal.h b/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/internal.h index 3062909b..92f13142 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/internal.h +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/internal.h @@ -439,11 +439,18 @@ int ec_get_x_coordinate_as_bytes(const EC_GROUP *group, uint8_t *out, size_t *out_len, size_t max_out, const EC_RAW_POINT *p); -// ec_point_to_bytes behaves like |EC_POINT_point2oct| but takes an -// |EC_AFFINE|. +// ec_point_byte_len returns the number of bytes in the byte representation of +// a non-infinity point in |group|, encoded according to |form|, or zero if +// |form| is invalid. +size_t ec_point_byte_len(const EC_GROUP *group, point_conversion_form_t form); + +// ec_point_to_bytes encodes |point| according to |form| and writes the result +// |buf|. It returns the size of the output on success or zero on error. At most +// |max_out| bytes will be written. The buffer should be at least +// |ec_point_byte_len| long to guarantee success. size_t ec_point_to_bytes(const EC_GROUP *group, const EC_AFFINE *point, point_conversion_form_t form, uint8_t *buf, - size_t len); + size_t max_out); // ec_point_from_uncompressed parses |in| as a point in uncompressed form and // sets the result to |out|. It returns one on success and zero if the input was @@ -553,6 +560,12 @@ struct ec_method_st { // // This function is used in hash-to-curve and may be NULL in curves not used // with hash-to-curve. + // + // TODO(https://crbug.com/boringssl/567): hash-to-curve uses this as part of + // computing a square root, which is what compressed coordinates ultimately + // needs to avoid |BIGNUM|. Can we unify this a bit? By generalizing to + // arbitrary exponentiation, we also miss an opportunity to use a specialized + // addition chain. void (*felem_exp)(const EC_GROUP *group, EC_FELEM *out, const EC_FELEM *a, const BN_ULONG *exp, size_t num_exp); @@ -643,6 +656,11 @@ void ec_GFp_mont_mul_precomp(const EC_GROUP *group, EC_RAW_POINT *r, const EC_PRECOMP *p0, const EC_SCALAR *scalar0, const EC_PRECOMP *p1, const EC_SCALAR *scalar1, const EC_PRECOMP *p2, const EC_SCALAR *scalar2); +void ec_GFp_mont_felem_reduce(const EC_GROUP *group, EC_FELEM *out, + const BN_ULONG *words, size_t num); +void ec_GFp_mont_felem_exp(const EC_GROUP *group, EC_FELEM *out, + const EC_FELEM *a, const BN_ULONG *exp, + size_t num_exp); // ec_compute_wNAF writes the modified width-(w+1) Non-Adjacent Form (wNAF) of // |scalar| to |out|. |out| must have room for |bits| + 1 elements, each of diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/oct.c b/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/oct.c index 1f8dd202..1ae005c5 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/oct.c +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/oct.c @@ -73,9 +73,7 @@ #include "internal.h" -size_t ec_point_to_bytes(const EC_GROUP *group, const EC_AFFINE *point, - point_conversion_form_t form, uint8_t *buf, - size_t len) { +size_t ec_point_byte_len(const EC_GROUP *group, point_conversion_form_t form) { if (form != POINT_CONVERSION_COMPRESSED && form != POINT_CONVERSION_UNCOMPRESSED) { OPENSSL_PUT_ERROR(EC, EC_R_INVALID_FORM); @@ -88,27 +86,30 @@ size_t ec_point_to_bytes(const EC_GROUP *group, const EC_AFFINE *point, // Uncompressed points have a second coordinate. output_len += field_len; } + return output_len; +} - // if 'buf' is NULL, just return required length - if (buf != NULL) { - if (len < output_len) { - OPENSSL_PUT_ERROR(EC, EC_R_BUFFER_TOO_SMALL); - return 0; - } +size_t ec_point_to_bytes(const EC_GROUP *group, const EC_AFFINE *point, + point_conversion_form_t form, uint8_t *buf, + size_t max_out) { + size_t output_len = ec_point_byte_len(group, form); + if (max_out < output_len) { + OPENSSL_PUT_ERROR(EC, EC_R_BUFFER_TOO_SMALL); + return 0; + } - size_t field_len_out; - ec_felem_to_bytes(group, buf + 1, &field_len_out, &point->X); - assert(field_len_out == field_len); + size_t field_len; + ec_felem_to_bytes(group, buf + 1, &field_len, &point->X); + assert(field_len == BN_num_bytes(&group->field)); - if (form == POINT_CONVERSION_UNCOMPRESSED) { - ec_felem_to_bytes(group, buf + 1 + field_len, &field_len_out, &point->Y); - assert(field_len_out == field_len); - buf[0] = form; - } else { - uint8_t y_buf[EC_MAX_BYTES]; - ec_felem_to_bytes(group, y_buf, &field_len_out, &point->Y); - buf[0] = form + (y_buf[field_len_out - 1] & 1); - } + if (form == POINT_CONVERSION_UNCOMPRESSED) { + ec_felem_to_bytes(group, buf + 1 + field_len, &field_len, &point->Y); + assert(field_len == BN_num_bytes(&group->field)); + buf[0] = form; + } else { + uint8_t y_buf[EC_MAX_BYTES]; + ec_felem_to_bytes(group, y_buf, &field_len, &point->Y); + buf[0] = form + (y_buf[field_len - 1] & 1); } return output_len; @@ -209,16 +210,46 @@ int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point, size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form, uint8_t *buf, - size_t len, BN_CTX *ctx) { + size_t max_out, BN_CTX *ctx) { if (EC_GROUP_cmp(group, point->group, NULL) != 0) { OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); return 0; } + if (buf == NULL) { + // When |buf| is NULL, just return the number of bytes that would be + // written, without doing an expensive Jacobian-to-affine conversion. + if (ec_GFp_simple_is_at_infinity(group, &point->raw)) { + OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY); + return 0; + } + return ec_point_byte_len(group, form); + } EC_AFFINE affine; if (!ec_jacobian_to_affine(group, &affine, &point->raw)) { return 0; } - return ec_point_to_bytes(group, &affine, form, buf, len); + return ec_point_to_bytes(group, &affine, form, buf, max_out); +} + +size_t EC_POINT_point2buf(const EC_GROUP *group, const EC_POINT *point, + point_conversion_form_t form, uint8_t **out_buf, + BN_CTX *ctx) { + *out_buf = NULL; + size_t len = EC_POINT_point2oct(group, point, form, NULL, 0, ctx); + if (len == 0) { + return 0; + } + uint8_t *buf = OPENSSL_malloc(len); + if (buf == NULL) { + return 0; + } + len = EC_POINT_point2oct(group, point, form, buf, len, ctx); + if (len == 0) { + OPENSSL_free(buf); + return 0; + } + *out_buf = buf; + return len; } int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, @@ -289,8 +320,7 @@ int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, } if (!BN_mod_sqrt(y, tmp1, &group->field, ctx)) { - unsigned long err = ERR_peek_last_error(); - + uint32_t err = ERR_peek_last_error(); if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE) { ERR_clear_error(); diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/p256-nistz.c b/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/p256-nistz.c index 657df8cd..47a6e154 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/p256-nistz.c +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/p256-nistz.c @@ -625,6 +625,10 @@ DEFINE_METHOD_FUNCTION(EC_METHOD, EC_GFp_nistz256_method) { out->felem_sqr = ec_GFp_mont_felem_sqr; out->felem_to_bytes = ec_GFp_mont_felem_to_bytes; out->felem_from_bytes = ec_GFp_mont_felem_from_bytes; + out->felem_reduce = ec_GFp_mont_felem_reduce; + // TODO(davidben): This should use the specialized field arithmetic + // implementation, rather than the generic one. + out->felem_exp = ec_GFp_mont_felem_exp; out->scalar_inv0_montgomery = ecp_nistz256_inv0_mod_ord; out->scalar_to_montgomery_inv_vartime = ecp_nistz256_scalar_to_montgomery_inv_vartime; diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/p256.c b/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/p256.c index b75181b1..3433cffe 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/p256.c +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/p256.c @@ -30,10 +30,6 @@ #include "../delocate.h" #include "./internal.h" -#if defined(OPENSSL_NO_ASM) -#define FIAT_P256_NO_ASM -#endif - #if defined(BORINGSSL_HAS_UINT128) #define BORINGSSL_NISTP256_64BIT 1 #include "../../../third_party/fiat/p256_64.h" @@ -743,6 +739,10 @@ DEFINE_METHOD_FUNCTION(EC_METHOD, EC_GFp_nistp256_method) { out->felem_sqr = ec_GFp_mont_felem_sqr; out->felem_to_bytes = ec_GFp_mont_felem_to_bytes; out->felem_from_bytes = ec_GFp_mont_felem_from_bytes; + out->felem_reduce = ec_GFp_mont_felem_reduce; + // TODO(davidben): This should use the specialized field arithmetic + // implementation, rather than the generic one. + out->felem_exp = ec_GFp_mont_felem_exp; out->scalar_inv0_montgomery = ec_simple_scalar_inv0_montgomery; out->scalar_to_montgomery_inv_vartime = ec_simple_scalar_to_montgomery_inv_vartime; diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/wnaf.c b/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/wnaf.c index ebabc3d1..53256e36 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/wnaf.c +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/wnaf.c @@ -205,7 +205,6 @@ int ec_GFp_mont_mul_public_batch(const EC_GROUP *group, EC_RAW_POINT *r, wNAF_alloc = OPENSSL_malloc(num * sizeof(wNAF_alloc[0])); precomp_alloc = OPENSSL_malloc(num * sizeof(precomp_alloc[0])); if (wNAF_alloc == NULL || precomp_alloc == NULL) { - OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); goto err; } wNAF = wNAF_alloc; diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/ecdsa/ecdsa.c b/Sources/CNIOBoringSSL/crypto/fipsmodule/ecdsa/ecdsa.c index 5aedb63c..c29891ae 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/ecdsa/ecdsa.c +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/ecdsa/ecdsa.c @@ -333,7 +333,13 @@ ECDSA_SIG *ECDSA_do_sign(const uint8_t *digest, size_t digest_len, SHA512_Update(&sha, digest, digest_len); SHA512_Final(additional_data, &sha); + // Cap iterations so callers who supply invalid values as custom groups do not + // infinite loop. This does not impact valid parameters (e.g. those covered by + // FIPS) because the probability of requiring even one retry is negligible, + // let alone 32. + static const int kMaxIterations = 32; ECDSA_SIG *ret = NULL; + int iters = 0; for (;;) { EC_SCALAR k; if (!ec_random_nonzero_scalar(group, &k, additional_data)) { @@ -346,6 +352,12 @@ ECDSA_SIG *ECDSA_do_sign(const uint8_t *digest, size_t digest_len, if (ret != NULL || !retry) { goto out; } + + iters++; + if (iters > kMaxIterations) { + OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_TOO_MANY_ITERATIONS); + goto out; + } } out: diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-armv4.ios.arm.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-armv4-ios.ios.arm.S similarity index 96% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-armv4.ios.arm.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-armv4-ios.ios.arm.S index 6d9f1b64..53dbe2b6 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-armv4.ios.arm.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-armv4-ios.ios.arm.S @@ -10,7 +10,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -257,7 +257,11 @@ Lgmult_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 // !OPENSSL_NO_ASM +#endif // !OPENSSL_NO_ASM && defined(__ARMEL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif #endif // defined(__arm__) && defined(__APPLE__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-armv4.linux.arm.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-armv4-linux.linux.arm.S similarity index 96% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-armv4.linux.arm.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-armv4-linux.linux.arm.S index 3b495ce2..b0707fa0 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-armv4.linux.arm.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-armv4-linux.linux.arm.S @@ -10,8 +10,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__arm__) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -252,9 +251,11 @@ 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 // !OPENSSL_NO_ASM && defined(__ARMEL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM -.section .note.GNU-stack,"",%progbits #endif // defined(__arm__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-neon-armv8.ios.aarch64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-neon-armv8-ios.ios.aarch64.S similarity index 97% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-neon-armv8.ios.aarch64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-neon-armv8-ios.ios.aarch64.S index cd3c17e1..0f28cd7c 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-neon-armv8.ios.aarch64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-neon-armv8-ios.ios.aarch64.S @@ -10,7 +10,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -342,7 +342,11 @@ Lmasks: .byte 71,72,65,83,72,32,102,111,114,32,65,82,77,118,56,44,32,100,101,114,105,118,101,100,32,102,114,111,109,32,65,82,77,118,52,32,118,101,114,115,105,111,110,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 // !OPENSSL_NO_ASM +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif #endif // defined(__aarch64__) && defined(__APPLE__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-neon-armv8.linux.aarch64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-neon-armv8-linux.linux.aarch64.S similarity index 97% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-neon-armv8.linux.aarch64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-neon-armv8-linux.linux.aarch64.S index dcba2809..be1899d0 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-neon-armv8.linux.aarch64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-neon-armv8-linux.linux.aarch64.S @@ -10,8 +10,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__aarch64__) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -343,9 +342,11 @@ gcm_ghash_neon: .byte 71,72,65,83,72,32,102,111,114,32,65,82,77,118,56,44,32,100,101,114,105,118,101,100,32,102,114,111,109,32,65,82,77,118,52,32,118,101,114,115,105,111,110,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 // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM -.section .note.GNU-stack,"",%progbits #endif // defined(__aarch64__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-ssse3-x86.linux.x86.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-ssse3-x86-linux.linux.x86.S similarity index 93% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-ssse3-x86.linux.x86.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-ssse3-x86-linux.linux.x86.S index 08324bff..21ad952b 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-ssse3-x86.linux.x86.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-ssse3-x86-linux.linux.x86.S @@ -3,7 +3,13 @@ // This file is generated from a similarly-named Perl script in the BoringSSL // source tree. Do not edit by hand. -#if defined(__i386__) +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -292,8 +298,11 @@ gcm_ghash_ssse3: .align 16 .Llow4_mask: .long 252645135,252645135,252645135,252645135 +#endif // !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -.section .note.GNU-stack,"",@progbits #endif // defined(__i386__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-ssse3-x86_64.linux.x86_64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-ssse3-x86_64-linux.linux.x86_64.S similarity index 96% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-ssse3-x86_64.linux.x86_64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-ssse3-x86_64-linux.linux.x86_64.S index 814d88bf..5c817bcf 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-ssse3-x86_64.linux.x86_64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-ssse3-x86_64-linux.linux.x86_64.S @@ -9,7 +9,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -25,7 +25,7 @@ .align 16 gcm_gmult_ssse3: .cfi_startproc -.Lgmult_seh_begin: + movdqu (%rdi),%xmm0 movdqa .Lreverse_bytes(%rip),%xmm10 movdqa .Llow4_mask(%rip),%xmm2 @@ -201,8 +201,8 @@ gcm_gmult_ssse3: pxor %xmm5,%xmm5 pxor %xmm6,%xmm6 .byte 0xf3,0xc3 -.Lgmult_seh_end: .cfi_endproc + .size gcm_gmult_ssse3,.-gcm_gmult_ssse3 @@ -214,8 +214,8 @@ gcm_gmult_ssse3: .hidden gcm_ghash_ssse3 .align 16 gcm_ghash_ssse3: -.Lghash_seh_begin: .cfi_startproc + movdqu (%rdi),%xmm0 movdqa .Lreverse_bytes(%rip),%xmm10 movdqa .Llow4_mask(%rip),%xmm11 @@ -413,10 +413,11 @@ gcm_ghash_ssse3: pxor %xmm5,%xmm5 pxor %xmm6,%xmm6 .byte 0xf3,0xc3 -.Lghash_seh_end: .cfi_endproc + .size gcm_ghash_ssse3,.-gcm_ghash_ssse3 +.section .rodata .align 16 @@ -425,8 +426,12 @@ gcm_ghash_ssse3: .Llow4_mask: .quad 0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f +.text +#endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -.section .note.GNU-stack,"",@progbits #endif // defined(__x86_64__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-ssse3-x86_64.mac.x86_64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-ssse3-x86_64-mac.mac.x86_64.S similarity index 96% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-ssse3-x86_64.mac.x86_64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-ssse3-x86_64-mac.mac.x86_64.S index da8a4ef4..3ed2119c 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-ssse3-x86_64.mac.x86_64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-ssse3-x86_64-mac.mac.x86_64.S @@ -9,7 +9,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -25,7 +25,7 @@ .p2align 4 _gcm_gmult_ssse3: -L$gmult_seh_begin: + movdqu (%rdi),%xmm0 movdqa L$reverse_bytes(%rip),%xmm10 movdqa L$low4_mask(%rip),%xmm2 @@ -201,7 +201,7 @@ L$oop_row_3: pxor %xmm5,%xmm5 pxor %xmm6,%xmm6 .byte 0xf3,0xc3 -L$gmult_seh_end: + @@ -214,7 +214,7 @@ L$gmult_seh_end: .private_extern _gcm_ghash_ssse3 .p2align 4 _gcm_ghash_ssse3: -L$ghash_seh_begin: + movdqu (%rdi),%xmm0 movdqa L$reverse_bytes(%rip),%xmm10 @@ -413,10 +413,11 @@ L$oop_row_6: pxor %xmm5,%xmm5 pxor %xmm6,%xmm6 .byte 0xf3,0xc3 -L$ghash_seh_end: + +.section __DATA,__const .p2align 4 @@ -425,6 +426,11 @@ L$reverse_bytes: L$low4_mask: .quad 0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f +.text +#endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif #endif // defined(__x86_64__) && defined(__APPLE__) #if defined(__linux__) && defined(__ELF__) diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-x86.linux.x86.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-x86-linux.linux.x86.S similarity index 94% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-x86.linux.x86.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-x86-linux.linux.x86.S index 859e740b..b7129414 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-x86.linux.x86.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-x86-linux.linux.x86.S @@ -3,7 +3,13 @@ // This file is generated from a similarly-named Perl script in the BoringSSL // source tree. Do not edit by hand. -#if defined(__i386__) +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -328,8 +334,11 @@ gcm_ghash_clmul: .byte 82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112 .byte 112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62 .byte 0 +#endif // !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -.section .note.GNU-stack,"",@progbits #endif // defined(__i386__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-x86_64.linux.x86_64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-x86_64-linux.linux.x86_64.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-x86_64.linux.x86_64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-x86_64-linux.linux.x86_64.S index eca324c1..92a74788 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-x86_64.linux.x86_64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-x86_64-linux.linux.x86_64.S @@ -9,7 +9,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -22,6 +22,7 @@ .align 16 gcm_init_clmul: .cfi_startproc + .L_init_clmul: movdqu (%rsi),%xmm2 pshufd $78,%xmm2,%xmm2 @@ -174,6 +175,7 @@ gcm_init_clmul: movdqu %xmm4,80(%rdi) .byte 0xf3,0xc3 .cfi_endproc + .size gcm_init_clmul,.-gcm_init_clmul .globl gcm_gmult_clmul .hidden gcm_gmult_clmul @@ -235,6 +237,7 @@ gcm_gmult_clmul: .align 32 gcm_ghash_clmul: .cfi_startproc + .L_ghash_clmul: movdqa .Lbswap_mask(%rip),%xmm10 @@ -615,6 +618,7 @@ gcm_ghash_clmul: movdqu %xmm0,(%rdi) .byte 0xf3,0xc3 .cfi_endproc + .size gcm_ghash_clmul,.-gcm_ghash_clmul .globl gcm_init_avx .hidden gcm_init_avx @@ -724,6 +728,7 @@ gcm_init_avx: vzeroupper .byte 0xf3,0xc3 + .cfi_endproc .size gcm_init_avx,.-gcm_init_avx .globl gcm_gmult_avx @@ -1113,7 +1118,9 @@ gcm_ghash_avx: vzeroupper .byte 0xf3,0xc3 .cfi_endproc + .size gcm_ghash_avx,.-gcm_ghash_avx +.section .rodata .align 64 .Lbswap_mask: .byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 @@ -1125,8 +1132,12 @@ gcm_ghash_avx: .byte 71,72,65,83,72,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .align 64 +.text +#endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -.section .note.GNU-stack,"",@progbits #endif // defined(__x86_64__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-x86_64.mac.x86_64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-x86_64-mac.mac.x86_64.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-x86_64.mac.x86_64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-x86_64-mac.mac.x86_64.S index ccbc7f3c..c375fa18 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-x86_64.mac.x86_64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-x86_64-mac.mac.x86_64.S @@ -9,7 +9,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -21,6 +21,7 @@ .p2align 4 _gcm_init_clmul: + L$_init_clmul: movdqu (%rsi),%xmm2 pshufd $78,%xmm2,%xmm2 @@ -174,6 +175,7 @@ L$_init_clmul: .byte 0xf3,0xc3 + .globl _gcm_gmult_clmul .private_extern _gcm_gmult_clmul @@ -234,6 +236,7 @@ L$_gmult_clmul: .p2align 5 _gcm_ghash_clmul: + L$_ghash_clmul: movdqa L$bswap_mask(%rip),%xmm10 @@ -615,6 +618,7 @@ L$done: .byte 0xf3,0xc3 + .globl _gcm_init_avx .private_extern _gcm_init_avx @@ -725,6 +729,7 @@ L$init_start_avx: .byte 0xf3,0xc3 + .globl _gcm_gmult_avx .private_extern _gcm_gmult_avx @@ -1113,6 +1118,8 @@ L$tail_no_xor_avx: .byte 0xf3,0xc3 + +.section __DATA,__const .p2align 6 L$bswap_mask: .byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 @@ -1124,6 +1131,11 @@ L$7_mask: .byte 71,72,65,83,72,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .p2align 6 +.text +#endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif #endif // defined(__x86_64__) && defined(__APPLE__) #if defined(__linux__) && defined(__ELF__) diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/ghashv8-armx32.ios.arm.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/ghashv8-armv7-ios.ios.arm.S similarity index 96% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/ghashv8-armx32.ios.arm.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/ghashv8-armv7-ios.ios.arm.S index c12cdb20..37a69270 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/ghashv8-armx32.ios.arm.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/ghashv8-armv7-ios.ios.arm.S @@ -10,7 +10,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -259,7 +259,11 @@ Ldone_v8: .align 2 .align 2 #endif -#endif // !OPENSSL_NO_ASM +#endif // !OPENSSL_NO_ASM && defined(__ARMEL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif #endif // defined(__arm__) && defined(__APPLE__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/ghashv8-armx32.linux.arm.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/ghashv8-armv7-linux.linux.arm.S similarity index 96% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/ghashv8-armx32.linux.arm.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/ghashv8-armv7-linux.linux.arm.S index 19f868ec..4768765c 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/ghashv8-armx32.linux.arm.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/ghashv8-armv7-linux.linux.arm.S @@ -10,8 +10,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__arm__) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -254,9 +253,11 @@ gcm_ghash_v8: .align 2 .align 2 #endif +#endif // !OPENSSL_NO_ASM && defined(__ARMEL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM -.section .note.GNU-stack,"",%progbits #endif // defined(__arm__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/ghashv8-armx64.ios.aarch64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/ghashv8-armv8-ios.ios.aarch64.S similarity index 98% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/ghashv8-armx64.ios.aarch64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/ghashv8-armv8-ios.ios.aarch64.S index bc33a2c9..c05bd15a 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/ghashv8-armx64.ios.aarch64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/ghashv8-armv8-ios.ios.aarch64.S @@ -10,7 +10,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -572,7 +572,11 @@ Ldone4x: .align 2 .align 2 #endif -#endif // !OPENSSL_NO_ASM +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif #endif // defined(__aarch64__) && defined(__APPLE__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/ghashv8-armx64.linux.aarch64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/ghashv8-armv8-linux.linux.aarch64.S similarity index 98% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/ghashv8-armx64.linux.aarch64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/ghashv8-armv8-linux.linux.aarch64.S index 8a2e1f20..0a03b37a 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/ghashv8-armx64.linux.aarch64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/ghashv8-armv8-linux.linux.aarch64.S @@ -10,8 +10,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__aarch64__) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -573,9 +572,11 @@ gcm_ghash_v8_4x: .align 2 .align 2 #endif +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM -.section .note.GNU-stack,"",%progbits #endif // defined(__aarch64__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/hmac/hmac.c b/Sources/CNIOBoringSSL/crypto/fipsmodule/hmac/hmac.c index 77f62adc..3730c997 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/hmac/hmac.c +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/hmac/hmac.c @@ -151,6 +151,7 @@ int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, size_t key_len, size_t block_size = EVP_MD_block_size(md); assert(block_size <= sizeof(key_block)); + assert(EVP_MD_size(md) <= block_size); if (block_size < key_len) { // Long keys are hashed. if (!EVP_DigestInit_ex(&ctx->md_ctx, md, impl) || @@ -164,23 +165,21 @@ 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 != EVP_MAX_MD_BLOCK_SIZE) { - OPENSSL_memset(&key_block[key_block_len], 0, sizeof(key_block) - key_block_len); - } + OPENSSL_memset(key_block + key_block_len, 0, block_size - key_block_len); - for (size_t i = 0; i < EVP_MAX_MD_BLOCK_SIZE; i++) { + for (size_t i = 0; i < block_size; i++) { pad[i] = 0x36 ^ key_block[i]; } if (!EVP_DigestInit_ex(&ctx->i_ctx, md, impl) || - !EVP_DigestUpdate(&ctx->i_ctx, pad, EVP_MD_block_size(md))) { + !EVP_DigestUpdate(&ctx->i_ctx, pad, block_size)) { goto out; } - for (size_t i = 0; i < EVP_MAX_MD_BLOCK_SIZE; i++) { + for (size_t i = 0; i < block_size; i++) { pad[i] = 0x5c ^ key_block[i]; } if (!EVP_DigestInit_ex(&ctx->o_ctx, md, impl) || - !EVP_DigestUpdate(&ctx->o_ctx, pad, EVP_MD_block_size(md))) { + !EVP_DigestUpdate(&ctx->o_ctx, pad, block_size)) { goto out; } diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/md5-586.linux.x86.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/md5-586-linux.linux.x86.S similarity index 96% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/md5-586.linux.x86.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/md5-586-linux.linux.x86.S index 891c31cc..aae8b0d2 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/md5-586.linux.x86.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/md5-586-linux.linux.x86.S @@ -3,7 +3,13 @@ // This file is generated from a similarly-named Perl script in the BoringSSL // source tree. Do not edit by hand. -#if defined(__i386__) +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -686,8 +692,11 @@ md5_block_asm_data_order: popl %esi ret .size md5_block_asm_data_order,.-.L_md5_block_asm_data_order_begin +#endif // !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -.section .note.GNU-stack,"",@progbits #endif // defined(__i386__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/md5-x86_64.linux.x86_64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/md5-x86_64-linux.linux.x86_64.S similarity index 98% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/md5-x86_64.linux.x86_64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/md5-x86_64-linux.linux.x86_64.S index a01dbc81..ccbbc40f 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/md5-x86_64.linux.x86_64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/md5-x86_64-linux.linux.x86_64.S @@ -9,7 +9,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -701,7 +701,10 @@ md5_block_asm_data_order: .cfi_endproc .size md5_block_asm_data_order,.-md5_block_asm_data_order #endif -.section .note.GNU-stack,"",@progbits +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif #endif // defined(__x86_64__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/md5-x86_64.mac.x86_64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/md5-x86_64-mac.mac.x86_64.S similarity index 98% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/md5-x86_64.mac.x86_64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/md5-x86_64-mac.mac.x86_64.S index 03bad95a..69606dd8 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/md5-x86_64.mac.x86_64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/md5-x86_64-mac.mac.x86_64.S @@ -9,7 +9,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -695,6 +695,10 @@ L$epilogue: .byte 0xf3,0xc3 +#endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif #endif // defined(__x86_64__) && defined(__APPLE__) #if defined(__linux__) && defined(__ELF__) diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/modes/gcm.c b/Sources/CNIOBoringSSL/crypto/fipsmodule/modes/gcm.c index 38d0083d..1c965564 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/modes/gcm.c +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/modes/gcm.c @@ -132,6 +132,46 @@ void gcm_init_ssse3(u128 Htable[16], const uint64_t H[2]) { (*gcm_ghash_p)((ctx)->Xi.u, (ctx)->gcm_key.Htable, in, len) #endif // GCM_FUNCREF +#if defined(HW_GCM) && defined(OPENSSL_X86_64) +static size_t hw_gcm_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, uint8_t ivec[16], + uint64_t *Xi) { + return aesni_gcm_encrypt(in, out, len, key, ivec, Xi); +} + +static size_t hw_gcm_decrypt(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, uint8_t ivec[16], + uint64_t *Xi) { + return aesni_gcm_decrypt(in, out, len, key, ivec, Xi); +} +#endif // HW_GCM && X86_64 + +#if defined(HW_GCM) && defined(OPENSSL_AARCH64) + +static size_t hw_gcm_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, uint8_t ivec[16], + uint64_t *Xi) { + const size_t len_blocks = len & kSizeTWithoutLower4Bits; + if (!len_blocks) { + return 0; + } + aes_gcm_enc_kernel(in, len_blocks * 8, out, Xi, ivec, key); + return len_blocks; +} + +static size_t hw_gcm_decrypt(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, uint8_t ivec[16], + uint64_t *Xi) { + const size_t len_blocks = len & kSizeTWithoutLower4Bits; + if (!len_blocks) { + return 0; + } + aes_gcm_dec_kernel(in, len_blocks * 8, out, Xi, ivec, key); + return len_blocks; +} + +#endif // HW_GCM && AARCH64 + void CRYPTO_ghash_init(gmult_func *out_mult, ghash_func *out_hash, u128 *out_key, u128 out_table[16], int *out_is_avx, const uint8_t gcm_key[16]) { @@ -190,13 +230,6 @@ void CRYPTO_ghash_init(gmult_func *out_mult, ghash_func *out_hash, *out_hash = gcm_ghash_neon; return; } -#elif defined(GHASH_ASM_PPC64LE) - if (CRYPTO_is_PPC64LE_vcrypto_capable()) { - gcm_init_p8(out_table, H); - *out_mult = gcm_gmult_p8; - *out_hash = gcm_ghash_p8; - return; - } #endif gcm_init_nohw(out_table, H); @@ -217,7 +250,12 @@ void CRYPTO_gcm128_init_key(GCM128_KEY *gcm_key, const AES_KEY *aes_key, CRYPTO_ghash_init(&gcm_key->gmult, &gcm_key->ghash, &gcm_key->H, gcm_key->Htable, &is_avx, ghash_key); - gcm_key->use_aesni_gcm_crypt = (is_avx && block_is_hwaes) ? 1 : 0; +#if defined(OPENSSL_AARCH64) && !defined(OPENSSL_NO_ASM) + gcm_key->use_hw_gcm_crypt = (gcm_pmull_capable() && block_is_hwaes) ? 1 : + 0; +#else + gcm_key->use_hw_gcm_crypt = (is_avx && block_is_hwaes) ? 1 : 0; +#endif } void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const AES_KEY *key, @@ -544,12 +582,12 @@ int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, const AES_KEY *key, } } -#if defined(AESNI_GCM) +#if defined(HW_GCM) // Check |len| to work around a C language bug. See https://crbug.com/1019588. - if (ctx->gcm_key.use_aesni_gcm_crypt && len > 0) { - // |aesni_gcm_encrypt| may not process all the input given to it. It may + if (ctx->gcm_key.use_hw_gcm_crypt && len > 0) { + // |hw_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); + size_t bulk = hw_gcm_encrypt(in, out, len, key, ctx->Yi.c, ctx->Xi.u); in += bulk; out += bulk; len -= bulk; @@ -632,12 +670,12 @@ int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, const AES_KEY *key, } } -#if defined(AESNI_GCM) +#if defined(HW_GCM) // Check |len| to work around a C language bug. See https://crbug.com/1019588. - if (ctx->gcm_key.use_aesni_gcm_crypt && len > 0) { - // |aesni_gcm_decrypt| may not process all the input given to it. It may + if (ctx->gcm_key.use_hw_gcm_crypt && len > 0) { + // |hw_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); + size_t bulk = hw_gcm_decrypt(in, out, len, key, ctx->Yi.c, ctx->Xi.u); in += bulk; out += bulk; len -= bulk; diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/modes/internal.h b/Sources/CNIOBoringSSL/crypto/fipsmodule/modes/internal.h index 5a081485..6a24a801 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/modes/internal.h +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/modes/internal.h @@ -136,9 +136,9 @@ typedef struct gcm128_key_st { block128_f block; - // use_aesni_gcm_crypt is true if this context should use the assembly - // functions |aesni_gcm_encrypt| and |aesni_gcm_decrypt| to process data. - unsigned use_aesni_gcm_crypt:1; + // use_hw_gcm_crypt is true if this context should use platform-specific + // assembly to process GCM data. + unsigned use_hw_gcm_crypt:1; } GCM128_KEY; // GCM128_CONTEXT contains state for a single GCM operation. The structure @@ -267,7 +267,7 @@ 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 *in, size_t len); -#define AESNI_GCM +#define HW_GCM size_t aesni_gcm_encrypt(const uint8_t *in, uint8_t *out, size_t len, const AES_KEY *key, uint8_t ivec[16], uint64_t *Xi); size_t aesni_gcm_decrypt(const uint8_t *in, uint8_t *out, size_t len, @@ -279,6 +279,7 @@ size_t aesni_gcm_decrypt(const uint8_t *in, uint8_t *out, size_t len, #endif // OPENSSL_X86 #elif defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64) + #define GHASH_ASM_ARM #define GCM_FUNCREF @@ -298,13 +299,15 @@ void gcm_gmult_neon(uint64_t Xi[2], const u128 Htable[16]); void gcm_ghash_neon(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, size_t len); -#elif defined(OPENSSL_PPC64LE) -#define GHASH_ASM_PPC64LE -#define GCM_FUNCREF -void gcm_init_p8(u128 Htable[16], const uint64_t Xi[2]); -void gcm_gmult_p8(uint64_t Xi[2], const u128 Htable[16]); -void gcm_ghash_p8(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, - size_t len); +#if defined(OPENSSL_AARCH64) +#define HW_GCM +// These functions are defined in aesv8-gcm-armv8.pl. +void aes_gcm_enc_kernel(const uint8_t *in, uint64_t in_bits, void *out, + void *Xi, uint8_t *ivec, const AES_KEY *key); +void aes_gcm_dec_kernel(const uint8_t *in, uint64_t in_bits, void *out, + void *Xi, uint8_t *ivec, const AES_KEY *key); +#endif + #endif #endif // OPENSSL_NO_ASM diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/p256-armv8-asm.ios.aarch64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/p256-armv8-asm-ios.ios.aarch64.S similarity index 96% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/p256-armv8-asm.ios.aarch64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/p256-armv8-asm-ios.ios.aarch64.S index 8bd50ec2..e7005f21 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/p256-armv8-asm.ios.aarch64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/p256-armv8-asm-ios.ios.aarch64.S @@ -10,13 +10,13 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif #include "CNIOBoringSSL_arm_arch.h" -.text +.section __TEXT,__const .align 5 Lpoly: .quad 0xffffffffffffffff,0x00000000ffffffff,0x0000000000000000,0xffffffff00000001 @@ -32,6 +32,7 @@ LordK: .quad 0xccd1c8aaee00bc4f .byte 69,67,80,95,78,73,83,84,90,50,53,54,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .align 2 +.text // void ecp_nistz256_mul_mont(BN_ULONG x0[4],const BN_ULONG x1[4], // const BN_ULONG x2[4]); @@ -48,8 +49,10 @@ _ecp_nistz256_mul_mont: ldr x3,[x2] // bp[0] ldp x4,x5,[x1] ldp x6,x7,[x1,#16] - ldr x12,Lpoly+8 - ldr x13,Lpoly+24 + adrp x13,Lpoly@PAGE + add x13,x13,Lpoly@PAGEOFF + ldr x12,[x13,#8] + ldr x13,[x13,#24] bl __ecp_nistz256_mul_mont @@ -72,8 +75,10 @@ _ecp_nistz256_sqr_mont: ldp x4,x5,[x1] ldp x6,x7,[x1,#16] - ldr x12,Lpoly+8 - ldr x13,Lpoly+24 + adrp x13,Lpoly@PAGE + add x13,x13,Lpoly@PAGEOFF + ldr x12,[x13,#8] + ldr x13,[x13,#24] bl __ecp_nistz256_sqr_mont @@ -95,8 +100,10 @@ _ecp_nistz256_div_by_2: ldp x14,x15,[x1] ldp x16,x17,[x1,#16] - ldr x12,Lpoly+8 - ldr x13,Lpoly+24 + adrp x13,Lpoly@PAGE + add x13,x13,Lpoly@PAGEOFF + ldr x12,[x13,#8] + ldr x13,[x13,#24] bl __ecp_nistz256_div_by_2 @@ -117,8 +124,10 @@ _ecp_nistz256_mul_by_2: ldp x14,x15,[x1] ldp x16,x17,[x1,#16] - ldr x12,Lpoly+8 - ldr x13,Lpoly+24 + adrp x13,Lpoly@PAGE + add x13,x13,Lpoly@PAGEOFF + ldr x12,[x13,#8] + ldr x13,[x13,#24] mov x8,x14 mov x9,x15 mov x10,x16 @@ -143,8 +152,10 @@ _ecp_nistz256_mul_by_3: ldp x14,x15,[x1] ldp x16,x17,[x1,#16] - ldr x12,Lpoly+8 - ldr x13,Lpoly+24 + adrp x13,Lpoly@PAGE + add x13,x13,Lpoly@PAGEOFF + ldr x12,[x13,#8] + ldr x13,[x13,#24] mov x8,x14 mov x9,x15 mov x10,x16 @@ -181,8 +192,10 @@ _ecp_nistz256_sub: ldp x14,x15,[x1] ldp x16,x17,[x1,#16] - ldr x12,Lpoly+8 - ldr x13,Lpoly+24 + adrp x13,Lpoly@PAGE + add x13,x13,Lpoly@PAGEOFF + ldr x12,[x13,#8] + ldr x13,[x13,#24] bl __ecp_nistz256_sub_from @@ -206,8 +219,10 @@ _ecp_nistz256_neg: mov x15,xzr mov x16,xzr mov x17,xzr - ldr x12,Lpoly+8 - ldr x13,Lpoly+24 + adrp x13,Lpoly@PAGE + add x13,x13,Lpoly@PAGEOFF + ldr x12,[x13,#8] + ldr x13,[x13,#24] bl __ecp_nistz256_sub_from @@ -603,9 +618,11 @@ Ldouble_shortcut: mov x21,x0 ldp x16,x17,[x1,#48] mov x22,x1 - ldr x12,Lpoly+8 + adrp x13,Lpoly@PAGE + add x13,x13,Lpoly@PAGEOFF + ldr x12,[x13,#8] mov x8,x14 - ldr x13,Lpoly+24 + ldr x13,[x13,#24] mov x9,x15 ldp x4,x5,[x22,#64] // forward load for p256_sqr_mont mov x10,x16 @@ -749,8 +766,10 @@ _ecp_nistz256_point_add: mov x21,x0 mov x22,x1 mov x23,x2 - ldr x12,Lpoly+8 - ldr x13,Lpoly+24 + adrp x13,Lpoly@PAGE + add x13,x13,Lpoly@PAGEOFF + ldr x12,[x13,#8] + ldr x13,[x13,#24] orr x8,x4,x5 orr x10,x6,x7 orr x25,x8,x10 @@ -1001,8 +1020,10 @@ _ecp_nistz256_point_add_affine: mov x21,x0 mov x22,x1 mov x23,x2 - ldr x12,Lpoly+8 - ldr x13,Lpoly+24 + adrp x13,Lpoly@PAGE + add x13,x13,Lpoly@PAGEOFF + ldr x12,[x13,#8] + ldr x13,[x13,#24] ldp x4,x5,[x1,#64] // in1_z ldp x6,x7,[x1,#64+16] @@ -1148,7 +1169,8 @@ _ecp_nistz256_point_add_affine: ldp x10,x11,[x23,#0+48] stp x14,x15,[x21,#0] stp x16,x17,[x21,#0+16] - adr x23,Lone_mont-64 + adrp x23,Lone_mont@PAGE-64 + add x23,x23,Lone_mont@PAGEOFF-64 ldp x14,x15,[x22,#32] // in1 cmp x24,#0 // ~, remember? ldp x16,x17,[x22,#32+16] @@ -1207,7 +1229,8 @@ _ecp_nistz256_ord_mul_mont: stp x21,x22,[sp,#32] stp x23,x24,[sp,#48] - adr x23,Lord + adrp x23,Lord@PAGE + add x23,x23,Lord@PAGEOFF ldr x3,[x2] // bp[0] ldp x4,x5,[x1] ldp x6,x7,[x1,#16] @@ -1404,7 +1427,7 @@ _ecp_nistz256_ord_mul_mont: //////////////////////////////////////////////////////////////////////// // void ecp_nistz256_ord_sqr_mont(uint64_t res[4], uint64_t a[4], -// int rep); +// uint64_t rep); .globl _ecp_nistz256_ord_sqr_mont .private_extern _ecp_nistz256_ord_sqr_mont @@ -1418,7 +1441,8 @@ _ecp_nistz256_ord_sqr_mont: stp x21,x22,[sp,#32] stp x23,x24,[sp,#48] - adr x23,Lord + adrp x23,Lord@PAGE + add x23,x23,Lord@PAGEOFF ldp x4,x5,[x1] ldp x6,x7,[x1,#16] @@ -1709,7 +1733,11 @@ Lselect_w7_loop: ret -#endif // !OPENSSL_NO_ASM +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif #endif // defined(__aarch64__) && defined(__APPLE__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/p256-armv8-asm.linux.aarch64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/p256-armv8-asm-linux.linux.aarch64.S similarity index 96% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/p256-armv8-asm.linux.aarch64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/p256-armv8-asm-linux.linux.aarch64.S index 1cea49f5..84f9e785 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/p256-armv8-asm.linux.aarch64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/p256-armv8-asm-linux.linux.aarch64.S @@ -10,14 +10,13 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__aarch64__) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif #include "CNIOBoringSSL_arm_arch.h" -.text +.section .rodata .align 5 .Lpoly: .quad 0xffffffffffffffff,0x00000000ffffffff,0x0000000000000000,0xffffffff00000001 @@ -33,6 +32,7 @@ .quad 0xccd1c8aaee00bc4f .byte 69,67,80,95,78,73,83,84,90,50,53,54,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .align 2 +.text // void ecp_nistz256_mul_mont(BN_ULONG x0[4],const BN_ULONG x1[4], // const BN_ULONG x2[4]); @@ -49,8 +49,10 @@ ecp_nistz256_mul_mont: ldr x3,[x2] // bp[0] ldp x4,x5,[x1] ldp x6,x7,[x1,#16] - ldr x12,.Lpoly+8 - ldr x13,.Lpoly+24 + adrp x13,.Lpoly + add x13,x13,:lo12:.Lpoly + ldr x12,[x13,#8] + ldr x13,[x13,#24] bl __ecp_nistz256_mul_mont @@ -73,8 +75,10 @@ ecp_nistz256_sqr_mont: ldp x4,x5,[x1] ldp x6,x7,[x1,#16] - ldr x12,.Lpoly+8 - ldr x13,.Lpoly+24 + adrp x13,.Lpoly + add x13,x13,:lo12:.Lpoly + ldr x12,[x13,#8] + ldr x13,[x13,#24] bl __ecp_nistz256_sqr_mont @@ -96,8 +100,10 @@ ecp_nistz256_div_by_2: ldp x14,x15,[x1] ldp x16,x17,[x1,#16] - ldr x12,.Lpoly+8 - ldr x13,.Lpoly+24 + adrp x13,.Lpoly + add x13,x13,:lo12:.Lpoly + ldr x12,[x13,#8] + ldr x13,[x13,#24] bl __ecp_nistz256_div_by_2 @@ -118,8 +124,10 @@ ecp_nistz256_mul_by_2: ldp x14,x15,[x1] ldp x16,x17,[x1,#16] - ldr x12,.Lpoly+8 - ldr x13,.Lpoly+24 + adrp x13,.Lpoly + add x13,x13,:lo12:.Lpoly + ldr x12,[x13,#8] + ldr x13,[x13,#24] mov x8,x14 mov x9,x15 mov x10,x16 @@ -144,8 +152,10 @@ ecp_nistz256_mul_by_3: ldp x14,x15,[x1] ldp x16,x17,[x1,#16] - ldr x12,.Lpoly+8 - ldr x13,.Lpoly+24 + adrp x13,.Lpoly + add x13,x13,:lo12:.Lpoly + ldr x12,[x13,#8] + ldr x13,[x13,#24] mov x8,x14 mov x9,x15 mov x10,x16 @@ -182,8 +192,10 @@ ecp_nistz256_sub: ldp x14,x15,[x1] ldp x16,x17,[x1,#16] - ldr x12,.Lpoly+8 - ldr x13,.Lpoly+24 + adrp x13,.Lpoly + add x13,x13,:lo12:.Lpoly + ldr x12,[x13,#8] + ldr x13,[x13,#24] bl __ecp_nistz256_sub_from @@ -207,8 +219,10 @@ ecp_nistz256_neg: mov x15,xzr mov x16,xzr mov x17,xzr - ldr x12,.Lpoly+8 - ldr x13,.Lpoly+24 + adrp x13,.Lpoly + add x13,x13,:lo12:.Lpoly + ldr x12,[x13,#8] + ldr x13,[x13,#24] bl __ecp_nistz256_sub_from @@ -604,9 +618,11 @@ ecp_nistz256_point_double: mov x21,x0 ldp x16,x17,[x1,#48] mov x22,x1 - ldr x12,.Lpoly+8 + adrp x13,.Lpoly + add x13,x13,:lo12:.Lpoly + ldr x12,[x13,#8] mov x8,x14 - ldr x13,.Lpoly+24 + ldr x13,[x13,#24] mov x9,x15 ldp x4,x5,[x22,#64] // forward load for p256_sqr_mont mov x10,x16 @@ -750,8 +766,10 @@ ecp_nistz256_point_add: mov x21,x0 mov x22,x1 mov x23,x2 - ldr x12,.Lpoly+8 - ldr x13,.Lpoly+24 + adrp x13,.Lpoly + add x13,x13,:lo12:.Lpoly + ldr x12,[x13,#8] + ldr x13,[x13,#24] orr x8,x4,x5 orr x10,x6,x7 orr x25,x8,x10 @@ -1002,8 +1020,10 @@ ecp_nistz256_point_add_affine: mov x21,x0 mov x22,x1 mov x23,x2 - ldr x12,.Lpoly+8 - ldr x13,.Lpoly+24 + adrp x13,.Lpoly + add x13,x13,:lo12:.Lpoly + ldr x12,[x13,#8] + ldr x13,[x13,#24] ldp x4,x5,[x1,#64] // in1_z ldp x6,x7,[x1,#64+16] @@ -1149,7 +1169,8 @@ ecp_nistz256_point_add_affine: ldp x10,x11,[x23,#0+48] stp x14,x15,[x21,#0] stp x16,x17,[x21,#0+16] - adr x23,.Lone_mont-64 + adrp x23,.Lone_mont-64 + add x23,x23,:lo12:.Lone_mont-64 ldp x14,x15,[x22,#32] // in1 cmp x24,#0 // ~, remember? ldp x16,x17,[x22,#32+16] @@ -1208,7 +1229,8 @@ ecp_nistz256_ord_mul_mont: stp x21,x22,[sp,#32] stp x23,x24,[sp,#48] - adr x23,.Lord + adrp x23,.Lord + add x23,x23,:lo12:.Lord ldr x3,[x2] // bp[0] ldp x4,x5,[x1] ldp x6,x7,[x1,#16] @@ -1405,7 +1427,7 @@ ecp_nistz256_ord_mul_mont: //////////////////////////////////////////////////////////////////////// // void ecp_nistz256_ord_sqr_mont(uint64_t res[4], uint64_t a[4], -// int rep); +// uint64_t rep); .globl ecp_nistz256_ord_sqr_mont .hidden ecp_nistz256_ord_sqr_mont .type ecp_nistz256_ord_sqr_mont,%function @@ -1419,7 +1441,8 @@ ecp_nistz256_ord_sqr_mont: stp x21,x22,[sp,#32] stp x23,x24,[sp,#48] - adr x23,.Lord + adrp x23,.Lord + add x23,x23,:lo12:.Lord ldp x4,x5,[x1] ldp x6,x7,[x1,#16] @@ -1710,9 +1733,11 @@ ecp_nistz256_select_w7: ret .size ecp_nistz256_select_w7,.-ecp_nistz256_select_w7 +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM -.section .note.GNU-stack,"",%progbits #endif // defined(__aarch64__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/p256-x86_64-asm.linux.x86_64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/p256-x86_64-asm-linux.linux.x86_64.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/p256-x86_64-asm.linux.x86_64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/p256-x86_64-asm-linux.linux.x86_64.S index d83a8d37..1e47c89a 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/p256-x86_64-asm.linux.x86_64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/p256-x86_64-asm-linux.linux.x86_64.S @@ -9,7 +9,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -18,6 +18,7 @@ .hidden OPENSSL_ia32cap_P +.section .rodata .align 64 .Lpoly: .quad 0xffffffffffffffff, 0x00000000ffffffff, 0x0000000000000000, 0xffffffff00000001 @@ -36,6 +37,7 @@ .quad 0xf3b9cac2fc632551, 0xbce6faada7179e84, 0xffffffffffffffff, 0xffffffff00000000 .LordK: .quad 0xccd1c8aaee00bc4f +.text @@ -4542,7 +4544,10 @@ ecp_nistz256_point_add_affinex: .cfi_endproc .size ecp_nistz256_point_add_affinex,.-ecp_nistz256_point_add_affinex #endif -.section .note.GNU-stack,"",@progbits +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif #endif // defined(__x86_64__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/p256-x86_64-asm.mac.x86_64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/p256-x86_64-asm-mac.mac.x86_64.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/p256-x86_64-asm.mac.x86_64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/p256-x86_64-asm-mac.mac.x86_64.S index 42c6a432..027ffc92 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/p256-x86_64-asm.mac.x86_64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/p256-x86_64-asm-mac.mac.x86_64.S @@ -9,7 +9,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -17,6 +17,7 @@ +.section __DATA,__const .p2align 6 L$poly: .quad 0xffffffffffffffff, 0x00000000ffffffff, 0x0000000000000000, 0xffffffff00000001 @@ -35,6 +36,7 @@ L$ord: .quad 0xf3b9cac2fc632551, 0xbce6faada7179e84, 0xffffffffffffffff, 0xffffffff00000000 L$ordK: .quad 0xccd1c8aaee00bc4f +.text @@ -4466,6 +4468,10 @@ L$add_affinex_epilogue: .byte 0xf3,0xc3 +#endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif #endif // defined(__x86_64__) && defined(__APPLE__) #if defined(__linux__) && defined(__ELF__) diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/p256_beeu-armv8-asm.ios.aarch64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/p256_beeu-armv8-asm-ios.ios.aarch64.S similarity index 96% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/p256_beeu-armv8-asm.ios.aarch64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/p256_beeu-armv8-asm-ios.ios.aarch64.S index f1215166..00699a6a 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/p256_beeu-armv8-asm.ios.aarch64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/p256_beeu-armv8-asm-ios.ios.aarch64.S @@ -10,7 +10,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -316,7 +316,11 @@ Lbeeu_finish: AARCH64_VALIDATE_LINK_REGISTER ret -#endif // !OPENSSL_NO_ASM +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif #endif // defined(__aarch64__) && defined(__APPLE__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/p256_beeu-armv8-asm.linux.aarch64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/p256_beeu-armv8-asm-linux.linux.aarch64.S similarity index 96% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/p256_beeu-armv8-asm.linux.aarch64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/p256_beeu-armv8-asm-linux.linux.aarch64.S index d7eb3c32..2bf88d8f 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/p256_beeu-armv8-asm.linux.aarch64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/p256_beeu-armv8-asm-linux.linux.aarch64.S @@ -10,8 +10,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__aarch64__) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -317,9 +316,11 @@ beeu_mod_inverse_vartime: AARCH64_VALIDATE_LINK_REGISTER ret .size beeu_mod_inverse_vartime,.-beeu_mod_inverse_vartime +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM -.section .note.GNU-stack,"",%progbits #endif // defined(__aarch64__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/p256_beeu-x86_64-asm.linux.x86_64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/p256_beeu-x86_64-asm-linux.linux.x86_64.S similarity index 96% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/p256_beeu-x86_64-asm.linux.x86_64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/p256_beeu-x86_64-asm-linux.linux.x86_64.S index 64579d01..70da97ec 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/p256_beeu-x86_64-asm.linux.x86_64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/p256_beeu-x86_64-asm-linux.linux.x86_64.S @@ -9,7 +9,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -342,7 +342,10 @@ beeu_mod_inverse_vartime: .size beeu_mod_inverse_vartime, .-beeu_mod_inverse_vartime #endif -.section .note.GNU-stack,"",@progbits +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif #endif // defined(__x86_64__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/p256_beeu-x86_64-asm.mac.x86_64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/p256_beeu-x86_64-asm-mac.mac.x86_64.S similarity index 95% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/p256_beeu-x86_64-asm.mac.x86_64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/p256_beeu-x86_64-asm-mac.mac.x86_64.S index 7b2f65ac..9875069e 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/p256_beeu-x86_64-asm.mac.x86_64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/p256_beeu-x86_64-asm-mac.mac.x86_64.S @@ -9,7 +9,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -327,6 +327,10 @@ L$beeu_finish: +#endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif #endif // defined(__x86_64__) && defined(__APPLE__) #if defined(__linux__) && defined(__ELF__) diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/rand/fork_detect.c b/Sources/CNIOBoringSSL/crypto/fipsmodule/rand/fork_detect.c index 18ca0bb1..b23274cd 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/rand/fork_detect.c +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/rand/fork_detect.c @@ -40,10 +40,11 @@ DEFINE_STATIC_ONCE(g_fork_detect_once); DEFINE_STATIC_MUTEX(g_fork_detect_lock); DEFINE_BSS_GET(volatile char *, g_fork_detect_addr); DEFINE_BSS_GET(uint64_t, g_fork_generation); -DEFINE_BSS_GET(int, g_ignore_madv_wipeonfork); +DEFINE_BSS_GET(int, g_force_madv_wipeonfork); +DEFINE_BSS_GET(int, g_force_madv_wipeonfork_enabled); static void init_fork_detect(void) { - if (*g_ignore_madv_wipeonfork_bss_get()) { + if (*g_force_madv_wipeonfork_bss_get()) { return; } @@ -93,7 +94,14 @@ uint64_t CRYPTO_get_fork_generation(void) { // not assume that it has exclusive access to it. volatile char *const flag_ptr = *g_fork_detect_addr_bss_get(); if (flag_ptr == NULL) { - // Our kernel is too old to support |MADV_WIPEONFORK|. + // Our kernel is too old to support |MADV_WIPEONFORK| or + // |g_force_madv_wipeonfork| is set. + if (*g_force_madv_wipeonfork_bss_get() && + *g_force_madv_wipeonfork_enabled_bss_get()) { + // A constant generation number to simulate support, even if the kernel + // doesn't support it. + return 42; + } return 0; } @@ -125,8 +133,9 @@ uint64_t CRYPTO_get_fork_generation(void) { return current_generation; } -void CRYPTO_fork_detect_ignore_madv_wipeonfork_for_testing(void) { - *g_ignore_madv_wipeonfork_bss_get() = 1; +void CRYPTO_fork_detect_force_madv_wipeonfork_for_testing(int on) { + *g_force_madv_wipeonfork_bss_get() = 1; + *g_force_madv_wipeonfork_enabled_bss_get() = on; } #else // !OPENSSL_LINUX diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/rand/fork_detect.h b/Sources/CNIOBoringSSL/crypto/fipsmodule/rand/fork_detect.h index 85368679..468aedfb 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/rand/fork_detect.h +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/rand/fork_detect.h @@ -38,9 +38,10 @@ extern "C" { // should only be used as a hardening measure. OPENSSL_EXPORT uint64_t CRYPTO_get_fork_generation(void); -// CRYPTO_fork_detect_ignore_madv_wipeonfork_for_testing is an internal detail +// CRYPTO_fork_detect_force_madv_wipeonfork_for_testing is an internal detail // used for testing purposes. -OPENSSL_EXPORT void CRYPTO_fork_detect_ignore_madv_wipeonfork_for_testing(void); +OPENSSL_EXPORT void CRYPTO_fork_detect_force_madv_wipeonfork_for_testing( + int on); #if defined(__cplusplus) } // extern C diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/rand/getrandom_fillin.h b/Sources/CNIOBoringSSL/crypto/fipsmodule/rand/getrandom_fillin.h index 272e03b6..3f767152 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/rand/getrandom_fillin.h +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/rand/getrandom_fillin.h @@ -30,8 +30,6 @@ #define EXPECTED_NR_getrandom 278 #elif defined(OPENSSL_ARM) #define EXPECTED_NR_getrandom 384 -#elif defined(OPENSSL_PPC64LE) -#define EXPECTED_NR_getrandom 359 #elif defined(OPENSSL_RISCV64) #define EXPECTED_NR_getrandom 278 #endif diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/rand/rand.c b/Sources/CNIOBoringSSL/crypto/fipsmodule/rand/rand.c index de5270a0..c2053168 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/rand/rand.c +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/rand/rand.c @@ -169,12 +169,6 @@ void CRYPTO_get_seed_entropy(uint8_t *out_entropy, size_t out_entropy_len, } else { CRYPTO_sysrand_for_seed(out_entropy, out_entropy_len); } - - if (boringssl_fips_break_test("CRNG")) { - // This breaks the "continuous random number generator test" defined in FIPS - // 140-2, section 4.9.2, and implemented in |rand_get_seed|. - OPENSSL_memset(out_entropy, 0, out_entropy_len); - } } // In passive entropy mode, entropy is supplied from outside of the module via @@ -416,11 +410,6 @@ void RAND_bytes_with_additional_data(uint8_t *out, size_t out_len, // Take a read lock around accesses to |state->drbg|. This is needed to // avoid returning bad entropy if we race with // |rand_thread_state_clear_all|. - // - // This lock must be taken after any calls to |CRYPTO_sysrand| to avoid a - // bug on ppc64le. glibc may implement pthread locks by wrapping user code - // in a hardware transaction, but, on some older versions of glibc and the - // kernel, syscalls made with |syscall| did not abort the transaction. CRYPTO_STATIC_MUTEX_lock_read(state_clear_all_lock_bss_get()); #endif if (!CTR_DRBG_reseed(&state->drbg, seed, reseed_additional_data, diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/rdrand-x86_64.linux.x86_64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/rdrand-x86_64-linux.linux.x86_64.S similarity index 87% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/rdrand-x86_64.linux.x86_64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/rdrand-x86_64-linux.linux.x86_64.S index e81105b5..8c9b2041 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/rdrand-x86_64.linux.x86_64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/rdrand-x86_64-linux.linux.x86_64.S @@ -9,7 +9,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -62,7 +62,10 @@ CRYPTO_rdrand_multiple8_buf: .cfi_endproc .size CRYPTO_rdrand_multiple8_buf,.-CRYPTO_rdrand_multiple8_buf #endif -.section .note.GNU-stack,"",@progbits +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif #endif // defined(__x86_64__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/rdrand-x86_64.mac.x86_64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/rdrand-x86_64-mac.mac.x86_64.S similarity index 85% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/rdrand-x86_64.mac.x86_64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/rdrand-x86_64-mac.mac.x86_64.S index 62733dc9..fea4c8b3 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/rdrand-x86_64.mac.x86_64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/rdrand-x86_64-mac.mac.x86_64.S @@ -9,7 +9,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -61,6 +61,10 @@ L$err: .byte 0xf3,0xc3 +#endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif #endif // defined(__x86_64__) && defined(__APPLE__) #if defined(__linux__) && defined(__ELF__) diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/rsa/blinding.c b/Sources/CNIOBoringSSL/crypto/fipsmodule/rsa/blinding.c index a5fff39e..0a8a8e96 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/rsa/blinding.c +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/rsa/blinding.c @@ -132,7 +132,6 @@ static int bn_blinding_create_param(BN_BLINDING *b, const BIGNUM *e, 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; } OPENSSL_memset(ret, 0, sizeof(BN_BLINDING)); diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/rsa/internal.h b/Sources/CNIOBoringSSL/crypto/fipsmodule/rsa/internal.h index 8b58bc9a..272ad6e6 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/rsa/internal.h +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/rsa/internal.h @@ -67,6 +67,8 @@ extern "C" { #endif +#define RSA_PKCS1_PADDING_SIZE 11 + // Default implementations of RSA operations. const RSA_METHOD *RSA_default_method(void); @@ -75,8 +77,6 @@ size_t rsa_default_size(const RSA *rsa); int rsa_default_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *in, size_t in_len, int padding); -int rsa_default_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, - const uint8_t *in, size_t in_len, int padding); int rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, size_t len); @@ -90,21 +90,13 @@ int BN_BLINDING_invert(BIGNUM *n, const BN_BLINDING *b, BN_MONT_CTX *mont_ctx, BN_CTX *ctx); +int PKCS1_MGF1(uint8_t *out, size_t len, const uint8_t *seed, size_t seed_len, + const EVP_MD *md); int RSA_padding_add_PKCS1_type_1(uint8_t *to, size_t to_len, const uint8_t *from, size_t from_len); int RSA_padding_check_PKCS1_type_1(uint8_t *out, size_t *out_len, size_t max_out, const uint8_t *from, size_t from_len); -int RSA_padding_add_PKCS1_type_2(uint8_t *to, size_t to_len, - const uint8_t *from, size_t from_len); -int RSA_padding_check_PKCS1_type_2(uint8_t *out, size_t *out_len, - size_t max_out, const uint8_t *from, - size_t from_len); -int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *out, size_t *out_len, - size_t max_out, const uint8_t *from, - size_t from_len, const uint8_t *param, - size_t param_len, const EVP_MD *md, - const EVP_MD *mgf1md); int RSA_padding_add_none(uint8_t *to, size_t to_len, const uint8_t *from, size_t from_len); @@ -112,10 +104,16 @@ int RSA_padding_add_none(uint8_t *to, size_t to_len, const uint8_t *from, // within DoS bounds. int rsa_check_public_key(const RSA *rsa); -// RSA_private_transform calls either the method-specific |private_transform| -// function (if given) or the generic one. See the comment for -// |private_transform| in |rsa_meth_st|. -int RSA_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, +// rsa_private_transform_no_self_test calls either the method-specific +// |private_transform| function (if given) or the generic one. See the comment +// for |private_transform| in |rsa_meth_st|. +int rsa_private_transform_no_self_test(RSA *rsa, uint8_t *out, + const uint8_t *in, size_t len); + +// rsa_private_transform acts the same as |rsa_private_transform_no_self_test| +// but, in FIPS mode, performs an RSA self test before calling the default RSA +// implementation. +int rsa_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, size_t len); diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/rsa/padding.c b/Sources/CNIOBoringSSL/crypto/fipsmodule/rsa/padding.c index dd38831d..bc4a377f 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/rsa/padding.c +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/rsa/padding.c @@ -71,8 +71,6 @@ #include "../../internal.h" -#define RSA_PKCS1_PADDING_SIZE 11 - int RSA_padding_add_PKCS1_type_1(uint8_t *to, size_t to_len, const uint8_t *from, size_t from_len) { // See RFC 8017, section 9.2. @@ -146,109 +144,6 @@ int RSA_padding_check_PKCS1_type_1(uint8_t *out, size_t *out_len, return 1; } -static void rand_nonzero(uint8_t *out, size_t len) { - FIPS_service_indicator_lock_state(); - RAND_bytes(out, len); - - for (size_t i = 0; i < len; i++) { - while (out[i] == 0) { - RAND_bytes(out + i, 1); - } - } - - FIPS_service_indicator_unlock_state(); -} - -int RSA_padding_add_PKCS1_type_2(uint8_t *to, size_t to_len, - const uint8_t *from, size_t from_len) { - // See RFC 8017, section 7.2.1. - if (to_len < RSA_PKCS1_PADDING_SIZE) { - OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); - return 0; - } - - if (from_len > to_len - RSA_PKCS1_PADDING_SIZE) { - OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); - return 0; - } - - to[0] = 0; - to[1] = 2; - - size_t padding_len = to_len - 3 - from_len; - rand_nonzero(to + 2, padding_len); - to[2 + padding_len] = 0; - OPENSSL_memcpy(to + to_len - from_len, from, from_len); - return 1; -} - -int RSA_padding_check_PKCS1_type_2(uint8_t *out, size_t *out_len, - size_t max_out, const uint8_t *from, - size_t from_len) { - if (from_len == 0) { - OPENSSL_PUT_ERROR(RSA, RSA_R_EMPTY_PUBLIC_KEY); - return 0; - } - - // PKCS#1 v1.5 decryption. See "PKCS #1 v2.2: RSA Cryptography - // Standard", section 7.2.2. - if (from_len < RSA_PKCS1_PADDING_SIZE) { - // |from| is zero-padded to the size of the RSA modulus, a public value, so - // this can be rejected in non-constant time. - OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); - return 0; - } - - crypto_word_t first_byte_is_zero = constant_time_eq_w(from[0], 0); - crypto_word_t second_byte_is_two = constant_time_eq_w(from[1], 2); - - crypto_word_t zero_index = 0, looking_for_index = CONSTTIME_TRUE_W; - for (size_t i = 2; i < from_len; i++) { - crypto_word_t equals0 = constant_time_is_zero_w(from[i]); - zero_index = - constant_time_select_w(looking_for_index & equals0, i, zero_index); - looking_for_index = constant_time_select_w(equals0, 0, looking_for_index); - } - - // The input must begin with 00 02. - crypto_word_t valid_index = first_byte_is_zero; - valid_index &= second_byte_is_two; - - // We must have found the end of PS. - valid_index &= ~looking_for_index; - - // PS must be at least 8 bytes long, and it starts two bytes into |from|. - valid_index &= constant_time_ge_w(zero_index, 2 + 8); - - // Skip the zero byte. - zero_index++; - - // NOTE: Although this logic attempts to be constant time, the API contracts - // of this function and |RSA_decrypt| with |RSA_PKCS1_PADDING| make it - // impossible to completely avoid Bleichenbacher's attack. Consumers should - // use |RSA_PADDING_NONE| and perform the padding check in constant-time - // combined with a swap to a random session key or other mitigation. - CONSTTIME_DECLASSIFY(&valid_index, sizeof(valid_index)); - CONSTTIME_DECLASSIFY(&zero_index, sizeof(zero_index)); - - if (!valid_index) { - OPENSSL_PUT_ERROR(RSA, RSA_R_PKCS_DECODING_ERROR); - return 0; - } - - const size_t msg_len = from_len - zero_index; - if (msg_len > max_out) { - // This shouldn't happen because this function is always called with - // |max_out| as the key size and |from_len| is bounded by the key size. - OPENSSL_PUT_ERROR(RSA, RSA_R_PKCS_DECODING_ERROR); - return 0; - } - - OPENSSL_memcpy(out, &from[zero_index], msg_len); - *out_len = msg_len; - return 1; -} - int RSA_padding_add_none(uint8_t *to, size_t to_len, const uint8_t *from, size_t from_len) { if (from_len > to_len) { @@ -265,8 +160,8 @@ int RSA_padding_add_none(uint8_t *to, size_t to_len, const uint8_t *from, return 1; } -static int PKCS1_MGF1(uint8_t *out, size_t len, const uint8_t *seed, - size_t seed_len, const EVP_MD *md) { +int PKCS1_MGF1(uint8_t *out, size_t len, const uint8_t *seed, size_t seed_len, + const EVP_MD *md) { int ret = 0; EVP_MD_CTX ctx; EVP_MD_CTX_init(&ctx); @@ -310,180 +205,6 @@ static int PKCS1_MGF1(uint8_t *out, size_t len, const uint8_t *seed, return ret; } -int RSA_padding_add_PKCS1_OAEP_mgf1(uint8_t *to, size_t to_len, - const uint8_t *from, size_t from_len, - const uint8_t *param, size_t param_len, - const EVP_MD *md, const EVP_MD *mgf1md) { - if (md == NULL) { - md = EVP_sha1(); - } - if (mgf1md == NULL) { - mgf1md = md; - } - - size_t mdlen = EVP_MD_size(md); - - if (to_len < 2 * mdlen + 2) { - OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); - return 0; - } - - size_t emlen = to_len - 1; - if (from_len > emlen - 2 * mdlen - 1) { - OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); - return 0; - } - - if (emlen < 2 * mdlen + 1) { - OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); - return 0; - } - - to[0] = 0; - uint8_t *seed = to + 1; - uint8_t *db = to + mdlen + 1; - - uint8_t *dbmask = NULL; - int ret = 0; - FIPS_service_indicator_lock_state(); - if (!EVP_Digest(param, param_len, db, NULL, md, NULL)) { - goto out; - } - OPENSSL_memset(db + mdlen, 0, emlen - from_len - 2 * mdlen - 1); - db[emlen - from_len - mdlen - 1] = 0x01; - OPENSSL_memcpy(db + emlen - from_len - mdlen, from, from_len); - if (!RAND_bytes(seed, mdlen)) { - goto out; - } - - dbmask = OPENSSL_malloc(emlen - mdlen); - if (dbmask == NULL) { - OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); - goto out; - } - - if (!PKCS1_MGF1(dbmask, emlen - mdlen, seed, mdlen, mgf1md)) { - goto out; - } - for (size_t i = 0; i < emlen - mdlen; i++) { - db[i] ^= dbmask[i]; - } - - uint8_t seedmask[EVP_MAX_MD_SIZE]; - if (!PKCS1_MGF1(seedmask, mdlen, db, emlen - mdlen, mgf1md)) { - goto out; - } - for (size_t i = 0; i < mdlen; i++) { - seed[i] ^= seedmask[i]; - } - ret = 1; - -out: - OPENSSL_free(dbmask); - FIPS_service_indicator_unlock_state(); - return ret; -} - -int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *out, size_t *out_len, - size_t max_out, const uint8_t *from, - size_t from_len, const uint8_t *param, - size_t param_len, const EVP_MD *md, - const EVP_MD *mgf1md) { - uint8_t *db = NULL; - - if (md == NULL) { - md = EVP_sha1(); - } - if (mgf1md == NULL) { - mgf1md = md; - } - - size_t mdlen = EVP_MD_size(md); - - // The encoded message is one byte smaller than the modulus to ensure that it - // doesn't end up greater than the modulus. Thus there's an extra "+1" here - // compared to https://tools.ietf.org/html/rfc2437#section-9.1.1.2. - if (from_len < 1 + 2*mdlen + 1) { - // 'from_len' is the length of the modulus, i.e. does not depend on the - // particular ciphertext. - goto decoding_err; - } - - size_t dblen = from_len - mdlen - 1; - FIPS_service_indicator_lock_state(); - db = OPENSSL_malloc(dblen); - if (db == NULL) { - OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); - goto err; - } - - const uint8_t *maskedseed = from + 1; - const uint8_t *maskeddb = from + 1 + mdlen; - - uint8_t seed[EVP_MAX_MD_SIZE]; - if (!PKCS1_MGF1(seed, mdlen, maskeddb, dblen, mgf1md)) { - goto err; - } - for (size_t i = 0; i < mdlen; i++) { - seed[i] ^= maskedseed[i]; - } - - if (!PKCS1_MGF1(db, dblen, seed, mdlen, mgf1md)) { - goto err; - } - for (size_t i = 0; i < dblen; i++) { - db[i] ^= maskeddb[i]; - } - - uint8_t phash[EVP_MAX_MD_SIZE]; - if (!EVP_Digest(param, param_len, phash, NULL, md, NULL)) { - goto err; - } - - crypto_word_t bad = ~constant_time_is_zero_w(CRYPTO_memcmp(db, phash, mdlen)); - bad |= ~constant_time_is_zero_w(from[0]); - - crypto_word_t looking_for_one_byte = CONSTTIME_TRUE_W; - size_t one_index = 0; - for (size_t i = mdlen; i < dblen; i++) { - crypto_word_t equals1 = constant_time_eq_w(db[i], 1); - crypto_word_t equals0 = constant_time_eq_w(db[i], 0); - one_index = - constant_time_select_w(looking_for_one_byte & equals1, i, one_index); - looking_for_one_byte = - constant_time_select_w(equals1, 0, looking_for_one_byte); - bad |= looking_for_one_byte & ~equals0; - } - - bad |= looking_for_one_byte; - - if (bad) { - goto decoding_err; - } - - one_index++; - size_t mlen = dblen - one_index; - if (max_out < mlen) { - OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE); - goto err; - } - - OPENSSL_memcpy(out, db + one_index, mlen); - *out_len = mlen; - OPENSSL_free(db); - FIPS_service_indicator_unlock_state(); - return 1; - -decoding_err: - // to avoid chosen ciphertext attacks, the error message should not reveal - // which kind of decoding error happened - OPENSSL_PUT_ERROR(RSA, RSA_R_OAEP_DECODING_ERROR); - err: - OPENSSL_free(db); - FIPS_service_indicator_unlock_state(); - return 0; -} - static const uint8_t kPSSZeroes[] = {0, 0, 0, 0, 0, 0, 0, 0}; int RSA_verify_PKCS1_PSS_mgf1(const RSA *rsa, const uint8_t *mHash, @@ -500,9 +221,9 @@ int RSA_verify_PKCS1_PSS_mgf1(const RSA *rsa, const uint8_t *mHash, FIPS_service_indicator_lock_state(); // Negative sLen has special meanings: - // -1 sLen == hLen - // -2 salt length is autorecovered from signature - // -N reserved + // -1 sLen == hLen + // -2 salt length is autorecovered from signature + // -N reserved size_t hLen = EVP_MD_size(Hash); if (sLen == -1) { sLen = (int)hLen; @@ -537,7 +258,6 @@ int RSA_verify_PKCS1_PSS_mgf1(const RSA *rsa, const uint8_t *mHash, const uint8_t *H = EM + maskedDBLen; DB = OPENSSL_malloc(maskedDBLen); if (!DB) { - OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); goto err; } if (!PKCS1_MGF1(DB, maskedDBLen, H, hLen, mgf1Hash)) { @@ -647,7 +367,6 @@ int RSA_padding_add_PKCS1_PSS_mgf1(const RSA *rsa, unsigned char *EM, if (sLen > 0) { salt = OPENSSL_malloc(sLen); if (!salt) { - OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); goto err; } if (!RAND_bytes(salt, sLen)) { diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/rsa/rsa.c b/Sources/CNIOBoringSSL/crypto/fipsmodule/rsa/rsa.c index 197ed7b8..05a6d24e 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/rsa/rsa.c +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/rsa/rsa.c @@ -88,7 +88,6 @@ RSA *RSA_new(void) { return RSA_new_method(NULL); } RSA *RSA_new_method(const ENGINE *engine) { RSA *rsa = OPENSSL_malloc(sizeof(RSA)); if (rsa == NULL) { - OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); return NULL; } @@ -289,21 +288,6 @@ int RSA_set0_crt_params(RSA *rsa, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp) { return 1; } -int RSA_public_encrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa, - int padding) { - size_t out_len; - - if (!RSA_encrypt(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) { - return -1; - } - - if (out_len > INT_MAX) { - OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW); - return -1; - } - return (int)out_len; -} - static int rsa_sign_raw_no_self_test(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *in, size_t in_len, int padding) { @@ -321,58 +305,6 @@ int RSA_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, padding); } -int RSA_private_encrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa, - int padding) { - size_t out_len; - - if (!RSA_sign_raw(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) { - return -1; - } - - if (out_len > INT_MAX) { - OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW); - return -1; - } - return (int)out_len; -} - -int RSA_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, - const uint8_t *in, size_t in_len, int padding) { - if (rsa->meth->decrypt) { - return rsa->meth->decrypt(rsa, out_len, out, max_out, in, in_len, padding); - } - - return rsa_default_decrypt(rsa, out_len, out, max_out, in, in_len, padding); -} - -int RSA_private_decrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa, - int padding) { - size_t out_len; - if (!RSA_decrypt(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) { - return -1; - } - - if (out_len > INT_MAX) { - OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW); - return -1; - } - return (int)out_len; -} - -int RSA_public_decrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa, - int padding) { - size_t out_len; - if (!RSA_verify_raw(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) { - return -1; - } - - if (out_len > INT_MAX) { - OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW); - return -1; - } - return (int)out_len; -} - unsigned RSA_size(const RSA *rsa) { size_t ret = rsa->meth->size ? rsa->meth->size(rsa) : rsa_default_size(rsa); // RSA modulus sizes are bounded by |BIGNUM|, which must fit in |unsigned|. @@ -530,7 +462,6 @@ int RSA_add_pkcs1_prefix(uint8_t **out_msg, size_t *out_msg_len, uint8_t *signed_msg = OPENSSL_malloc(signed_msg_len); if (!signed_msg) { - OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); return 0; } @@ -610,7 +541,6 @@ int RSA_sign_pss_mgf1(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, size_t padded_len = RSA_size(rsa); uint8_t *padded = OPENSSL_malloc(padded_len); if (padded == NULL) { - OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); return 0; } @@ -644,7 +574,6 @@ int rsa_verify_no_self_test(int hash_nid, const uint8_t *digest, buf = OPENSSL_malloc(rsa_size); if (!buf) { - OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); return 0; } @@ -691,7 +620,6 @@ int RSA_verify_pss_mgf1(RSA *rsa, const uint8_t *digest, size_t digest_len, size_t em_len = RSA_size(rsa); uint8_t *em = OPENSSL_malloc(em_len); if (em == NULL) { - OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); return 0; } @@ -772,7 +700,6 @@ int RSA_check_key(const RSA *key) { BN_CTX *ctx = BN_CTX_new(); if (ctx == NULL) { - OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); return 0; } @@ -787,7 +714,8 @@ int RSA_check_key(const RSA *key) { // Check that p * q == n. Before we multiply, we check that p and q are in // bounds, to avoid a DoS vector in |bn_mul_consttime| below. Note that - // n was bound by |rsa_check_public_key|. + // n was bound by |rsa_check_public_key|. This also implicitly checks p and q + // are odd, which is a necessary condition for Montgomery reduction. if (BN_is_negative(key->p) || BN_cmp(key->p, key->n) >= 0 || BN_is_negative(key->q) || BN_cmp(key->q, key->n) >= 0) { OPENSSL_PUT_ERROR(RSA, RSA_R_N_NOT_EQUAL_P_Q); @@ -899,7 +827,6 @@ int RSA_check_fips(RSA *key) { BN_CTX *ctx = BN_CTX_new(); if (ctx == NULL) { - OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); return 0; } @@ -946,7 +873,6 @@ int RSA_check_fips(RSA *key) { unsigned sig_len = RSA_size(key); uint8_t *sig = OPENSSL_malloc(sig_len); if (sig == NULL) { - OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); return 0; } @@ -969,8 +895,8 @@ int RSA_check_fips(RSA *key) { return ret; } -int RSA_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, - size_t len) { +int rsa_private_transform_no_self_test(RSA *rsa, uint8_t *out, + const uint8_t *in, size_t len) { if (rsa->meth->private_transform) { return rsa->meth->private_transform(rsa, out, in, len); } @@ -978,6 +904,12 @@ int RSA_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, return rsa_default_private_transform(rsa, out, in, len); } +int rsa_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, + size_t len) { + boringssl_ensure_rsa_self_test(); + return rsa_private_transform_no_self_test(rsa, out, in, len); +} + int RSA_flags(const RSA *rsa) { return rsa->flags; } int RSA_test_flags(const RSA *rsa, int flags) { return rsa->flags & flags; } diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/rsa/rsa_impl.c b/Sources/CNIOBoringSSL/crypto/fipsmodule/rsa/rsa_impl.c index 19947ef5..2413cd4e 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/rsa/rsa_impl.c +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/rsa/rsa_impl.c @@ -85,6 +85,13 @@ int rsa_check_public_key(const RSA *rsa) { return 0; } + // RSA moduli must be odd. In addition to being necessary for RSA in general, + // we cannot setup Montgomery reduction with even moduli. + if (!BN_is_odd(rsa->n)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_RSA_PARAMETERS); + 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 @@ -259,95 +266,6 @@ size_t rsa_default_size(const RSA *rsa) { return BN_num_bytes(rsa->n); } -int RSA_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, - const uint8_t *in, size_t in_len, int padding) { - boringssl_ensure_rsa_self_test(); - - if (!rsa_check_public_key(rsa)) { - return 0; - } - - const unsigned rsa_size = RSA_size(rsa); - BIGNUM *f, *result; - uint8_t *buf = NULL; - BN_CTX *ctx = NULL; - int i, ret = 0; - - if (max_out < rsa_size) { - OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL); - return 0; - } - - ctx = BN_CTX_new(); - if (ctx == NULL) { - goto err; - } - - BN_CTX_start(ctx); - f = BN_CTX_get(ctx); - result = BN_CTX_get(ctx); - buf = OPENSSL_malloc(rsa_size); - if (!f || !result || !buf) { - OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); - goto err; - } - - switch (padding) { - case RSA_PKCS1_PADDING: - i = RSA_padding_add_PKCS1_type_2(buf, rsa_size, in, in_len); - break; - case RSA_PKCS1_OAEP_PADDING: - // Use the default parameters: SHA-1 for both hashes and no label. - i = RSA_padding_add_PKCS1_OAEP_mgf1(buf, rsa_size, in, in_len, - NULL, 0, NULL, NULL); - break; - case RSA_NO_PADDING: - i = RSA_padding_add_none(buf, rsa_size, in, in_len); - break; - default: - OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE); - goto err; - } - - if (i <= 0) { - goto err; - } - - if (BN_bin2bn(buf, rsa_size, f) == NULL) { - goto err; - } - - if (BN_ucmp(f, rsa->n) >= 0) { - // usually the padding functions would catch this - OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_MODULUS); - goto err; - } - - if (!BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx) || - !BN_mod_exp_mont(result, f, rsa->e, &rsa->mont_n->N, ctx, rsa->mont_n)) { - goto err; - } - - // put in leading 0 bytes if the number is less than the length of the - // modulus - if (!BN_bn2bin_padded(out, rsa_size, result)) { - OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); - goto err; - } - - *out_len = rsa_size; - ret = 1; - -err: - if (ctx != NULL) { - BN_CTX_end(ctx); - BN_CTX_free(ctx); - } - OPENSSL_free(buf); - - return ret; -} - // MAX_BLINDINGS_PER_RSA defines the maximum number of cached BN_BLINDINGs per // RSA*. Then this limit is exceeded, BN_BLINDING objects will be created and // destroyed as needed. @@ -365,7 +283,7 @@ int RSA_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, // // On success, the index of the assigned BN_BLINDING is written to // |*index_used| and must be passed to |rsa_blinding_release| when finished. -static BN_BLINDING *rsa_blinding_get(RSA *rsa, unsigned *index_used, +static BN_BLINDING *rsa_blinding_get(RSA *rsa, size_t *index_used, BN_CTX *ctx) { assert(ctx != NULL); assert(rsa->mont_n != NULL); @@ -376,7 +294,7 @@ static BN_BLINDING *rsa_blinding_get(RSA *rsa, unsigned *index_used, // Wipe the blinding cache on |fork|. if (rsa->blinding_fork_generation != fork_generation) { - for (unsigned i = 0; i < rsa->num_blindings; i++) { + for (size_t i = 0; i < rsa->num_blindings; i++) { // The inuse flag must be zero unless we were forked from a // multi-threaded process, in which case calling back into BoringSSL is // forbidden. @@ -407,7 +325,7 @@ static BN_BLINDING *rsa_blinding_get(RSA *rsa, unsigned *index_used, // Double the length of the cache. static_assert(MAX_BLINDINGS_PER_RSA < UINT_MAX / 2, "MAX_BLINDINGS_PER_RSA too large"); - unsigned new_num_blindings = rsa->num_blindings * 2; + size_t new_num_blindings = rsa->num_blindings * 2; if (new_num_blindings == 0) { new_num_blindings = 1; } @@ -416,8 +334,6 @@ static BN_BLINDING *rsa_blinding_get(RSA *rsa, unsigned *index_used, } assert(new_num_blindings > rsa->num_blindings); - static_assert(MAX_BLINDINGS_PER_RSA < UINT_MAX / sizeof(BN_BLINDING *), - "MAX_BLINDINGS_PER_RSA too large"); BN_BLINDING **new_blindings = OPENSSL_malloc(sizeof(BN_BLINDING *) * new_num_blindings); uint8_t *new_blindings_inuse = OPENSSL_malloc(new_num_blindings); @@ -429,10 +345,10 @@ static BN_BLINDING *rsa_blinding_get(RSA *rsa, unsigned *index_used, sizeof(BN_BLINDING *) * rsa->num_blindings); OPENSSL_memcpy(new_blindings_inuse, rsa->blindings_inuse, rsa->num_blindings); - for (unsigned i = rsa->num_blindings; i < new_num_blindings; i++) { + for (size_t i = rsa->num_blindings; i < new_num_blindings; i++) { new_blindings[i] = BN_BLINDING_new(); if (new_blindings[i] == NULL) { - for (unsigned j = rsa->num_blindings; j < i; j++) { + for (size_t j = rsa->num_blindings; j < i; j++) { BN_BLINDING_free(new_blindings[j]); } goto err; @@ -466,7 +382,7 @@ static BN_BLINDING *rsa_blinding_get(RSA *rsa, unsigned *index_used, // rsa_blinding_release marks the cached BN_BLINDING at the given index as free // for other threads to use. static void rsa_blinding_release(RSA *rsa, BN_BLINDING *blinding, - unsigned blinding_index) { + size_t blinding_index) { if (blinding_index == MAX_BLINDINGS_PER_RSA) { // This blinding wasn't cached. BN_BLINDING_free(blinding); @@ -493,7 +409,6 @@ int rsa_default_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out, buf = OPENSSL_malloc(rsa_size); if (buf == NULL) { - OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); goto err; } @@ -513,7 +428,7 @@ int rsa_default_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out, goto err; } - if (!RSA_private_transform(rsa, out, buf, rsa_size)) { + if (!rsa_private_transform_no_self_test(rsa, out, buf, rsa_size)) { goto err; } @@ -527,72 +442,6 @@ int rsa_default_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out, return ret; } -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) { - boringssl_ensure_rsa_self_test(); - - const unsigned rsa_size = RSA_size(rsa); - uint8_t *buf = NULL; - int ret = 0; - - if (max_out < rsa_size) { - OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL); - return 0; - } - - if (padding == RSA_NO_PADDING) { - buf = out; - } else { - // Allocate a temporary buffer to hold the padded plaintext. - buf = OPENSSL_malloc(rsa_size); - if (buf == NULL) { - OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); - goto err; - } - } - - if (in_len != rsa_size) { - OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_LEN_NOT_EQUAL_TO_MOD_LEN); - goto err; - } - - if (!RSA_private_transform(rsa, buf, in, rsa_size)) { - goto err; - } - - switch (padding) { - case RSA_PKCS1_PADDING: - ret = - RSA_padding_check_PKCS1_type_2(out, out_len, rsa_size, buf, rsa_size); - break; - case RSA_PKCS1_OAEP_PADDING: - // Use the default parameters: SHA-1 for both hashes and no label. - ret = RSA_padding_check_PKCS1_OAEP_mgf1(out, out_len, rsa_size, buf, - rsa_size, NULL, 0, NULL, NULL); - break; - case RSA_NO_PADDING: - *out_len = rsa_size; - ret = 1; - break; - default: - OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE); - goto err; - } - - CONSTTIME_DECLASSIFY(&ret, sizeof(ret)); - if (!ret) { - OPENSSL_PUT_ERROR(RSA, RSA_R_PADDING_CHECK_FAILED); - } else { - CONSTTIME_DECLASSIFY(out, *out_len); - } - -err: - if (padding != RSA_NO_PADDING) { - OPENSSL_free(buf); - } - - return ret; -} static int mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx); @@ -628,7 +477,6 @@ int rsa_verify_raw_no_self_test(RSA *rsa, size_t *out_len, uint8_t *out, 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; } @@ -638,7 +486,6 @@ int rsa_verify_raw_no_self_test(RSA *rsa, size_t *out_len, uint8_t *out, // Allocate a temporary buffer to hold the padded plaintext. buf = OPENSSL_malloc(rsa_size); if (buf == NULL) { - OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); goto err; } } @@ -707,7 +554,7 @@ int rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, BIGNUM *f, *result; BN_CTX *ctx = NULL; - unsigned blinding_index = 0; + size_t blinding_index = 0; BN_BLINDING *blinding = NULL; int ret = 0; @@ -720,10 +567,11 @@ int rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, result = BN_CTX_get(ctx); if (f == NULL || result == NULL) { - OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); goto err; } + // The caller should have ensured this. + assert(len == BN_num_bytes(rsa->n)); if (BN_bin2bn(in, len, f) == NULL) { goto err; } @@ -785,16 +633,16 @@ int rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, // works when the CRT isn't used. That attack is much less likely to succeed // than the CRT attack, but there have likely been improvements since 1997. // - // This check is cheap assuming |e| is small; it almost always is. + // This check is cheap assuming |e| is small, which we require in + // |rsa_check_public_key|. if (rsa->e != NULL) { BIGNUM *vrfy = BN_CTX_get(ctx); if (vrfy == NULL || !BN_mod_exp_mont(vrfy, result, rsa->e, rsa->n, ctx, rsa->mont_n) || - !BN_equal_consttime(vrfy, f)) { + !constant_time_declassify_int(BN_equal_consttime(vrfy, f))) { OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); goto err; } - } if (do_blinding && @@ -808,6 +656,7 @@ int rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, // // See Falko Strenzke, "Manger's Attack revisited", ICICS 2010. assert(result->width == rsa->mont_n->N.width); + bn_assert_fits_in_bytes(result, len); if (!BN_bn2bin_padded(out, len, result)) { OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); goto err; @@ -926,11 +775,18 @@ static int mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) { // so it is correct mod q. Finally, the result is bounded by [m1, n + m1), // and the result is at least |m1|, so this must be the unique answer in // [0, n). - !bn_mul_consttime(r0, r0, q, ctx) || - !bn_uadd_consttime(r0, r0, m1) || - // The result should be bounded by |n|, but fixed-width operations may - // bound the width slightly higher, so fix it. - !bn_resize_words(r0, n->width)) { + !bn_mul_consttime(r0, r0, q, ctx) || // + !bn_uadd_consttime(r0, r0, m1)) { + goto err; + } + + // The result should be bounded by |n|, but fixed-width operations may + // bound the width slightly higher, so fix it. This trips constant-time checks + // because a naive data flow analysis does not realize the excess words are + // publicly zero. + assert(BN_cmp(r0, n) < 0); + bn_assert_fits_in_bytes(r0, BN_num_bytes(n)); + if (!bn_resize_words(r0, n->width)) { goto err; } diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/rsaz-avx2.linux.x86_64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/rsaz-avx2-linux.linux.x86_64.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/rsaz-avx2.linux.x86_64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/rsaz-avx2-linux.linux.x86_64.S index edddc728..11e3200f 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/rsaz-avx2.linux.x86_64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/rsaz-avx2-linux.linux.x86_64.S @@ -9,7 +9,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1735,6 +1735,7 @@ rsaz_1024_gather5_avx2: .cfi_endproc .LSEH_end_rsaz_1024_gather5: .size rsaz_1024_gather5_avx2,.-rsaz_1024_gather5_avx2 +.section .rodata .align 64 .Land_mask: .quad 0x1fffffff,0x1fffffff,0x1fffffff,0x1fffffff @@ -1747,8 +1748,12 @@ rsaz_1024_gather5_avx2: .long 2,2,2,2, 3,3,3,3 .long 4,4,4,4, 4,4,4,4 .align 64 +.text +#endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -.section .note.GNU-stack,"",@progbits #endif // defined(__x86_64__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/rsaz-avx2.mac.x86_64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/rsaz-avx2-mac.mac.x86_64.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/rsaz-avx2.mac.x86_64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/rsaz-avx2-mac.mac.x86_64.S index a1061778..bb27e63f 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/rsaz-avx2.mac.x86_64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/rsaz-avx2-mac.mac.x86_64.S @@ -9,7 +9,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1735,6 +1735,7 @@ L$oop_gather_1024: L$SEH_end_rsaz_1024_gather5: +.section __DATA,__const .p2align 6 L$and_mask: .quad 0x1fffffff,0x1fffffff,0x1fffffff,0x1fffffff @@ -1747,6 +1748,11 @@ L$inc: .long 2,2,2,2, 3,3,3,3 .long 4,4,4,4, 4,4,4,4 .p2align 6 +.text +#endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif #endif // defined(__x86_64__) && defined(__APPLE__) #if defined(__linux__) && defined(__ELF__) diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/self_check/self_check.c b/Sources/CNIOBoringSSL/crypto/fipsmodule/self_check/self_check.c index e26bb121..4b007333 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/self_check/self_check.c +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/self_check/self_check.c @@ -318,6 +318,9 @@ static int boringssl_self_test_rsa(void) { fprintf(stderr, "RSA key construction failed\n"); goto err; } + // Disable blinding for the power-on tests because it's not needed and + // triggers an entropy draw. + rsa_key->flags |= RSA_FLAG_NO_BLINDING; // RSA Sign KAT diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/service_indicator/service_indicator.c b/Sources/CNIOBoringSSL/crypto/fipsmodule/service_indicator/service_indicator.c index d985c5ff..d98dbe4f 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/service_indicator/service_indicator.c +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/service_indicator/service_indicator.c @@ -51,7 +51,6 @@ static struct fips_service_indicator_state *service_indicator_get(void) { if (indicator == NULL) { indicator = OPENSSL_malloc(sizeof(struct fips_service_indicator_state)); if (indicator == NULL) { - OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE); return NULL; } @@ -239,8 +238,9 @@ static void evp_md_ctx_verify_service_indicator(const EVP_MD_CTX *ctx, } } else if (pkey_type == EVP_PKEY_EC) { // Check if the MD type and the elliptic curve are approved. - if (md_ok(md_type) && is_ec_fips_approved(EC_GROUP_get_curve_name( - ctx->pctx->pkey->pkey.ec->group))) { + if (md_ok(md_type) && + is_ec_fips_approved(EC_GROUP_get_curve_name( + EC_KEY_get0_group(EVP_PKEY_get0_EC_KEY(ctx->pctx->pkey))))) { FIPS_service_indicator_update_state(); } } diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha/internal.h b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha/internal.h index ce139b2e..eff74dcf 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha/internal.h +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha/internal.h @@ -22,23 +22,14 @@ extern "C" { #endif -#if defined(OPENSSL_PPC64LE) || \ - (!defined(OPENSSL_NO_ASM) && \ - (defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \ - defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64))) -// POWER has an intrinsics-based implementation of SHA-1 and thus the functions -// normally defined in assembly are available even with |OPENSSL_NO_ASM| in -// this case. -#define SHA1_ASM -void sha1_block_data_order(uint32_t *state, const uint8_t *in, - size_t num_blocks); -#endif - #if !defined(OPENSSL_NO_ASM) && \ (defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \ defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) +#define SHA1_ASM #define SHA256_ASM #define SHA512_ASM +void sha1_block_data_order(uint32_t *state, const uint8_t *in, + size_t num_blocks); void sha256_block_data_order(uint32_t *state, const uint8_t *in, size_t num_blocks); void sha512_block_data_order(uint64_t *state, const uint8_t *in, diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha/sha1-altivec.c b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha/sha1-altivec.c deleted file mode 100644 index 57974346..00000000 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha/sha1-altivec.c +++ /dev/null @@ -1,361 +0,0 @@ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] */ - -// Altivec-optimized SHA1 in C. This is tested on ppc64le only. -// -// References: -// https://software.intel.com/en-us/articles/improving-the-performance-of-the-secure-hash-algorithm-1 -// http://arctic.org/~dean/crypto/sha1.html -// -// This code used the generic SHA-1 from OpenSSL as a basis and AltiVec -// optimisations were added on top. - -#include - -#if defined(OPENSSL_PPC64LE) - -#include - -void sha1_block_data_order(uint32_t *state, const uint8_t *data, size_t num); - -static uint32_t rotate(uint32_t a, int n) { return (a << n) | (a >> (32 - n)); } - -typedef vector unsigned int vec_uint32_t; -typedef vector unsigned char vec_uint8_t; - -// Vector constants -static const vec_uint8_t k_swap_endianness = {3, 2, 1, 0, 7, 6, 5, 4, - 11, 10, 9, 8, 15, 14, 13, 12}; - -// Shift amounts for byte and bit shifts and rotations -static const vec_uint8_t k_4_bytes = {32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32}; -static const vec_uint8_t k_12_bytes = {96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96}; - -#define K_00_19 0x5a827999UL -#define K_20_39 0x6ed9eba1UL -#define K_40_59 0x8f1bbcdcUL -#define K_60_79 0xca62c1d6UL - -// Vector versions of the above. -static const vec_uint32_t K_00_19_x_4 = {K_00_19, K_00_19, K_00_19, K_00_19}; -static const vec_uint32_t K_20_39_x_4 = {K_20_39, K_20_39, K_20_39, K_20_39}; -static const vec_uint32_t K_40_59_x_4 = {K_40_59, K_40_59, K_40_59, K_40_59}; -static const vec_uint32_t K_60_79_x_4 = {K_60_79, K_60_79, K_60_79, K_60_79}; - -// vector message scheduling: compute message schedule for round i..i+3 where i -// is divisible by 4. We return the schedule w[i..i+3] as a vector. In -// addition, we also precompute sum w[i..+3] and an additive constant K. This -// is done to offload some computation of f() in the integer execution units. -// -// Byte shifting code below may not be correct for big-endian systems. -static vec_uint32_t sched_00_15(vec_uint32_t *pre_added, const void *data, - vec_uint32_t k) { - const vector unsigned char unaligned_data = - vec_vsx_ld(0, (const unsigned char*) data); - const vec_uint32_t v = (vec_uint32_t) unaligned_data; - const vec_uint32_t w = vec_perm(v, v, k_swap_endianness); - vec_st(w + k, 0, pre_added); - return w; -} - -// Compute w[i..i+3] using these steps for i in [16, 20, 24, 28] -// -// w'[i ] = (w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16]) <<< 1 -// w'[i+1] = (w[i-2] ^ w[i-7] ^ w[i-13] ^ w[i-15]) <<< 1 -// w'[i+2] = (w[i-1] ^ w[i-6] ^ w[i-12] ^ w[i-14]) <<< 1 -// w'[i+3] = ( 0 ^ w[i-5] ^ w[i-11] ^ w[i-13]) <<< 1 -// -// w[ i] = w'[ i] -// w[i+1] = w'[i+1] -// w[i+2] = w'[i+2] -// w[i+3] = w'[i+3] ^ (w'[i] <<< 1) -static vec_uint32_t sched_16_31(vec_uint32_t *pre_added, vec_uint32_t minus_4, - vec_uint32_t minus_8, vec_uint32_t minus_12, - vec_uint32_t minus_16, vec_uint32_t k) { - const vec_uint32_t minus_3 = vec_sro(minus_4, k_4_bytes); - const vec_uint32_t minus_14 = vec_sld((minus_12), (minus_16), 8); - const vec_uint32_t k_1_bit = vec_splat_u32(1); - const vec_uint32_t w_prime = - vec_rl(minus_3 ^ minus_8 ^ minus_14 ^ minus_16, k_1_bit); - const vec_uint32_t w = - w_prime ^ vec_rl(vec_slo(w_prime, k_12_bytes), k_1_bit); - vec_st(w + k, 0, pre_added); - return w; -} - -// Compute w[i..i+3] using this relation for i in [32, 36, 40 ... 76] -// w[i] = (w[i-6] ^ w[i-16] ^ w[i-28] ^ w[i-32]), 2) <<< 2 -static vec_uint32_t sched_32_79(vec_uint32_t *pre_added, vec_uint32_t minus_4, - vec_uint32_t minus_8, vec_uint32_t minus_16, - vec_uint32_t minus_28, vec_uint32_t minus_32, - vec_uint32_t k) { - const vec_uint32_t minus_6 = vec_sld(minus_4, minus_8, 8); - const vec_uint32_t k_2_bits = vec_splat_u32(2); - const vec_uint32_t w = - vec_rl(minus_6 ^ minus_16 ^ minus_28 ^ minus_32, k_2_bits); - vec_st(w + k, 0, pre_added); - return w; -} - -// As pointed out by Wei Dai , F() below can be simplified -// to the code in F_00_19. Wei attributes these optimisations to Peter -// Gutmann's SHS code, and he attributes it to Rich Schroeppel. #define -// F(x,y,z) (((x) & (y)) | ((~(x)) & (z))) I've just become aware of another -// tweak to be made, again from Wei Dai, in F_40_59, (x&a)|(y&a) -> (x|y)&a -#define F_00_19(b, c, d) ((((c) ^ (d)) & (b)) ^ (d)) -#define F_20_39(b, c, d) ((b) ^ (c) ^ (d)) -#define F_40_59(b, c, d) (((b) & (c)) | (((b) | (c)) & (d))) -#define F_60_79(b, c, d) F_20_39(b, c, d) - -// We pre-added the K constants during message scheduling. -#define BODY_00_19(i, a, b, c, d, e, f) \ - do { \ - (f) = w[i] + (e) + rotate((a), 5) + F_00_19((b), (c), (d)); \ - (b) = rotate((b), 30); \ - } while (0) - -#define BODY_20_39(i, a, b, c, d, e, f) \ - do { \ - (f) = w[i] + (e) + rotate((a), 5) + F_20_39((b), (c), (d)); \ - (b) = rotate((b), 30); \ - } while (0) - -#define BODY_40_59(i, a, b, c, d, e, f) \ - do { \ - (f) = w[i] + (e) + rotate((a), 5) + F_40_59((b), (c), (d)); \ - (b) = rotate((b), 30); \ - } while (0) - -#define BODY_60_79(i, a, b, c, d, e, f) \ - do { \ - (f) = w[i] + (e) + rotate((a), 5) + F_60_79((b), (c), (d)); \ - (b) = rotate((b), 30); \ - } while (0) - -void sha1_block_data_order(uint32_t *state, const uint8_t *data, size_t num) { - uint32_t A, B, C, D, E, T; - - A = state[0]; - B = state[1]; - C = state[2]; - D = state[3]; - E = state[4]; - - for (;;) { - vec_uint32_t vw[20]; - const uint32_t *w = (const uint32_t *)&vw; - - vec_uint32_t k = K_00_19_x_4; - const vec_uint32_t w0 = sched_00_15(vw + 0, data + 0, k); - BODY_00_19(0, A, B, C, D, E, T); - BODY_00_19(1, T, A, B, C, D, E); - BODY_00_19(2, E, T, A, B, C, D); - BODY_00_19(3, D, E, T, A, B, C); - - const vec_uint32_t w4 = sched_00_15(vw + 1, data + 16, k); - BODY_00_19(4, C, D, E, T, A, B); - BODY_00_19(5, B, C, D, E, T, A); - BODY_00_19(6, A, B, C, D, E, T); - BODY_00_19(7, T, A, B, C, D, E); - - const vec_uint32_t w8 = sched_00_15(vw + 2, data + 32, k); - BODY_00_19(8, E, T, A, B, C, D); - BODY_00_19(9, D, E, T, A, B, C); - BODY_00_19(10, C, D, E, T, A, B); - BODY_00_19(11, B, C, D, E, T, A); - - const vec_uint32_t w12 = sched_00_15(vw + 3, data + 48, k); - BODY_00_19(12, A, B, C, D, E, T); - BODY_00_19(13, T, A, B, C, D, E); - BODY_00_19(14, E, T, A, B, C, D); - BODY_00_19(15, D, E, T, A, B, C); - - const vec_uint32_t w16 = sched_16_31(vw + 4, w12, w8, w4, w0, k); - BODY_00_19(16, C, D, E, T, A, B); - BODY_00_19(17, B, C, D, E, T, A); - BODY_00_19(18, A, B, C, D, E, T); - BODY_00_19(19, T, A, B, C, D, E); - - k = K_20_39_x_4; - const vec_uint32_t w20 = sched_16_31(vw + 5, w16, w12, w8, w4, k); - BODY_20_39(20, E, T, A, B, C, D); - BODY_20_39(21, D, E, T, A, B, C); - BODY_20_39(22, C, D, E, T, A, B); - BODY_20_39(23, B, C, D, E, T, A); - - const vec_uint32_t w24 = sched_16_31(vw + 6, w20, w16, w12, w8, k); - BODY_20_39(24, A, B, C, D, E, T); - BODY_20_39(25, T, A, B, C, D, E); - BODY_20_39(26, E, T, A, B, C, D); - BODY_20_39(27, D, E, T, A, B, C); - - const vec_uint32_t w28 = sched_16_31(vw + 7, w24, w20, w16, w12, k); - BODY_20_39(28, C, D, E, T, A, B); - BODY_20_39(29, B, C, D, E, T, A); - BODY_20_39(30, A, B, C, D, E, T); - BODY_20_39(31, T, A, B, C, D, E); - - const vec_uint32_t w32 = sched_32_79(vw + 8, w28, w24, w16, w4, w0, k); - BODY_20_39(32, E, T, A, B, C, D); - BODY_20_39(33, D, E, T, A, B, C); - BODY_20_39(34, C, D, E, T, A, B); - BODY_20_39(35, B, C, D, E, T, A); - - const vec_uint32_t w36 = sched_32_79(vw + 9, w32, w28, w20, w8, w4, k); - BODY_20_39(36, A, B, C, D, E, T); - BODY_20_39(37, T, A, B, C, D, E); - BODY_20_39(38, E, T, A, B, C, D); - BODY_20_39(39, D, E, T, A, B, C); - - k = K_40_59_x_4; - const vec_uint32_t w40 = sched_32_79(vw + 10, w36, w32, w24, w12, w8, k); - BODY_40_59(40, C, D, E, T, A, B); - BODY_40_59(41, B, C, D, E, T, A); - BODY_40_59(42, A, B, C, D, E, T); - BODY_40_59(43, T, A, B, C, D, E); - - const vec_uint32_t w44 = sched_32_79(vw + 11, w40, w36, w28, w16, w12, k); - BODY_40_59(44, E, T, A, B, C, D); - BODY_40_59(45, D, E, T, A, B, C); - BODY_40_59(46, C, D, E, T, A, B); - BODY_40_59(47, B, C, D, E, T, A); - - const vec_uint32_t w48 = sched_32_79(vw + 12, w44, w40, w32, w20, w16, k); - BODY_40_59(48, A, B, C, D, E, T); - BODY_40_59(49, T, A, B, C, D, E); - BODY_40_59(50, E, T, A, B, C, D); - BODY_40_59(51, D, E, T, A, B, C); - - const vec_uint32_t w52 = sched_32_79(vw + 13, w48, w44, w36, w24, w20, k); - BODY_40_59(52, C, D, E, T, A, B); - BODY_40_59(53, B, C, D, E, T, A); - BODY_40_59(54, A, B, C, D, E, T); - BODY_40_59(55, T, A, B, C, D, E); - - const vec_uint32_t w56 = sched_32_79(vw + 14, w52, w48, w40, w28, w24, k); - BODY_40_59(56, E, T, A, B, C, D); - BODY_40_59(57, D, E, T, A, B, C); - BODY_40_59(58, C, D, E, T, A, B); - BODY_40_59(59, B, C, D, E, T, A); - - k = K_60_79_x_4; - const vec_uint32_t w60 = sched_32_79(vw + 15, w56, w52, w44, w32, w28, k); - BODY_60_79(60, A, B, C, D, E, T); - BODY_60_79(61, T, A, B, C, D, E); - BODY_60_79(62, E, T, A, B, C, D); - BODY_60_79(63, D, E, T, A, B, C); - - const vec_uint32_t w64 = sched_32_79(vw + 16, w60, w56, w48, w36, w32, k); - BODY_60_79(64, C, D, E, T, A, B); - BODY_60_79(65, B, C, D, E, T, A); - BODY_60_79(66, A, B, C, D, E, T); - BODY_60_79(67, T, A, B, C, D, E); - - const vec_uint32_t w68 = sched_32_79(vw + 17, w64, w60, w52, w40, w36, k); - BODY_60_79(68, E, T, A, B, C, D); - BODY_60_79(69, D, E, T, A, B, C); - BODY_60_79(70, C, D, E, T, A, B); - BODY_60_79(71, B, C, D, E, T, A); - - const vec_uint32_t w72 = sched_32_79(vw + 18, w68, w64, w56, w44, w40, k); - BODY_60_79(72, A, B, C, D, E, T); - BODY_60_79(73, T, A, B, C, D, E); - BODY_60_79(74, E, T, A, B, C, D); - BODY_60_79(75, D, E, T, A, B, C); - - // We don't use the last value - (void)sched_32_79(vw + 19, w72, w68, w60, w48, w44, k); - BODY_60_79(76, C, D, E, T, A, B); - BODY_60_79(77, B, C, D, E, T, A); - BODY_60_79(78, A, B, C, D, E, T); - BODY_60_79(79, T, A, B, C, D, E); - - const uint32_t mask = 0xffffffffUL; - state[0] = (state[0] + E) & mask; - state[1] = (state[1] + T) & mask; - state[2] = (state[2] + A) & mask; - state[3] = (state[3] + B) & mask; - state[4] = (state[4] + C) & mask; - - data += 64; - if (--num == 0) { - break; - } - - A = state[0]; - B = state[1]; - C = state[2]; - D = state[3]; - E = state[4]; - } -} - -#endif // OPENSSL_PPC64LE - -#undef K_00_19 -#undef K_20_39 -#undef K_40_59 -#undef K_60_79 -#undef F_00_19 -#undef F_20_39 -#undef F_40_59 -#undef F_60_79 -#undef BODY_00_19 -#undef BODY_20_39 -#undef BODY_40_59 -#undef BODY_60_79 diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-586.linux.x86.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-586-linux.linux.x86.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-586.linux.x86.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-586-linux.linux.x86.S index e278903e..0e2a28eb 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-586.linux.x86.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-586-linux.linux.x86.S @@ -3,7 +3,13 @@ // This file is generated from a similarly-named Perl script in the BoringSSL // source tree. Do not edit by hand. -#if defined(__i386__) +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -3806,8 +3812,11 @@ _sha1_block_data_order_avx: .byte 102,111,114,109,32,102,111,114,32,120,56,54,44,32,67,82 .byte 89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112 .byte 114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +#endif // !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -.section .note.GNU-stack,"",@progbits #endif // defined(__i386__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-armv4-large.ios.arm.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-armv4-large-ios.ios.arm.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-armv4-large.ios.arm.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-armv4-large-ios.ios.arm.S index c85ee85c..396b499d 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-armv4-large.ios.arm.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-armv4-large-ios.ios.arm.S @@ -10,7 +10,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1517,7 +1517,11 @@ OPENSSL_armcap_P: .long 0 .private_extern _OPENSSL_armcap_P #endif -#endif // !OPENSSL_NO_ASM +#endif // !OPENSSL_NO_ASM && defined(__ARMEL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif #endif // defined(__arm__) && defined(__APPLE__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-armv4-large.linux.arm.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-armv4-large-linux.linux.arm.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-armv4-large.linux.arm.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-armv4-large-linux.linux.arm.S index 6907a0b2..b39467c0 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-armv4-large.linux.arm.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-armv4-large-linux.linux.arm.S @@ -10,8 +10,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__arm__) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1508,9 +1507,11 @@ sha1_block_data_order_armv8: .comm OPENSSL_armcap_P,4,4 .hidden OPENSSL_armcap_P #endif +#endif // !OPENSSL_NO_ASM && defined(__ARMEL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM -.section .note.GNU-stack,"",%progbits #endif // defined(__arm__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-armv8.ios.aarch64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-armv8-ios.ios.aarch64.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-armv8.ios.aarch64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-armv8-ios.ios.aarch64.S index bdb3122e..16e548ee 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-armv8.ios.aarch64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-armv8-ios.ios.aarch64.S @@ -10,7 +10,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1234,7 +1234,11 @@ Lconst: .byte 83,72,65,49,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .align 2 .align 2 -#endif // !OPENSSL_NO_ASM +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif #endif // defined(__aarch64__) && defined(__APPLE__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-armv8.linux.aarch64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-armv8-linux.linux.aarch64.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-armv8.linux.aarch64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-armv8-linux.linux.aarch64.S index 738f12bc..9f9e994e 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-armv8.linux.aarch64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-armv8-linux.linux.aarch64.S @@ -10,8 +10,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__aarch64__) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1235,9 +1234,11 @@ sha1_block_armv8: .byte 83,72,65,49,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .align 2 .align 2 +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM -.section .note.GNU-stack,"",%progbits #endif // defined(__aarch64__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-x86_64.linux.x86_64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-x86_64-linux.linux.x86_64.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-x86_64.linux.x86_64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-x86_64-linux.linux.x86_64.S index 039a6aa3..e416fd2c 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-x86_64.linux.x86_64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-x86_64-linux.linux.x86_64.S @@ -9,7 +9,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1301,6 +1301,7 @@ _shaext_shortcut: leaq 64(%rsi),%r8 paddd %xmm4,%xmm1 cmovneq %r8,%rsi + prefetcht0 512(%rsi) movdqa %xmm0,%xmm8 .byte 15,56,201,229 movdqa %xmm0,%xmm2 @@ -5451,6 +5452,7 @@ _avx2_shortcut: .byte 0xf3,0xc3 .cfi_endproc .size sha1_block_data_order_avx2,.-sha1_block_data_order_avx2 +.section .rodata .align 64 K_XX_XX: .long 0x5a827999,0x5a827999,0x5a827999,0x5a827999 @@ -5466,8 +5468,12 @@ K_XX_XX: .byte 0xf,0xe,0xd,0xc,0xb,0xa,0x9,0x8,0x7,0x6,0x5,0x4,0x3,0x2,0x1,0x0 .byte 83,72,65,49,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .align 64 +.text +#endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -.section .note.GNU-stack,"",@progbits #endif // defined(__x86_64__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-x86_64.mac.x86_64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-x86_64-mac.mac.x86_64.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-x86_64.mac.x86_64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-x86_64-mac.mac.x86_64.S index 23797c42..75ef79cb 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-x86_64.mac.x86_64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-x86_64-mac.mac.x86_64.S @@ -9,7 +9,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1300,6 +1300,7 @@ L$oop_shaext: leaq 64(%rsi),%r8 paddd %xmm4,%xmm1 cmovneq %r8,%rsi + prefetcht0 512(%rsi) movdqa %xmm0,%xmm8 .byte 15,56,201,229 movdqa %xmm0,%xmm2 @@ -5450,6 +5451,7 @@ L$epilogue_avx2: .byte 0xf3,0xc3 +.section __DATA,__const .p2align 6 K_XX_XX: .long 0x5a827999,0x5a827999,0x5a827999,0x5a827999 @@ -5465,6 +5467,11 @@ K_XX_XX: .byte 0xf,0xe,0xd,0xc,0xb,0xa,0x9,0x8,0x7,0x6,0x5,0x4,0x3,0x2,0x1,0x0 .byte 83,72,65,49,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .p2align 6 +.text +#endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif #endif // defined(__x86_64__) && defined(__APPLE__) #if defined(__linux__) && defined(__ELF__) diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-586.linux.x86.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-586-linux.linux.x86.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-586.linux.x86.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-586-linux.linux.x86.S index 18c31a20..4969055b 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-586.linux.x86.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-586-linux.linux.x86.S @@ -3,7 +3,13 @@ // This file is generated from a similarly-named Perl script in the BoringSSL // source tree. Do not edit by hand. -#if defined(__i386__) +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -5565,8 +5571,11 @@ sha256_block_data_order: popl %ebp ret .size sha256_block_data_order,.-.L_sha256_block_data_order_begin +#endif // !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -.section .note.GNU-stack,"",@progbits #endif // defined(__i386__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-armv4.ios.arm.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-armv4-ios.ios.arm.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-armv4.ios.arm.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-armv4-ios.ios.arm.S index 405080fd..e75b9635 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-armv4.ios.arm.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-armv4-ios.ios.arm.S @@ -10,7 +10,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -2845,7 +2845,11 @@ OPENSSL_armcap_P: .long 0 .private_extern _OPENSSL_armcap_P #endif -#endif // !OPENSSL_NO_ASM +#endif // !OPENSSL_NO_ASM && defined(__ARMEL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif #endif // defined(__arm__) && defined(__APPLE__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-armv4.linux.arm.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-armv4-linux.linux.arm.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-armv4.linux.arm.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-armv4-linux.linux.arm.S index f132da91..0393f516 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-armv4.linux.arm.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-armv4-linux.linux.arm.S @@ -10,8 +10,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__arm__) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -2836,9 +2835,11 @@ sha256_block_data_order_armv8: .comm OPENSSL_armcap_P,4,4 .hidden OPENSSL_armcap_P #endif +#endif // !OPENSSL_NO_ASM && defined(__ARMEL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM -.section .note.GNU-stack,"",%progbits #endif // defined(__arm__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-armv8.ios.aarch64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-armv8-ios.ios.aarch64.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-armv8.ios.aarch64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-armv8-ios.ios.aarch64.S index b5d2d996..61e490e1 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-armv8.ios.aarch64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-armv8-ios.ios.aarch64.S @@ -10,7 +10,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1211,7 +1211,11 @@ Loop_hw: ret #endif -#endif // !OPENSSL_NO_ASM +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif #endif // defined(__aarch64__) && defined(__APPLE__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-armv8.linux.aarch64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-armv8-linux.linux.aarch64.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-armv8.linux.aarch64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-armv8-linux.linux.aarch64.S index b7255a3d..a8c28bca 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-armv8.linux.aarch64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-armv8-linux.linux.aarch64.S @@ -10,8 +10,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__aarch64__) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1212,9 +1211,11 @@ sha256_block_armv8: ret .size sha256_block_armv8,.-sha256_block_armv8 #endif +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM -.section .note.GNU-stack,"",%progbits #endif // defined(__aarch64__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-x86_64.linux.x86_64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-x86_64-linux.linux.x86_64.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-x86_64.linux.x86_64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-x86_64-linux.linux.x86_64.S index f611dd7a..1bd2f4b1 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-x86_64.linux.x86_64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-x86_64-linux.linux.x86_64.S @@ -9,7 +9,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1742,6 +1742,7 @@ sha256_block_data_order: .byte 0xf3,0xc3 .cfi_endproc .size sha256_block_data_order,.-sha256_block_data_order +.section .rodata .align 64 .type K256,@object K256: @@ -1785,6 +1786,7 @@ K256: .long 0xffffffff,0xffffffff,0x03020100,0x0b0a0908 .long 0xffffffff,0xffffffff,0x03020100,0x0b0a0908 .byte 83,72,65,50,53,54,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.text .type sha256_block_data_order_shaext,@function .align 64 sha256_block_data_order_shaext: @@ -4183,7 +4185,10 @@ sha256_block_data_order_avx: .cfi_endproc .size sha256_block_data_order_avx,.-sha256_block_data_order_avx #endif -.section .note.GNU-stack,"",@progbits +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif #endif // defined(__x86_64__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-x86_64.mac.x86_64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-x86_64-mac.mac.x86_64.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-x86_64.mac.x86_64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-x86_64-mac.mac.x86_64.S index a6f72595..30a2c1b4 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-x86_64.mac.x86_64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-x86_64-mac.mac.x86_64.S @@ -9,7 +9,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1741,6 +1741,7 @@ L$epilogue: .byte 0xf3,0xc3 +.section __DATA,__const .p2align 6 K256: @@ -1784,6 +1785,7 @@ K256: .long 0xffffffff,0xffffffff,0x03020100,0x0b0a0908 .long 0xffffffff,0xffffffff,0x03020100,0x0b0a0908 .byte 83,72,65,50,53,54,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.text .p2align 6 sha256_block_data_order_shaext: @@ -4181,6 +4183,10 @@ L$epilogue_avx: .byte 0xf3,0xc3 +#endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif #endif // defined(__x86_64__) && defined(__APPLE__) #if defined(__linux__) && defined(__ELF__) diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-586.linux.x86.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-586-linux.linux.x86.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-586.linux.x86.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-586-linux.linux.x86.S index b62e0862..f924354b 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-586.linux.x86.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-586-linux.linux.x86.S @@ -3,7 +3,13 @@ // This file is generated from a similarly-named Perl script in the BoringSSL // source tree. Do not edit by hand. -#if defined(__i386__) +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -2835,8 +2841,11 @@ sha512_block_data_order: .byte 67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97 .byte 112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103 .byte 62,0 +#endif // !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -.section .note.GNU-stack,"",@progbits #endif // defined(__i386__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-armv4.ios.arm.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-armv4-ios.ios.arm.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-armv4.ios.arm.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-armv4-ios.ios.arm.S index 4dcdaf5a..510d6fea 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-armv4.ios.arm.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-armv4-ios.ios.arm.S @@ -10,7 +10,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1898,7 +1898,11 @@ OPENSSL_armcap_P: .long 0 .private_extern _OPENSSL_armcap_P #endif -#endif // !OPENSSL_NO_ASM +#endif // !OPENSSL_NO_ASM && defined(__ARMEL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif #endif // defined(__arm__) && defined(__APPLE__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-armv4.linux.arm.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-armv4-linux.linux.arm.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-armv4.linux.arm.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-armv4-linux.linux.arm.S index 689ca91e..a53351b2 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-armv4.linux.arm.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-armv4-linux.linux.arm.S @@ -10,8 +10,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__arm__) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1891,9 +1890,11 @@ sha512_block_data_order_neon: .comm OPENSSL_armcap_P,4,4 .hidden OPENSSL_armcap_P #endif +#endif // !OPENSSL_NO_ASM && defined(__ARMEL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM -.section .note.GNU-stack,"",%progbits #endif // defined(__arm__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-armv8.ios.aarch64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-armv8-ios.ios.aarch64.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-armv8.ios.aarch64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-armv8-ios.ios.aarch64.S index 40167b7e..a420021c 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-armv8.ios.aarch64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-armv8-ios.ios.aarch64.S @@ -10,7 +10,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1613,7 +1613,11 @@ Loop_hw: ret #endif -#endif // !OPENSSL_NO_ASM +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif #endif // defined(__aarch64__) && defined(__APPLE__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-armv8.linux.aarch64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-armv8-linux.linux.aarch64.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-armv8.linux.aarch64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-armv8-linux.linux.aarch64.S index e715e58d..135ddac9 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-armv8.linux.aarch64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-armv8-linux.linux.aarch64.S @@ -10,8 +10,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__aarch64__) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1614,9 +1613,11 @@ sha512_block_armv8: ret .size sha512_block_armv8,.-sha512_block_armv8 #endif +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM -.section .note.GNU-stack,"",%progbits #endif // defined(__aarch64__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-x86_64.linux.x86_64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-x86_64-linux.linux.x86_64.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-x86_64.linux.x86_64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-x86_64-linux.linux.x86_64.S index 2d0f335c..b1063615 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-x86_64.linux.x86_64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-x86_64-linux.linux.x86_64.S @@ -9,7 +9,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1738,6 +1738,7 @@ sha512_block_data_order: .byte 0xf3,0xc3 .cfi_endproc .size sha512_block_data_order,.-sha512_block_data_order +.section .rodata .align 64 .type K512,@object K512: @@ -1825,6 +1826,7 @@ K512: .quad 0x0001020304050607,0x08090a0b0c0d0e0f .quad 0x0001020304050607,0x08090a0b0c0d0e0f .byte 83,72,65,53,49,50,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.text .type sha512_block_data_order_avx,@function .align 64 sha512_block_data_order_avx: @@ -2991,7 +2993,10 @@ sha512_block_data_order_avx: .cfi_endproc .size sha512_block_data_order_avx,.-sha512_block_data_order_avx #endif -.section .note.GNU-stack,"",@progbits +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif #endif // defined(__x86_64__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-x86_64.mac.x86_64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-x86_64-mac.mac.x86_64.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-x86_64.mac.x86_64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-x86_64-mac.mac.x86_64.S index 5c00a6f7..0008bf2c 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-x86_64.mac.x86_64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-x86_64-mac.mac.x86_64.S @@ -9,7 +9,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1737,6 +1737,7 @@ L$epilogue: .byte 0xf3,0xc3 +.section __DATA,__const .p2align 6 K512: @@ -1824,6 +1825,7 @@ K512: .quad 0x0001020304050607,0x08090a0b0c0d0e0f .quad 0x0001020304050607,0x08090a0b0c0d0e0f .byte 83,72,65,53,49,50,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.text .p2align 6 sha512_block_data_order_avx: @@ -2989,6 +2991,10 @@ L$epilogue_avx: .byte 0xf3,0xc3 +#endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif #endif // defined(__x86_64__) && defined(__APPLE__) #if defined(__linux__) && defined(__ELF__) diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-armv7.ios.arm.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-armv7-ios.ios.arm.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-armv7.ios.arm.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-armv7-ios.ios.arm.S index 37912592..c59d66d5 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-armv7.ios.arm.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-armv7-ios.ios.arm.S @@ -10,7 +10,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1264,7 +1264,11 @@ Lctr32_done: vldmia sp!, {d8,d9,d10,d11,d12,d13,d14,d15} ldmia sp!, {r7,r8,r9,r10,r11, pc} @ return -#endif // !OPENSSL_NO_ASM +#endif // !OPENSSL_NO_ASM && defined(__ARMEL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif #endif // defined(__arm__) && defined(__APPLE__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-armv7.linux.arm.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-armv7-linux.linux.arm.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-armv7.linux.arm.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-armv7-linux.linux.arm.S index b6fc2c10..3c4a80cb 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-armv7.linux.arm.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-armv7-linux.linux.arm.S @@ -10,8 +10,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__arm__) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1233,9 +1232,11 @@ vpaes_ctr32_encrypt_blocks: vldmia sp!, {d8,d9,d10,d11,d12,d13,d14,d15} ldmia sp!, {r7,r8,r9,r10,r11, pc} @ return .size vpaes_ctr32_encrypt_blocks,.-vpaes_ctr32_encrypt_blocks +#endif // !OPENSSL_NO_ASM && defined(__ARMEL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM -.section .note.GNU-stack,"",%progbits #endif // defined(__arm__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-armv8.ios.aarch64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-armv8-ios.ios.aarch64.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-armv8.ios.aarch64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-armv8-ios.ios.aarch64.S index fea011af..f3f95a73 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-armv8.ios.aarch64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-armv8-ios.ios.aarch64.S @@ -10,7 +10,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1231,7 +1231,11 @@ Lctr32_done: AARCH64_VALIDATE_LINK_REGISTER ret -#endif // !OPENSSL_NO_ASM +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif #endif // defined(__aarch64__) && defined(__APPLE__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-armv8.linux.aarch64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-armv8-linux.linux.aarch64.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-armv8.linux.aarch64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-armv8-linux.linux.aarch64.S index 6034268a..875cfba3 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-armv8.linux.aarch64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-armv8-linux.linux.aarch64.S @@ -10,8 +10,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__aarch64__) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1232,9 +1231,11 @@ vpaes_ctr32_encrypt_blocks: AARCH64_VALIDATE_LINK_REGISTER ret .size vpaes_ctr32_encrypt_blocks,.-vpaes_ctr32_encrypt_blocks +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM -.section .note.GNU-stack,"",%progbits #endif // defined(__aarch64__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-x86.linux.x86.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-x86-linux.linux.x86.S similarity index 97% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-x86.linux.x86.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-x86-linux.linux.x86.S index a44f2e16..6f4189de 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-x86.linux.x86.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-x86-linux.linux.x86.S @@ -3,7 +3,13 @@ // This file is generated from a similarly-named Perl script in the BoringSSL // source tree. Do not edit by hand. -#if defined(__i386__) +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -706,8 +712,11 @@ vpaes_cbc_encrypt: popl %ebp ret .size vpaes_cbc_encrypt,.-.L_vpaes_cbc_encrypt_begin +#endif // !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -.section .note.GNU-stack,"",@progbits #endif // defined(__i386__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-x86_64.linux.x86_64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-x86_64-linux.linux.x86_64.S similarity index 98% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-x86_64.linux.x86_64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-x86_64-linux.linux.x86_64.S index c821d36a..4f52c5bc 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-x86_64.linux.x86_64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-x86_64-linux.linux.x86_64.S @@ -9,7 +9,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1022,6 +1022,7 @@ _vpaes_preheat: .type _vpaes_consts,@object +.section .rodata .align 64 _vpaes_consts: .Lk_inv: @@ -1131,8 +1132,12 @@ _vpaes_consts: .byte 86,101,99,116,111,114,32,80,101,114,109,117,116,97,116,105,111,110,32,65,69,83,32,102,111,114,32,120,56,54,95,54,52,47,83,83,83,69,51,44,32,77,105,107,101,32,72,97,109,98,117,114,103,32,40,83,116,97,110,102,111,114,100,32,85,110,105,118,101,114,115,105,116,121,41,0 .align 64 .size _vpaes_consts,.-_vpaes_consts +.text +#endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -.section .note.GNU-stack,"",@progbits #endif // defined(__x86_64__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-x86_64.mac.x86_64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-x86_64-mac.mac.x86_64.S similarity index 98% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-x86_64.mac.x86_64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-x86_64-mac.mac.x86_64.S index f87404b8..9a374629 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-x86_64.mac.x86_64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-x86_64-mac.mac.x86_64.S @@ -9,7 +9,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1020,6 +1020,7 @@ _vpaes_preheat: +.section __DATA,__const .p2align 6 _vpaes_consts: L$k_inv: @@ -1129,6 +1130,11 @@ L$ctr_add_two: .byte 86,101,99,116,111,114,32,80,101,114,109,117,116,97,116,105,111,110,32,65,69,83,32,102,111,114,32,120,56,54,95,54,52,47,83,83,83,69,51,44,32,77,105,107,101,32,72,97,109,98,117,114,103,32,40,83,116,97,110,102,111,114,100,32,85,110,105,118,101,114,115,105,116,121,41,0 .p2align 6 +.text +#endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif #endif // defined(__x86_64__) && defined(__APPLE__) #if defined(__linux__) && defined(__ELF__) diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/x86-mont.linux.x86.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/x86-mont-linux.linux.x86.S similarity index 95% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/x86-mont.linux.x86.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/x86-mont-linux.linux.x86.S index c0b284ba..021df1df 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/x86-mont.linux.x86.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/x86-mont-linux.linux.x86.S @@ -3,7 +3,13 @@ // This file is generated from a similarly-named Perl script in the BoringSSL // source tree. Do not edit by hand. -#if defined(__i386__) +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -482,8 +488,11 @@ bn_mul_mont: .byte 54,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121 .byte 32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46 .byte 111,114,103,62,0 +#endif // !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -.section .note.GNU-stack,"",@progbits #endif // defined(__i386__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/x86_64-mont.linux.x86_64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/x86_64-mont-linux.linux.x86_64.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/x86_64-mont.linux.x86_64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/x86_64-mont-linux.linux.x86_64.S index f24bdc9c..9591d03e 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/x86_64-mont.linux.x86_64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/x86_64-mont-linux.linux.x86_64.S @@ -9,7 +9,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1259,7 +1259,10 @@ bn_mulx4x_mont: .byte 77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .align 16 #endif -.section .note.GNU-stack,"",@progbits +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif #endif // defined(__x86_64__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/x86_64-mont.mac.x86_64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/x86_64-mont-mac.mac.x86_64.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/x86_64-mont.mac.x86_64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/x86_64-mont-mac.mac.x86_64.S index aa62b060..d1575f7c 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/x86_64-mont.mac.x86_64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/x86_64-mont-mac.mac.x86_64.S @@ -9,7 +9,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1256,6 +1256,10 @@ L$mulx4x_epilogue: .byte 77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .p2align 4 #endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif #endif // defined(__x86_64__) && defined(__APPLE__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/x86_64-mont5.linux.x86_64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/x86_64-mont5-linux.linux.x86_64.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/x86_64-mont5.linux.x86_64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/x86_64-mont5-linux.linux.x86_64.S index 01e28d77..a9a40976 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/x86_64-mont5.linux.x86_64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/x86_64-mont5-linux.linux.x86_64.S @@ -9,7 +9,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -209,6 +209,7 @@ bn_mul_mont_gather5: por %xmm2,%xmm0 por %xmm3,%xmm1 por %xmm1,%xmm0 + pshufd $0x4e,%xmm0,%xmm1 por %xmm1,%xmm0 leaq 256(%r12),%r12 @@ -332,6 +333,7 @@ bn_mul_mont_gather5: por %xmm2,%xmm4 por %xmm3,%xmm5 por %xmm5,%xmm4 + pshufd $0x4e,%xmm4,%xmm0 por %xmm4,%xmm0 leaq 256(%r12),%r12 @@ -700,6 +702,7 @@ mul4x_internal: por %xmm2,%xmm0 por %xmm3,%xmm1 por %xmm1,%xmm0 + pshufd $0x4e,%xmm0,%xmm1 por %xmm1,%xmm0 leaq 256(%r12),%r12 @@ -907,6 +910,7 @@ mul4x_internal: por %xmm2,%xmm4 por %xmm3,%xmm5 por %xmm5,%xmm4 + pshufd $0x4e,%xmm4,%xmm0 por %xmm4,%xmm0 leaq 256(%r12),%r12 @@ -2323,6 +2327,7 @@ mulx4x_internal: por %xmm2,%xmm0 por %xmm3,%xmm1 pxor %xmm1,%xmm0 + pshufd $0x4e,%xmm0,%xmm1 por %xmm1,%xmm0 leaq 256(%rdi),%rdi @@ -2473,6 +2478,7 @@ mulx4x_internal: por %xmm2,%xmm4 por %xmm3,%xmm5 por %xmm5,%xmm4 + pshufd $0x4e,%xmm4,%xmm0 por %xmm4,%xmm0 leaq 256(%rdi),%rdi @@ -3421,6 +3427,15 @@ bn_scatter5: .cfi_startproc cmpl $0,%esi jz .Lscatter_epilogue + + + + + + + + + leaq (%rdx,%rcx,8),%rdx .Lscatter: movq (%rdi),%rax @@ -3589,6 +3604,7 @@ bn_gather5: por %xmm3,%xmm5 por %xmm5,%xmm4 leaq 256(%r11),%r11 + pshufd $0x4e,%xmm4,%xmm0 por %xmm4,%xmm0 movq %xmm0,(%rdi) @@ -3602,13 +3618,18 @@ bn_gather5: .LSEH_end_bn_gather5: .cfi_endproc .size bn_gather5,.-bn_gather5 +.section .rodata .align 64 .Linc: .long 0,0, 1,1 .long 2,2, 2,2 .byte 77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,119,105,116,104,32,115,99,97,116,116,101,114,47,103,97,116,104,101,114,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.text +#endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -.section .note.GNU-stack,"",@progbits #endif // defined(__x86_64__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/fipsmodule/x86_64-mont5.mac.x86_64.S b/Sources/CNIOBoringSSL/crypto/fipsmodule/x86_64-mont5-mac.mac.x86_64.S similarity index 99% rename from Sources/CNIOBoringSSL/crypto/fipsmodule/x86_64-mont5.mac.x86_64.S rename to Sources/CNIOBoringSSL/crypto/fipsmodule/x86_64-mont5-mac.mac.x86_64.S index b9e4bb17..cd58ea58 100644 --- a/Sources/CNIOBoringSSL/crypto/fipsmodule/x86_64-mont5.mac.x86_64.S +++ b/Sources/CNIOBoringSSL/crypto/fipsmodule/x86_64-mont5-mac.mac.x86_64.S @@ -9,7 +9,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -208,6 +208,7 @@ L$mul_body: por %xmm2,%xmm0 por %xmm3,%xmm1 por %xmm1,%xmm0 + pshufd $0x4e,%xmm0,%xmm1 por %xmm1,%xmm0 leaq 256(%r12),%r12 @@ -331,6 +332,7 @@ L$outer: por %xmm2,%xmm4 por %xmm3,%xmm5 por %xmm5,%xmm4 + pshufd $0x4e,%xmm4,%xmm0 por %xmm4,%xmm0 leaq 256(%r12),%r12 @@ -699,6 +701,7 @@ mul4x_internal: por %xmm2,%xmm0 por %xmm3,%xmm1 por %xmm1,%xmm0 + pshufd $0x4e,%xmm0,%xmm1 por %xmm1,%xmm0 leaq 256(%r12),%r12 @@ -906,6 +909,7 @@ L$outer4x: por %xmm2,%xmm4 por %xmm3,%xmm5 por %xmm5,%xmm4 + pshufd $0x4e,%xmm4,%xmm0 por %xmm4,%xmm0 leaq 256(%r12),%r12 @@ -2322,6 +2326,7 @@ mulx4x_internal: por %xmm2,%xmm0 por %xmm3,%xmm1 pxor %xmm1,%xmm0 + pshufd $0x4e,%xmm0,%xmm1 por %xmm1,%xmm0 leaq 256(%rdi),%rdi @@ -2472,6 +2477,7 @@ L$mulx4x_outer: por %xmm2,%xmm4 por %xmm3,%xmm5 por %xmm5,%xmm4 + pshufd $0x4e,%xmm4,%xmm0 por %xmm4,%xmm0 leaq 256(%rdi),%rdi @@ -3420,6 +3426,15 @@ _bn_scatter5: cmpl $0,%esi jz L$scatter_epilogue + + + + + + + + + leaq (%rdx,%rcx,8),%rdx L$scatter: movq (%rdi),%rax @@ -3588,6 +3603,7 @@ L$gather: por %xmm3,%xmm5 por %xmm5,%xmm4 leaq 256(%r11),%r11 + pshufd $0x4e,%xmm4,%xmm0 por %xmm4,%xmm0 movq %xmm0,(%rdi) @@ -3601,11 +3617,17 @@ L$gather: L$SEH_end_bn_gather5: +.section __DATA,__const .p2align 6 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 +.text +#endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif #endif // defined(__x86_64__) && defined(__APPLE__) #if defined(__linux__) && defined(__ELF__) diff --git a/Sources/CNIOBoringSSL/crypto/hpke/hpke.c b/Sources/CNIOBoringSSL/crypto/hpke/hpke.c index 35de7ffc..59593b1e 100644 --- a/Sources/CNIOBoringSSL/crypto/hpke/hpke.c +++ b/Sources/CNIOBoringSSL/crypto/hpke/hpke.c @@ -250,7 +250,6 @@ void EVP_HPKE_KEY_cleanup(EVP_HPKE_KEY *key) { EVP_HPKE_KEY *EVP_HPKE_KEY_new(void) { EVP_HPKE_KEY *key = OPENSSL_malloc(sizeof(EVP_HPKE_KEY)); if (key == NULL) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); return NULL; } EVP_HPKE_KEY_zero(key); @@ -465,7 +464,6 @@ void EVP_HPKE_CTX_cleanup(EVP_HPKE_CTX *ctx) { EVP_HPKE_CTX *EVP_HPKE_CTX_new(void) { EVP_HPKE_CTX *ctx = OPENSSL_malloc(sizeof(EVP_HPKE_CTX)); if (ctx == NULL) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); return NULL; } EVP_HPKE_CTX_zero(ctx); diff --git a/Sources/CNIOBoringSSL/crypto/hrss/asm/poly_rq_mul.S b/Sources/CNIOBoringSSL/crypto/hrss/asm/poly_rq_mul.S index f6538fe4..d377a093 100644 --- a/Sources/CNIOBoringSSL/crypto/hrss/asm/poly_rq_mul.S +++ b/Sources/CNIOBoringSSL/crypto/hrss/asm/poly_rq_mul.S @@ -14,7 +14,7 @@ // 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(OPENSSL_SMALL) && defined(__linux__) +#if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_SMALL) && defined(__linux__) && defined(__x86_64__) #if defined(BORINGSSL_PREFIX) #include @@ -8491,7 +8491,7 @@ ret #endif #if defined(__ELF__) -.section .note.GNU-stack,"",@progbits +.section .note.GNU-stack,"",%progbits #endif #endif // defined(__x86_64__) && defined(__linux__) #if defined(__linux__) && defined(__ELF__) diff --git a/Sources/CNIOBoringSSL/crypto/internal.h b/Sources/CNIOBoringSSL/crypto/internal.h index a2155024..26668af7 100644 --- a/Sources/CNIOBoringSSL/crypto/internal.h +++ b/Sources/CNIOBoringSSL/crypto/internal.h @@ -166,7 +166,7 @@ extern "C" { #if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || defined(OPENSSL_ARM) || \ - defined(OPENSSL_AARCH64) || defined(OPENSSL_PPC64LE) + defined(OPENSSL_AARCH64) // OPENSSL_cpuid_setup initializes the platform-specific feature cache. void OPENSSL_cpuid_setup(void); #endif @@ -225,6 +225,16 @@ typedef __uint128_t uint128_t; #define OPENSSL_SSE2 #endif +#if defined(BORINGSSL_MALLOC_FAILURE_TESTING) +// OPENSSL_reset_malloc_counter_for_testing, when malloc testing is enabled, +// resets the internal malloc counter, to simulate further malloc failures. This +// should be called in between independent tests, at a point where failure from +// a previous test will not impact subsequent ones. +OPENSSL_EXPORT void OPENSSL_reset_malloc_counter_for_testing(void); +#else +OPENSSL_INLINE void OPENSSL_reset_malloc_counter_for_testing(void) {} +#endif + // Pointer utility functions. @@ -302,7 +312,7 @@ typedef uint32_t crypto_word_t; // always has the same output for a given input. This allows it to eliminate // dead code, move computations across loops, and vectorize. static inline crypto_word_t value_barrier_w(crypto_word_t a) { -#if !defined(OPENSSL_NO_ASM) && (defined(__GNUC__) || defined(__clang__)) +#if defined(__GNUC__) || defined(__clang__) __asm__("" : "+r"(a) : /* no inputs */); #endif return a; @@ -310,7 +320,7 @@ static inline crypto_word_t value_barrier_w(crypto_word_t a) { // value_barrier_u32 behaves like |value_barrier_w| but takes a |uint32_t|. static inline uint32_t value_barrier_u32(uint32_t a) { -#if !defined(OPENSSL_NO_ASM) && (defined(__GNUC__) || defined(__clang__)) +#if defined(__GNUC__) || defined(__clang__) __asm__("" : "+r"(a) : /* no inputs */); #endif return a; @@ -318,7 +328,7 @@ static inline uint32_t value_barrier_u32(uint32_t a) { // value_barrier_u64 behaves like |value_barrier_w| but takes a |uint64_t|. static inline uint64_t value_barrier_u64(uint64_t a) { -#if !defined(OPENSSL_NO_ASM) && (defined(__GNUC__) || defined(__clang__)) +#if defined(__GNUC__) || defined(__clang__) __asm__("" : "+r"(a) : /* no inputs */); #endif return a; @@ -465,20 +475,44 @@ static inline int constant_time_select_int(crypto_word_t mask, int a, int b) { // of memory as secret. Secret data is tracked as it flows to registers and // other parts of a memory. If secret data is used as a condition for a branch, // or as a memory index, it will trigger warnings in valgrind. -#define CONSTTIME_SECRET(x, y) VALGRIND_MAKE_MEM_UNDEFINED(x, y) +#define CONSTTIME_SECRET(ptr, len) VALGRIND_MAKE_MEM_UNDEFINED(ptr, len) // CONSTTIME_DECLASSIFY takes a pointer and a number of bytes and marks that // region of memory as public. Public data is not subject to constant-time // rules. -#define CONSTTIME_DECLASSIFY(x, y) VALGRIND_MAKE_MEM_DEFINED(x, y) +#define CONSTTIME_DECLASSIFY(ptr, len) VALGRIND_MAKE_MEM_DEFINED(ptr, len) #else -#define CONSTTIME_SECRET(x, y) -#define CONSTTIME_DECLASSIFY(x, y) +#define CONSTTIME_SECRET(ptr, len) +#define CONSTTIME_DECLASSIFY(ptr, len) #endif // BORINGSSL_CONSTANT_TIME_VALIDATION +static inline crypto_word_t constant_time_declassify_w(crypto_word_t v) { + // Return |v| through a value barrier to be safe. Valgrind-based constant-time + // validation is partly to check the compiler has not undone any constant-time + // work. Any place |BORINGSSL_CONSTANT_TIME_VALIDATION| influences + // optimizations, this validation is inaccurate. + // + // However, by sending pointers through valgrind, we likely inhibit escape + // analysis. On local variables, particularly booleans, we likely + // significantly impact optimizations. + // + // Thus, to be safe, stick a value barrier, in hopes of comparably inhibiting + // compiler analysis. + CONSTTIME_DECLASSIFY(&v, sizeof(v)); + return value_barrier_w(v); +} + +static inline int constant_time_declassify_int(int v) { + static_assert(sizeof(uint32_t) == sizeof(int), + "int is not the same size as uint32_t"); + // See comment above. + CONSTTIME_DECLASSIFY(&v, sizeof(v)); + return value_barrier_u32(v); +} + // Thread-safe initialisation. @@ -1251,16 +1285,6 @@ OPENSSL_INLINE int CRYPTO_is_ARMv8_PMULL_capable(void) { #endif // OPENSSL_ARM || OPENSSL_AARCH64 -#if defined(OPENSSL_PPC64LE) - -// CRYPTO_is_PPC64LE_vcrypto_capable returns true iff the current CPU supports -// the Vector.AES category of instructions. -int CRYPTO_is_PPC64LE_vcrypto_capable(void); - -extern unsigned long OPENSSL_ppc64le_hwcap2; - -#endif // OPENSSL_PPC64LE - #if defined(BORINGSSL_DISPATCH_TEST) // Runtime CPU dispatch testing support @@ -1275,6 +1299,13 @@ extern unsigned long OPENSSL_ppc64le_hwcap2; extern uint8_t BORINGSSL_function_hit[7]; #endif // BORINGSSL_DISPATCH_TEST +// OPENSSL_vasprintf_internal is just like |vasprintf(3)|. If |system_malloc| is +// 0, memory will be allocated with |OPENSSL_malloc| and must be freed with +// |OPENSSL_free|. Otherwise the system |malloc| function is used and the memory +// must be freed with the system |free| function. +OPENSSL_EXPORT int OPENSSL_vasprintf_internal(char **str, const char *format, + va_list args, int system_malloc) + OPENSSL_PRINTF_FORMAT_FUNC(2, 0); #if defined(__cplusplus) } // extern C diff --git a/Sources/CNIOBoringSSL/crypto/kyber/internal.h b/Sources/CNIOBoringSSL/crypto/kyber/internal.h new file mode 100644 index 00000000..b630baa6 --- /dev/null +++ b/Sources/CNIOBoringSSL/crypto/kyber/internal.h @@ -0,0 +1,91 @@ +/* Copyright (c) 2023, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_CRYPTO_KYBER_INTERNAL_H +#define OPENSSL_HEADER_CRYPTO_KYBER_INTERNAL_H + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// KYBER_ENCAP_ENTROPY is the number of bytes of uniformly random entropy +// necessary to encapsulate a secret. The entropy will be leaked to the +// decapsulating party. +#define KYBER_ENCAP_ENTROPY 32 + +// KYBER_GENERATE_KEY_ENTROPY is the number of bytes of uniformly random entropy +// necessary to generate a key. +#define KYBER_GENERATE_KEY_ENTROPY 64 + +struct BORINGSSL_keccak_st { + uint64_t state[25]; + size_t rate_bytes; + size_t offset; +}; + +enum boringssl_keccak_config_t { + boringssl_sha3_256, + boringssl_sha3_512, + boringssl_shake128, + boringssl_shake256, +}; + +// BORINGSSL_keccak hashes |in_len| bytes from |in| and writes |out_len| bytes +// of output to |out|. If the |config| specifies a fixed-output function, like +// SHA3-256, then |out_len| must be the correct length for that function. +OPENSSL_EXPORT void BORINGSSL_keccak(uint8_t *out, size_t out_len, + const uint8_t *in, size_t in_len, + enum boringssl_keccak_config_t config); + +// BORINGSSL_keccak_init absorbs |in_len| bytes from |in| and sets up |ctx| for +// squeezing. The |config| must specify a SHAKE variant, otherwise callers +// should use |BORINGSSL_keccak|. +OPENSSL_EXPORT void BORINGSSL_keccak_init( + struct BORINGSSL_keccak_st *ctx, const uint8_t *in, size_t in_len, + enum boringssl_keccak_config_t config); + +// BORINGSSL_keccak_squeeze writes |out_len| bytes to |out| from |ctx|. +OPENSSL_EXPORT void BORINGSSL_keccak_squeeze(struct BORINGSSL_keccak_st *ctx, + uint8_t *out, size_t out_len); + +// KYBER_generate_key_external_entropy is a deterministic function to create a +// pair of Kyber768 keys, using the supplied entropy. The entropy needs to be +// uniformly random generated. This function is should only be used for tests, +// regular callers should use the non-deterministic |KYBER_generate_key| +// directly. +OPENSSL_EXPORT void KYBER_generate_key_external_entropy( + uint8_t out_encoded_public_key[KYBER_PUBLIC_KEY_BYTES], + struct KYBER_private_key *out_private_key, + const uint8_t entropy[KYBER_GENERATE_KEY_ENTROPY]); + +// KYBER_encap_external_entropy is a deterministic function to encapsulate +// |out_shared_secret_len| bytes of |out_shared_secret| to |ciphertext|, using +// |KYBER_ENCAP_ENTROPY| bytes of |entropy| for randomization. The +// decapsulating side will be able to recover |entropy| in full. This +// function is should only be used for tests, regular callers should use the +// non-deterministic |KYBER_encap| directly. +OPENSSL_EXPORT void KYBER_encap_external_entropy( + uint8_t out_ciphertext[KYBER_CIPHERTEXT_BYTES], uint8_t *out_shared_secret, + size_t out_shared_secret_len, const struct KYBER_public_key *public_key, + const uint8_t entropy[KYBER_ENCAP_ENTROPY]); + +#if defined(__cplusplus) +} +#endif + +#endif // OPENSSL_HEADER_CRYPTO_KYBER_INTERNAL_H diff --git a/Sources/CNIOBoringSSL/crypto/kyber/keccak.c b/Sources/CNIOBoringSSL/crypto/kyber/keccak.c new file mode 100644 index 00000000..130c6c25 --- /dev/null +++ b/Sources/CNIOBoringSSL/crypto/kyber/keccak.c @@ -0,0 +1,204 @@ +/* Copyright (c) 2023, 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 + +#include +#include + +#include "../internal.h" +#include "./internal.h" + + +// keccak_f implements the Keccak-1600 permutation as described at +// https://keccak.team/keccak_specs_summary.html. Each lane is represented as a +// 64-bit value and the 5×5 lanes are stored as an array in row-major order. +static void keccak_f(uint64_t state[25]) { + static const int kNumRounds = 24; + for (int round = 0; round < kNumRounds; round++) { + // θ step + uint64_t c[5]; + for (int x = 0; x < 5; x++) { + c[x] = state[x] ^ state[x + 5] ^ state[x + 10] ^ state[x + 15] ^ + state[x + 20]; + } + + for (int x = 0; x < 5; x++) { + const uint64_t d = c[(x + 4) % 5] ^ CRYPTO_rotl_u64(c[(x + 1) % 5], 1); + for (int y = 0; y < 5; y++) { + state[y * 5 + x] ^= d; + } + } + + // ρ and π steps. + // + // These steps involve a mapping of the state matrix. Each input point, + // (x,y), is rotated and written to the point (y, 2x + 3y). In the Keccak + // pseudo-code a separate array is used because an in-place operation would + // overwrite some values that are subsequently needed. However, the mapping + // forms a trail through 24 of the 25 values so we can do it in place with + // only a single temporary variable. + // + // Start with (1, 0). The value here will be mapped and end up at (0, 2). + // That value will end up at (2, 1), then (1, 2), and so on. After 24 + // steps, 24 of the 25 values have been hit (as this mapping is injective) + // and the sequence will repeat. All that remains is to handle the element + // at (0, 0), but the rotation for that element is zero, and it goes to (0, + // 0), so we can ignore it. + static const uint8_t kIndexes[24] = {10, 7, 11, 17, 18, 3, 5, 16, + 8, 21, 24, 4, 15, 23, 19, 13, + 12, 2, 20, 14, 22, 9, 6, 1}; + static const uint8_t kRotations[24] = {1, 3, 6, 10, 15, 21, 28, 36, + 45, 55, 2, 14, 27, 41, 56, 8, + 25, 43, 62, 18, 39, 61, 20, 44}; + uint64_t prev_value = state[1]; + for (int i = 0; i < 24; i++) { + const uint64_t value = CRYPTO_rotl_u64(prev_value, kRotations[i]); + const size_t index = kIndexes[i]; + prev_value = state[index]; + state[index] = value; + } + + // χ step + for (int y = 0; y < 5; y++) { + const int row_index = 5 * y; + const uint64_t orig_x0 = state[row_index]; + const uint64_t orig_x1 = state[row_index + 1]; + state[row_index] ^= ~orig_x1 & state[row_index + 2]; + state[row_index + 1] ^= ~state[row_index + 2] & state[row_index + 3]; + state[row_index + 2] ^= ~state[row_index + 3] & state[row_index + 4]; + state[row_index + 3] ^= ~state[row_index + 4] & orig_x0; + state[row_index + 4] ^= ~orig_x0 & orig_x1; + } + + // ι step + // + // From https://keccak.team/files/Keccak-reference-3.0.pdf, section + // 1.2, the round constants are based on the output of a LFSR. Thus, as + // suggested in the appendix of of + // https://keccak.team/keccak_specs_summary.html, the values are + // simply encoded here. + static const uint64_t kRoundConstants[24] = { + 0x0000000000000001, 0x0000000000008082, 0x800000000000808a, + 0x8000000080008000, 0x000000000000808b, 0x0000000080000001, + 0x8000000080008081, 0x8000000000008009, 0x000000000000008a, + 0x0000000000000088, 0x0000000080008009, 0x000000008000000a, + 0x000000008000808b, 0x800000000000008b, 0x8000000000008089, + 0x8000000000008003, 0x8000000000008002, 0x8000000000000080, + 0x000000000000800a, 0x800000008000000a, 0x8000000080008081, + 0x8000000000008080, 0x0000000080000001, 0x8000000080008008, + }; + + state[0] ^= kRoundConstants[round]; + } +} + +static void keccak_init(struct BORINGSSL_keccak_st *ctx, + size_t *out_required_out_len, const uint8_t *in, + size_t in_len, enum boringssl_keccak_config_t config) { + size_t capacity_bytes; + uint8_t terminator; + switch (config) { + case boringssl_sha3_256: + capacity_bytes = 512 / 8; + *out_required_out_len = 32; + terminator = 0x06; + break; + case boringssl_sha3_512: + capacity_bytes = 1024 / 8; + *out_required_out_len = 64; + terminator = 0x06; + break; + case boringssl_shake128: + capacity_bytes = 256 / 8; + *out_required_out_len = 0; + terminator = 0x1f; + break; + case boringssl_shake256: + capacity_bytes = 512 / 8; + *out_required_out_len = 0; + terminator = 0x1f; + break; + default: + abort(); + } + + OPENSSL_memset(ctx, 0, sizeof(*ctx)); + ctx->rate_bytes = 200 - capacity_bytes; + assert(ctx->rate_bytes % 8 == 0); + const size_t rate_words = ctx->rate_bytes / 8; + + while (in_len >= ctx->rate_bytes) { + for (size_t i = 0; i < rate_words; i++) { + ctx->state[i] ^= CRYPTO_load_u64_le(in + 8 * i); + } + keccak_f(ctx->state); + in += ctx->rate_bytes; + in_len -= ctx->rate_bytes; + } + + // XOR the final block. Accessing |ctx->state| as a |uint8_t*| is allowed by + // strict aliasing because we require |uint8_t| to be a character type. + uint8_t *state_bytes = (uint8_t *)ctx->state; + assert(in_len < ctx->rate_bytes); + for (size_t i = 0; i < in_len; i++) { + state_bytes[i] ^= in[i]; + } + state_bytes[in_len] ^= terminator; + state_bytes[ctx->rate_bytes - 1] ^= 0x80; + keccak_f(ctx->state); +} + +void BORINGSSL_keccak(uint8_t *out, size_t out_len, const uint8_t *in, + size_t in_len, enum boringssl_keccak_config_t config) { + struct BORINGSSL_keccak_st ctx; + size_t required_out_len; + keccak_init(&ctx, &required_out_len, in, in_len, config); + if (required_out_len != 0 && out_len != required_out_len) { + abort(); + } + BORINGSSL_keccak_squeeze(&ctx, out, out_len); +} + +void BORINGSSL_keccak_init(struct BORINGSSL_keccak_st *ctx, const uint8_t *in, + size_t in_len, + enum boringssl_keccak_config_t config) { + size_t required_out_len; + keccak_init(ctx, &required_out_len, in, in_len, config); + if (required_out_len != 0) { + abort(); + } +} + +void BORINGSSL_keccak_squeeze(struct BORINGSSL_keccak_st *ctx, uint8_t *out, + size_t out_len) { + // Accessing |ctx->state| as a |uint8_t*| is allowed by strict aliasing + // because we require |uint8_t| to be a character type. + const uint8_t *state_bytes = (const uint8_t *)ctx->state; + while (out_len) { + size_t remaining = ctx->rate_bytes - ctx->offset; + size_t todo = out_len; + if (todo > remaining) { + todo = remaining; + } + OPENSSL_memcpy(out, &state_bytes[ctx->offset], todo); + out += todo; + out_len -= todo; + ctx->offset += todo; + if (ctx->offset == ctx->rate_bytes) { + keccak_f(ctx->state); + ctx->offset = 0; + } + } +} diff --git a/Sources/CNIOBoringSSL/crypto/kyber/kyber.c b/Sources/CNIOBoringSSL/crypto/kyber/kyber.c new file mode 100644 index 00000000..0fc113bb --- /dev/null +++ b/Sources/CNIOBoringSSL/crypto/kyber/kyber.c @@ -0,0 +1,826 @@ +/* Copyright (c) 2023, 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 + +#include +#include + +#include +#include + +#include "../internal.h" +#include "./internal.h" + + +// See +// https://pq-crystals.org/kyber/data/kyber-specification-round3-20210804.pdf + +#define DEGREE 256 +#define RANK 3 + +static const size_t kBarrettMultiplier = 5039; +static const unsigned kBarrettShift = 24; +static const uint16_t kPrime = 3329; +static const int kLog2Prime = 12; +static const uint16_t kHalfPrime = (/*kPrime=*/3329 - 1) / 2; +static const int kDU = 10; +static const int kDV = 4; +// kInverseDegree is 128^-1 mod 3329; 128 because kPrime does not have a 512th +// root of unity. +static const uint16_t kInverseDegree = 3303; +static const size_t kEncodedVectorSize = + (/*kLog2Prime=*/12 * DEGREE / 8) * RANK; +static const size_t kCompressedVectorSize = /*kDU=*/10 * RANK * DEGREE / 8; + +typedef struct scalar { + // On every function entry and exit, 0 <= c < kPrime. + uint16_t c[DEGREE]; +} scalar; + +typedef struct vector { + scalar v[RANK]; +} vector; + +typedef struct matrix { + scalar v[RANK][RANK]; +} matrix; + +// This bit of Python will be referenced in some of the following comments: +// +// p = 3329 +// +// def bitreverse(i): +// ret = 0 +// for n in range(7): +// bit = i & 1 +// ret <<= 1 +// ret |= bit +// i >>= 1 +// return ret + +// kNTTRoots = [pow(17, bitreverse(i), p) for i in range(128)] +static const uint16_t kNTTRoots[128] = { + 1, 1729, 2580, 3289, 2642, 630, 1897, 848, 1062, 1919, 193, 797, + 2786, 3260, 569, 1746, 296, 2447, 1339, 1476, 3046, 56, 2240, 1333, + 1426, 2094, 535, 2882, 2393, 2879, 1974, 821, 289, 331, 3253, 1756, + 1197, 2304, 2277, 2055, 650, 1977, 2513, 632, 2865, 33, 1320, 1915, + 2319, 1435, 807, 452, 1438, 2868, 1534, 2402, 2647, 2617, 1481, 648, + 2474, 3110, 1227, 910, 17, 2761, 583, 2649, 1637, 723, 2288, 1100, + 1409, 2662, 3281, 233, 756, 2156, 3015, 3050, 1703, 1651, 2789, 1789, + 1847, 952, 1461, 2687, 939, 2308, 2437, 2388, 733, 2337, 268, 641, + 1584, 2298, 2037, 3220, 375, 2549, 2090, 1645, 1063, 319, 2773, 757, + 2099, 561, 2466, 2594, 2804, 1092, 403, 1026, 1143, 2150, 2775, 886, + 1722, 1212, 1874, 1029, 2110, 2935, 885, 2154, +}; + +// kInverseNTTRoots = [pow(17, -bitreverse(i), p) for i in range(128)] +static const uint16_t kInverseNTTRoots[128] = { + 1, 1600, 40, 749, 2481, 1432, 2699, 687, 1583, 2760, 69, 543, + 2532, 3136, 1410, 2267, 2508, 1355, 450, 936, 447, 2794, 1235, 1903, + 1996, 1089, 3273, 283, 1853, 1990, 882, 3033, 2419, 2102, 219, 855, + 2681, 1848, 712, 682, 927, 1795, 461, 1891, 2877, 2522, 1894, 1010, + 1414, 2009, 3296, 464, 2697, 816, 1352, 2679, 1274, 1052, 1025, 2132, + 1573, 76, 2998, 3040, 1175, 2444, 394, 1219, 2300, 1455, 2117, 1607, + 2443, 554, 1179, 2186, 2303, 2926, 2237, 525, 735, 863, 2768, 1230, + 2572, 556, 3010, 2266, 1684, 1239, 780, 2954, 109, 1292, 1031, 1745, + 2688, 3061, 992, 2596, 941, 892, 1021, 2390, 642, 1868, 2377, 1482, + 1540, 540, 1678, 1626, 279, 314, 1173, 2573, 3096, 48, 667, 1920, + 2229, 1041, 2606, 1692, 680, 2746, 568, 3312, +}; + +// kModRoots = [pow(17, 2*bitreverse(i) + 1, p) for i in range(128)] +static const uint16_t kModRoots[128] = { + 17, 3312, 2761, 568, 583, 2746, 2649, 680, 1637, 1692, 723, 2606, + 2288, 1041, 1100, 2229, 1409, 1920, 2662, 667, 3281, 48, 233, 3096, + 756, 2573, 2156, 1173, 3015, 314, 3050, 279, 1703, 1626, 1651, 1678, + 2789, 540, 1789, 1540, 1847, 1482, 952, 2377, 1461, 1868, 2687, 642, + 939, 2390, 2308, 1021, 2437, 892, 2388, 941, 733, 2596, 2337, 992, + 268, 3061, 641, 2688, 1584, 1745, 2298, 1031, 2037, 1292, 3220, 109, + 375, 2954, 2549, 780, 2090, 1239, 1645, 1684, 1063, 2266, 319, 3010, + 2773, 556, 757, 2572, 2099, 1230, 561, 2768, 2466, 863, 2594, 735, + 2804, 525, 1092, 2237, 403, 2926, 1026, 2303, 1143, 2186, 2150, 1179, + 2775, 554, 886, 2443, 1722, 1607, 1212, 2117, 1874, 1455, 1029, 2300, + 2110, 1219, 2935, 394, 885, 2444, 2154, 1175, +}; + +// reduce_once reduces 0 <= x < 2*kPrime, mod kPrime. +static uint16_t reduce_once(uint16_t x) { + assert(x < 2 * kPrime); + const uint16_t subtracted = x - kPrime; + uint16_t mask = 0u - (subtracted >> 15); + // On Aarch64, omitting a |value_barrier_u16| results in a 2x speedup of Kyber + // overall and Clang still produces constant-time code using `csel`. On other + // platforms & compilers on godbolt that we care about, this code also + // produces constant-time output. + return (mask & x) | (~mask & subtracted); +} + +// constant time reduce x mod kPrime using Barrett reduction. x must be less +// than kPrime + 2×kPrime². +static uint16_t reduce(uint32_t x) { + assert(x < kPrime + 2u * kPrime * kPrime); + uint64_t product = (uint64_t)x * kBarrettMultiplier; + uint32_t quotient = product >> kBarrettShift; + uint32_t remainder = x - quotient * kPrime; + return reduce_once(remainder); +} + +static void scalar_zero(scalar *out) { OPENSSL_memset(out, 0, sizeof(*out)); } + +static void vector_zero(vector *out) { OPENSSL_memset(out, 0, sizeof(*out)); } + +// In place number theoretic transform of a given scalar. +// Note that Kyber's kPrime 3329 does not have a 512th root of unity, so this +// transform leaves off the last iteration of the usual FFT code, with the 128 +// relevant roots of unity being stored in |kNTTRoots|. This means the output +// should be seen as 128 elements in GF(3329^2), with the coefficients of the +// elements being consecutive entries in |s->c|. +static void scalar_ntt(scalar *s) { + int offset = DEGREE; + // `int` is used here because using `size_t` throughout caused a ~5% slowdown + // with Clang 14 on Aarch64. + for (int step = 1; step < DEGREE / 2; step <<= 1) { + offset >>= 1; + int k = 0; + for (int i = 0; i < step; i++) { + const uint32_t step_root = kNTTRoots[i + step]; + for (int j = k; j < k + offset; j++) { + uint16_t odd = reduce(step_root * s->c[j + offset]); + uint16_t even = s->c[j]; + s->c[j] = reduce_once(odd + even); + s->c[j + offset] = reduce_once(even - odd + kPrime); + } + k += 2 * offset; + } + } +} + +static void vector_ntt(vector *a) { + for (int i = 0; i < RANK; i++) { + scalar_ntt(&a->v[i]); + } +} + +// In place inverse number theoretic transform of a given scalar, with pairs of +// entries of s->v being interpreted as elements of GF(3329^2). Just as with the +// number theoretic transform, this leaves off the first step of the normal iFFT +// to account for the fact that 3329 does not have a 512th root of unity, using +// the precomputed 128 roots of unity stored in |kInverseNTTRoots|. +static void scalar_inverse_ntt(scalar *s) { + int step = DEGREE / 2; + // `int` is used here because using `size_t` throughout caused a ~5% slowdown + // with Clang 14 on Aarch64. + for (int offset = 2; offset < DEGREE; offset <<= 1) { + step >>= 1; + int k = 0; + for (int i = 0; i < step; i++) { + uint32_t step_root = kInverseNTTRoots[i + step]; + for (int j = k; j < k + offset; j++) { + uint16_t odd = s->c[j + offset]; + uint16_t even = s->c[j]; + s->c[j] = reduce_once(odd + even); + s->c[j + offset] = reduce(step_root * (even - odd + kPrime)); + } + k += 2 * offset; + } + } + for (int i = 0; i < DEGREE; i++) { + s->c[i] = reduce(s->c[i] * kInverseDegree); + } +} + +static void vector_inverse_ntt(vector *a) { + for (int i = 0; i < RANK; i++) { + scalar_inverse_ntt(&a->v[i]); + } +} + +static void scalar_add(scalar *lhs, const scalar *rhs) { + for (int i = 0; i < DEGREE; i++) { + lhs->c[i] = reduce_once(lhs->c[i] + rhs->c[i]); + } +} + +static void scalar_sub(scalar *lhs, const scalar *rhs) { + for (int i = 0; i < DEGREE; i++) { + lhs->c[i] = reduce_once(lhs->c[i] - rhs->c[i] + kPrime); + } +} + +// Multiplying two scalars in the number theoretically transformed state. Since +// 3329 does not have a 512th root of unity, this means we have to interpret +// the 2*ith and (2*i+1)th entries of the scalar as elements of GF(3329)[X]/(X^2 +// - 17^(2*bitreverse(i)+1)) The value of 17^(2*bitreverse(i)+1) mod 3329 is +// stored in the precomputed |kModRoots| table. Note that our Barrett transform +// only allows us to multipy two reduced numbers together, so we need some +// intermediate reduction steps, even if an uint64_t could hold 3 multiplied +// numbers. +static void scalar_mult(scalar *out, const scalar *lhs, const scalar *rhs) { + for (int i = 0; i < DEGREE / 2; i++) { + uint32_t real_real = (uint32_t)lhs->c[2 * i] * rhs->c[2 * i]; + uint32_t img_img = (uint32_t)rhs->c[2 * i + 1] * lhs->c[2 * i + 1]; + uint32_t real_img = (uint32_t)lhs->c[2 * i] * rhs->c[2 * i + 1]; + uint32_t img_real = (uint32_t)lhs->c[2 * i + 1] * rhs->c[2 * i]; + out->c[2 * i] = + reduce(real_real + (uint32_t)reduce(img_img) * kModRoots[i]); + out->c[2 * i + 1] = reduce(img_real + real_img); + } +} + +static void vector_add(vector *lhs, const vector *rhs) { + for (int i = 0; i < RANK; i++) { + scalar_add(&lhs->v[i], &rhs->v[i]); + } +} + +static void matrix_mult(vector *out, const matrix *m, const vector *a) { + vector_zero(out); + for (int i = 0; i < RANK; i++) { + for (int j = 0; j < RANK; j++) { + scalar product; + scalar_mult(&product, &m->v[i][j], &a->v[j]); + scalar_add(&out->v[i], &product); + } + } +} + +static void matrix_mult_transpose(vector *out, const matrix *m, + const vector *a) { + vector_zero(out); + for (int i = 0; i < RANK; i++) { + for (int j = 0; j < RANK; j++) { + scalar product; + scalar_mult(&product, &m->v[j][i], &a->v[j]); + scalar_add(&out->v[i], &product); + } + } +} + +static void scalar_inner_product(scalar *out, const vector *lhs, + const vector *rhs) { + scalar_zero(out); + for (int i = 0; i < RANK; i++) { + scalar product; + scalar_mult(&product, &lhs->v[i], &rhs->v[i]); + scalar_add(out, &product); + } +} + +// Algorithm 1 of the Kyber spec. Rejection samples a Keccak stream to get +// uniformly distributed elements. This is used for matrix expansion and only +// operates on public inputs. +static void scalar_from_keccak_vartime(scalar *out, + struct BORINGSSL_keccak_st *keccak_ctx) { + uint8_t bytes[3]; + for (int i = 0; i < DEGREE;) { + BORINGSSL_keccak_squeeze(keccak_ctx, bytes, sizeof(bytes)); + uint16_t d1 = bytes[0] + 256 * (bytes[1] % 16); + uint16_t d2 = bytes[1] / 16 + 16 * bytes[2]; + if (d1 < kPrime) { + out->c[i++] = d1; + } + if (d2 < kPrime && i < DEGREE) { + out->c[i++] = d2; + } + } +} + +// Algorithm 2 of the Kyber spec, with eta fixed to two and the PRF call +// included. Creates binominally distributed elements by sampling 2*|eta| bits, +// and setting the coefficient to the count of the first bits minus the count of +// the second bits, resulting in a centered binomial distribution. Since eta is +// two this gives -2/2 with a probability of 1/16, -1/1 with probability 1/4, +// and 0 with probability 3/8. +static void scalar_centered_binomial_distribution_eta_2_with_prf( + scalar *out, const uint8_t input[33]) { + uint8_t entropy[128]; + static_assert(sizeof(entropy) == 2 * /*kEta=*/2 * DEGREE / 8, ""); + BORINGSSL_keccak(entropy, sizeof(entropy), input, 33, boringssl_shake256); + + for (int i = 0; i < DEGREE; i += 2) { + uint8_t byte = entropy[i / 2]; + + uint16_t value = kPrime; + value += (byte & 1) + ((byte >> 1) & 1); + value -= ((byte >> 2) & 1) + ((byte >> 3) & 1); + out->c[i] = reduce_once(value); + + byte >>= 4; + value = kPrime; + value += (byte & 1) + ((byte >> 1) & 1); + value -= ((byte >> 2) & 1) + ((byte >> 3) & 1); + out->c[i + 1] = reduce_once(value); + } +} + +// Generates a secret vector by using +// |scalar_centered_binomial_distribution_eta_2_with_prf|, using the given seed +// appending and incrementing |counter| for entry of the vector. +static void vector_generate_secret_eta_2(vector *out, uint8_t *counter, + const uint8_t seed[32]) { + uint8_t input[33]; + OPENSSL_memcpy(input, seed, 32); + for (int i = 0; i < RANK; i++) { + input[32] = (*counter)++; + scalar_centered_binomial_distribution_eta_2_with_prf(&out->v[i], input); + } +} + +// Expands the matrix of a seed for key generation and for encaps-CPA. +static void matrix_expand(matrix *out, const uint8_t rho[32]) { + uint8_t input[34]; + OPENSSL_memcpy(input, rho, 32); + for (int i = 0; i < RANK; i++) { + for (int j = 0; j < RANK; j++) { + input[32] = i; + input[33] = j; + struct BORINGSSL_keccak_st keccak_ctx; + BORINGSSL_keccak_init(&keccak_ctx, input, sizeof(input), + boringssl_shake128); + scalar_from_keccak_vartime(&out->v[i][j], &keccak_ctx); + } + } +} + +static const uint8_t kMasks[8] = {0x01, 0x03, 0x07, 0x0f, + 0x1f, 0x3f, 0x7f, 0xff}; + +static void scalar_encode(uint8_t *out, const scalar *s, int bits) { + assert(bits <= (int)sizeof(*s->c) * 8 && bits != 1); + + uint8_t out_byte = 0; + int out_byte_bits = 0; + + for (int i = 0; i < DEGREE; i++) { + uint16_t element = s->c[i]; + int element_bits_done = 0; + + while (element_bits_done < bits) { + int chunk_bits = bits - element_bits_done; + int out_bits_remaining = 8 - out_byte_bits; + if (chunk_bits >= out_bits_remaining) { + chunk_bits = out_bits_remaining; + out_byte |= (element & kMasks[chunk_bits - 1]) << out_byte_bits; + *out = out_byte; + out++; + out_byte_bits = 0; + out_byte = 0; + } else { + out_byte |= (element & kMasks[chunk_bits - 1]) << out_byte_bits; + out_byte_bits += chunk_bits; + } + + element_bits_done += chunk_bits; + element >>= chunk_bits; + } + } + + if (out_byte_bits > 0) { + *out = out_byte; + } +} + +// scalar_encode_1 is |scalar_encode| specialised for |bits| == 1. +static void scalar_encode_1(uint8_t out[32], const scalar *s) { + for (int i = 0; i < DEGREE; i += 8) { + uint8_t out_byte = 0; + for (int j = 0; j < 8; j++) { + out_byte |= (s->c[i + j] & 1) << j; + } + *out = out_byte; + out++; + } +} + +// Encodes an entire vector into 32*|RANK|*|bits| bytes. Note that since 256 +// (DEGREE) is divisible by 8, the individual vector entries will always fill a +// whole number of bytes, so we do not need to worry about bit packing here. +static void vector_encode(uint8_t *out, const vector *a, int bits) { + for (int i = 0; i < RANK; i++) { + scalar_encode(out + i * bits * DEGREE / 8, &a->v[i], bits); + } +} + +// scalar_decode parses |DEGREE * bits| bits from |in| into |DEGREE| values in +// |out|. It returns one on success and zero if any parsed value is >= +// |kPrime|. +static int scalar_decode(scalar *out, const uint8_t *in, int bits) { + assert(bits <= (int)sizeof(*out->c) * 8 && bits != 1); + + uint8_t in_byte = 0; + int in_byte_bits_left = 0; + + for (int i = 0; i < DEGREE; i++) { + uint16_t element = 0; + int element_bits_done = 0; + + while (element_bits_done < bits) { + if (in_byte_bits_left == 0) { + in_byte = *in; + in++; + in_byte_bits_left = 8; + } + + int chunk_bits = bits - element_bits_done; + if (chunk_bits > in_byte_bits_left) { + chunk_bits = in_byte_bits_left; + } + + element |= (in_byte & kMasks[chunk_bits - 1]) << element_bits_done; + in_byte_bits_left -= chunk_bits; + in_byte >>= chunk_bits; + + element_bits_done += chunk_bits; + } + + if (element >= kPrime) { + return 0; + } + out->c[i] = element; + } + + return 1; +} + +// scalar_decode_1 is |scalar_decode| specialised for |bits| == 1. +static void scalar_decode_1(scalar *out, const uint8_t in[32]) { + for (int i = 0; i < DEGREE; i += 8) { + uint8_t in_byte = *in; + in++; + for (int j = 0; j < 8; j++) { + out->c[i + j] = in_byte & 1; + in_byte >>= 1; + } + } +} + +// Decodes 32*|RANK|*|bits| bytes from |in| into |out|. It returns one on +// success or zero if any parsed value is >= |kPrime|. +static int vector_decode(vector *out, const uint8_t *in, int bits) { + for (int i = 0; i < RANK; i++) { + if (!scalar_decode(&out->v[i], in + i * bits * DEGREE / 8, bits)) { + return 0; + } + } + return 1; +} + +// Compresses (lossily) an input |x| mod 3329 into |bits| many bits by grouping +// numbers close to each other together. The formula used is +// round(2^|bits|/kPrime*x) mod 2^|bits|. +// Uses Barrett reduction to achieve constant time. Since we need both the +// remainder (for rounding) and the quotient (as the result), we cannot use +// |reduce| here, but need to do the Barrett reduction directly. +static uint16_t compress(uint16_t x, int bits) { + uint32_t product = (uint32_t)x << bits; + uint32_t quotient = ((uint64_t)product * kBarrettMultiplier) >> kBarrettShift; + uint32_t remainder = product - quotient * kPrime; + + // Adjust the quotient to round correctly: + // 0 <= remainder <= kHalfPrime round to 0 + // kHalfPrime < remainder <= kPrime + kHalfPrime round to 1 + // kPrime + kHalfPrime < remainder < 2 * kPrime round to 2 + assert(remainder < 2u * kPrime); + quotient += 1 & constant_time_lt_w(kHalfPrime, remainder); + quotient += 1 & constant_time_lt_w(kPrime + kHalfPrime, remainder); + return quotient & ((1 << bits) - 1); +} + +// Decompresses |x| by using an equi-distant representative. The formula is +// round(kPrime/2^|bits|*x). Note that 2^|bits| being the divisor allows us to +// implement this logic using only bit operations. +static uint16_t decompress(uint16_t x, int bits) { + uint32_t product = (uint32_t)x * kPrime; + uint32_t power = 1 << bits; + // This is |product| % power, since |power| is a power of 2. + uint32_t remainder = product & (power - 1); + // This is |product| / power, since |power| is a power of 2. + uint32_t lower = product >> bits; + // The rounding logic works since the first half of numbers mod |power| have a + // 0 as first bit, and the second half has a 1 as first bit, since |power| is + // a power of 2. As a 12 bit number, |remainder| is always positive, so we + // will shift in 0s for a right shift. + return lower + (remainder >> (bits - 1)); +} + +static void scalar_compress(scalar *s, int bits) { + for (int i = 0; i < DEGREE; i++) { + s->c[i] = compress(s->c[i], bits); + } +} + +static void scalar_decompress(scalar *s, int bits) { + for (int i = 0; i < DEGREE; i++) { + s->c[i] = decompress(s->c[i], bits); + } +} + +static void vector_compress(vector *a, int bits) { + for (int i = 0; i < RANK; i++) { + scalar_compress(&a->v[i], bits); + } +} + +static void vector_decompress(vector *a, int bits) { + for (int i = 0; i < RANK; i++) { + scalar_decompress(&a->v[i], bits); + } +} + +struct public_key { + vector t; + uint8_t rho[32]; + uint8_t public_key_hash[32]; + matrix m; +}; + +static struct public_key *public_key_from_external( + const struct KYBER_public_key *external) { + static_assert(sizeof(struct KYBER_public_key) >= sizeof(struct public_key), + "Kyber public key is too small"); + static_assert(alignof(struct KYBER_public_key) >= alignof(struct public_key), + "Kyber public key align incorrect"); + return (struct public_key *)external; +} + +struct private_key { + struct public_key pub; + vector s; + uint8_t fo_failure_secret[32]; +}; + +static struct private_key *private_key_from_external( + const struct KYBER_private_key *external) { + static_assert(sizeof(struct KYBER_private_key) >= sizeof(struct private_key), + "Kyber private key too small"); + static_assert( + alignof(struct KYBER_private_key) >= alignof(struct private_key), + "Kyber private key align incorrect"); + return (struct private_key *)external; +} + +// Calls |KYBER_generate_key_external_entropy| with random bytes from +// |RAND_bytes|. +void KYBER_generate_key(uint8_t out_encoded_public_key[KYBER_PUBLIC_KEY_BYTES], + struct KYBER_private_key *out_private_key) { + uint8_t entropy[KYBER_GENERATE_KEY_ENTROPY]; + RAND_bytes(entropy, sizeof(entropy)); + KYBER_generate_key_external_entropy(out_encoded_public_key, out_private_key, + entropy); +} + +static int kyber_marshal_public_key(CBB *out, const struct public_key *pub) { + uint8_t *vector_output; + if (!CBB_add_space(out, &vector_output, kEncodedVectorSize)) { + return 0; + } + vector_encode(vector_output, &pub->t, kLog2Prime); + if (!CBB_add_bytes(out, pub->rho, sizeof(pub->rho))) { + return 0; + } + return 1; +} + +// Algorithms 4 and 7 of the Kyber spec. Algorithms are combined since key +// generation is not part of the FO transform, and the spec uses Algorithm 7 to +// specify the actual key format. +void KYBER_generate_key_external_entropy( + uint8_t out_encoded_public_key[KYBER_PUBLIC_KEY_BYTES], + struct KYBER_private_key *out_private_key, + const uint8_t entropy[KYBER_GENERATE_KEY_ENTROPY]) { + struct private_key *priv = private_key_from_external(out_private_key); + uint8_t hashed[64]; + BORINGSSL_keccak(hashed, sizeof(hashed), entropy, 32, boringssl_sha3_512); + const uint8_t *const rho = hashed; + const uint8_t *const sigma = hashed + 32; + OPENSSL_memcpy(priv->pub.rho, hashed, sizeof(priv->pub.rho)); + matrix_expand(&priv->pub.m, rho); + uint8_t counter = 0; + vector_generate_secret_eta_2(&priv->s, &counter, sigma); + vector_ntt(&priv->s); + vector error; + vector_generate_secret_eta_2(&error, &counter, sigma); + vector_ntt(&error); + matrix_mult_transpose(&priv->pub.t, &priv->pub.m, &priv->s); + vector_add(&priv->pub.t, &error); + + CBB cbb; + CBB_init_fixed(&cbb, out_encoded_public_key, KYBER_PUBLIC_KEY_BYTES); + if (!kyber_marshal_public_key(&cbb, &priv->pub)) { + abort(); + } + + BORINGSSL_keccak(priv->pub.public_key_hash, sizeof(priv->pub.public_key_hash), + out_encoded_public_key, KYBER_PUBLIC_KEY_BYTES, + boringssl_sha3_256); + OPENSSL_memcpy(priv->fo_failure_secret, entropy + 32, 32); +} + +void KYBER_public_from_private(struct KYBER_public_key *out_public_key, + const struct KYBER_private_key *private_key) { + struct public_key *const pub = public_key_from_external(out_public_key); + const struct private_key *const priv = private_key_from_external(private_key); + *pub = priv->pub; +} + +// Algorithm 5 of the Kyber spec. Encrypts a message with given randomness to +// the ciphertext in |out|. Without applying the Fujisaki-Okamoto transform this +// would not result in a CCA secure scheme, since lattice schemes are vulnerable +// to decryption failure oracles. +static void encrypt_cpa(uint8_t out[KYBER_CIPHERTEXT_BYTES], + const struct public_key *pub, const uint8_t message[32], + const uint8_t randomness[32]) { + uint8_t counter = 0; + vector secret; + vector_generate_secret_eta_2(&secret, &counter, randomness); + vector_ntt(&secret); + vector error; + vector_generate_secret_eta_2(&error, &counter, randomness); + uint8_t input[33]; + OPENSSL_memcpy(input, randomness, 32); + input[32] = counter; + scalar scalar_error; + scalar_centered_binomial_distribution_eta_2_with_prf(&scalar_error, input); + vector u; + matrix_mult(&u, &pub->m, &secret); + vector_inverse_ntt(&u); + vector_add(&u, &error); + scalar v; + scalar_inner_product(&v, &pub->t, &secret); + scalar_inverse_ntt(&v); + scalar_add(&v, &scalar_error); + scalar expanded_message; + scalar_decode_1(&expanded_message, message); + scalar_decompress(&expanded_message, 1); + scalar_add(&v, &expanded_message); + vector_compress(&u, kDU); + vector_encode(out, &u, kDU); + scalar_compress(&v, kDV); + scalar_encode(out + kCompressedVectorSize, &v, kDV); +} + +// Calls KYBER_encap_external_entropy| with random bytes from |RAND_bytes| +void KYBER_encap(uint8_t out_ciphertext[KYBER_CIPHERTEXT_BYTES], + uint8_t *out_shared_secret, size_t out_shared_secret_len, + const struct KYBER_public_key *public_key) { + uint8_t entropy[KYBER_ENCAP_ENTROPY]; + RAND_bytes(entropy, KYBER_ENCAP_ENTROPY); + KYBER_encap_external_entropy(out_ciphertext, out_shared_secret, + out_shared_secret_len, public_key, entropy); +} + +// Algorithm 8 of the Kyber spec, safe for line 2 of the spec. The spec there +// hashes the output of the system's random number generator, since the FO +// transform will reveal it to the decrypting party. There is no reason to do +// this when a secure random number generator is used. When an insecure random +// number generator is used, the caller should switch to a secure one before +// calling this method. +void KYBER_encap_external_entropy( + uint8_t out_ciphertext[KYBER_CIPHERTEXT_BYTES], uint8_t *out_shared_secret, + size_t out_shared_secret_len, const struct KYBER_public_key *public_key, + const uint8_t entropy[KYBER_ENCAP_ENTROPY]) { + const struct public_key *pub = public_key_from_external(public_key); + uint8_t input[64]; + OPENSSL_memcpy(input, entropy, KYBER_ENCAP_ENTROPY); + OPENSSL_memcpy(input + KYBER_ENCAP_ENTROPY, pub->public_key_hash, + sizeof(input) - KYBER_ENCAP_ENTROPY); + uint8_t prekey_and_randomness[64]; + BORINGSSL_keccak(prekey_and_randomness, sizeof(prekey_and_randomness), input, + sizeof(input), boringssl_sha3_512); + encrypt_cpa(out_ciphertext, pub, entropy, prekey_and_randomness + 32); + BORINGSSL_keccak(prekey_and_randomness + 32, 32, out_ciphertext, + KYBER_CIPHERTEXT_BYTES, boringssl_sha3_256); + BORINGSSL_keccak(out_shared_secret, out_shared_secret_len, + prekey_and_randomness, sizeof(prekey_and_randomness), + boringssl_shake256); +} + +// Algorithm 6 of the Kyber spec. +static void decrypt_cpa(uint8_t out[32], const struct private_key *priv, + const uint8_t ciphertext[KYBER_CIPHERTEXT_BYTES]) { + vector u; + vector_decode(&u, ciphertext, kDU); + vector_decompress(&u, kDU); + vector_ntt(&u); + scalar v; + scalar_decode(&v, ciphertext + kCompressedVectorSize, kDV); + scalar_decompress(&v, kDV); + scalar mask; + scalar_inner_product(&mask, &priv->s, &u); + scalar_inverse_ntt(&mask); + scalar_sub(&v, &mask); + scalar_compress(&v, 1); + scalar_encode_1(out, &v); +} + +// Algorithm 9 of the Kyber spec, performing the FO transform by running +// encrypt_cpa on the decrypted message. The spec does not allow the decryption +// failure to be passed on to the caller, and instead returns a result that is +// deterministic but unpredictable to anyone without knowledge of the private +// key. +void KYBER_decap(uint8_t *out_shared_secret, size_t out_shared_secret_len, + const uint8_t ciphertext[KYBER_CIPHERTEXT_BYTES], + const struct KYBER_private_key *private_key) { + const struct private_key *priv = private_key_from_external(private_key); + uint8_t decrypted[64]; + decrypt_cpa(decrypted, priv, ciphertext); + OPENSSL_memcpy(decrypted + 32, priv->pub.public_key_hash, + sizeof(decrypted) - 32); + uint8_t prekey_and_randomness[64]; + BORINGSSL_keccak(prekey_and_randomness, sizeof(prekey_and_randomness), + decrypted, sizeof(decrypted), boringssl_sha3_512); + uint8_t expected_ciphertext[KYBER_CIPHERTEXT_BYTES]; + encrypt_cpa(expected_ciphertext, &priv->pub, decrypted, + prekey_and_randomness + 32); + uint8_t mask = + constant_time_eq_int_8(CRYPTO_memcmp(ciphertext, expected_ciphertext, + sizeof(expected_ciphertext)), + 0); + uint8_t input[64]; + for (int i = 0; i < 32; i++) { + input[i] = constant_time_select_8(mask, prekey_and_randomness[i], + priv->fo_failure_secret[i]); + } + BORINGSSL_keccak(input + 32, 32, ciphertext, KYBER_CIPHERTEXT_BYTES, + boringssl_sha3_256); + BORINGSSL_keccak(out_shared_secret, out_shared_secret_len, input, + sizeof(input), boringssl_shake256); +} + +int KYBER_marshal_public_key(CBB *out, + const struct KYBER_public_key *public_key) { + return kyber_marshal_public_key(out, public_key_from_external(public_key)); +} + +// kyber_parse_public_key_no_hash parses |in| into |pub| but doesn't calculate +// the value of |pub->public_key_hash|. +static int kyber_parse_public_key_no_hash(struct public_key *pub, CBS *in) { + CBS t_bytes; + if (!CBS_get_bytes(in, &t_bytes, kEncodedVectorSize) || + !vector_decode(&pub->t, CBS_data(&t_bytes), kLog2Prime) || + !CBS_copy_bytes(in, pub->rho, sizeof(pub->rho))) { + return 0; + } + matrix_expand(&pub->m, pub->rho); + return 1; +} + +int KYBER_parse_public_key(struct KYBER_public_key *public_key, CBS *in) { + struct public_key *pub = public_key_from_external(public_key); + CBS orig_in = *in; + if (!kyber_parse_public_key_no_hash(pub, in) || // + CBS_len(in) != 0) { + return 0; + } + BORINGSSL_keccak(pub->public_key_hash, sizeof(pub->public_key_hash), + CBS_data(&orig_in), CBS_len(&orig_in), boringssl_sha3_256); + return 1; +} + +int KYBER_marshal_private_key(CBB *out, + const struct KYBER_private_key *private_key) { + const struct private_key *const priv = private_key_from_external(private_key); + uint8_t *s_output; + if (!CBB_add_space(out, &s_output, kEncodedVectorSize)) { + return 0; + } + vector_encode(s_output, &priv->s, kLog2Prime); + if (!kyber_marshal_public_key(out, &priv->pub) || + !CBB_add_bytes(out, priv->pub.public_key_hash, + sizeof(priv->pub.public_key_hash)) || + !CBB_add_bytes(out, priv->fo_failure_secret, + sizeof(priv->fo_failure_secret))) { + return 0; + } + return 1; +} + +int KYBER_parse_private_key(struct KYBER_private_key *out_private_key, + CBS *in) { + struct private_key *const priv = private_key_from_external(out_private_key); + + CBS s_bytes; + if (!CBS_get_bytes(in, &s_bytes, kEncodedVectorSize) || + !vector_decode(&priv->s, CBS_data(&s_bytes), kLog2Prime) || + !kyber_parse_public_key_no_hash(&priv->pub, in) || + !CBS_copy_bytes(in, priv->pub.public_key_hash, + sizeof(priv->pub.public_key_hash)) || + !CBS_copy_bytes(in, priv->fo_failure_secret, + sizeof(priv->fo_failure_secret)) || + CBS_len(in) != 0) { + return 0; + } + return 1; +} diff --git a/Sources/CNIOBoringSSL/crypto/mem.c b/Sources/CNIOBoringSSL/crypto/mem.c index 1539de67..e0548c96 100644 --- a/Sources/CNIOBoringSSL/crypto/mem.c +++ b/Sources/CNIOBoringSSL/crypto/mem.c @@ -57,8 +57,11 @@ #include #include +#include +#include #include #include +#include #include @@ -68,6 +71,12 @@ OPENSSL_MSVC_PRAGMA(warning(push, 3)) OPENSSL_MSVC_PRAGMA(warning(pop)) #endif +#if defined(BORINGSSL_MALLOC_FAILURE_TESTING) +#include +#include +#include +#endif + #include "internal.h" @@ -120,7 +129,7 @@ WEAK_SYMBOL_FUNC(void, sdallocx, (void *ptr, size_t size, int flags)); // primitives used must tolerate every other synchronization primitive linked // into the process, including pthreads locks. Failing to meet these constraints // may result in deadlocks, crashes, or memory corruption. -WEAK_SYMBOL_FUNC(void*, OPENSSL_memory_alloc, (size_t size)); +WEAK_SYMBOL_FUNC(void *, OPENSSL_memory_alloc, (size_t size)); WEAK_SYMBOL_FUNC(void, OPENSSL_memory_free, (void *ptr)); WEAK_SYMBOL_FUNC(size_t, OPENSSL_memory_get_size, (void *ptr)); @@ -128,17 +137,107 @@ WEAK_SYMBOL_FUNC(size_t, OPENSSL_memory_get_size, (void *ptr)); // are linking in BoringSSL and, roughly, what version they are using. static const uint8_t kBoringSSLBinaryTag[18] = { // 16 bytes of magic tag. - 0x8c, 0x62, 0x20, 0x0b, 0xd2, 0xa0, 0x72, 0x58, - 0x44, 0xa8, 0x96, 0x69, 0xad, 0x55, 0x7e, 0xec, + 0x8c, + 0x62, + 0x20, + 0x0b, + 0xd2, + 0xa0, + 0x72, + 0x58, + 0x44, + 0xa8, + 0x96, + 0x69, + 0xad, + 0x55, + 0x7e, + 0xec, // Current source iteration. Incremented ~monthly. - 3, 0, + 3, + 0, }; +#if defined(BORINGSSL_MALLOC_FAILURE_TESTING) +static struct CRYPTO_STATIC_MUTEX malloc_failure_lock = + CRYPTO_STATIC_MUTEX_INIT; +static uint64_t current_malloc_count = 0; +static uint64_t malloc_number_to_fail = 0; +static int malloc_failure_enabled = 0, break_on_malloc_fail = 0, + any_malloc_failed = 0; + +static void malloc_exit_handler(void) { + CRYPTO_STATIC_MUTEX_lock_read(&malloc_failure_lock); + if (any_malloc_failed) { + // Signal to the test driver that some allocation failed, so it knows to + // increment the counter and continue. + _exit(88); + } + CRYPTO_STATIC_MUTEX_unlock_read(&malloc_failure_lock); +} + +static void init_malloc_failure(void) { + const char *env = getenv("MALLOC_NUMBER_TO_FAIL"); + if (env != NULL && env[0] != 0) { + char *endptr; + malloc_number_to_fail = strtoull(env, &endptr, 10); + if (*endptr == 0) { + malloc_failure_enabled = 1; + atexit(malloc_exit_handler); + } + } + break_on_malloc_fail = getenv("MALLOC_BREAK_ON_FAIL") != NULL; +} + +// should_fail_allocation returns one if the current allocation should fail and +// zero otherwise. +static int should_fail_allocation() { + static CRYPTO_once_t once = CRYPTO_ONCE_INIT; + CRYPTO_once(&once, init_malloc_failure); + if (!malloc_failure_enabled) { + return 0; + } + + // We lock just so multi-threaded tests are still correct, but we won't test + // every malloc exhaustively. + CRYPTO_STATIC_MUTEX_lock_write(&malloc_failure_lock); + int should_fail = current_malloc_count == malloc_number_to_fail; + current_malloc_count++; + any_malloc_failed = any_malloc_failed || should_fail; + CRYPTO_STATIC_MUTEX_unlock_write(&malloc_failure_lock); + + if (should_fail && break_on_malloc_fail) { + raise(SIGTRAP); + } + if (should_fail) { + errno = ENOMEM; + } + return should_fail; +} + +void OPENSSL_reset_malloc_counter_for_testing(void) { + CRYPTO_STATIC_MUTEX_lock_write(&malloc_failure_lock); + current_malloc_count = 0; + CRYPTO_STATIC_MUTEX_unlock_write(&malloc_failure_lock); +} + +#else +static int should_fail_allocation(void) { return 0; } +#endif + void *OPENSSL_malloc(size_t size) { + if (should_fail_allocation()) { + goto err; + } + if (OPENSSL_memory_alloc != NULL) { assert(OPENSSL_memory_free != NULL); assert(OPENSSL_memory_get_size != NULL); - return OPENSSL_memory_alloc(size); + void *ptr = OPENSSL_memory_alloc(size); + if (ptr == NULL && size != 0) { + goto err; + } + return ptr; } if (size + OPENSSL_MALLOC_PREFIX < size) { @@ -150,18 +249,23 @@ void *OPENSSL_malloc(size_t size) { // rare code path. uint8_t unused = *(volatile uint8_t *)kBoringSSLBinaryTag; (void) unused; - return NULL; + goto err; } void *ptr = malloc(size + OPENSSL_MALLOC_PREFIX); if (ptr == NULL) { - return NULL; + goto err; } *(size_t *)ptr = size; __asan_poison_memory_region(ptr, OPENSSL_MALLOC_PREFIX); return ((uint8_t *)ptr) + OPENSSL_MALLOC_PREFIX; + + err: + // This only works because ERR does not call OPENSSL_malloc. + OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE); + return NULL; } void OPENSSL_free(void *orig_ptr) { @@ -239,9 +343,7 @@ void OPENSSL_cleanse(void *ptr, size_t len) { #endif // !OPENSSL_NO_ASM } -void OPENSSL_clear_free(void *ptr, size_t unused) { - OPENSSL_free(ptr); -} +void OPENSSL_clear_free(void *ptr, size_t unused) { OPENSSL_free(ptr); } int CRYPTO_secure_malloc_init(size_t size, size_t min_size) { return 0; } @@ -308,6 +410,34 @@ char *OPENSSL_strdup(const char *s) { return ret; } +int OPENSSL_isalpha(int c) { + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); +} + +int OPENSSL_isdigit(int c) { return c >= '0' && c <= '9'; } + +int OPENSSL_isxdigit(int c) { + return OPENSSL_isdigit(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); +} + +int OPENSSL_fromxdigit(uint8_t *out, int c) { + if (OPENSSL_isdigit(c)) { + *out = c - '0'; + return 1; + } + if ('a' <= c && c <= 'f') { + *out = c - 'a' + 10; + return 1; + } + if ('A' <= c && c <= 'F') { + *out = c - 'A' + 10; + return 1; + } + return 0; +} + +int OPENSSL_isalnum(int c) { return OPENSSL_isalpha(c) || OPENSSL_isdigit(c); } + int OPENSSL_tolower(int c) { if (c >= 'A' && c <= 'Z') { return c + ('a' - 'A'); @@ -315,6 +445,11 @@ int OPENSSL_tolower(int c) { return c; } +int OPENSSL_isspace(int c) { + return c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r' || + c == ' '; +} + int OPENSSL_strcasecmp(const char *a, const char *b) { for (size_t i = 0;; i++) { const int aa = OPENSSL_tolower(a[i]); @@ -359,6 +494,62 @@ int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args) { return vsnprintf(buf, n, format, args); } +int OPENSSL_vasprintf_internal(char **str, const char *format, va_list args, + int system_malloc) { + void *(*allocate)(size_t) = system_malloc ? malloc : OPENSSL_malloc; + void (*deallocate)(void *) = system_malloc ? free : OPENSSL_free; + void *(*reallocate)(void *, size_t) = + system_malloc ? realloc : OPENSSL_realloc; + char *candidate = NULL; + size_t candidate_len = 64; // TODO(bbe) what's the best initial size? + + if ((candidate = allocate(candidate_len)) == NULL) { + goto err; + } + va_list args_copy; + va_copy(args_copy, args); + int ret = vsnprintf(candidate, candidate_len, format, args_copy); + va_end(args_copy); + if (ret < 0) { + goto err; + } + if ((size_t)ret >= candidate_len) { + // Too big to fit in allocation. + char *tmp; + + candidate_len = (size_t)ret + 1; + if ((tmp = reallocate(candidate, candidate_len)) == NULL) { + goto err; + } + candidate = tmp; + ret = vsnprintf(candidate, candidate_len, format, args); + } + // At this point this should not happen unless vsnprintf is insane. + if (ret < 0 || (size_t)ret >= candidate_len) { + goto err; + } + *str = candidate; + return ret; + + err: + deallocate(candidate); + *str = NULL; + errno = ENOMEM; + return -1; +} + +int OPENSSL_vasprintf(char **str, const char *format, va_list args) { + return OPENSSL_vasprintf_internal(str, format, args, /*system_malloc=*/0); +} + +int OPENSSL_asprintf(char **str, const char *format, ...) { + va_list args; + va_start(args, format); + int ret = OPENSSL_vasprintf(str, format, args); + va_end(args); + return ret; +} + char *OPENSSL_strndup(const char *str, size_t size) { size = OPENSSL_strnlen(str, size); @@ -370,7 +561,6 @@ char *OPENSSL_strndup(const char *str, size_t size) { } char *ret = OPENSSL_malloc(alloc_size); if (ret == NULL) { - OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE); return NULL; } @@ -409,7 +599,6 @@ void *OPENSSL_memdup(const void *data, size_t size) { void *ret = OPENSSL_malloc(size); if (ret == NULL) { - OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE); return NULL; } diff --git a/Sources/CNIOBoringSSL/crypto/obj/obj.c b/Sources/CNIOBoringSSL/crypto/obj/obj.c index 384b00f6..691403d0 100644 --- a/Sources/CNIOBoringSSL/crypto/obj/obj.c +++ b/Sources/CNIOBoringSSL/crypto/obj/obj.c @@ -155,7 +155,6 @@ ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o) { return r; err: - OPENSSL_PUT_ERROR(OBJ, ERR_R_MALLOC_FAILURE); OPENSSL_free(ln); OPENSSL_free(sn); OPENSSL_free(data); @@ -506,25 +505,37 @@ static int cmp_long_name(const ASN1_OBJECT *a, const ASN1_OBJECT *b) { // obj_add_object inserts |obj| into the various global hashes for run-time // added objects. It returns one on success or zero otherwise. static int obj_add_object(ASN1_OBJECT *obj) { - int ok; - ASN1_OBJECT *old_object; - obj->flags &= ~(ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | ASN1_OBJECT_FLAG_DYNAMIC_DATA); CRYPTO_STATIC_MUTEX_lock_write(&global_added_lock); if (global_added_by_nid == NULL) { global_added_by_nid = lh_ASN1_OBJECT_new(hash_nid, cmp_nid); + } + if (global_added_by_data == NULL) { global_added_by_data = lh_ASN1_OBJECT_new(hash_data, cmp_data); - global_added_by_short_name = lh_ASN1_OBJECT_new(hash_short_name, cmp_short_name); + } + if (global_added_by_short_name == NULL) { + global_added_by_short_name = + lh_ASN1_OBJECT_new(hash_short_name, cmp_short_name); + } + if (global_added_by_long_name == NULL) { global_added_by_long_name = lh_ASN1_OBJECT_new(hash_long_name, cmp_long_name); } + int ok = 0; + if (global_added_by_nid == NULL || + global_added_by_data == NULL || + global_added_by_short_name == NULL || + global_added_by_long_name == NULL) { + goto err; + } + // We don't pay attention to |old_object| (which contains any previous object // that was evicted from the hashes) because we don't have a reference count // on ASN1_OBJECT values. Also, we should never have duplicates nids and so // should always have objects in |global_added_by_nid|. - + ASN1_OBJECT *old_object; ok = lh_ASN1_OBJECT_insert(global_added_by_nid, &old_object, obj); if (obj->length != 0 && obj->data != NULL) { ok &= lh_ASN1_OBJECT_insert(global_added_by_data, &old_object, obj); @@ -535,8 +546,9 @@ static int obj_add_object(ASN1_OBJECT *obj) { if (obj->ln != NULL) { ok &= lh_ASN1_OBJECT_insert(global_added_by_long_name, &old_object, obj); } - CRYPTO_STATIC_MUTEX_unlock_write(&global_added_lock); +err: + CRYPTO_STATIC_MUTEX_unlock_write(&global_added_lock); return ok; } diff --git a/Sources/CNIOBoringSSL/crypto/obj/obj_dat.h b/Sources/CNIOBoringSSL/crypto/obj/obj_dat.h index cc185f1b..d879233a 100644 --- a/Sources/CNIOBoringSSL/crypto/obj/obj_dat.h +++ b/Sources/CNIOBoringSSL/crypto/obj/obj_dat.h @@ -57,7 +57,7 @@ /* This file is generated by crypto/obj/objects.go. */ -#define NUM_NID 964 +#define NUM_NID 967 static const uint8_t kObjectData[] = { /* NID_rsadsi */ @@ -8782,6 +8782,9 @@ static const ASN1_OBJECT kObjects[NUM_NID] = { {"X448", "X448", NID_X448, 3, &kObjectData[6184], 0}, {"SHA512-256", "sha512-256", NID_sha512_256, 9, &kObjectData[6187], 0}, {"HKDF", "hkdf", NID_hkdf, 0, NULL, 0}, + {"X25519Kyber768", "X25519Kyber768", NID_X25519Kyber768, 0, NULL, 0}, + {"P256Kyber768", "P256Kyber768", NID_P256Kyber768, 0, NULL, 0}, + {"P384Kyber768", "P384Kyber768", NID_P384Kyber768, 0, NULL, 0}, }; static const uint16_t kNIDsInShortNameOrder[] = { @@ -8915,6 +8918,8 @@ static const uint16_t kNIDsInShortNameOrder[] = { 18 /* OU */, 749 /* Oakley-EC2N-3 */, 750 /* Oakley-EC2N-4 */, + 965 /* P256Kyber768 */, + 966 /* P384Kyber768 */, 9 /* PBE-MD2-DES */, 168 /* PBE-MD2-RC2-64 */, 10 /* PBE-MD5-DES */, @@ -8981,6 +8986,7 @@ static const uint16_t kNIDsInShortNameOrder[] = { 458 /* UID */, 0 /* UNDEF */, 948 /* X25519 */, + 964 /* X25519Kyber768 */, 961 /* X448 */, 11 /* X500 */, 378 /* X500algorithms */, @@ -9828,6 +9834,8 @@ static const uint16_t kNIDsInLongNameOrder[] = { 366 /* OCSP Nonce */, 371 /* OCSP Service Locator */, 180 /* OCSP Signing */, + 965 /* P256Kyber768 */, + 966 /* P384Kyber768 */, 161 /* PBES2 */, 69 /* PBKDF2 */, 162 /* PBMAC1 */, @@ -9852,6 +9860,7 @@ static const uint16_t kNIDsInLongNameOrder[] = { 133 /* Time Stamping */, 375 /* Trust Root */, 948 /* X25519 */, + 964 /* X25519Kyber768 */, 961 /* X448 */, 12 /* X509 */, 402 /* X509v3 AC Targeting */, diff --git a/Sources/CNIOBoringSSL/crypto/pem/pem_info.c b/Sources/CNIOBoringSSL/crypto/pem/pem_info.c index 1e4ae964..042c3dec 100644 --- a/Sources/CNIOBoringSSL/crypto/pem/pem_info.c +++ b/Sources/CNIOBoringSSL/crypto/pem/pem_info.c @@ -1,4 +1,3 @@ -/* crypto/pem/pem_info.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -140,7 +139,6 @@ STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, if (sk == NULL) { ret = sk_X509_INFO_new_null(); if (ret == NULL) { - OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); return NULL; } } else { diff --git a/Sources/CNIOBoringSSL/crypto/pem/pem_lib.c b/Sources/CNIOBoringSSL/crypto/pem/pem_lib.c index 8531ad4e..6f9bb695 100644 --- a/Sources/CNIOBoringSSL/crypto/pem/pem_lib.c +++ b/Sources/CNIOBoringSSL/crypto/pem/pem_lib.c @@ -1,4 +1,3 @@ -/* crypto/pem/pem_lib.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -76,10 +75,11 @@ #define MIN_LENGTH 4 -static int load_iv(char **fromp, unsigned char *to, int num); +static int load_iv(char **fromp, unsigned char *to, size_t num); static int check_pem(const char *nm, const char *name); -void PEM_proc_type(char *buf, int type) { +// PEM_proc_type appends a Proc-Type header to |buf|, determined by |type|. +static void PEM_proc_type(char buf[PEM_BUFSIZE], int type) { const char *str; if (type == PEM_TYPE_ENCRYPTED) { @@ -97,24 +97,27 @@ void PEM_proc_type(char *buf, int type) { OPENSSL_strlcat(buf, "\n", PEM_BUFSIZE); } -void PEM_dek_info(char *buf, const char *type, int len, char *str) { +// PEM_dek_info appends a DEK-Info header to |buf|, with an algorithm of |type| +// and a single parameter, specified by hex-encoding |len| bytes from |str|. +static void PEM_dek_info(char buf[PEM_BUFSIZE], const char *type, size_t len, + char *str) { static const unsigned char map[17] = "0123456789ABCDEF"; - long i; - int j; OPENSSL_strlcat(buf, "DEK-Info: ", PEM_BUFSIZE); OPENSSL_strlcat(buf, type, PEM_BUFSIZE); OPENSSL_strlcat(buf, ",", PEM_BUFSIZE); - j = strlen(buf); - if (j + (len * 2) + 1 > PEM_BUFSIZE) { + size_t buf_len = strlen(buf); + // We must write an additional |2 * len + 2| bytes after |buf_len|, including + // the trailing newline and NUL. + if (len > (PEM_BUFSIZE - buf_len - 2) / 2) { 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]; + for (size_t i = 0; i < len; i++) { + buf[buf_len + i * 2] = map[(str[i] >> 4) & 0x0f]; + buf[buf_len + i * 2 + 1] = map[(str[i]) & 0x0f]; } - buf[j + i * 2] = '\n'; - buf[j + i * 2 + 1] = '\0'; + buf[buf_len + len * 2] = '\n'; + buf[buf_len + len * 2 + 1] = '\0'; } void *PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x, @@ -299,7 +302,6 @@ int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, void *x, // 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; @@ -320,7 +322,7 @@ int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, void *x, } kstr = (unsigned char *)buf; } - assert(iv_len <= (int)sizeof(iv)); + assert(iv_len <= sizeof(iv)); if (!RAND_bytes(iv, iv_len)) { // Generate a salt goto err; } @@ -334,7 +336,7 @@ int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, void *x, OPENSSL_cleanse(buf, PEM_BUFSIZE); } - assert(strlen(objstr) + 23 + 2 * iv_len + 13 <= sizeof buf); + assert(strlen(objstr) + 23 + 2 * iv_len + 13 <= sizeof(buf)); buf[0] = '\0'; PEM_proc_type(buf, PEM_TYPE_ENCRYPTED); @@ -465,8 +467,8 @@ int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher) { p = header; for (;;) { c = *header; - if (!(((c >= 'A') && (c <= 'Z')) || (c == '-') || - ((c >= '0') && (c <= '9')))) { + if (!((c >= 'A' && c <= 'Z') || c == '-' || + OPENSSL_isdigit(c))) { break; } header++; @@ -494,28 +496,22 @@ int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher) { return 1; } -static int load_iv(char **fromp, unsigned char *to, int num) { - int v, i; +static int load_iv(char **fromp, unsigned char *to, size_t num) { + uint8_t v; char *from; from = *fromp; - for (i = 0; i < num; i++) { + for (size_t 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 { + for (size_t i = 0; i < num; i++) { + if (!OPENSSL_fromxdigit(&v, *from)) { OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_IV_CHARS); return 0; } from++; - to[i / 2] |= v << (long)((!(i & 1)) * 4); + to[i / 2] |= v << (!(i & 1)) * 4; } *fromp = from; @@ -559,7 +555,6 @@ int PEM_write_bio(BIO *bp, const char *name, const char *header, buf = OPENSSL_malloc(PEM_BUFSIZE * 8); if (buf == NULL) { - reason = ERR_R_MALLOC_FAILURE; goto err; } @@ -622,7 +617,6 @@ int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data, BUF_MEM_free(nameB); BUF_MEM_free(headerB); BUF_MEM_free(dataB); - OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); return 0; } @@ -648,7 +642,6 @@ int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data, continue; } if (!BUF_MEM_grow(nameB, i + 9)) { - OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); goto err; } OPENSSL_memcpy(nameB->data, &(buf[11]), i - 6); @@ -658,7 +651,6 @@ int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data, } hl = 0; if (!BUF_MEM_grow(headerB, 256)) { - OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); goto err; } headerB->data[0] = '\0'; @@ -678,7 +670,6 @@ int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data, 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) { @@ -692,7 +683,6 @@ int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data, bl = 0; if (!BUF_MEM_grow(dataB, 1024)) { - OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); goto err; } dataB->data[0] = '\0'; @@ -719,7 +709,6 @@ int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data, break; } if (!BUF_MEM_grow_clean(dataB, i + bl + 9)) { - OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); goto err; } OPENSSL_memcpy(&(dataB->data[bl]), buf, i); @@ -796,5 +785,5 @@ int PEM_def_callback(char *buf, int size, int rwflag, void *userdata) { return 0; } OPENSSL_strlcpy(buf, userdata, (size_t)size); - return len; + return (int)len; } diff --git a/Sources/CNIOBoringSSL/crypto/pem/pem_oth.c b/Sources/CNIOBoringSSL/crypto/pem/pem_oth.c index 906dc044..9deace72 100644 --- a/Sources/CNIOBoringSSL/crypto/pem/pem_oth.c +++ b/Sources/CNIOBoringSSL/crypto/pem/pem_oth.c @@ -1,4 +1,3 @@ -/* crypto/pem/pem_oth.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * diff --git a/Sources/CNIOBoringSSL/crypto/pem/pem_pk8.c b/Sources/CNIOBoringSSL/crypto/pem/pem_pk8.c index baec0c66..a8dbc487 100644 --- a/Sources/CNIOBoringSSL/crypto/pem/pem_pk8.c +++ b/Sources/CNIOBoringSSL/crypto/pem/pem_pk8.c @@ -64,10 +64,10 @@ #include #include -static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, int nid, +static int do_pk8pkey(BIO *bp, const EVP_PKEY *x, int isder, int nid, const EVP_CIPHER *enc, char *kstr, int klen, pem_password_cb *cb, void *u); -static int do_pk8pkey_fp(FILE *bp, EVP_PKEY *x, int isder, int nid, +static int do_pk8pkey_fp(FILE *bp, const EVP_PKEY *x, int isder, int nid, const EVP_CIPHER *enc, char *kstr, int klen, pem_password_cb *cb, void *u); @@ -76,29 +76,30 @@ static int do_pk8pkey_fp(FILE *bp, EVP_PKEY *x, int isder, int nid, // 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) { +int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, const EVP_PKEY *x, int nid, + char *kstr, int klen, pem_password_cb *cb, + void *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) { +int PEM_write_bio_PKCS8PrivateKey(BIO *bp, const EVP_PKEY *x, + const EVP_CIPHER *enc, char *kstr, int klen, + pem_password_cb *cb, void *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, +int i2d_PKCS8PrivateKey_bio(BIO *bp, const EVP_PKEY *x, const EVP_CIPHER *enc, char *kstr, int klen, pem_password_cb *cb, void *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 i2d_PKCS8PrivateKey_nid_bio(BIO *bp, const EVP_PKEY *x, int nid, char *kstr, int klen, pem_password_cb *cb, void *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, +static int do_pk8pkey(BIO *bp, const EVP_PKEY *x, int isder, int nid, const EVP_CIPHER *enc, char *kstr, int klen, pem_password_cb *cb, void *u) { X509_SIG *p8; @@ -190,28 +191,29 @@ EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, } -int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, +int i2d_PKCS8PrivateKey_fp(FILE *fp, const EVP_PKEY *x, const EVP_CIPHER *enc, char *kstr, int klen, pem_password_cb *cb, void *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 i2d_PKCS8PrivateKey_nid_fp(FILE *fp, const EVP_PKEY *x, int nid, char *kstr, int klen, pem_password_cb *cb, void *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) { +int PEM_write_PKCS8PrivateKey_nid(FILE *fp, const EVP_PKEY *x, int nid, + char *kstr, int klen, pem_password_cb *cb, + void *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) { +int PEM_write_PKCS8PrivateKey(FILE *fp, const EVP_PKEY *x, + const EVP_CIPHER *enc, char *kstr, int klen, + pem_password_cb *cb, void *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, +static int do_pk8pkey_fp(FILE *fp, const EVP_PKEY *x, int isder, int nid, const EVP_CIPHER *enc, char *kstr, int klen, pem_password_cb *cb, void *u) { BIO *bp; diff --git a/Sources/CNIOBoringSSL/crypto/pem/pem_x509.c b/Sources/CNIOBoringSSL/crypto/pem/pem_x509.c index ab6a64fa..bad8160d 100644 --- a/Sources/CNIOBoringSSL/crypto/pem/pem_x509.c +++ b/Sources/CNIOBoringSSL/crypto/pem/pem_x509.c @@ -1,4 +1,3 @@ -/* pem_x509.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 2001. diff --git a/Sources/CNIOBoringSSL/crypto/pem/pem_xaux.c b/Sources/CNIOBoringSSL/crypto/pem/pem_xaux.c index 84111553..569d609f 100644 --- a/Sources/CNIOBoringSSL/crypto/pem/pem_xaux.c +++ b/Sources/CNIOBoringSSL/crypto/pem/pem_xaux.c @@ -1,4 +1,3 @@ -/* pem_xaux.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 2001. diff --git a/Sources/CNIOBoringSSL/crypto/pkcs7/pkcs7_x509.c b/Sources/CNIOBoringSSL/crypto/pkcs7/pkcs7_x509.c index 710047e0..4259145d 100644 --- a/Sources/CNIOBoringSSL/crypto/pkcs7/pkcs7_x509.c +++ b/Sources/CNIOBoringSSL/crypto/pkcs7/pkcs7_x509.c @@ -328,7 +328,6 @@ int i2d_PKCS7(const PKCS7 *p7, uint8_t **out) { if (*out == NULL) { *out = OPENSSL_malloc(p7->ber_len); if (*out == NULL) { - OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE); return -1; } OPENSSL_memcpy(*out, p7->ber_bytes, p7->ber_len); diff --git a/Sources/CNIOBoringSSL/crypto/pkcs8/pkcs8.c b/Sources/CNIOBoringSSL/crypto/pkcs8/pkcs8.c index 11084c6f..fa0634b9 100644 --- a/Sources/CNIOBoringSSL/crypto/pkcs8/pkcs8.c +++ b/Sources/CNIOBoringSSL/crypto/pkcs8/pkcs8.c @@ -76,7 +76,6 @@ static int pkcs12_encode_password(const char *in, size_t in_len, uint8_t **out, size_t *out_len) { CBB cbb; if (!CBB_init(&cbb, in_len * 2)) { - OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE); return 0; } @@ -162,7 +161,6 @@ int pkcs12_key_gen(const char *pass, size_t pass_len, const uint8_t *salt, I = OPENSSL_malloc(I_len); if (I_len != 0 && I == NULL) { - OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE); goto err; } @@ -390,7 +388,6 @@ int pkcs8_pbe_decrypt(uint8_t **out, size_t *out_len, CBS *algorithm, buf = OPENSSL_malloc(in_len); if (buf == NULL) { - OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE); goto err; } diff --git a/Sources/CNIOBoringSSL/crypto/pkcs8/pkcs8_x509.c b/Sources/CNIOBoringSSL/crypto/pkcs8/pkcs8_x509.c index 433dfa6d..92b7c09f 100644 --- a/Sources/CNIOBoringSSL/crypto/pkcs8/pkcs8_x509.c +++ b/Sources/CNIOBoringSSL/crypto/pkcs8/pkcs8_x509.c @@ -334,7 +334,6 @@ static int parse_bag_attributes(CBS *attrs, uint8_t **out_friendly_name, // Convert the friendly name to UTF-8. CBB cbb; if (!CBB_init(&cbb, CBS_len(&value))) { - OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE); goto err; } while (CBS_len(&value) != 0) { @@ -347,7 +346,6 @@ static int parse_bag_attributes(CBS *attrs, uint8_t **out_friendly_name, } } if (!CBB_finish(&cbb, out_friendly_name, out_friendly_name_len)) { - OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE); CBB_cleanup(&cbb); goto err; } @@ -782,7 +780,9 @@ PKCS12* d2i_PKCS12_bio(BIO *bio, PKCS12 **out_p12) { } for (;;) { - int n = BIO_read(bio, &buf->data[used], buf->length - used); + size_t max_read = buf->length - used; + int n = BIO_read(bio, &buf->data[used], + max_read > INT_MAX ? INT_MAX : (int)max_read); if (n < 0) { if (used == 0) { goto out; @@ -842,7 +842,6 @@ int i2d_PKCS12(const PKCS12 *p12, uint8_t **out) { if (*out == NULL) { *out = OPENSSL_malloc(p12->ber_len); if (*out == NULL) { - OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE); return -1; } OPENSSL_memcpy(*out, p12->ber_bytes, p12->ber_len); @@ -881,7 +880,6 @@ int PKCS12_parse(const PKCS12 *p12, const char *password, EVP_PKEY **out_pkey, if (!ca_certs) { ca_certs = sk_X509_new_null(); if (ca_certs == NULL) { - OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE); return 0; } ca_certs_alloced = 1; diff --git a/Sources/CNIOBoringSSL/crypto/poly1305/poly1305.c b/Sources/CNIOBoringSSL/crypto/poly1305/poly1305.c index 4254983e..ca2e5018 100644 --- a/Sources/CNIOBoringSSL/crypto/poly1305/poly1305.c +++ b/Sources/CNIOBoringSSL/crypto/poly1305/poly1305.c @@ -241,7 +241,6 @@ void CRYPTO_poly1305_update(poly1305_state *statep, const uint8_t *in, void CRYPTO_poly1305_finish(poly1305_state *statep, uint8_t mac[16]) { struct poly1305_state_st *state = poly1305_aligned_state(statep); - uint64_t f0, f1, f2, f3; uint32_t g0, g1, g2, g3, g4; uint32_t b, nb; @@ -294,22 +293,22 @@ void CRYPTO_poly1305_finish(poly1305_state *statep, uint8_t mac[16]) { state->h3 = (state->h3 & nb) | (g3 & b); state->h4 = (state->h4 & nb) | (g4 & b); - f0 = ((state->h0) | (state->h1 << 26)) + - (uint64_t)CRYPTO_load_u32_le(&state->key[0]); - f1 = ((state->h1 >> 6) | (state->h2 << 20)) + - (uint64_t)CRYPTO_load_u32_le(&state->key[4]); - f2 = ((state->h2 >> 12) | (state->h3 << 14)) + - (uint64_t)CRYPTO_load_u32_le(&state->key[8]); - f3 = ((state->h3 >> 18) | (state->h4 << 8)) + - (uint64_t)CRYPTO_load_u32_le(&state->key[12]); + uint64_t f0 = ((state->h0) | (state->h1 << 26)) + + (uint64_t)CRYPTO_load_u32_le(&state->key[0]); + uint64_t f1 = ((state->h1 >> 6) | (state->h2 << 20)) + + (uint64_t)CRYPTO_load_u32_le(&state->key[4]); + uint64_t f2 = ((state->h2 >> 12) | (state->h3 << 14)) + + (uint64_t)CRYPTO_load_u32_le(&state->key[8]); + uint64_t f3 = ((state->h3 >> 18) | (state->h4 << 8)) + + (uint64_t)CRYPTO_load_u32_le(&state->key[12]); - CRYPTO_store_u32_le(&mac[0], f0); + CRYPTO_store_u32_le(&mac[0], (uint32_t)f0); f1 += (f0 >> 32); - CRYPTO_store_u32_le(&mac[4], f1); + CRYPTO_store_u32_le(&mac[4], (uint32_t)f1); f2 += (f1 >> 32); - CRYPTO_store_u32_le(&mac[8], f2); + CRYPTO_store_u32_le(&mac[8], (uint32_t)f2); f3 += (f2 >> 32); - CRYPTO_store_u32_le(&mac[12], f3); + CRYPTO_store_u32_le(&mac[12], (uint32_t)f3); } #endif // !BORINGSSL_HAS_UINT128 || !OPENSSL_X86_64 diff --git a/Sources/CNIOBoringSSL/crypto/poly1305/poly1305_arm_asm.S b/Sources/CNIOBoringSSL/crypto/poly1305/poly1305_arm_asm.S index be201d97..e493c6ab 100644 --- a/Sources/CNIOBoringSSL/crypto/poly1305/poly1305_arm_asm.S +++ b/Sources/CNIOBoringSSL/crypto/poly1305/poly1305_arm_asm.S @@ -6,7 +6,7 @@ #endif #endif -#if defined(__arm__) && !defined(OPENSSL_NO_ASM) && !defined(__APPLE__) +#if defined(__ARMEL__) && !defined(OPENSSL_NO_ASM) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include @@ -2024,7 +2024,7 @@ vst1.8 d4,[r0,: 64] add sp,sp,#0 bx lr -#endif /* __arm__ && !OPENSSL_NO_ASM && !__APPLE__ */ +#endif /* __ARMEL__ && !OPENSSL_NO_ASM && __ELF__ */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/Sources/CNIOBoringSSL/crypto/rand_extra/passive.c b/Sources/CNIOBoringSSL/crypto/rand_extra/passive.c index e1ce9293..e3c527be 100644 --- a/Sources/CNIOBoringSSL/crypto/rand_extra/passive.c +++ b/Sources/CNIOBoringSSL/crypto/rand_extra/passive.c @@ -15,21 +15,143 @@ #include #include "../fipsmodule/rand/internal.h" +#include "../internal.h" #if defined(BORINGSSL_FIPS) +#define ENTROPY_READ_LEN \ + (/* last_block size */ 16 + CTR_DRBG_ENTROPY_LEN * BORINGSSL_FIPS_OVERREAD) + +#if defined(OPENSSL_ANDROID) + +#include +#include +#include +#include +#include +#include + +// socket_history_t enumerates whether the entropy daemon should be contacted +// for a given entropy request. Values other than socket_not_yet_attempted are +// sticky so if the first attempt to read from the daemon fails it's assumed +// that the daemon is not present and no more attempts will be made. If the +// first attempt is successful then attempts will be made forever more. +enum socket_history_t { + // initial value, no connections to the entropy daemon have been made yet. + socket_not_yet_attempted = 0, + // reading from the entropy daemon was successful + socket_success, + // reading from the entropy daemon failed. + socket_failed, +}; + +static _Atomic enum socket_history_t g_socket_history = + socket_not_yet_attempted; + +// DAEMON_RESPONSE_LEN is the number of bytes that the entropy daemon replies +// with. +#define DAEMON_RESPONSE_LEN 496 + +static_assert(ENTROPY_READ_LEN == DAEMON_RESPONSE_LEN, + "entropy daemon response length mismatch"); + +static int get_seed_from_daemon(uint8_t *out_entropy, size_t out_entropy_len) { + // |RAND_need_entropy| should never call this function for more than + // |DAEMON_RESPONSE_LEN| bytes. + if (out_entropy_len > DAEMON_RESPONSE_LEN) { + abort(); + } + + const enum socket_history_t socket_history = atomic_load(&g_socket_history); + if (socket_history == socket_failed) { + return 0; + } + + int ret = 0; + const int sock = socket(AF_UNIX, SOCK_STREAM, 0); + if (sock < 0) { + goto out; + } + + struct sockaddr_un sun; + memset(&sun, 0, sizeof(sun)); + sun.sun_family = AF_UNIX; + static const char kSocketPath[] = "/dev/socket/prng_seeder"; + static_assert(sizeof(kSocketPath) <= UNIX_PATH_MAX, + "kSocketPath too long"); + OPENSSL_memcpy(sun.sun_path, kSocketPath, sizeof(kSocketPath)); + + if (connect(sock, (struct sockaddr *)&sun, sizeof(sun))) { + goto out; + } + + uint8_t buffer[DAEMON_RESPONSE_LEN]; + size_t done = 0; + while (done < sizeof(buffer)) { + ssize_t n; + do { + n = read(sock, buffer + done, sizeof(buffer) - done); + } while (n == -1 && errno == EINTR); + + if (n < 1) { + goto out; + } + done += n; + } + + if (done != DAEMON_RESPONSE_LEN) { + // The daemon should always write |DAEMON_RESPONSE_LEN| bytes on every + // connection. + goto out; + } + + assert(out_entropy_len <= DAEMON_RESPONSE_LEN); + OPENSSL_memcpy(out_entropy, buffer, out_entropy_len); + ret = 1; + +out: + if (socket_history == socket_not_yet_attempted) { + enum socket_history_t expected = socket_history; + // If another thread has already updated |g_socket_history| then we defer + // to their value. + atomic_compare_exchange_strong(&g_socket_history, &expected, + (ret == 0) ? socket_failed : socket_success); + } + + close(sock); + return ret; +} + +#else + +static int get_seed_from_daemon(uint8_t *out_entropy, size_t out_entropy_len) { + return 0; +} + +#endif // OPENSSL_ANDROID + // RAND_need_entropy is called by the FIPS module when it has blocked because of // a lack of entropy. This signal is used as an indication to feed it more. void RAND_need_entropy(size_t bytes_needed) { - uint8_t buf[/* last_block size */ 16 + - CTR_DRBG_ENTROPY_LEN * BORINGSSL_FIPS_OVERREAD]; + uint8_t buf[ENTROPY_READ_LEN]; size_t todo = sizeof(buf); if (todo > bytes_needed) { todo = bytes_needed; } int want_additional_input; - CRYPTO_get_seed_entropy(buf, todo, &want_additional_input); + if (get_seed_from_daemon(buf, todo)) { + want_additional_input = 1; + } else { + CRYPTO_get_seed_entropy(buf, todo, &want_additional_input); + } + + if (boringssl_fips_break_test("CRNG")) { + // This breaks the "continuous random number generator test" defined in FIPS + // 140-2, section 4.9.2, and implemented in |rand_get_seed|. + OPENSSL_memset(buf, 0, todo); + } + RAND_load_entropy(buf, todo, want_additional_input); } diff --git a/Sources/CNIOBoringSSL/crypto/asn1/a_print.c b/Sources/CNIOBoringSSL/crypto/rsa_extra/internal.h similarity index 84% rename from Sources/CNIOBoringSSL/crypto/asn1/a_print.c rename to Sources/CNIOBoringSSL/crypto/rsa_extra/internal.h index 67596cbd..6317cfc0 100644 --- a/Sources/CNIOBoringSSL/crypto/asn1/a_print.c +++ b/Sources/CNIOBoringSSL/crypto/rsa_extra/internal.h @@ -54,29 +54,24 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ -#include -#include +#ifndef OPENSSL_HEADER_RSA_EXTRA_INTERNAL_H +#define OPENSSL_HEADER_RSA_EXTRA_INTERNAL_H -#include "internal.h" +#if defined(__cplusplus) +extern "C" { +#endif -int ASN1_PRINTABLE_type(const unsigned char *s, int len) { - if (len < 0) { - len = strlen((const char *)s); - } +int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *out, size_t *out_len, + size_t max_out, const uint8_t *from, + size_t from_len, const uint8_t *param, + size_t param_len, const EVP_MD *md, + const EVP_MD *mgf1md); - int printable = 1; - for (int i = 0; i < len; i++) { - unsigned char c = s[i]; - if (c & 0x80) { - // No need to continue iterating. - return V_ASN1_T61STRING; - } - if (!asn1_is_printable(c)) { - printable = 0; - } - } - return printable ? V_ASN1_PRINTABLESTRING : V_ASN1_IA5STRING; -} +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_RSA_EXTRA_INTERNAL_H diff --git a/Sources/CNIOBoringSSL/crypto/rsa_extra/rsa_crypt.c b/Sources/CNIOBoringSSL/crypto/rsa_extra/rsa_crypt.c new file mode 100644 index 00000000..3f7b91b6 --- /dev/null +++ b/Sources/CNIOBoringSSL/crypto/rsa_extra/rsa_crypt.c @@ -0,0 +1,563 @@ +/* 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 + +#include + +#include +#include +#include +#include +#include +#include + +#include "../fipsmodule/bn/internal.h" +#include "../fipsmodule/rsa/internal.h" +#include "../internal.h" +#include "internal.h" + + +static void rand_nonzero(uint8_t *out, size_t len) { + RAND_bytes(out, len); + + for (size_t i = 0; i < len; i++) { + while (out[i] == 0) { + RAND_bytes(out + i, 1); + } + } +} + +int RSA_padding_add_PKCS1_OAEP_mgf1(uint8_t *to, size_t to_len, + const uint8_t *from, size_t from_len, + const uint8_t *param, size_t param_len, + const EVP_MD *md, const EVP_MD *mgf1md) { + if (md == NULL) { + md = EVP_sha1(); + } + if (mgf1md == NULL) { + mgf1md = md; + } + + size_t mdlen = EVP_MD_size(md); + + if (to_len < 2 * mdlen + 2) { + OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); + return 0; + } + + size_t emlen = to_len - 1; + if (from_len > emlen - 2 * mdlen - 1) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + return 0; + } + + if (emlen < 2 * mdlen + 1) { + OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); + return 0; + } + + to[0] = 0; + uint8_t *seed = to + 1; + uint8_t *db = to + mdlen + 1; + + uint8_t *dbmask = NULL; + int ret = 0; + if (!EVP_Digest(param, param_len, db, NULL, md, NULL)) { + goto out; + } + OPENSSL_memset(db + mdlen, 0, emlen - from_len - 2 * mdlen - 1); + db[emlen - from_len - mdlen - 1] = 0x01; + OPENSSL_memcpy(db + emlen - from_len - mdlen, from, from_len); + if (!RAND_bytes(seed, mdlen)) { + goto out; + } + + dbmask = OPENSSL_malloc(emlen - mdlen); + if (dbmask == NULL) { + goto out; + } + + if (!PKCS1_MGF1(dbmask, emlen - mdlen, seed, mdlen, mgf1md)) { + goto out; + } + for (size_t i = 0; i < emlen - mdlen; i++) { + db[i] ^= dbmask[i]; + } + + uint8_t seedmask[EVP_MAX_MD_SIZE]; + if (!PKCS1_MGF1(seedmask, mdlen, db, emlen - mdlen, mgf1md)) { + goto out; + } + for (size_t i = 0; i < mdlen; i++) { + seed[i] ^= seedmask[i]; + } + ret = 1; + +out: + OPENSSL_free(dbmask); + return ret; +} + +int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *out, size_t *out_len, + size_t max_out, const uint8_t *from, + size_t from_len, const uint8_t *param, + size_t param_len, const EVP_MD *md, + const EVP_MD *mgf1md) { + uint8_t *db = NULL; + + if (md == NULL) { + md = EVP_sha1(); + } + if (mgf1md == NULL) { + mgf1md = md; + } + + size_t mdlen = EVP_MD_size(md); + + // The encoded message is one byte smaller than the modulus to ensure that it + // doesn't end up greater than the modulus. Thus there's an extra "+1" here + // compared to https://tools.ietf.org/html/rfc2437#section-9.1.1.2. + if (from_len < 1 + 2 * mdlen + 1) { + // 'from_len' is the length of the modulus, i.e. does not depend on the + // particular ciphertext. + goto decoding_err; + } + + size_t dblen = from_len - mdlen - 1; + db = OPENSSL_malloc(dblen); + if (db == NULL) { + goto err; + } + + const uint8_t *maskedseed = from + 1; + const uint8_t *maskeddb = from + 1 + mdlen; + + uint8_t seed[EVP_MAX_MD_SIZE]; + if (!PKCS1_MGF1(seed, mdlen, maskeddb, dblen, mgf1md)) { + goto err; + } + for (size_t i = 0; i < mdlen; i++) { + seed[i] ^= maskedseed[i]; + } + + if (!PKCS1_MGF1(db, dblen, seed, mdlen, mgf1md)) { + goto err; + } + for (size_t i = 0; i < dblen; i++) { + db[i] ^= maskeddb[i]; + } + + uint8_t phash[EVP_MAX_MD_SIZE]; + if (!EVP_Digest(param, param_len, phash, NULL, md, NULL)) { + goto err; + } + + crypto_word_t bad = ~constant_time_is_zero_w(CRYPTO_memcmp(db, phash, mdlen)); + bad |= ~constant_time_is_zero_w(from[0]); + + crypto_word_t looking_for_one_byte = CONSTTIME_TRUE_W; + size_t one_index = 0; + for (size_t i = mdlen; i < dblen; i++) { + crypto_word_t equals1 = constant_time_eq_w(db[i], 1); + crypto_word_t equals0 = constant_time_eq_w(db[i], 0); + one_index = + constant_time_select_w(looking_for_one_byte & equals1, i, one_index); + looking_for_one_byte = + constant_time_select_w(equals1, 0, looking_for_one_byte); + bad |= looking_for_one_byte & ~equals0; + } + + bad |= looking_for_one_byte; + + // Whether the overall padding was valid or not in OAEP is public. + if (constant_time_declassify_w(bad)) { + goto decoding_err; + } + + // Once the padding is known to be valid, the output length is also public. + static_assert(sizeof(size_t) <= sizeof(crypto_word_t), + "size_t does not fit in crypto_word_t"); + one_index = constant_time_declassify_w(one_index); + + one_index++; + size_t mlen = dblen - one_index; + if (max_out < mlen) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE); + goto err; + } + + OPENSSL_memcpy(out, db + one_index, mlen); + *out_len = mlen; + OPENSSL_free(db); + return 1; + +decoding_err: + // To avoid chosen ciphertext attacks, the error message should not reveal + // which kind of decoding error happened. + OPENSSL_PUT_ERROR(RSA, RSA_R_OAEP_DECODING_ERROR); +err: + OPENSSL_free(db); + return 0; +} + +static int rsa_padding_add_PKCS1_type_2(uint8_t *to, size_t to_len, + const uint8_t *from, size_t from_len) { + // See RFC 8017, section 7.2.1. + if (to_len < RSA_PKCS1_PADDING_SIZE) { + OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); + return 0; + } + + if (from_len > to_len - RSA_PKCS1_PADDING_SIZE) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + return 0; + } + + to[0] = 0; + to[1] = 2; + + size_t padding_len = to_len - 3 - from_len; + rand_nonzero(to + 2, padding_len); + to[2 + padding_len] = 0; + OPENSSL_memcpy(to + to_len - from_len, from, from_len); + return 1; +} + +static int rsa_padding_check_PKCS1_type_2(uint8_t *out, size_t *out_len, + size_t max_out, const uint8_t *from, + size_t from_len) { + if (from_len == 0) { + OPENSSL_PUT_ERROR(RSA, RSA_R_EMPTY_PUBLIC_KEY); + return 0; + } + + // PKCS#1 v1.5 decryption. See "PKCS #1 v2.2: RSA Cryptography + // Standard", section 7.2.2. + if (from_len < RSA_PKCS1_PADDING_SIZE) { + // |from| is zero-padded to the size of the RSA modulus, a public value, so + // this can be rejected in non-constant time. + OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); + return 0; + } + + crypto_word_t first_byte_is_zero = constant_time_eq_w(from[0], 0); + crypto_word_t second_byte_is_two = constant_time_eq_w(from[1], 2); + + crypto_word_t zero_index = 0, looking_for_index = CONSTTIME_TRUE_W; + for (size_t i = 2; i < from_len; i++) { + crypto_word_t equals0 = constant_time_is_zero_w(from[i]); + zero_index = + constant_time_select_w(looking_for_index & equals0, i, zero_index); + looking_for_index = constant_time_select_w(equals0, 0, looking_for_index); + } + + // The input must begin with 00 02. + crypto_word_t valid_index = first_byte_is_zero; + valid_index &= second_byte_is_two; + + // We must have found the end of PS. + valid_index &= ~looking_for_index; + + // PS must be at least 8 bytes long, and it starts two bytes into |from|. + valid_index &= constant_time_ge_w(zero_index, 2 + 8); + + // Skip the zero byte. + zero_index++; + + // NOTE: Although this logic attempts to be constant time, the API contracts + // of this function and |RSA_decrypt| with |RSA_PKCS1_PADDING| make it + // impossible to completely avoid Bleichenbacher's attack. Consumers should + // use |RSA_PADDING_NONE| and perform the padding check in constant-time + // combined with a swap to a random session key or other mitigation. + CONSTTIME_DECLASSIFY(&valid_index, sizeof(valid_index)); + CONSTTIME_DECLASSIFY(&zero_index, sizeof(zero_index)); + + if (!valid_index) { + OPENSSL_PUT_ERROR(RSA, RSA_R_PKCS_DECODING_ERROR); + return 0; + } + + const size_t msg_len = from_len - zero_index; + if (msg_len > max_out) { + // This shouldn't happen because this function is always called with + // |max_out| as the key size and |from_len| is bounded by the key size. + OPENSSL_PUT_ERROR(RSA, RSA_R_PKCS_DECODING_ERROR); + return 0; + } + + OPENSSL_memcpy(out, &from[zero_index], msg_len); + *out_len = msg_len; + return 1; +} + +int RSA_public_encrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa, + int padding) { + size_t out_len; + + if (!RSA_encrypt(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) { + return -1; + } + + if (out_len > INT_MAX) { + OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW); + return -1; + } + return (int)out_len; +} + +int RSA_private_encrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa, + int padding) { + size_t out_len; + + if (!RSA_sign_raw(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) { + return -1; + } + + if (out_len > INT_MAX) { + OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW); + return -1; + } + return (int)out_len; +} + +int RSA_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, + const uint8_t *in, size_t in_len, int padding) { + if (!rsa_check_public_key(rsa)) { + return 0; + } + + const unsigned rsa_size = RSA_size(rsa); + BIGNUM *f, *result; + uint8_t *buf = NULL; + BN_CTX *ctx = NULL; + int i, ret = 0; + + if (max_out < rsa_size) { + OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL); + return 0; + } + + ctx = BN_CTX_new(); + if (ctx == NULL) { + goto err; + } + + BN_CTX_start(ctx); + f = BN_CTX_get(ctx); + result = BN_CTX_get(ctx); + buf = OPENSSL_malloc(rsa_size); + if (!f || !result || !buf) { + goto err; + } + + switch (padding) { + case RSA_PKCS1_PADDING: + i = rsa_padding_add_PKCS1_type_2(buf, rsa_size, in, in_len); + break; + case RSA_PKCS1_OAEP_PADDING: + // Use the default parameters: SHA-1 for both hashes and no label. + i = RSA_padding_add_PKCS1_OAEP_mgf1(buf, rsa_size, in, in_len, NULL, 0, + NULL, NULL); + break; + case RSA_NO_PADDING: + i = RSA_padding_add_none(buf, rsa_size, in, in_len); + break; + default: + OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } + + if (i <= 0) { + goto err; + } + + if (BN_bin2bn(buf, rsa_size, f) == NULL) { + goto err; + } + + if (BN_ucmp(f, rsa->n) >= 0) { + // usually the padding functions would catch this + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_MODULUS); + goto err; + } + + if (!BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx) || + !BN_mod_exp_mont(result, f, rsa->e, &rsa->mont_n->N, ctx, rsa->mont_n)) { + goto err; + } + + // put in leading 0 bytes if the number is less than the length of the + // modulus + if (!BN_bn2bin_padded(out, rsa_size, result)) { + OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); + goto err; + } + + *out_len = rsa_size; + ret = 1; + +err: + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + OPENSSL_free(buf); + + return ret; +} + +static int rsa_default_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, + size_t max_out, const uint8_t *in, size_t in_len, + int padding) { + const unsigned rsa_size = RSA_size(rsa); + uint8_t *buf = NULL; + int ret = 0; + + if (max_out < rsa_size) { + OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL); + return 0; + } + + if (padding == RSA_NO_PADDING) { + buf = out; + } else { + // Allocate a temporary buffer to hold the padded plaintext. + buf = OPENSSL_malloc(rsa_size); + if (buf == NULL) { + goto err; + } + } + + if (in_len != rsa_size) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_LEN_NOT_EQUAL_TO_MOD_LEN); + goto err; + } + + if (!rsa_private_transform(rsa, buf, in, rsa_size)) { + goto err; + } + + switch (padding) { + case RSA_PKCS1_PADDING: + ret = + rsa_padding_check_PKCS1_type_2(out, out_len, rsa_size, buf, rsa_size); + break; + case RSA_PKCS1_OAEP_PADDING: + // Use the default parameters: SHA-1 for both hashes and no label. + ret = RSA_padding_check_PKCS1_OAEP_mgf1(out, out_len, rsa_size, buf, + rsa_size, NULL, 0, NULL, NULL); + break; + case RSA_NO_PADDING: + *out_len = rsa_size; + ret = 1; + break; + default: + OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } + + CONSTTIME_DECLASSIFY(&ret, sizeof(ret)); + if (!ret) { + OPENSSL_PUT_ERROR(RSA, RSA_R_PADDING_CHECK_FAILED); + } else { + CONSTTIME_DECLASSIFY(out, *out_len); + } + +err: + if (padding != RSA_NO_PADDING) { + OPENSSL_free(buf); + } + + return ret; +} + +int RSA_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, + const uint8_t *in, size_t in_len, int padding) { + if (rsa->meth->decrypt) { + return rsa->meth->decrypt(rsa, out_len, out, max_out, in, in_len, padding); + } + + return rsa_default_decrypt(rsa, out_len, out, max_out, in, in_len, padding); +} + +int RSA_private_decrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa, + int padding) { + size_t out_len; + if (!RSA_decrypt(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) { + return -1; + } + + if (out_len > INT_MAX) { + OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW); + return -1; + } + return (int)out_len; +} + +int RSA_public_decrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa, + int padding) { + size_t out_len; + if (!RSA_verify_raw(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) { + return -1; + } + + if (out_len > INT_MAX) { + OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW); + return -1; + } + return (int)out_len; +} diff --git a/Sources/CNIOBoringSSL/crypto/stack/stack.c b/Sources/CNIOBoringSSL/crypto/stack/stack.c index 89887a69..f7c90126 100644 --- a/Sources/CNIOBoringSSL/crypto/stack/stack.c +++ b/Sources/CNIOBoringSSL/crypto/stack/stack.c @@ -212,7 +212,7 @@ void *sk_delete(_STACK *sk, size_t where) { if (where != sk->num - 1) { OPENSSL_memmove(&sk->data[where], &sk->data[where + 1], - sizeof(void *) * (sk->num - where - 1)); + sizeof(void *) * (sk->num - where - 1)); } sk->num--; @@ -233,6 +233,22 @@ void *sk_delete_ptr(_STACK *sk, const void *p) { return NULL; } +void sk_delete_if(_STACK *sk, OPENSSL_sk_call_delete_if_func call_func, + OPENSSL_sk_delete_if_func func, void *data) { + if (sk == NULL) { + return; + } + + size_t new_num = 0; + for (size_t i = 0; i < sk->num; i++) { + if (!call_func(func, sk->data[i], data)) { + sk->data[new_num] = sk->data[i]; + new_num++; + } + } + sk->num = new_num; +} + int sk_find(const _STACK *sk, size_t *out_index, const void *p, OPENSSL_sk_call_cmp_func call_cmp_func) { if (sk == NULL) { @@ -399,7 +415,8 @@ int sk_is_sorted(const _STACK *sk) { if (!sk) { return 1; } - return sk->sorted; + // Zero- and one-element lists are always sorted. + return sk->sorted || (sk->comp != NULL && sk->num < 2); } OPENSSL_sk_cmp_func sk_set_cmp_func(_STACK *sk, OPENSSL_sk_cmp_func comp) { diff --git a/Sources/CNIOBoringSSL/crypto/thread_pthread.c b/Sources/CNIOBoringSSL/crypto/thread_pthread.c index 8bba3673..82cbbfe5 100644 --- a/Sources/CNIOBoringSSL/crypto/thread_pthread.c +++ b/Sources/CNIOBoringSSL/crypto/thread_pthread.c @@ -12,6 +12,8 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +// Ensure we can't call OPENSSL_malloc circularly. +#define _BORINGSSL_PROHIBIT_OPENSSL_MALLOC #include "internal.h" #if defined(OPENSSL_PTHREADS) @@ -21,9 +23,6 @@ #include #include -#include - - static_assert(sizeof(CRYPTO_MUTEX) >= sizeof(pthread_rwlock_t), "CRYPTO_MUTEX is too small"); static_assert(alignof(CRYPTO_MUTEX) >= alignof(pthread_rwlock_t), @@ -118,7 +117,7 @@ static void thread_local_destructor(void *arg) { } } - OPENSSL_free(pointers); + free(pointers); } static pthread_once_t g_thread_local_init_once = PTHREAD_ONCE_INIT; @@ -153,14 +152,14 @@ int CRYPTO_set_thread_local(thread_local_data_t index, void *value, void **pointers = pthread_getspecific(g_thread_local_key); if (pointers == NULL) { - pointers = OPENSSL_malloc(sizeof(void *) * NUM_OPENSSL_THREAD_LOCALS); + pointers = malloc(sizeof(void *) * NUM_OPENSSL_THREAD_LOCALS); if (pointers == NULL) { destructor(value); return 0; } OPENSSL_memset(pointers, 0, sizeof(void *) * NUM_OPENSSL_THREAD_LOCALS); if (pthread_setspecific(g_thread_local_key, pointers) != 0) { - OPENSSL_free(pointers); + free(pointers); destructor(value); return 0; } diff --git a/Sources/CNIOBoringSSL/crypto/thread_win.c b/Sources/CNIOBoringSSL/crypto/thread_win.c index dc874409..57e4f9be 100644 --- a/Sources/CNIOBoringSSL/crypto/thread_win.c +++ b/Sources/CNIOBoringSSL/crypto/thread_win.c @@ -12,6 +12,8 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +// Ensure we can't call OPENSSL_malloc circularly. +#define _BORINGSSL_PROHIBIT_OPENSSL_MALLOC #include "internal.h" #if defined(OPENSSL_WINDOWS_THREADS) @@ -24,9 +26,6 @@ OPENSSL_MSVC_PRAGMA(warning(pop)) #include #include -#include - - static_assert(sizeof(CRYPTO_MUTEX) >= sizeof(SRWLOCK), "CRYPTO_MUTEX is too small"); static_assert(alignof(CRYPTO_MUTEX) >= alignof(SRWLOCK), @@ -129,7 +128,7 @@ static void NTAPI thread_local_destructor(PVOID module, DWORD reason, } } - OPENSSL_free(pointers); + free(pointers); } // Thread Termination Callbacks. @@ -234,14 +233,14 @@ int CRYPTO_set_thread_local(thread_local_data_t index, void *value, void **pointers = get_thread_locals(); if (pointers == NULL) { - pointers = OPENSSL_malloc(sizeof(void *) * NUM_OPENSSL_THREAD_LOCALS); + pointers = malloc(sizeof(void *) * NUM_OPENSSL_THREAD_LOCALS); if (pointers == NULL) { destructor(value); return 0; } OPENSSL_memset(pointers, 0, sizeof(void *) * NUM_OPENSSL_THREAD_LOCALS); if (TlsSetValue(g_thread_local_key, pointers) == 0) { - OPENSSL_free(pointers); + free(pointers); destructor(value); return 0; } diff --git a/Sources/CNIOBoringSSL/crypto/trust_token/internal.h b/Sources/CNIOBoringSSL/crypto/trust_token/internal.h index c84b3ac6..b35794af 100644 --- a/Sources/CNIOBoringSSL/crypto/trust_token/internal.h +++ b/Sources/CNIOBoringSSL/crypto/trust_token/internal.h @@ -71,6 +71,7 @@ typedef struct { // TRUST_TOKEN_PRETOKEN represents the intermediate state a client keeps during // a Trust_Token issuance operation. typedef struct pmb_pretoken_st { + uint8_t salt[TRUST_TOKEN_NONCE_SIZE]; uint8_t t[TRUST_TOKEN_NONCE_SIZE]; EC_SCALAR r; EC_AFFINE Tp; @@ -100,18 +101,22 @@ int pmbtoken_exp1_client_key_from_bytes(TRUST_TOKEN_CLIENT_KEY *key, const uint8_t *in, size_t len); int pmbtoken_exp1_issuer_key_from_bytes(TRUST_TOKEN_ISSUER_KEY *key, const uint8_t *in, size_t len); -STACK_OF(TRUST_TOKEN_PRETOKEN) * pmbtoken_exp1_blind(CBB *cbb, size_t count); +STACK_OF(TRUST_TOKEN_PRETOKEN) *pmbtoken_exp1_blind(CBB *cbb, size_t count, + int include_message, + const uint8_t *msg, + size_t msg_len); int pmbtoken_exp1_sign(const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, size_t num_requested, size_t num_to_issue, uint8_t private_metadata); -STACK_OF(TRUST_TOKEN) * - pmbtoken_exp1_unblind(const TRUST_TOKEN_CLIENT_KEY *key, - const STACK_OF(TRUST_TOKEN_PRETOKEN) * pretokens, - CBS *cbs, size_t count, uint32_t key_id); +STACK_OF(TRUST_TOKEN) *pmbtoken_exp1_unblind( + const TRUST_TOKEN_CLIENT_KEY *key, + const STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens, CBS *cbs, size_t count, + uint32_t key_id); int pmbtoken_exp1_read(const TRUST_TOKEN_ISSUER_KEY *key, uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE], uint8_t *out_private_metadata, const uint8_t *token, - size_t token_len); + size_t token_len, int include_message, + const uint8_t *msg, size_t msg_len); // pmbtoken_exp1_get_h_for_testing returns H in uncompressed coordinates. This // function is used to confirm H was computed as expected. @@ -128,23 +133,59 @@ int pmbtoken_exp2_client_key_from_bytes(TRUST_TOKEN_CLIENT_KEY *key, const uint8_t *in, size_t len); int pmbtoken_exp2_issuer_key_from_bytes(TRUST_TOKEN_ISSUER_KEY *key, const uint8_t *in, size_t len); -STACK_OF(TRUST_TOKEN_PRETOKEN) * pmbtoken_exp2_blind(CBB *cbb, size_t count); +STACK_OF(TRUST_TOKEN_PRETOKEN) *pmbtoken_exp2_blind(CBB *cbb, size_t count, + int include_message, + const uint8_t *msg, + size_t msg_len); int pmbtoken_exp2_sign(const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, size_t num_requested, size_t num_to_issue, uint8_t private_metadata); -STACK_OF(TRUST_TOKEN) * - pmbtoken_exp2_unblind(const TRUST_TOKEN_CLIENT_KEY *key, - const STACK_OF(TRUST_TOKEN_PRETOKEN) * pretokens, - CBS *cbs, size_t count, uint32_t key_id); +STACK_OF(TRUST_TOKEN) *pmbtoken_exp2_unblind( + const TRUST_TOKEN_CLIENT_KEY *key, + const STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens, CBS *cbs, size_t count, + uint32_t key_id); int pmbtoken_exp2_read(const TRUST_TOKEN_ISSUER_KEY *key, uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE], uint8_t *out_private_metadata, const uint8_t *token, - size_t token_len); + size_t token_len, int include_message, + const uint8_t *msg, size_t msg_len); // pmbtoken_exp2_get_h_for_testing returns H in uncompressed coordinates. This // function is used to confirm H was computed as expected. OPENSSL_EXPORT int pmbtoken_exp2_get_h_for_testing(uint8_t out[97]); +// The following functions implement the corresponding |TRUST_TOKENS_METHOD| +// functions for |TRUST_TOKENS_pst_v1|'s PMBTokens construction which uses +// P-384. +int pmbtoken_pst1_generate_key(CBB *out_private, CBB *out_public); +int pmbtoken_pst1_derive_key_from_secret(CBB *out_private, CBB *out_public, + const uint8_t *secret, + size_t secret_len); +int pmbtoken_pst1_client_key_from_bytes(TRUST_TOKEN_CLIENT_KEY *key, + const uint8_t *in, size_t len); +int pmbtoken_pst1_issuer_key_from_bytes(TRUST_TOKEN_ISSUER_KEY *key, + const uint8_t *in, size_t len); +STACK_OF(TRUST_TOKEN_PRETOKEN) *pmbtoken_pst1_blind(CBB *cbb, size_t count, + int include_message, + const uint8_t *msg, + size_t msg_len); +int pmbtoken_pst1_sign(const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, + size_t num_requested, size_t num_to_issue, + uint8_t private_metadata); +STACK_OF(TRUST_TOKEN) *pmbtoken_pst1_unblind( + const TRUST_TOKEN_CLIENT_KEY *key, + const STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens, CBS *cbs, size_t count, + uint32_t key_id); +int pmbtoken_pst1_read(const TRUST_TOKEN_ISSUER_KEY *key, + uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE], + uint8_t *out_private_metadata, const uint8_t *token, + size_t token_len, int include_message, + const uint8_t *msg, size_t msg_len); + +// pmbtoken_pst1_get_h_for_testing returns H in uncompressed coordinates. This +// function is used to confirm H was computed as expected. +OPENSSL_EXPORT int pmbtoken_pst1_get_h_for_testing(uint8_t out[97]); + // VOPRF. // @@ -165,18 +206,48 @@ int voprf_exp2_client_key_from_bytes(TRUST_TOKEN_CLIENT_KEY *key, const uint8_t *in, size_t len); int voprf_exp2_issuer_key_from_bytes(TRUST_TOKEN_ISSUER_KEY *key, const uint8_t *in, size_t len); -STACK_OF(TRUST_TOKEN_PRETOKEN) * voprf_exp2_blind(CBB *cbb, size_t count); +STACK_OF(TRUST_TOKEN_PRETOKEN) *voprf_exp2_blind(CBB *cbb, size_t count, + int include_message, + const uint8_t *msg, + size_t msg_len); int voprf_exp2_sign(const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, size_t num_requested, size_t num_to_issue, uint8_t private_metadata); -STACK_OF(TRUST_TOKEN) * - voprf_exp2_unblind(const TRUST_TOKEN_CLIENT_KEY *key, - const STACK_OF(TRUST_TOKEN_PRETOKEN) * pretokens, - CBS *cbs, size_t count, uint32_t key_id); +STACK_OF(TRUST_TOKEN) *voprf_exp2_unblind( + const TRUST_TOKEN_CLIENT_KEY *key, + const STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens, CBS *cbs, size_t count, + uint32_t key_id); int voprf_exp2_read(const TRUST_TOKEN_ISSUER_KEY *key, uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE], uint8_t *out_private_metadata, const uint8_t *token, - size_t token_len); + size_t token_len, int include_message, const uint8_t *msg, + size_t msg_len); + +// The following functions implement the corresponding |TRUST_TOKENS_METHOD| +// functions for |TRUST_TOKENS_pst_v1|'s VOPRF construction which uses P-384. +int voprf_pst1_generate_key(CBB *out_private, CBB *out_public); +int voprf_pst1_derive_key_from_secret(CBB *out_private, CBB *out_public, + const uint8_t *secret, size_t secret_len); +int voprf_pst1_client_key_from_bytes(TRUST_TOKEN_CLIENT_KEY *key, + const uint8_t *in, size_t len); +int voprf_pst1_issuer_key_from_bytes(TRUST_TOKEN_ISSUER_KEY *key, + const uint8_t *in, size_t len); +STACK_OF(TRUST_TOKEN_PRETOKEN) *voprf_pst1_blind(CBB *cbb, size_t count, + int include_message, + const uint8_t *msg, + size_t msg_len); +int voprf_pst1_sign(const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, + size_t num_requested, size_t num_to_issue, + uint8_t private_metadata); +STACK_OF(TRUST_TOKEN) *voprf_pst1_unblind( + const TRUST_TOKEN_CLIENT_KEY *key, + const STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens, CBS *cbs, size_t count, + uint32_t key_id); +int voprf_pst1_read(const TRUST_TOKEN_ISSUER_KEY *key, + uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE], + uint8_t *out_private_metadata, const uint8_t *token, + size_t token_len, int include_message, const uint8_t *msg, + size_t msg_len); // Trust Tokens internals. @@ -191,7 +262,7 @@ struct trust_token_method_st { // |secret| and writes their serialized forms into |out_private| and // |out_public|. It returns one on success and zero on failure. int (*derive_key_from_secret)(CBB *out_private, CBB *out_public, - const uint8_t *secret, size_t secret_len); + const uint8_t *secret, size_t secret_len); // client_key_from_bytes decodes a client key from |in| and sets |key| // to the resulting key. It returns one on success and zero @@ -205,14 +276,17 @@ struct trust_token_method_st { int (*issuer_key_from_bytes)(TRUST_TOKEN_ISSUER_KEY *key, const uint8_t *in, size_t len); - // blind generates a new issuance request for |count| tokens. On + // blind generates a new issuance request for |count| tokens. If + // |include_message| is set, then |msg| is used to derive the token nonces. On // success, it returns a newly-allocated |STACK_OF(TRUST_TOKEN_PRETOKEN)| and // writes a request to the issuer to |cbb|. On failure, it returns NULL. The - // |STACK_OF(TRUST_TOKEN_PRETOKEN)|s should be passed to |pmbtoken_unblind| when - // the server responds. + // |STACK_OF(TRUST_TOKEN_PRETOKEN)|s should be passed to |pmbtoken_unblind| + // when the server responds. // // This function implements the AT.Usr0 operation. - STACK_OF(TRUST_TOKEN_PRETOKEN) * (*blind)(CBB *cbb, size_t count); + STACK_OF(TRUST_TOKEN_PRETOKEN) *(*blind)(CBB *cbb, size_t count, + int include_message, + const uint8_t *msg, size_t msg_len); // sign parses a request for |num_requested| tokens from |cbs| and // issues |num_to_issue| tokens with |key| and a private metadata value of @@ -232,20 +306,22 @@ struct trust_token_method_st { // returns NULL. // // This function implements the AT.Usr1 operation. - STACK_OF(TRUST_TOKEN) * - (*unblind)(const TRUST_TOKEN_CLIENT_KEY *key, - const STACK_OF(TRUST_TOKEN_PRETOKEN) * pretokens, CBS *cbs, - size_t count, uint32_t key_id); - - // read parses a PMBToken from |token| and verifies it using |key|. On - // success, it returns one and stores the nonce and private metadata bit in - // |out_nonce| and |*out_private_metadata|. Otherwise, it returns zero. Note - // that, unlike the output of |unblind|, |token| does not have a - // four-byte key ID prepended. + STACK_OF(TRUST_TOKEN) *(*unblind)( + const TRUST_TOKEN_CLIENT_KEY *key, + const STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens, CBS *cbs, size_t count, + uint32_t key_id); + + // read parses a token from |token| and verifies it using |key|. If + // |include_message| is set, then the nonce is derived from |msg| and the salt + // in the token. On success, it returns one and stores the nonce and private + // metadata bit in |out_nonce| and |*out_private_metadata|. Otherwise, it + // returns zero. Note that, unlike the output of |unblind|, |token| does not + // have a four-byte key ID prepended. int (*read)(const TRUST_TOKEN_ISSUER_KEY *key, uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE], uint8_t *out_private_metadata, const uint8_t *token, - size_t token_len); + size_t token_len, int include_message, const uint8_t *msg, + size_t msg_len); // whether the construction supports private metadata. int has_private_metadata; @@ -284,7 +360,7 @@ struct trust_token_client_st { size_t num_keys; // pretokens is the intermediate state during an active issuance. - STACK_OF(TRUST_TOKEN_PRETOKEN)* pretokens; + STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens; // srr_key is the public key used to verify the signature of the SRR. EVP_PKEY *srr_key; diff --git a/Sources/CNIOBoringSSL/crypto/trust_token/pmbtoken.c b/Sources/CNIOBoringSSL/crypto/trust_token/pmbtoken.c index efcbc4b6..668651f7 100644 --- a/Sources/CNIOBoringSSL/crypto/trust_token/pmbtoken.c +++ b/Sources/CNIOBoringSSL/crypto/trust_token/pmbtoken.c @@ -123,8 +123,7 @@ static int derive_scalar_from_secret(const PMBTOKEN_METHOD *method, static int point_to_cbb(CBB *out, const EC_GROUP *group, const EC_AFFINE *point) { - size_t len = - ec_point_to_bytes(group, point, POINT_CONVERSION_UNCOMPRESSED, NULL, 0); + size_t len = ec_point_byte_len(group, POINT_CONVERSION_UNCOMPRESSED); if (len == 0) { return 0; } @@ -325,12 +324,14 @@ static int pmbtoken_issuer_key_from_bytes(const PMBTOKEN_METHOD *method, return 1; } -static STACK_OF(TRUST_TOKEN_PRETOKEN) * - pmbtoken_blind(const PMBTOKEN_METHOD *method, CBB *cbb, size_t count) { +static STACK_OF(TRUST_TOKEN_PRETOKEN) *pmbtoken_blind( + const PMBTOKEN_METHOD *method, CBB *cbb, size_t count, int include_message, + const uint8_t *msg, size_t msg_len) { + SHA512_CTX hash_ctx; + const EC_GROUP *group = method->group; STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens = sk_TRUST_TOKEN_PRETOKEN_new_null(); if (pretokens == NULL) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } @@ -339,17 +340,24 @@ static STACK_OF(TRUST_TOKEN_PRETOKEN) * TRUST_TOKEN_PRETOKEN *pretoken = OPENSSL_malloc(sizeof(TRUST_TOKEN_PRETOKEN)); if (pretoken == NULL || !sk_TRUST_TOKEN_PRETOKEN_push(pretokens, pretoken)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); TRUST_TOKEN_PRETOKEN_free(pretoken); goto err; } - RAND_bytes(pretoken->t, sizeof(pretoken->t)); + RAND_bytes(pretoken->salt, sizeof(pretoken->salt)); + if (include_message) { + assert(SHA512_DIGEST_LENGTH == TRUST_TOKEN_NONCE_SIZE); + SHA512_Init(&hash_ctx); + SHA512_Update(&hash_ctx, pretoken->salt, sizeof(pretoken->salt)); + SHA512_Update(&hash_ctx, msg, msg_len); + SHA512_Final(pretoken->t, &hash_ctx); + } else { + OPENSSL_memcpy(pretoken->t, pretoken->salt, TRUST_TOKEN_NONCE_SIZE); + } // We sample |pretoken->r| in Montgomery form to simplify inverting. if (!ec_random_nonzero_scalar(group, &pretoken->r, kDefaultAdditionalData)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } @@ -384,7 +392,6 @@ static int scalar_to_cbb(CBB *out, const EC_GROUP *group, uint8_t *buf; size_t scalar_len = BN_num_bytes(&group->order); if (!CBB_add_space(out, &buf, scalar_len)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); return 0; } ec_scalar_to_bytes(group, buf, &scalar_len, scalar); @@ -424,7 +431,6 @@ static int hash_c_dleq(const PMBTOKEN_METHOD *method, EC_SCALAR *out, !point_to_cbb(&cbb, method->group, K1) || !CBB_finish(&cbb, &buf, &len) || !method->hash_c(method->group, out, buf, len)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } @@ -462,7 +468,6 @@ static int hash_c_dleqor(const PMBTOKEN_METHOD *method, EC_SCALAR *out, !point_to_cbb(&cbb, method->group, K11) || !CBB_finish(&cbb, &buf, &len) || !method->hash_c(method->group, out, buf, len)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } @@ -494,7 +499,6 @@ static int hash_c_batch(const PMBTOKEN_METHOD *method, EC_SCALAR *out, !CBB_add_u16(&cbb, (uint16_t)index) || !CBB_finish(&cbb, &buf, &len) || !method->hash_c(method->group, out, buf, len)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } @@ -629,7 +633,6 @@ static int dleq_generate(const PMBTOKEN_METHOD *method, CBB *cbb, if (!scalar_to_cbb(cbb, group, &cs) || !scalar_to_cbb(cbb, group, &us) || !scalar_to_cbb(cbb, group, &vs)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); return 0; } @@ -665,7 +668,6 @@ static int dleq_generate(const PMBTOKEN_METHOD *method, CBB *cbb, !scalar_to_cbb(cbb, group, &u1) || !scalar_to_cbb(cbb, group, &v0) || !scalar_to_cbb(cbb, group, &v1)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); return 0; } @@ -824,7 +826,6 @@ static int pmbtoken_sign(const PMBTOKEN_METHOD *method, !point_to_cbb(&batch_cbb, method->group, &key->pubs) || !point_to_cbb(&batch_cbb, method->group, &key->pub0) || !point_to_cbb(&batch_cbb, method->group, &key->pub1)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } @@ -865,7 +866,6 @@ static int pmbtoken_sign(const PMBTOKEN_METHOD *method, !point_to_cbb(&batch_cbb, group, &affines[0]) || !point_to_cbb(&batch_cbb, group, &affines[1]) || !point_to_cbb(&batch_cbb, group, &affines[2])) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } Tps[i] = Tp; @@ -934,29 +934,24 @@ static int pmbtoken_sign(const PMBTOKEN_METHOD *method, return ret; } -static STACK_OF(TRUST_TOKEN) * - pmbtoken_unblind(const PMBTOKEN_METHOD *method, - const TRUST_TOKEN_CLIENT_KEY *key, - const STACK_OF(TRUST_TOKEN_PRETOKEN) * pretokens, CBS *cbs, - size_t count, uint32_t key_id) { +static STACK_OF(TRUST_TOKEN) *pmbtoken_unblind( + const PMBTOKEN_METHOD *method, const TRUST_TOKEN_CLIENT_KEY *key, + const STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens, CBS *cbs, size_t count, + uint32_t key_id) { const EC_GROUP *group = method->group; if (count > sk_TRUST_TOKEN_PRETOKEN_num(pretokens)) { OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE); return NULL; } - int ok = 0; - STACK_OF(TRUST_TOKEN) *ret = sk_TRUST_TOKEN_new_null(); - if (ret == NULL) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); - return NULL; - } - if (count > ((size_t)-1) / sizeof(EC_RAW_POINT) || count > ((size_t)-1) / sizeof(EC_SCALAR)) { OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW); - return 0; + return NULL; } + + int ok = 0; + STACK_OF(TRUST_TOKEN) *ret = sk_TRUST_TOKEN_new_null(); EC_RAW_POINT *Tps = OPENSSL_malloc(count * sizeof(EC_RAW_POINT)); EC_RAW_POINT *Sps = OPENSSL_malloc(count * sizeof(EC_RAW_POINT)); EC_RAW_POINT *Wps = OPENSSL_malloc(count * sizeof(EC_RAW_POINT)); @@ -964,16 +959,16 @@ static STACK_OF(TRUST_TOKEN) * EC_SCALAR *es = OPENSSL_malloc(count * sizeof(EC_SCALAR)); CBB batch_cbb; CBB_zero(&batch_cbb); - if (!Tps || - !Sps || - !Wps || - !Wsps || - !es || + if (ret == NULL || + Tps == NULL || + Sps == NULL || + Wps == NULL || + Wsps == NULL || + es == NULL || !CBB_init(&batch_cbb, 0) || !point_to_cbb(&batch_cbb, method->group, &key->pubs) || !point_to_cbb(&batch_cbb, method->group, &key->pub0) || !point_to_cbb(&batch_cbb, method->group, &key->pub1)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } @@ -1004,7 +999,6 @@ static STACK_OF(TRUST_TOKEN) * !point_to_cbb(&batch_cbb, group, &Sp_affine) || !point_to_cbb(&batch_cbb, group, &Wp_affine) || !point_to_cbb(&batch_cbb, group, &Wsp_affine)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } @@ -1025,7 +1019,7 @@ static STACK_OF(TRUST_TOKEN) * if (!CBB_init(&token_cbb, 4 + TRUST_TOKEN_NONCE_SIZE + 3 * (2 + point_len)) || !CBB_add_u32(&token_cbb, key_id) || - !CBB_add_bytes(&token_cbb, pretoken->t, TRUST_TOKEN_NONCE_SIZE) || + !CBB_add_bytes(&token_cbb, pretoken->salt, TRUST_TOKEN_NONCE_SIZE) || !cbb_add_prefixed_point(&token_cbb, group, &affines[0], method->prefix_point) || !cbb_add_prefixed_point(&token_cbb, group, &affines[1], @@ -1042,7 +1036,6 @@ static STACK_OF(TRUST_TOKEN) * CBB_cleanup(&token_cbb); if (token == NULL || !sk_TRUST_TOKEN_push(ret, token)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); TRUST_TOKEN_free(token); goto err; } @@ -1097,12 +1090,13 @@ static int pmbtoken_read(const PMBTOKEN_METHOD *method, const TRUST_TOKEN_ISSUER_KEY *key, uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE], uint8_t *out_private_metadata, const uint8_t *token, - size_t token_len) { + size_t token_len, int include_message, + const uint8_t *msg, size_t msg_len) { const EC_GROUP *group = method->group; - CBS cbs; + CBS cbs, salt; CBS_init(&cbs, token, token_len); EC_AFFINE S, W, Ws; - if (!CBS_copy_bytes(&cbs, out_nonce, TRUST_TOKEN_NONCE_SIZE) || + if (!CBS_get_bytes(&cbs, &salt, TRUST_TOKEN_NONCE_SIZE) || !cbs_get_prefixed_point(&cbs, group, &S, method->prefix_point) || !cbs_get_prefixed_point(&cbs, group, &W, method->prefix_point) || !cbs_get_prefixed_point(&cbs, group, &Ws, method->prefix_point) || @@ -1111,6 +1105,16 @@ static int pmbtoken_read(const PMBTOKEN_METHOD *method, return 0; } + if (include_message) { + SHA512_CTX hash_ctx; + assert(SHA512_DIGEST_LENGTH == TRUST_TOKEN_NONCE_SIZE); + SHA512_Init(&hash_ctx); + SHA512_Update(&hash_ctx, CBS_data(&salt), CBS_len(&salt)); + SHA512_Update(&hash_ctx, msg, msg_len); + SHA512_Final(out_nonce, &hash_ctx); + } else { + OPENSSL_memcpy(out_nonce, CBS_data(&salt), CBS_len(&salt)); + } EC_RAW_POINT T; if (!method->hash_t(group, &T, out_nonce)) { @@ -1181,7 +1185,6 @@ static int pmbtoken_exp1_hash_s(const EC_GROUP *group, EC_RAW_POINT *out, !CBB_finish(&cbb, &buf, &len) || !ec_hash_to_curve_p384_xmd_sha512_sswu_draft07( group, out, kHashSLabel, sizeof(kHashSLabel), buf, len)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } @@ -1276,11 +1279,15 @@ int pmbtoken_exp1_issuer_key_from_bytes(TRUST_TOKEN_ISSUER_KEY *key, return pmbtoken_issuer_key_from_bytes(&pmbtoken_exp1_method, key, in, len); } -STACK_OF(TRUST_TOKEN_PRETOKEN) * pmbtoken_exp1_blind(CBB *cbb, size_t count) { +STACK_OF(TRUST_TOKEN_PRETOKEN) *pmbtoken_exp1_blind(CBB *cbb, size_t count, + int include_message, + const uint8_t *msg, + size_t msg_len) { if (!pmbtoken_exp1_init_method()) { return NULL; } - return pmbtoken_blind(&pmbtoken_exp1_method, cbb, count); + return pmbtoken_blind(&pmbtoken_exp1_method, cbb, count, include_message, msg, + msg_len); } int pmbtoken_exp1_sign(const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, @@ -1293,10 +1300,10 @@ int pmbtoken_exp1_sign(const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, num_to_issue, private_metadata); } -STACK_OF(TRUST_TOKEN) * - pmbtoken_exp1_unblind(const TRUST_TOKEN_CLIENT_KEY *key, - const STACK_OF(TRUST_TOKEN_PRETOKEN) * pretokens, - CBS *cbs, size_t count, uint32_t key_id) { +STACK_OF(TRUST_TOKEN) *pmbtoken_exp1_unblind( + const TRUST_TOKEN_CLIENT_KEY *key, + const STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens, CBS *cbs, size_t count, + uint32_t key_id) { if (!pmbtoken_exp1_init_method()) { return NULL; } @@ -1307,12 +1314,14 @@ STACK_OF(TRUST_TOKEN) * int pmbtoken_exp1_read(const TRUST_TOKEN_ISSUER_KEY *key, uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE], uint8_t *out_private_metadata, const uint8_t *token, - size_t token_len) { + size_t token_len, int include_message, + const uint8_t *msg, size_t msg_len) { if (!pmbtoken_exp1_init_method()) { return 0; } return pmbtoken_read(&pmbtoken_exp1_method, key, out_nonce, - out_private_metadata, token, token_len); + out_private_metadata, token, token_len, include_message, + msg, msg_len); } int pmbtoken_exp1_get_h_for_testing(uint8_t out[97]) { @@ -1349,7 +1358,6 @@ static int pmbtoken_exp2_hash_s(const EC_GROUP *group, EC_RAW_POINT *out, !CBB_finish(&cbb, &buf, &len) || !ec_hash_to_curve_p384_xmd_sha512_sswu_draft07( group, out, kHashSLabel, sizeof(kHashSLabel), buf, len)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } @@ -1445,11 +1453,15 @@ int pmbtoken_exp2_issuer_key_from_bytes(TRUST_TOKEN_ISSUER_KEY *key, return pmbtoken_issuer_key_from_bytes(&pmbtoken_exp2_method, key, in, len); } -STACK_OF(TRUST_TOKEN_PRETOKEN) * pmbtoken_exp2_blind(CBB *cbb, size_t count) { +STACK_OF(TRUST_TOKEN_PRETOKEN) *pmbtoken_exp2_blind(CBB *cbb, size_t count, + int include_message, + const uint8_t *msg, + size_t msg_len) { if (!pmbtoken_exp2_init_method()) { return NULL; } - return pmbtoken_blind(&pmbtoken_exp2_method, cbb, count); + return pmbtoken_blind(&pmbtoken_exp2_method, cbb, count, include_message, msg, + msg_len); } int pmbtoken_exp2_sign(const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, @@ -1462,10 +1474,10 @@ int pmbtoken_exp2_sign(const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, num_to_issue, private_metadata); } -STACK_OF(TRUST_TOKEN) * - pmbtoken_exp2_unblind(const TRUST_TOKEN_CLIENT_KEY *key, - const STACK_OF(TRUST_TOKEN_PRETOKEN) * pretokens, - CBS *cbs, size_t count, uint32_t key_id) { +STACK_OF(TRUST_TOKEN) *pmbtoken_exp2_unblind( + const TRUST_TOKEN_CLIENT_KEY *key, + const STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens, CBS *cbs, size_t count, + uint32_t key_id) { if (!pmbtoken_exp2_init_method()) { return NULL; } @@ -1476,12 +1488,14 @@ STACK_OF(TRUST_TOKEN) * int pmbtoken_exp2_read(const TRUST_TOKEN_ISSUER_KEY *key, uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE], uint8_t *out_private_metadata, const uint8_t *token, - size_t token_len) { + size_t token_len, int include_message, + const uint8_t *msg, size_t msg_len) { if (!pmbtoken_exp2_init_method()) { return 0; } return pmbtoken_read(&pmbtoken_exp2_method, key, out_nonce, - out_private_metadata, token, token_len); + out_private_metadata, token, token_len, include_message, + msg, msg_len); } int pmbtoken_exp2_get_h_for_testing(uint8_t out[97]) { @@ -1494,3 +1508,177 @@ int pmbtoken_exp2_get_h_for_testing(uint8_t out[97]) { ec_point_to_bytes(pmbtoken_exp2_method.group, &h, POINT_CONVERSION_UNCOMPRESSED, out, 97) == 97; } + +// PMBTokens PST v1. + +static int pmbtoken_pst1_hash_t(const EC_GROUP *group, EC_RAW_POINT *out, + const uint8_t t[TRUST_TOKEN_NONCE_SIZE]) { + const uint8_t kHashTLabel[] = "PMBTokens PST V1 HashT"; + return ec_hash_to_curve_p384_xmd_sha384_sswu( + group, out, kHashTLabel, sizeof(kHashTLabel), t, TRUST_TOKEN_NONCE_SIZE); +} + +static int pmbtoken_pst1_hash_s(const EC_GROUP *group, EC_RAW_POINT *out, + const EC_AFFINE *t, + const uint8_t s[TRUST_TOKEN_NONCE_SIZE]) { + const uint8_t kHashSLabel[] = "PMBTokens PST V1 HashS"; + int ret = 0; + CBB cbb; + uint8_t *buf = NULL; + size_t len; + if (!CBB_init(&cbb, 0) || + !point_to_cbb(&cbb, group, t) || + !CBB_add_bytes(&cbb, s, TRUST_TOKEN_NONCE_SIZE) || + !CBB_finish(&cbb, &buf, &len) || + !ec_hash_to_curve_p384_xmd_sha384_sswu( + group, out, kHashSLabel, sizeof(kHashSLabel), buf, len)) { + goto err; + } + + ret = 1; + +err: + OPENSSL_free(buf); + CBB_cleanup(&cbb); + return ret; +} + +static int pmbtoken_pst1_hash_c(const EC_GROUP *group, EC_SCALAR *out, + uint8_t *buf, size_t len) { + const uint8_t kHashCLabel[] = "PMBTokens PST V1 HashC"; + return ec_hash_to_scalar_p384_xmd_sha384( + group, out, kHashCLabel, sizeof(kHashCLabel), buf, len); +} + +static int pmbtoken_pst1_hash_to_scalar(const EC_GROUP *group, EC_SCALAR *out, + uint8_t *buf, size_t len) { + const uint8_t kHashLabel[] = "PMBTokens PST V1 HashToScalar"; + return ec_hash_to_scalar_p384_xmd_sha384( + group, out, kHashLabel, sizeof(kHashLabel), buf, len); +} + +static int pmbtoken_pst1_ok = 0; +static PMBTOKEN_METHOD pmbtoken_pst1_method; +static CRYPTO_once_t pmbtoken_pst1_method_once = CRYPTO_ONCE_INIT; + +static void pmbtoken_pst1_init_method_impl(void) { + // This is the output of |ec_hash_to_scalar_p384_xmd_sha384| with DST + // "PMBTokens PST V1 HashH" and message "generator". + static const uint8_t kH[] = { + 0x04, 0x4c, 0xfa, 0xd4, 0x33, 0x6d, 0x8c, 0x4e, 0x18, 0xce, 0x1a, + 0x82, 0x7b, 0x53, 0x8c, 0xf8, 0x63, 0x18, 0xe5, 0xa3, 0x96, 0x0d, + 0x05, 0xde, 0xf4, 0x83, 0xa7, 0xd8, 0xde, 0x9c, 0x50, 0x81, 0x38, + 0xc9, 0x38, 0x25, 0xa3, 0x70, 0x97, 0xc1, 0x1c, 0x33, 0x2e, 0x83, + 0x68, 0x64, 0x9c, 0x53, 0x73, 0xc3, 0x03, 0xc1, 0xa9, 0xd8, 0x92, + 0xa2, 0x32, 0xf4, 0x22, 0x40, 0x07, 0x2d, 0x9b, 0x6f, 0xab, 0xff, + 0x2a, 0x92, 0x03, 0xb1, 0x73, 0x09, 0x1a, 0x6a, 0x4a, 0xc2, 0x4c, + 0xac, 0x13, 0x59, 0xf4, 0x28, 0x0e, 0x78, 0x69, 0xa5, 0xdf, 0x0d, + 0x74, 0xeb, 0x14, 0xca, 0x8a, 0x32, 0xbb, 0xd3, 0x91 + }; + + pmbtoken_pst1_ok = pmbtoken_init_method( + &pmbtoken_pst1_method, NID_secp384r1, kH, sizeof(kH), + pmbtoken_pst1_hash_t, pmbtoken_pst1_hash_s, pmbtoken_pst1_hash_c, + pmbtoken_pst1_hash_to_scalar, 0); +} + +static int pmbtoken_pst1_init_method(void) { + CRYPTO_once(&pmbtoken_pst1_method_once, pmbtoken_pst1_init_method_impl); + if (!pmbtoken_pst1_ok) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_INTERNAL_ERROR); + return 0; + } + return 1; +} + +int pmbtoken_pst1_generate_key(CBB *out_private, CBB *out_public) { + if (!pmbtoken_pst1_init_method()) { + return 0; + } + + return pmbtoken_generate_key(&pmbtoken_pst1_method, out_private, out_public); +} + + +int pmbtoken_pst1_derive_key_from_secret(CBB *out_private, CBB *out_public, + const uint8_t *secret, + size_t secret_len) { + if (!pmbtoken_pst1_init_method()) { + return 0; + } + + return pmbtoken_derive_key_from_secret(&pmbtoken_pst1_method, out_private, + out_public, secret, secret_len); +} + +int pmbtoken_pst1_client_key_from_bytes(TRUST_TOKEN_CLIENT_KEY *key, + const uint8_t *in, size_t len) { + if (!pmbtoken_pst1_init_method()) { + return 0; + } + return pmbtoken_client_key_from_bytes(&pmbtoken_pst1_method, key, in, len); +} + +int pmbtoken_pst1_issuer_key_from_bytes(TRUST_TOKEN_ISSUER_KEY *key, + const uint8_t *in, size_t len) { + if (!pmbtoken_pst1_init_method()) { + return 0; + } + return pmbtoken_issuer_key_from_bytes(&pmbtoken_pst1_method, key, in, len); +} + +STACK_OF(TRUST_TOKEN_PRETOKEN) *pmbtoken_pst1_blind(CBB *cbb, size_t count, + int include_message, + const uint8_t *msg, + size_t msg_len) { + if (!pmbtoken_pst1_init_method()) { + return NULL; + } + return pmbtoken_blind(&pmbtoken_pst1_method, cbb, count, include_message, msg, + msg_len); +} + +int pmbtoken_pst1_sign(const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, + size_t num_requested, size_t num_to_issue, + uint8_t private_metadata) { + if (!pmbtoken_pst1_init_method()) { + return 0; + } + return pmbtoken_sign(&pmbtoken_pst1_method, key, cbb, cbs, num_requested, + num_to_issue, private_metadata); +} + +STACK_OF(TRUST_TOKEN) *pmbtoken_pst1_unblind( + const TRUST_TOKEN_CLIENT_KEY *key, + const STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens, CBS *cbs, size_t count, + uint32_t key_id) { + if (!pmbtoken_pst1_init_method()) { + return NULL; + } + return pmbtoken_unblind(&pmbtoken_pst1_method, key, pretokens, cbs, count, + key_id); +} + +int pmbtoken_pst1_read(const TRUST_TOKEN_ISSUER_KEY *key, + uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE], + uint8_t *out_private_metadata, const uint8_t *token, + size_t token_len, int include_message, + const uint8_t *msg, size_t msg_len) { + if (!pmbtoken_pst1_init_method()) { + return 0; + } + return pmbtoken_read(&pmbtoken_pst1_method, key, out_nonce, + out_private_metadata, token, token_len, include_message, + msg, msg_len); +} + +int pmbtoken_pst1_get_h_for_testing(uint8_t out[97]) { + if (!pmbtoken_pst1_init_method()) { + return 0; + } + EC_AFFINE h; + return ec_jacobian_to_affine(pmbtoken_pst1_method.group, &h, + &pmbtoken_pst1_method.h) && + ec_point_to_bytes(pmbtoken_pst1_method.group, &h, + POINT_CONVERSION_UNCOMPRESSED, out, 97) == 97; +} diff --git a/Sources/CNIOBoringSSL/crypto/trust_token/trust_token.c b/Sources/CNIOBoringSSL/crypto/trust_token/trust_token.c index 2b4024b7..7d1a139f 100644 --- a/Sources/CNIOBoringSSL/crypto/trust_token/trust_token.c +++ b/Sources/CNIOBoringSSL/crypto/trust_token/trust_token.c @@ -78,6 +78,41 @@ const TRUST_TOKEN_METHOD *TRUST_TOKEN_experiment_v2_pmb(void) { return &kMethod; } +const TRUST_TOKEN_METHOD *TRUST_TOKEN_pst_v1_voprf(void) { + static const TRUST_TOKEN_METHOD kMethod = { + voprf_pst1_generate_key, + voprf_pst1_derive_key_from_secret, + voprf_pst1_client_key_from_bytes, + voprf_pst1_issuer_key_from_bytes, + voprf_pst1_blind, + voprf_pst1_sign, + voprf_pst1_unblind, + voprf_pst1_read, + 0, /* has_private_metadata */ + 6, /* max_keys */ + 0, /* has_srr */ + }; + return &kMethod; +} + +const TRUST_TOKEN_METHOD *TRUST_TOKEN_pst_v1_pmb(void) { + static const TRUST_TOKEN_METHOD kMethod = { + pmbtoken_pst1_generate_key, + pmbtoken_pst1_derive_key_from_secret, + pmbtoken_pst1_client_key_from_bytes, + pmbtoken_pst1_issuer_key_from_bytes, + pmbtoken_pst1_blind, + pmbtoken_pst1_sign, + pmbtoken_pst1_unblind, + pmbtoken_pst1_read, + 1, /* has_private_metadata */ + 3, /* max_keys */ + 0, /* has_srr */ + }; + return &kMethod; +} + + void TRUST_TOKEN_PRETOKEN_free(TRUST_TOKEN_PRETOKEN *pretoken) { OPENSSL_free(pretoken); } @@ -85,13 +120,11 @@ void TRUST_TOKEN_PRETOKEN_free(TRUST_TOKEN_PRETOKEN *pretoken) { TRUST_TOKEN *TRUST_TOKEN_new(const uint8_t *data, size_t len) { TRUST_TOKEN *ret = OPENSSL_malloc(sizeof(TRUST_TOKEN)); if (ret == NULL) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); return NULL; } OPENSSL_memset(ret, 0, sizeof(TRUST_TOKEN)); ret->data = OPENSSL_memdup(data, len); if (len != 0 && ret->data == NULL) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); OPENSSL_free(ret); return NULL; } @@ -174,7 +207,6 @@ TRUST_TOKEN_CLIENT *TRUST_TOKEN_CLIENT_new(const TRUST_TOKEN_METHOD *method, TRUST_TOKEN_CLIENT *ret = OPENSSL_malloc(sizeof(TRUST_TOKEN_CLIENT)); if (ret == NULL) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); return NULL; } OPENSSL_memset(ret, 0, sizeof(TRUST_TOKEN_CLIENT)); @@ -226,8 +258,9 @@ int TRUST_TOKEN_CLIENT_set_srr_key(TRUST_TOKEN_CLIENT *ctx, EVP_PKEY *key) { return 1; } -int TRUST_TOKEN_CLIENT_begin_issuance(TRUST_TOKEN_CLIENT *ctx, uint8_t **out, - size_t *out_len, size_t count) { +static int trust_token_client_begin_issuance_impl( + TRUST_TOKEN_CLIENT *ctx, uint8_t **out, size_t *out_len, size_t count, + int include_message, const uint8_t *msg, size_t msg_len) { if (count > ctx->max_batchsize) { count = ctx->max_batchsize; } @@ -237,17 +270,16 @@ int TRUST_TOKEN_CLIENT_begin_issuance(TRUST_TOKEN_CLIENT *ctx, uint8_t **out, STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens = NULL; if (!CBB_init(&request, 0) || !CBB_add_u16(&request, count)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } - pretokens = ctx->method->blind(&request, count); + pretokens = + ctx->method->blind(&request, count, include_message, msg, msg_len); if (pretokens == NULL) { goto err; } if (!CBB_finish(&request, out, out_len)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } @@ -262,6 +294,20 @@ int TRUST_TOKEN_CLIENT_begin_issuance(TRUST_TOKEN_CLIENT *ctx, uint8_t **out, return ret; } +int TRUST_TOKEN_CLIENT_begin_issuance(TRUST_TOKEN_CLIENT *ctx, uint8_t **out, + size_t *out_len, size_t count) { + return trust_token_client_begin_issuance_impl(ctx, out, out_len, count, + /*include_message=*/0, NULL, 0); +} + +int TRUST_TOKEN_CLIENT_begin_issuance_over_message( + TRUST_TOKEN_CLIENT *ctx, uint8_t **out, size_t *out_len, size_t count, + const uint8_t *msg, size_t msg_len) { + return trust_token_client_begin_issuance_impl( + ctx, out, out_len, count, /*include_message=*/1, msg, msg_len); +} + + STACK_OF(TRUST_TOKEN) * TRUST_TOKEN_CLIENT_finish_issuance(TRUST_TOKEN_CLIENT *ctx, size_t *out_key_index, @@ -329,7 +375,6 @@ int TRUST_TOKEN_CLIENT_begin_redemption(TRUST_TOKEN_CLIENT *ctx, uint8_t **out, !CBB_add_bytes(&inner, data, data_len) || (ctx->method->has_srr && !CBB_add_u64(&request, time)) || !CBB_finish(&request, out, out_len)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); CBB_cleanup(&request); return 0; } @@ -345,7 +390,6 @@ int TRUST_TOKEN_CLIENT_finish_redemption(TRUST_TOKEN_CLIENT *ctx, CBS_init(&in, response, response_len); if (!ctx->method->has_srr) { if (!CBS_stow(&in, out_rr, out_rr_len)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); return 0; } @@ -382,7 +426,6 @@ int TRUST_TOKEN_CLIENT_finish_redemption(TRUST_TOKEN_CLIENT *ctx, size_t srr_len, sig_len; if (!CBS_stow(&srr, &srr_buf, &srr_len) || !CBS_stow(&sig, &sig_buf, &sig_len)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); OPENSSL_free(srr_buf); OPENSSL_free(sig_buf); return 0; @@ -405,7 +448,6 @@ TRUST_TOKEN_ISSUER *TRUST_TOKEN_ISSUER_new(const TRUST_TOKEN_METHOD *method, TRUST_TOKEN_ISSUER *ret = OPENSSL_malloc(sizeof(TRUST_TOKEN_ISSUER)); if (ret == NULL) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); return NULL; } OPENSSL_memset(ret, 0, sizeof(TRUST_TOKEN_ISSUER)); @@ -463,7 +505,6 @@ int TRUST_TOKEN_ISSUER_set_metadata_key(TRUST_TOKEN_ISSUER *ctx, ctx->metadata_key_len = 0; ctx->metadata_key = OPENSSL_memdup(key, len); if (ctx->metadata_key == NULL) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); return 0; } ctx->metadata_key_len = len; @@ -515,7 +556,6 @@ int TRUST_TOKEN_ISSUER_issue(const TRUST_TOKEN_ISSUER *ctx, uint8_t **out, if (!CBB_init(&response, 0) || !CBB_add_u16(&response, num_to_issue) || !CBB_add_u32(&response, public_metadata)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } @@ -530,7 +570,6 @@ int TRUST_TOKEN_ISSUER_issue(const TRUST_TOKEN_ISSUER *ctx, uint8_t **out, } if (!CBB_finish(&response, out, out_len)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } @@ -542,13 +581,11 @@ int TRUST_TOKEN_ISSUER_issue(const TRUST_TOKEN_ISSUER *ctx, uint8_t **out, return ret; } - -int TRUST_TOKEN_ISSUER_redeem_raw(const TRUST_TOKEN_ISSUER *ctx, - uint32_t *out_public, uint8_t *out_private, - TRUST_TOKEN **out_token, - uint8_t **out_client_data, - size_t *out_client_data_len, - const uint8_t *request, size_t request_len) { +static int trust_token_issuer_redeem_impl( + const TRUST_TOKEN_ISSUER *ctx, uint32_t *out_public, uint8_t *out_private, + TRUST_TOKEN **out_token, uint8_t **out_client_data, + size_t *out_client_data_len, const uint8_t *request, size_t request_len, + int include_message, const uint8_t *msg, size_t msg_len) { CBS request_cbs, token_cbs; CBS_init(&request_cbs, request, request_len); if (!CBS_get_u16_length_prefixed(&request_cbs, &token_cbs)) { @@ -570,7 +607,8 @@ int TRUST_TOKEN_ISSUER_redeem_raw(const TRUST_TOKEN_ISSUER *ctx, uint8_t nonce[TRUST_TOKEN_NONCE_SIZE]; if (key == NULL || !ctx->method->read(&key->key, nonce, &private_metadata, - CBS_data(&token_cbs), CBS_len(&token_cbs))) { + CBS_data(&token_cbs), CBS_len(&token_cbs), + include_message, msg, msg_len)) { OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_TOKEN); return 0; } @@ -586,13 +624,11 @@ int TRUST_TOKEN_ISSUER_redeem_raw(const TRUST_TOKEN_ISSUER *ctx, uint8_t *client_data_buf = NULL; size_t client_data_len = 0; if (!CBS_stow(&client_data, &client_data_buf, &client_data_len)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } TRUST_TOKEN *token = TRUST_TOKEN_new(nonce, TRUST_TOKEN_NONCE_SIZE); if (token == NULL) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } *out_public = public_metadata; @@ -608,48 +644,26 @@ int TRUST_TOKEN_ISSUER_redeem_raw(const TRUST_TOKEN_ISSUER *ctx, return 0; } -// https://tools.ietf.org/html/rfc7049#section-2.1 -static int add_cbor_int_with_type(CBB *cbb, uint8_t major_type, - uint64_t value) { - if (value <= 23) { - return CBB_add_u8(cbb, value | major_type); - } - if (value <= 0xff) { - return CBB_add_u8(cbb, 0x18 | major_type) && CBB_add_u8(cbb, value); - } - if (value <= 0xffff) { - return CBB_add_u8(cbb, 0x19 | major_type) && CBB_add_u16(cbb, value); - } - if (value <= 0xffffffff) { - return CBB_add_u8(cbb, 0x1a | major_type) && CBB_add_u32(cbb, value); - } - if (value <= 0xffffffffffffffff) { - return CBB_add_u8(cbb, 0x1b | major_type) && CBB_add_u64(cbb, value); - } - - return 0; -} - -// https://tools.ietf.org/html/rfc7049#section-2.1 -static int add_cbor_int(CBB *cbb, uint64_t value) { - return add_cbor_int_with_type(cbb, 0, value); -} -// https://tools.ietf.org/html/rfc7049#section-2.1 -static int add_cbor_bytes(CBB *cbb, const uint8_t *data, size_t len) { - return add_cbor_int_with_type(cbb, 0x40, len) && - CBB_add_bytes(cbb, data, len); -} - -// https://tools.ietf.org/html/rfc7049#section-2.1 -static int add_cbor_text(CBB *cbb, const char *data, size_t len) { - return add_cbor_int_with_type(cbb, 0x60, len) && - CBB_add_bytes(cbb, (const uint8_t *)data, len); +int TRUST_TOKEN_ISSUER_redeem(const TRUST_TOKEN_ISSUER *ctx, + uint32_t *out_public, uint8_t *out_private, + TRUST_TOKEN **out_token, + uint8_t **out_client_data, + size_t *out_client_data_len, + const uint8_t *request, size_t request_len) { + return trust_token_issuer_redeem_impl(ctx, out_public, out_private, out_token, + out_client_data, out_client_data_len, + request, request_len, 0, NULL, 0); } -// https://tools.ietf.org/html/rfc7049#section-2.1 -static int add_cbor_map(CBB *cbb, uint8_t size) { - return add_cbor_int_with_type(cbb, 0xa0, size); +int TRUST_TOKEN_ISSUER_redeem_over_message( + const TRUST_TOKEN_ISSUER *ctx, uint32_t *out_public, uint8_t *out_private, + TRUST_TOKEN **out_token, uint8_t **out_client_data, + size_t *out_client_data_len, const uint8_t *request, size_t request_len, + const uint8_t *msg, size_t msg_len) { + return trust_token_issuer_redeem_impl(ctx, out_public, out_private, out_token, + out_client_data, out_client_data_len, + request, request_len, 1, msg, msg_len); } static uint8_t get_metadata_obfuscator(const uint8_t *key, size_t key_len, @@ -664,212 +678,6 @@ static uint8_t get_metadata_obfuscator(const uint8_t *key, size_t key_len, return metadata_obfuscator[0] >> 7; } -int TRUST_TOKEN_ISSUER_redeem(const TRUST_TOKEN_ISSUER *ctx, uint8_t **out, - size_t *out_len, TRUST_TOKEN **out_token, - uint8_t **out_client_data, - size_t *out_client_data_len, - uint64_t *out_redemption_time, - const uint8_t *request, size_t request_len, - uint64_t lifetime) { - CBS request_cbs, token_cbs; - CBS_init(&request_cbs, request, request_len); - if (!CBS_get_u16_length_prefixed(&request_cbs, &token_cbs)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_ERROR); - return 0; - } - - uint32_t public_metadata = 0; - uint8_t private_metadata = 0; - - CBS token_copy = token_cbs; - - // Parse the token. If there is an error, treat it as an invalid token. - if (!CBS_get_u32(&token_cbs, &public_metadata)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_TOKEN); - return 0; - } - - const struct trust_token_issuer_key_st *key = - trust_token_issuer_get_key(ctx, public_metadata); - uint8_t nonce[TRUST_TOKEN_NONCE_SIZE]; - if (key == NULL || - !ctx->method->read(&key->key, nonce, &private_metadata, - CBS_data(&token_cbs), CBS_len(&token_cbs))) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_TOKEN); - return 0; - } - - int ok = 0; - CBB response, srr; - uint8_t *srr_buf = NULL, *sig_buf = NULL, *client_data_buf = NULL; - size_t srr_len = 0, sig_len = 0, client_data_len = 0; - EVP_MD_CTX md_ctx; - EVP_MD_CTX_init(&md_ctx); - CBB_zero(&srr); - if (!CBB_init(&response, 0)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); - goto err; - } - - CBS client_data; - uint64_t redemption_time = 0; - if (!CBS_get_u16_length_prefixed(&request_cbs, &client_data) || - (ctx->method->has_srr && !CBS_get_u64(&request_cbs, &redemption_time))) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_ERROR); - goto err; - } - - const uint8_t kTokenHashDSTLabel[] = "TrustTokenV0 TokenHash"; - uint8_t token_hash[SHA256_DIGEST_LENGTH]; - SHA256_CTX sha_ctx; - SHA256_Init(&sha_ctx); - SHA256_Update(&sha_ctx, kTokenHashDSTLabel, sizeof(kTokenHashDSTLabel)); - SHA256_Update(&sha_ctx, CBS_data(&token_copy), CBS_len(&token_copy)); - SHA256_Final(token_hash, &sha_ctx); - - uint8_t metadata_obfuscator = get_metadata_obfuscator( - ctx->metadata_key, ctx->metadata_key_len, token_hash, sizeof(token_hash)); - - // The SRR is constructed as per the format described in - // https://docs.google.com/document/d/1TNnya6B8pyomDK2F1R9CL3dY10OAmqWlnCxsWyOBDVQ/edit#heading=h.7mkzvhpqb8l5 - - // The V2 protocol is intended to be used with - // |TRUST_TOKEN_ISSUER_redeem_raw|. However, we temporarily support it with - // |TRUST_TOKEN_ISSUER_redeem| to ease the transition for existing issuer - // callers. Those callers' consumers currently expect an expiry-timestamp - // field, so we fill in a placeholder value. - // - // TODO(svaldez): After the existing issues have migrated to - // |TRUST_TOKEN_ISSUER_redeem_raw| remove this logic. - uint64_t expiry_time = 0; - if (ctx->method->has_srr) { - expiry_time = redemption_time + lifetime; - } - - static const char kClientDataLabel[] = "client-data"; - static const char kExpiryTimestampLabel[] = "expiry-timestamp"; - static const char kMetadataLabel[] = "metadata"; - static const char kPrivateLabel[] = "private"; - static const char kPublicLabel[] = "public"; - static const char kTokenHashLabel[] = "token-hash"; - - // CBOR requires map keys to be sorted by length then sorted lexically. - // https://tools.ietf.org/html/rfc7049#section-3.9 - assert(strlen(kMetadataLabel) < strlen(kTokenHashLabel)); - assert(strlen(kTokenHashLabel) < strlen(kClientDataLabel)); - assert(strlen(kClientDataLabel) < strlen(kExpiryTimestampLabel)); - assert(strlen(kPublicLabel) < strlen(kPrivateLabel)); - - size_t map_entries = 4; - - if (!CBB_init(&srr, 0) || - !add_cbor_map(&srr, map_entries) || // SRR map - !add_cbor_text(&srr, kMetadataLabel, strlen(kMetadataLabel)) || - !add_cbor_map(&srr, 2) || // Metadata map - !add_cbor_text(&srr, kPublicLabel, strlen(kPublicLabel)) || - !add_cbor_int(&srr, public_metadata) || - !add_cbor_text(&srr, kPrivateLabel, strlen(kPrivateLabel)) || - !add_cbor_int(&srr, private_metadata ^ metadata_obfuscator) || - !add_cbor_text(&srr, kTokenHashLabel, strlen(kTokenHashLabel)) || - !add_cbor_bytes(&srr, token_hash, sizeof(token_hash)) || - !add_cbor_text(&srr, kClientDataLabel, strlen(kClientDataLabel)) || - !CBB_add_bytes(&srr, CBS_data(&client_data), CBS_len(&client_data)) || - !add_cbor_text(&srr, kExpiryTimestampLabel, - strlen(kExpiryTimestampLabel)) || - !add_cbor_int(&srr, expiry_time) || - !CBB_finish(&srr, &srr_buf, &srr_len)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (!EVP_DigestSignInit(&md_ctx, NULL, NULL, NULL, ctx->srr_key) || - !EVP_DigestSign(&md_ctx, NULL, &sig_len, srr_buf, srr_len)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_SRR_SIGNATURE_ERROR); - goto err; - } - - // Merge SRR and Signature into single string. - // TODO(svaldez): Expose API to construct this from the caller. - if (!ctx->method->has_srr) { - static const char kSRRHeader[] = "body=:"; - static const char kSRRSplit[] = ":, signature=:"; - static const char kSRREnd[] = ":"; - - size_t srr_b64_len, sig_b64_len; - if (!EVP_EncodedLength(&srr_b64_len, srr_len) || - !EVP_EncodedLength(&sig_b64_len, sig_len)) { - goto err; - } - - sig_buf = OPENSSL_malloc(sig_len); - uint8_t *srr_b64_buf = OPENSSL_malloc(srr_b64_len); - uint8_t *sig_b64_buf = OPENSSL_malloc(sig_b64_len); - if (!sig_buf || - !srr_b64_buf || - !sig_b64_buf || - !EVP_DigestSign(&md_ctx, sig_buf, &sig_len, srr_buf, srr_len) || - !CBB_add_bytes(&response, (const uint8_t *)kSRRHeader, - strlen(kSRRHeader)) || - !CBB_add_bytes(&response, srr_b64_buf, - EVP_EncodeBlock(srr_b64_buf, srr_buf, srr_len)) || - !CBB_add_bytes(&response, (const uint8_t *)kSRRSplit, - strlen(kSRRSplit)) || - !CBB_add_bytes(&response, sig_b64_buf, - EVP_EncodeBlock(sig_b64_buf, sig_buf, sig_len)) || - !CBB_add_bytes(&response, (const uint8_t *)kSRREnd, strlen(kSRREnd))) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); - OPENSSL_free(srr_b64_buf); - OPENSSL_free(sig_b64_buf); - goto err; - } - - OPENSSL_free(srr_b64_buf); - OPENSSL_free(sig_b64_buf); - } else { - CBB child; - uint8_t *ptr; - if (!CBB_add_u16_length_prefixed(&response, &child) || - !CBB_add_bytes(&child, srr_buf, srr_len) || - !CBB_add_u16_length_prefixed(&response, &child) || - !CBB_reserve(&child, &ptr, sig_len) || - !EVP_DigestSign(&md_ctx, ptr, &sig_len, srr_buf, srr_len) || - !CBB_did_write(&child, sig_len) || - !CBB_flush(&response)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); - goto err; - } - } - - if (!CBS_stow(&client_data, &client_data_buf, &client_data_len) || - !CBB_finish(&response, out, out_len)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); - goto err; - } - - TRUST_TOKEN *token = TRUST_TOKEN_new(nonce, TRUST_TOKEN_NONCE_SIZE); - if (token == NULL) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); - goto err; - } - *out_token = token; - *out_client_data = client_data_buf; - *out_client_data_len = client_data_len; - *out_redemption_time = redemption_time; - - ok = 1; - -err: - CBB_cleanup(&response); - CBB_cleanup(&srr); - OPENSSL_free(srr_buf); - OPENSSL_free(sig_buf); - EVP_MD_CTX_cleanup(&md_ctx); - if (!ok) { - OPENSSL_free(client_data_buf); - } - return ok; -} - int TRUST_TOKEN_decode_private_metadata(const TRUST_TOKEN_METHOD *method, uint8_t *out_value, const uint8_t *key, size_t key_len, const uint8_t *nonce, diff --git a/Sources/CNIOBoringSSL/crypto/trust_token/voprf.c b/Sources/CNIOBoringSSL/crypto/trust_token/voprf.c index a6af9b75..23449387 100644 --- a/Sources/CNIOBoringSSL/crypto/trust_token/voprf.c +++ b/Sources/CNIOBoringSSL/crypto/trust_token/voprf.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "../ec_extra/internal.h" #include "../fipsmodule/ec/internal.h" @@ -62,8 +63,7 @@ static int voprf_init_method(VOPRF_METHOD *method, int curve_nid, static int cbb_add_point(CBB *out, const EC_GROUP *group, const EC_AFFINE *point) { - size_t len = - ec_point_to_bytes(group, point, POINT_CONVERSION_UNCOMPRESSED, NULL, 0); + size_t len = ec_point_byte_len(group, POINT_CONVERSION_UNCOMPRESSED); if (len == 0) { return 0; } @@ -91,7 +91,6 @@ static int scalar_to_cbb(CBB *out, const EC_GROUP *group, uint8_t *buf; size_t scalar_len = BN_num_bytes(&group->order); if (!CBB_add_space(out, &buf, scalar_len)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); return 0; } ec_scalar_to_bytes(group, buf, &scalar_len, scalar); @@ -201,13 +200,17 @@ static int voprf_issuer_key_from_bytes(const VOPRF_METHOD *method, return 1; } -static STACK_OF(TRUST_TOKEN_PRETOKEN) * - voprf_blind(const VOPRF_METHOD *method, CBB *cbb, size_t count) { +static STACK_OF(TRUST_TOKEN_PRETOKEN) *voprf_blind(const VOPRF_METHOD *method, + CBB *cbb, size_t count, + int include_message, + const uint8_t *msg, + size_t msg_len) { + SHA512_CTX hash_ctx; + const EC_GROUP *group = method->group; STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens = sk_TRUST_TOKEN_PRETOKEN_new_null(); if (pretokens == NULL) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } @@ -217,18 +220,25 @@ static STACK_OF(TRUST_TOKEN_PRETOKEN) * OPENSSL_malloc(sizeof(TRUST_TOKEN_PRETOKEN)); if (pretoken == NULL || !sk_TRUST_TOKEN_PRETOKEN_push(pretokens, pretoken)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); TRUST_TOKEN_PRETOKEN_free(pretoken); goto err; } - RAND_bytes(pretoken->t, sizeof(pretoken->t)); + RAND_bytes(pretoken->salt, sizeof(pretoken->salt)); + if (include_message) { + assert(SHA512_DIGEST_LENGTH == TRUST_TOKEN_NONCE_SIZE); + SHA512_Init(&hash_ctx); + SHA512_Update(&hash_ctx, pretoken->salt, sizeof(pretoken->salt)); + SHA512_Update(&hash_ctx, msg, msg_len); + SHA512_Final(pretoken->t, &hash_ctx); + } else { + OPENSSL_memcpy(pretoken->t, pretoken->salt, TRUST_TOKEN_NONCE_SIZE); + } // We sample r in Montgomery form to simplify inverting. EC_SCALAR r; if (!ec_random_nonzero_scalar(group, &r, kDefaultAdditionalData)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } @@ -278,7 +288,6 @@ static int hash_to_scalar_dleq(const VOPRF_METHOD *method, EC_SCALAR *out, !cbb_add_point(&cbb, method->group, K1) || !CBB_finish(&cbb, &buf, &len) || !method->hash_to_scalar(method->group, out, buf, len)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } @@ -310,7 +319,6 @@ static int hash_to_scalar_batch(const VOPRF_METHOD *method, EC_SCALAR *out, !CBB_add_u16(&cbb, (uint16_t)index) || !CBB_finish(&cbb, &buf, &len) || !method->hash_to_scalar(method->group, out, buf, len)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } @@ -373,7 +381,6 @@ static int dleq_generate(const VOPRF_METHOD *method, CBB *cbb, // Store DLEQ proof in transcript. if (!scalar_to_cbb(cbb, group, &c) || !scalar_to_cbb(cbb, group, &u)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); return 0; } @@ -474,7 +481,6 @@ static int voprf_sign(const VOPRF_METHOD *method, !es || !CBB_init(&batch_cbb, 0) || !cbb_add_point(&batch_cbb, method->group, &key->pubs)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } @@ -494,7 +500,6 @@ static int voprf_sign(const VOPRF_METHOD *method, if (!cbb_add_point(&batch_cbb, group, &BT_affine) || !cbb_add_point(&batch_cbb, group, &Z_affine)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } BTs[i] = BT; @@ -548,39 +553,35 @@ static int voprf_sign(const VOPRF_METHOD *method, return ret; } -static STACK_OF(TRUST_TOKEN) * - voprf_unblind(const VOPRF_METHOD *method, const TRUST_TOKEN_CLIENT_KEY *key, - const STACK_OF(TRUST_TOKEN_PRETOKEN) * pretokens, CBS *cbs, - size_t count, uint32_t key_id) { +static STACK_OF(TRUST_TOKEN) *voprf_unblind( + const VOPRF_METHOD *method, const TRUST_TOKEN_CLIENT_KEY *key, + const STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens, CBS *cbs, size_t count, + uint32_t key_id) { const EC_GROUP *group = method->group; if (count > sk_TRUST_TOKEN_PRETOKEN_num(pretokens)) { OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE); return NULL; } - int ok = 0; - STACK_OF(TRUST_TOKEN) *ret = sk_TRUST_TOKEN_new_null(); - if (ret == NULL) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); - return NULL; - } - if (count > ((size_t)-1) / sizeof(EC_RAW_POINT) || count > ((size_t)-1) / sizeof(EC_SCALAR)) { OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW); - return 0; + return NULL; } + + int ok = 0; + STACK_OF(TRUST_TOKEN) *ret = sk_TRUST_TOKEN_new_null(); EC_RAW_POINT *BTs = OPENSSL_malloc(count * sizeof(EC_RAW_POINT)); EC_RAW_POINT *Zs = OPENSSL_malloc(count * sizeof(EC_RAW_POINT)); EC_SCALAR *es = OPENSSL_malloc(count * sizeof(EC_SCALAR)); CBB batch_cbb; CBB_zero(&batch_cbb); - if (!BTs || - !Zs || - !es || + if (ret == NULL || + BTs == NULL || + Zs == NULL || + es == NULL || !CBB_init(&batch_cbb, 0) || !cbb_add_point(&batch_cbb, method->group, &key->pubs)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } @@ -599,7 +600,6 @@ static STACK_OF(TRUST_TOKEN) * if (!cbb_add_point(&batch_cbb, group, &pretoken->Tp) || !cbb_add_point(&batch_cbb, group, &Z_affine)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } @@ -618,7 +618,7 @@ static STACK_OF(TRUST_TOKEN) * size_t point_len = 1 + 2 * BN_num_bytes(&group->field); if (!CBB_init(&token_cbb, 4 + TRUST_TOKEN_NONCE_SIZE + (2 + point_len)) || !CBB_add_u32(&token_cbb, key_id) || - !CBB_add_bytes(&token_cbb, pretoken->t, TRUST_TOKEN_NONCE_SIZE) || + !CBB_add_bytes(&token_cbb, pretoken->salt, TRUST_TOKEN_NONCE_SIZE) || !cbb_add_point(&token_cbb, group, &N_affine) || !CBB_flush(&token_cbb)) { CBB_cleanup(&token_cbb); @@ -630,7 +630,6 @@ static STACK_OF(TRUST_TOKEN) * CBB_cleanup(&token_cbb); if (token == NULL || !sk_TRUST_TOKEN_push(ret, token)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); TRUST_TOKEN_free(token); goto err; } @@ -677,18 +676,30 @@ static STACK_OF(TRUST_TOKEN) * static int voprf_read(const VOPRF_METHOD *method, const TRUST_TOKEN_ISSUER_KEY *key, uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE], - const uint8_t *token, size_t token_len) { + const uint8_t *token, size_t token_len, + int include_message, const uint8_t *msg, size_t msg_len) { const EC_GROUP *group = method->group; - CBS cbs; + CBS cbs, salt; CBS_init(&cbs, token, token_len); EC_AFFINE Ws; - if (!CBS_copy_bytes(&cbs, out_nonce, TRUST_TOKEN_NONCE_SIZE) || + if (!CBS_get_bytes(&cbs, &salt, TRUST_TOKEN_NONCE_SIZE) || !cbs_get_point(&cbs, group, &Ws) || CBS_len(&cbs) != 0) { OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_TOKEN); return 0; } + if (include_message) { + SHA512_CTX hash_ctx; + assert(SHA512_DIGEST_LENGTH == TRUST_TOKEN_NONCE_SIZE); + SHA512_Init(&hash_ctx); + SHA512_Update(&hash_ctx, CBS_data(&salt), CBS_len(&salt)); + SHA512_Update(&hash_ctx, msg, msg_len); + SHA512_Final(out_nonce, &hash_ctx); + } else { + OPENSSL_memcpy(out_nonce, CBS_data(&salt), CBS_len(&salt)); + } + EC_RAW_POINT T; if (!method->hash_to_group(group, &T, out_nonce)) { @@ -776,11 +787,15 @@ int voprf_exp2_issuer_key_from_bytes(TRUST_TOKEN_ISSUER_KEY *key, return voprf_issuer_key_from_bytes(&voprf_exp2_method, key, in, len); } -STACK_OF(TRUST_TOKEN_PRETOKEN) * voprf_exp2_blind(CBB *cbb, size_t count) { +STACK_OF(TRUST_TOKEN_PRETOKEN) *voprf_exp2_blind(CBB *cbb, size_t count, + int include_message, + const uint8_t *msg, + size_t msg_len) { if (!voprf_exp2_init_method()) { return NULL; } - return voprf_blind(&voprf_exp2_method, cbb, count); + return voprf_blind(&voprf_exp2_method, cbb, count, include_message, msg, + msg_len); } int voprf_exp2_sign(const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, @@ -793,23 +808,137 @@ int voprf_exp2_sign(const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, num_to_issue); } -STACK_OF(TRUST_TOKEN) * - voprf_exp2_unblind(const TRUST_TOKEN_CLIENT_KEY *key, - const STACK_OF(TRUST_TOKEN_PRETOKEN) * pretokens, - CBS *cbs, size_t count, uint32_t key_id) { +STACK_OF(TRUST_TOKEN) *voprf_exp2_unblind( + const TRUST_TOKEN_CLIENT_KEY *key, + const STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens, CBS *cbs, size_t count, + uint32_t key_id) { if (!voprf_exp2_init_method()) { return NULL; } - return voprf_unblind(&voprf_exp2_method, key, pretokens, cbs, count, - key_id); + return voprf_unblind(&voprf_exp2_method, key, pretokens, cbs, count, key_id); } int voprf_exp2_read(const TRUST_TOKEN_ISSUER_KEY *key, uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE], uint8_t *out_private_metadata, const uint8_t *token, - size_t token_len) { + size_t token_len, int include_message, const uint8_t *msg, + size_t msg_len) { if (!voprf_exp2_init_method()) { return 0; } - return voprf_read(&voprf_exp2_method, key, out_nonce, token, token_len); + return voprf_read(&voprf_exp2_method, key, out_nonce, token, token_len, + include_message, msg, msg_len); +} + +// VOPRF PST v1. + +static int voprf_pst1_hash_to_group(const EC_GROUP *group, EC_RAW_POINT *out, + const uint8_t t[TRUST_TOKEN_NONCE_SIZE]) { + const uint8_t kHashTLabel[] = "TrustToken VOPRF PST V1 HashToGroup"; + return ec_hash_to_curve_p384_xmd_sha384_sswu( + group, out, kHashTLabel, sizeof(kHashTLabel), t, TRUST_TOKEN_NONCE_SIZE); +} + +static int voprf_pst1_hash_to_scalar(const EC_GROUP *group, EC_SCALAR *out, + uint8_t *buf, size_t len) { + const uint8_t kHashCLabel[] = "TrustToken VOPRF PST V1 HashToScalar"; + return ec_hash_to_scalar_p384_xmd_sha384( + group, out, kHashCLabel, sizeof(kHashCLabel), buf, len); +} + +static int voprf_pst1_ok = 0; +static VOPRF_METHOD voprf_pst1_method; +static CRYPTO_once_t voprf_pst1_method_once = CRYPTO_ONCE_INIT; + +static void voprf_pst1_init_method_impl(void) { + voprf_pst1_ok = + voprf_init_method(&voprf_pst1_method, NID_secp384r1, + voprf_pst1_hash_to_group, voprf_pst1_hash_to_scalar); +} + +static int voprf_pst1_init_method(void) { + CRYPTO_once(&voprf_pst1_method_once, voprf_pst1_init_method_impl); + if (!voprf_pst1_ok) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_INTERNAL_ERROR); + return 0; + } + return 1; +} + +int voprf_pst1_generate_key(CBB *out_private, CBB *out_public) { + if (!voprf_pst1_init_method()) { + return 0; + } + + return voprf_generate_key(&voprf_pst1_method, out_private, out_public); +} + +int voprf_pst1_derive_key_from_secret(CBB *out_private, CBB *out_public, + const uint8_t *secret, + size_t secret_len) { + if (!voprf_pst1_init_method()) { + return 0; + } + + return voprf_derive_key_from_secret(&voprf_pst1_method, out_private, + out_public, secret, secret_len); +} + +int voprf_pst1_client_key_from_bytes(TRUST_TOKEN_CLIENT_KEY *key, + const uint8_t *in, size_t len) { + if (!voprf_pst1_init_method()) { + return 0; + } + return voprf_client_key_from_bytes(&voprf_pst1_method, key, in, len); +} + +int voprf_pst1_issuer_key_from_bytes(TRUST_TOKEN_ISSUER_KEY *key, + const uint8_t *in, size_t len) { + if (!voprf_pst1_init_method()) { + return 0; + } + return voprf_issuer_key_from_bytes(&voprf_pst1_method, key, in, len); +} + +STACK_OF(TRUST_TOKEN_PRETOKEN) *voprf_pst1_blind(CBB *cbb, size_t count, + int include_message, + const uint8_t *msg, + size_t msg_len) { + if (!voprf_pst1_init_method()) { + return NULL; + } + return voprf_blind(&voprf_pst1_method, cbb, count, include_message, msg, + msg_len); +} + +int voprf_pst1_sign(const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, + size_t num_requested, size_t num_to_issue, + uint8_t private_metadata) { + if (!voprf_pst1_init_method() || private_metadata != 0) { + return 0; + } + return voprf_sign(&voprf_pst1_method, key, cbb, cbs, num_requested, + num_to_issue); +} + +STACK_OF(TRUST_TOKEN) *voprf_pst1_unblind( + const TRUST_TOKEN_CLIENT_KEY *key, + const STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens, CBS *cbs, size_t count, + uint32_t key_id) { + if (!voprf_pst1_init_method()) { + return NULL; + } + return voprf_unblind(&voprf_pst1_method, key, pretokens, cbs, count, key_id); +} + +int voprf_pst1_read(const TRUST_TOKEN_ISSUER_KEY *key, + uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE], + uint8_t *out_private_metadata, const uint8_t *token, + size_t token_len, int include_message, const uint8_t *msg, + size_t msg_len) { + if (!voprf_pst1_init_method()) { + return 0; + } + return voprf_read(&voprf_pst1_method, key, out_nonce, token, token_len, + include_message, msg, msg_len); } diff --git a/Sources/CNIOBoringSSL/crypto/x509/a_digest.c b/Sources/CNIOBoringSSL/crypto/x509/a_digest.c index 3d38be0b..f123a085 100644 --- a/Sources/CNIOBoringSSL/crypto/x509/a_digest.c +++ b/Sources/CNIOBoringSSL/crypto/x509/a_digest.c @@ -68,7 +68,6 @@ int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data, i = i2d(data, NULL); if ((str = (unsigned char *)OPENSSL_malloc(i)) == NULL) { - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); return 0; } p = str; diff --git a/Sources/CNIOBoringSSL/crypto/x509/a_sign.c b/Sources/CNIOBoringSSL/crypto/x509/a_sign.c index 9e43cf60..3d48fdf0 100644 --- a/Sources/CNIOBoringSSL/crypto/x509/a_sign.c +++ b/Sources/CNIOBoringSSL/crypto/x509/a_sign.c @@ -62,6 +62,8 @@ #include #include +#include + #include "internal.h" int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, @@ -83,17 +85,13 @@ int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, 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; - + int ret = 0; + uint8_t *in = NULL, *out = NULL; if (signature->type != V_ASN1_BIT_STRING) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_TYPE); goto err; } - pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx); - // Write out the requested copies of the AlgorithmIdentifier. if (algor1 && !x509_digest_sign_algorithm(ctx, algor1)) { goto err; @@ -102,27 +100,37 @@ int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1, goto err; } - inl = ASN1_item_i2d(asn, &buf_in, it); - 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); + int in_len = ASN1_item_i2d(asn, &in, it); + if (in_len < 0) { + goto err; + } + + EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx); + size_t out_len = EVP_PKEY_size(pkey); + if (out_len > INT_MAX) { + OPENSSL_PUT_ERROR(X509, ERR_R_OVERFLOW); goto err; } - if (!EVP_DigestSign(ctx, buf_out, &outl, buf_in, inl)) { - outl = 0; + out = OPENSSL_malloc(out_len); + if (out == NULL) { + goto err; + } + + if (!EVP_DigestSign(ctx, out, &out_len, in, in_len)) { OPENSSL_PUT_ERROR(X509, ERR_R_EVP_LIB); goto err; } - ASN1_STRING_set0(signature, buf_out, outl); - buf_out = NULL; + + ASN1_STRING_set0(signature, out, (int)out_len); + out = NULL; signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); signature->flags |= ASN1_STRING_FLAG_BITS_LEFT; + ret = 1; + err: EVP_MD_CTX_cleanup(ctx); - OPENSSL_free(buf_in); - OPENSSL_free(buf_out); - return outl; + OPENSSL_free(in); + OPENSSL_free(out); + return ret; } diff --git a/Sources/CNIOBoringSSL/crypto/x509/a_verify.c b/Sources/CNIOBoringSSL/crypto/x509/a_verify.c index ea8a747d..68332a44 100644 --- a/Sources/CNIOBoringSSL/crypto/x509/a_verify.c +++ b/Sources/CNIOBoringSSL/crypto/x509/a_verify.c @@ -98,7 +98,6 @@ int ASN1_item_verify(const ASN1_ITEM *it, const X509_ALGOR *a, inl = ASN1_item_i2d(asn, &buf_in, it); if (buf_in == NULL) { - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); goto err; } diff --git a/Sources/CNIOBoringSSL/crypto/x509/asn1_gen.c b/Sources/CNIOBoringSSL/crypto/x509/asn1_gen.c index 2cdd06b9..58cdd190 100644 --- a/Sources/CNIOBoringSSL/crypto/x509/asn1_gen.c +++ b/Sources/CNIOBoringSSL/crypto/x509/asn1_gen.c @@ -56,11 +56,14 @@ #include +#include +#include +#include #include #include +#include #include -#include #include #include @@ -69,738 +72,515 @@ #include "../x509v3/internal.h" #include "internal.h" + // 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_STR(str, val) \ - { str, sizeof(str) - 1, val } +// ASN1_GEN_MAX_DEPTH is the maximum number of nested TLVs allowed. +#define ASN1_GEN_MAX_DEPTH 50 -#define ASN1_FLAG_EXP_MAX 20 -// Maximum number of nested sequences -#define ASN1_GEN_SEQ_MAX_DEPTH 50 +// ASN1_GEN_MAX_OUTPUT is the maximum output, in bytes, allowed. This limit is +// necessary because the SEQUENCE and SET section reference mechanism allows the +// output length to grow super-linearly with the input length. +#define ASN1_GEN_MAX_OUTPUT (64 * 1024) -// Input formats - -// ASCII: default +// ASN1_GEN_FORMAT_* are the values for the format modifiers. #define ASN1_GEN_FORMAT_ASCII 1 -// UTF8 #define ASN1_GEN_FORMAT_UTF8 2 -// Hex #define ASN1_GEN_FORMAT_HEX 3 -// List of bits #define ASN1_GEN_FORMAT_BITLIST 4 -struct tag_name_st { - const char *strnam; - size_t 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 ASN1_TYPE *generate_v3(const char *str, X509V3_CTX *cnf, int depth, - int *perr); +// generate_v3 converts |str| into an ASN.1 structure and writes the result to +// |cbb|. It returns one on success and zero on error. |depth| bounds recursion, +// and |format| specifies the current format modifier. +// +// If |tag| is non-zero, the structure is implicitly tagged with |tag|. |tag| +// must not have the constructed bit set. +static int generate_v3(CBB *cbb, const char *str, const X509V3_CTX *cnf, + CBS_ASN1_TAG tag, int format, int depth); + static int bitstr_cb(const char *elem, size_t len, void *bitstr); -static int asn1_cb(const char *elem, size_t 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, size_t vlen, int *ptag, - int *pclass); -static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf, - int depth, int *perr); -static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype); -static int asn1_str2tag(const char *tagstr, size_t len); - -ASN1_TYPE *ASN1_generate_v3(const char *str, X509V3_CTX *cnf) { - int err = 0; - ASN1_TYPE *ret = generate_v3(str, cnf, 0, &err); - if (err) { - OPENSSL_PUT_ERROR(ASN1, err); - } - return ret; -} -static ASN1_TYPE *generate_v3(const char *str, X509V3_CTX *cnf, int depth, - int *perr) { - 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) { - *perr = ASN1_R_UNKNOWN_TAG; +ASN1_TYPE *ASN1_generate_v3(const char *str, const X509V3_CTX *cnf) { + CBB cbb; + if (!CBB_init(&cbb, 0) || // + !generate_v3(&cbb, str, cnf, /*tag=*/0, ASN1_GEN_FORMAT_ASCII, + /*depth=*/0)) { + CBB_cleanup(&cbb); return NULL; } - if ((asn1_tags.utype == V_ASN1_SEQUENCE) || (asn1_tags.utype == V_ASN1_SET)) { - if (!cnf) { - *perr = ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG; - return NULL; - } - if (depth >= ASN1_GEN_SEQ_MAX_DEPTH) { - *perr = ASN1_R_ILLEGAL_NESTED_TAGGING; - return NULL; - } - ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf, depth, perr); - } else { - ret = asn1_str2type(asn1_tags.str, asn1_tags.format, asn1_tags.utype); - } - - if (!ret) { + // While not strictly necessary to avoid a DoS (we rely on any super-linear + // checks being performed internally), cap the overall output to + // |ASN1_GEN_MAX_OUTPUT| so the externally-visible behavior is consistent. + if (CBB_len(&cbb) > ASN1_GEN_MAX_OUTPUT) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG); + CBB_cleanup(&cbb); 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. - 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 - OPENSSL_memcpy(p, cpy_start, cpy_len); - - cp = new_der; - - // Obtain new ASN1_TYPE structure - ret = d2i_ASN1_TYPE(NULL, &cp, len); - -err: - OPENSSL_free(orig_der); - OPENSSL_free(new_der); + const uint8_t *der = CBB_data(&cbb); + ASN1_TYPE *ret = d2i_ASN1_TYPE(NULL, &der, CBB_len(&cbb)); + CBB_cleanup(&cbb); return ret; } -static int asn1_cb(const char *elem, size_t len, void *bitstr) { - tag_exp_arg *arg = bitstr; - if (elem == NULL) { - return -1; - } - - // Look for the ':' in name:value pairs. - const char *vstart = NULL; - size_t vlen = 0; - const char *colon = OPENSSL_memchr(elem, ':', len); - if (colon != NULL) { - vstart = colon + 1; - vlen = len - (vstart - elem); - len = colon - elem; - } - - int 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: { - int tmp_tag, tmp_class; - 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 cbs_str_equal(const CBS *cbs, const char *str) { + return CBS_len(cbs) == strlen(str) && + OPENSSL_memcmp(CBS_data(cbs), str, strlen(str)) == 0; } -static int parse_tagging(const char *vstart, size_t 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) { +// parse_tag decodes a tag specifier in |cbs|. It returns the tag on success or +// zero on error. +static CBS_ASN1_TAG parse_tag(const CBS *cbs) { + CBS copy = *cbs; + uint64_t num; + if (!CBS_get_u64_decimal(©, &num) || + num > CBS_ASN1_TAG_NUMBER_MASK) { 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) { + + CBS_ASN1_TAG tag_class = CBS_ASN1_CONTEXT_SPECIFIC; + // The tag may be suffixed by a class. + uint8_t c; + if (CBS_get_u8(©, &c)) { + switch (c) { case 'U': - *pclass = V_ASN1_UNIVERSAL; + tag_class = CBS_ASN1_UNIVERSAL; break; - case 'A': - *pclass = V_ASN1_APPLICATION; + tag_class = CBS_ASN1_APPLICATION; break; - case 'P': - *pclass = V_ASN1_PRIVATE; + tag_class = CBS_ASN1_PRIVATE; break; - case 'C': - *pclass = V_ASN1_CONTEXT_SPECIFIC; + tag_class = CBS_ASN1_CONTEXT_SPECIFIC; break; - - default: - erch[0] = *eptr; - erch[1] = 0; + default: { 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, - int depth, int *perr) { - 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 = generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf, - depth + 1, perr); - if (!typ) { - goto bad; - } - if (!sk_ASN1_TYPE_push(sk, typ)) { - goto bad; } } + if (CBS_len(©) != 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_MODIFIER); + return 0; + } } - // 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); + // Tag [UNIVERSAL 0] is reserved for indefinite-length end-of-contents. We + // also use zero in this file to indicator no explicit tagging. + if (tag_class == CBS_ASN1_UNIVERSAL && num == 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_NUMBER); + return 0; } - if (derlen < 0) { - goto bad; - } + return tag_class | (CBS_ASN1_TAG)num; +} - if (!(ret = ASN1_TYPE_new())) { - goto bad; - } +static int generate_wrapped(CBB *cbb, const char *str, const X509V3_CTX *cnf, + CBS_ASN1_TAG tag, int padding, int format, + int depth) { + CBB child; + return CBB_add_asn1(cbb, &child, tag) && + (!padding || CBB_add_u8(&child, 0)) && + generate_v3(&child, str, cnf, /*tag=*/0, format, depth + 1) && + CBB_flush(cbb); +} - if (!(ret->value.asn1_string = ASN1_STRING_type_new(utype))) { - goto bad; +static int generate_v3(CBB *cbb, const char *str, const X509V3_CTX *cnf, + CBS_ASN1_TAG tag, int format, int depth) { + assert((tag & CBS_ASN1_CONSTRUCTED) == 0); + if (depth > ASN1_GEN_MAX_DEPTH) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NESTED_TAGGING); + return 0; } - ret->type = utype; - - ret->value.asn1_string->data = der; - ret->value.asn1_string->length = derlen; + // Process modifiers. This function uses a mix of NUL-terminated strings and + // |CBS|. Several functions only work with NUL-terminated strings, so we need + // to keep track of when a slice spans the whole buffer. + for (;;) { + // Skip whitespace. + while (*str != '\0' && OPENSSL_isspace((unsigned char)*str)) { + str++; + } - der = NULL; + // Modifiers end at commas. + const char *comma = strchr(str, ','); + if (comma == NULL) { + break; + } -bad: - OPENSSL_free(der); - sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); - X509V3_section_free(cnf, sect); - return ret; -} + // Remove trailing whitespace. + CBS modifier; + CBS_init(&modifier, (const uint8_t *)str, comma - str); + for (;;) { + uint8_t v; + CBS copy = modifier; + if (!CBS_get_last_u8(©, &v) || !OPENSSL_isspace(v)) { + break; + } + modifier = copy; + } -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; - } + // Advance the string past the modifier, but save the original value. We + // will need to rewind if this is not a recognized modifier. + const char *str_old = str; + str = comma + 1; + + // Each modifier is either NAME:VALUE or NAME. + CBS name; + int has_value = CBS_get_until_first(&modifier, &name, ':'); + if (has_value) { + CBS_skip(&modifier, 1); // Skip the colon. + } else { + name = modifier; + CBS_init(&modifier, NULL, 0); + } - if (arg->exp_count == ASN1_FLAG_EXP_MAX) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_DEPTH_EXCEEDED); - return 0; + if (cbs_str_equal(&name, "FORMAT") || cbs_str_equal(&name, "FORM")) { + if (cbs_str_equal(&modifier, "ASCII")) { + format = ASN1_GEN_FORMAT_ASCII; + } else if (cbs_str_equal(&modifier, "UTF8")) { + format = ASN1_GEN_FORMAT_UTF8; + } else if (cbs_str_equal(&modifier, "HEX")) { + format = ASN1_GEN_FORMAT_HEX; + } else if (cbs_str_equal(&modifier, "BITLIST")) { + format = ASN1_GEN_FORMAT_BITLIST; + } else { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_FORMAT); + return 0; + } + } else if (cbs_str_equal(&name, "IMP") || + cbs_str_equal(&name, "IMPLICIT")) { + if (tag != 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NESTED_TAGGING); + return 0; + } + tag = parse_tag(&modifier); + if (tag == 0) { + return 0; + } + } else if (cbs_str_equal(&name, "EXP") || + cbs_str_equal(&name, "EXPLICIT")) { + // It would actually be supportable, but OpenSSL does not allow wrapping + // an explicit tag in an implicit tag. + if (tag != 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NESTED_TAGGING); + return 0; + } + tag = parse_tag(&modifier); + return tag != 0 && + generate_wrapped(cbb, str, cnf, tag | CBS_ASN1_CONSTRUCTED, + /*padding=*/0, format, depth); + } else if (cbs_str_equal(&name, "OCTWRAP")) { + tag = tag == 0 ? CBS_ASN1_OCTETSTRING : tag; + return generate_wrapped(cbb, str, cnf, tag, /*padding=*/0, format, depth); + } else if (cbs_str_equal(&name, "BITWRAP")) { + tag = tag == 0 ? CBS_ASN1_BITSTRING : tag; + return generate_wrapped(cbb, str, cnf, tag, /*padding=*/1, format, depth); + } else if (cbs_str_equal(&name, "SEQWRAP")) { + tag = tag == 0 ? CBS_ASN1_SEQUENCE : (tag | CBS_ASN1_CONSTRUCTED); + tag |= CBS_ASN1_CONSTRUCTED; + return generate_wrapped(cbb, str, cnf, tag, /*padding=*/0, format, depth); + } else if (cbs_str_equal(&name, "SETWRAP")) { + tag = tag == 0 ? CBS_ASN1_SET : (tag | CBS_ASN1_CONSTRUCTED); + return generate_wrapped(cbb, str, cnf, tag, /*padding=*/0, format, depth); + } else { + // If this was not a recognized modifier, rewind |str| to before splitting + // on the comma. The type itself consumes all remaining input. + str = str_old; + break; + } } - 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; + // The final element is, like modifiers, NAME:VALUE or NAME, but VALUE spans + // the length of the string, including any commas. + const char *colon = strchr(str, ':'); + CBS name; + const char *value; + int has_value = colon != NULL; + if (has_value) { + CBS_init(&name, (const uint8_t *)str, colon - str); + value = colon + 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, size_t len) { - static const struct tag_name_st 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), + CBS_init(&name, (const uint8_t *)str, strlen(str)); + value = ""; // Most types treat missing and empty value equivalently. + } + + static const struct { + const char *name; + CBS_ASN1_TAG type; + } kTypes[] = { + {"BOOL", CBS_ASN1_BOOLEAN}, + {"BOOLEAN", CBS_ASN1_BOOLEAN}, + {"NULL", CBS_ASN1_NULL}, + {"INT", CBS_ASN1_INTEGER}, + {"INTEGER", CBS_ASN1_INTEGER}, + {"ENUM", CBS_ASN1_ENUMERATED}, + {"ENUMERATED", CBS_ASN1_ENUMERATED}, + {"OID", CBS_ASN1_OBJECT}, + {"OBJECT", CBS_ASN1_OBJECT}, + {"UTCTIME", CBS_ASN1_UTCTIME}, + {"UTC", CBS_ASN1_UTCTIME}, + {"GENERALIZEDTIME", CBS_ASN1_GENERALIZEDTIME}, + {"GENTIME", CBS_ASN1_GENERALIZEDTIME}, + {"OCT", CBS_ASN1_OCTETSTRING}, + {"OCTETSTRING", CBS_ASN1_OCTETSTRING}, + {"BITSTR", CBS_ASN1_BITSTRING}, + {"BITSTRING", CBS_ASN1_BITSTRING}, + {"UNIVERSALSTRING", CBS_ASN1_UNIVERSALSTRING}, + {"UNIV", CBS_ASN1_UNIVERSALSTRING}, + {"IA5", CBS_ASN1_IA5STRING}, + {"IA5STRING", CBS_ASN1_IA5STRING}, + {"UTF8", CBS_ASN1_UTF8STRING}, + {"UTF8String", CBS_ASN1_UTF8STRING}, + {"BMP", CBS_ASN1_BMPSTRING}, + {"BMPSTRING", CBS_ASN1_BMPSTRING}, + {"PRINTABLESTRING", CBS_ASN1_PRINTABLESTRING}, + {"PRINTABLE", CBS_ASN1_PRINTABLESTRING}, + {"T61", CBS_ASN1_T61STRING}, + {"T61STRING", CBS_ASN1_T61STRING}, + {"TELETEXSTRING", CBS_ASN1_T61STRING}, + {"SEQUENCE", CBS_ASN1_SEQUENCE}, + {"SEQ", CBS_ASN1_SEQUENCE}, + {"SET", CBS_ASN1_SET}, }; - - for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(tnst); i++) { - if (len == tnst[i].len && strncmp(tnst[i].strnam, tagstr, len) == 0) { - return tnst[i].tag; + CBS_ASN1_TAG type = 0; + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kTypes); i++) { + if (cbs_str_equal(&name, kTypes[i].name)) { + type = kTypes[i].type; + break; } } - - 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 (type == 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_TAG); + return 0; } - if (!str) { - str = ""; + // If there is an implicit tag, use the constructed bit from the base type. + tag = tag == 0 ? type : (tag | (type & CBS_ASN1_CONSTRUCTED)); + CBB child; + if (!CBB_add_asn1(cbb, &child, tag)) { + return 0; } - switch (utype) { - case V_ASN1_NULL: - if (str && *str) { + switch (type) { + case CBS_ASN1_NULL: + if (*value != '\0') { OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NULL_VALUE); - goto bad_form; + return 0; } - break; + return CBB_flush(cbb); - case V_ASN1_BOOLEAN: + case CBS_ASN1_BOOLEAN: { if (format != ASN1_GEN_FORMAT_ASCII) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ASCII_FORMAT); - goto bad_form; + return 0; } - vtmp.name = NULL; - vtmp.section = NULL; - vtmp.value = (char *)str; - if (!X509V3_get_value_bool(&vtmp, &atmp->value.boolean)) { + ASN1_BOOLEAN boolean; + if (!X509V3_bool_from_string(value, &boolean)) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_BOOLEAN); - goto bad_str; + return 0; } - break; + return CBB_add_u8(&child, boolean ? 0xff : 0x00) && CBB_flush(cbb); + } - case V_ASN1_INTEGER: - case V_ASN1_ENUMERATED: + case CBS_ASN1_INTEGER: + case CBS_ASN1_ENUMERATED: { if (format != ASN1_GEN_FORMAT_ASCII) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_INTEGER_NOT_ASCII_FORMAT); - goto bad_form; + return 0; } - if (!(atmp->value.integer = s2i_ASN1_INTEGER(NULL, (char *)str))) { + ASN1_INTEGER *obj = s2i_ASN1_INTEGER(NULL, value); + if (obj == NULL) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_INTEGER); - goto bad_str; + return 0; } - break; + int len = i2c_ASN1_INTEGER(obj, NULL); + uint8_t *out; + int ok = len > 0 && // + CBB_add_space(&child, &out, len) && + i2c_ASN1_INTEGER(obj, &out) == len && + CBB_flush(cbb); + ASN1_INTEGER_free(obj); + return ok; + } - case V_ASN1_OBJECT: + case CBS_ASN1_OBJECT: { if (format != ASN1_GEN_FORMAT_ASCII) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_OBJECT_NOT_ASCII_FORMAT); - goto bad_form; + return 0; } - if (!(atmp->value.object = OBJ_txt2obj(str, 0))) { + ASN1_OBJECT *obj = OBJ_txt2obj(value, /*dont_search_names=*/0); + if (obj == NULL || obj->length == 0) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OBJECT); - goto bad_str; + return 0; } - break; + int ok = CBB_add_bytes(&child, obj->data, obj->length) && CBB_flush(cbb); + ASN1_OBJECT_free(obj); + return ok; + } - case V_ASN1_UTCTIME: - case V_ASN1_GENERALIZEDTIME: + case CBS_ASN1_UTCTIME: + case CBS_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; + return 0; } - atmp->value.asn1_string->type = utype; - if (!ASN1_TIME_check(atmp->value.asn1_string)) { + CBS value_cbs; + CBS_init(&value_cbs, (const uint8_t*)value, strlen(value)); + int ok = type == CBS_ASN1_UTCTIME + ? CBS_parse_utc_time(&value_cbs, NULL, + /*allow_timezone_offset=*/0) + : CBS_parse_generalized_time(&value_cbs, NULL, + /*allow_timezone_offset=*/0); + if (!ok) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_TIME_VALUE); - goto bad_str; + return 0; } + return CBB_add_bytes(&child, (const uint8_t *)value, strlen(value)) && + CBB_flush(cbb); + } - 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: - + case CBS_ASN1_UNIVERSALSTRING: + case CBS_ASN1_IA5STRING: + case CBS_ASN1_UTF8STRING: + case CBS_ASN1_BMPSTRING: + case CBS_ASN1_PRINTABLESTRING: + case CBS_ASN1_T61STRING: { + int encoding; if (format == ASN1_GEN_FORMAT_ASCII) { - format = MBSTRING_ASC; + encoding = MBSTRING_ASC; } else if (format == ASN1_GEN_FORMAT_UTF8) { - format = MBSTRING_UTF8; + encoding = MBSTRING_UTF8; } else { OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_FORMAT); - goto bad_form; + return 0; } - 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; + // |maxsize| is measured in code points, rather than bytes, but pass it in + // as a loose cap so fuzzers can exit from excessively long inputs + // earlier. This limit is not load-bearing because |ASN1_mbstring_ncopy|'s + // output is already linear in the input. + ASN1_STRING *obj = NULL; + if (ASN1_mbstring_ncopy(&obj, (const uint8_t *)value, -1, encoding, + ASN1_tag2bit(type), /*minsize=*/0, + /*maxsize=*/ASN1_GEN_MAX_OUTPUT) <= 0) { + return 0; } + int ok = CBB_add_bytes(&child, obj->data, obj->length) && CBB_flush(cbb); + ASN1_STRING_free(obj); + return ok; + } - break; - - case V_ASN1_BIT_STRING: - - case V_ASN1_OCTET_STRING: + case CBS_ASN1_BITSTRING: + if (format == ASN1_GEN_FORMAT_BITLIST) { + ASN1_BIT_STRING *obj = ASN1_BIT_STRING_new(); + if (obj == NULL) { + return 0; + } + if (!CONF_parse_list(value, ',', 1, bitstr_cb, obj)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_LIST_ERROR); + ASN1_BIT_STRING_free(obj); + return 0; + } + int len = i2c_ASN1_BIT_STRING(obj, NULL); + uint8_t *out; + int ok = len > 0 && // + CBB_add_space(&child, &out, len) && + i2c_ASN1_BIT_STRING(obj, &out) == len && // + CBB_flush(cbb); + ASN1_BIT_STRING_free(obj); + return ok; + } - if (!(atmp->value.asn1_string = ASN1_STRING_new())) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); - goto bad_form; + // The other formats are the same as OCTET STRING, but with the leading + // zero bytes. + if (!CBB_add_u8(&child, 0)) { + return 0; } + OPENSSL_FALLTHROUGH; + case CBS_ASN1_OCTETSTRING: + if (format == ASN1_GEN_FORMAT_ASCII) { + return CBB_add_bytes(&child, (const uint8_t *)value, strlen(value)) && + CBB_flush(cbb); + } if (format == ASN1_GEN_FORMAT_HEX) { - if (!(rdata = x509v3_hex_to_bytes((char *)str, &rdlen))) { + size_t len; + uint8_t *data = x509v3_hex_to_bytes(value, &len); + if (data == NULL) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_HEX); - goto bad_str; + return 0; } + int ok = CBB_add_bytes(&child, data, len) && CBB_flush(cbb); + OPENSSL_free(data); + return ok; + } - atmp->value.asn1_string->data = rdata; - atmp->value.asn1_string->length = rdlen; - atmp->value.asn1_string->type = utype; + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_BITSTRING_FORMAT); + return 0; - } 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; + case CBS_ASN1_SEQUENCE: + case CBS_ASN1_SET: + if (has_value) { + if (cnf == NULL) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG); + return 0; + } + const STACK_OF(CONF_VALUE) *section = X509V3_get_section(cnf, value); + if (section == NULL) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG); + return 0; + } + for (size_t i = 0; i < sk_CONF_VALUE_num(section); i++) { + const CONF_VALUE *conf = sk_CONF_VALUE_value(section, i); + if (!generate_v3(&child, conf->value, cnf, /*tag=*/0, + ASN1_GEN_FORMAT_ASCII, depth + 1)) { + return 0; + } + // This recursive call, by referencing |section|, is the one place + // where |generate_v3|'s output can be super-linear in the input. + // Check bounds here. + if (CBB_len(&child) > ASN1_GEN_MAX_OUTPUT) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG); + return 0; + } } - 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; + if (type == CBS_ASN1_SET) { + // The SET type here is a SET OF and must be sorted. + return CBB_flush_asn1_set_of(&child) && CBB_flush(cbb); } - - break; + return CBB_flush(cbb); default: - OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNSUPPORTED_TYPE); - goto bad_str; - break; + OPENSSL_PUT_ERROR(ASN1, ERR_R_INTERNAL_ERROR); + return 0; } - - 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, size_t 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) { + CBS cbs; + CBS_init(&cbs, (const uint8_t *)elem, len); + uint64_t bitnum; + if (!CBS_get_u64_decimal(&cbs, &bitnum) || CBS_len(&cbs) != 0 || + // Cap the highest allowed bit so this mechanism cannot be used to create + // extremely large allocations with short inputs. The highest named bit in + // RFC 5280 is 8, so 256 should give comfortable margin but still only + // allow a 32-byte allocation. + // + // We do not consider this function to be safe with untrusted inputs (even + // without bugs, it is prone to string injection vulnerabilities), so DoS + // is not truly a concern, but the limit is necessary to keep fuzzing + // effective. + bitnum > 256) { 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); + if (!ASN1_BIT_STRING_set_bit(bitstr, (int)bitnum, 1)) { return 0; } return 1; diff --git a/Sources/CNIOBoringSSL/crypto/x509/by_dir.c b/Sources/CNIOBoringSSL/crypto/x509/by_dir.c index 62a5ae11..4bccda55 100644 --- a/Sources/CNIOBoringSSL/crypto/x509/by_dir.c +++ b/Sources/CNIOBoringSSL/crypto/x509/by_dir.c @@ -1,4 +1,3 @@ -/* crypto/x509/by_dir.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -153,7 +152,8 @@ static int new_dir(X509_LOOKUP *lu) { 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) { +static int by_dir_hash_cmp(const BY_DIR_HASH *const *a, + const BY_DIR_HASH *const *b) { if ((*a)->hash > (*b)->hash) { return 1; } @@ -212,7 +212,6 @@ static int add_cert_dir(BY_DIR *ctx, const char *dir, int type) { if (ctx->dirs == NULL) { ctx->dirs = sk_BY_DIR_ENTRY_new_null(); if (!ctx->dirs) { - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); return 0; } } @@ -301,7 +300,6 @@ static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name, 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) { @@ -320,29 +318,8 @@ static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name, 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'; - } -#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); - } + BIO_snprintf(b->data, b->max, "%s/%08lx.%s%d", ent->dir, h, postfix, + k); #ifndef OPENSSL_NO_POSIX_IO #if defined(_WIN32) && !defined(stat) #define stat _stat diff --git a/Sources/CNIOBoringSSL/crypto/x509/by_file.c b/Sources/CNIOBoringSSL/crypto/x509/by_file.c index 724354f7..f0b7bce4 100644 --- a/Sources/CNIOBoringSSL/crypto/x509/by_file.c +++ b/Sources/CNIOBoringSSL/crypto/x509/by_file.c @@ -1,4 +1,3 @@ -/* crypto/x509/by_file.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * diff --git a/Sources/CNIOBoringSSL/crypto/x509/i2d_pr.c b/Sources/CNIOBoringSSL/crypto/x509/i2d_pr.c index 823642ae..868558a4 100644 --- a/Sources/CNIOBoringSSL/crypto/x509/i2d_pr.c +++ b/Sources/CNIOBoringSSL/crypto/x509/i2d_pr.c @@ -1,4 +1,3 @@ -/* crypto/asn1/i2d_pr.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -66,11 +65,11 @@ 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); + return i2d_RSAPrivateKey(EVP_PKEY_get0_RSA(a), pp); case EVP_PKEY_EC: - return i2d_ECPrivateKey(a->pkey.ec, pp); + return i2d_ECPrivateKey(EVP_PKEY_get0_EC_KEY(a), pp); case EVP_PKEY_DSA: - return i2d_DSAPrivateKey(a->pkey.dsa, pp); + return i2d_DSAPrivateKey(EVP_PKEY_get0_DSA(a), pp); default: // Although this file is in crypto/x509 for layering reasons, it emits // an error code from ASN1 for OpenSSL compatibility. diff --git a/Sources/CNIOBoringSSL/crypto/x509/internal.h b/Sources/CNIOBoringSSL/crypto/x509/internal.h index 6e763c81..98ce26c1 100644 --- a/Sources/CNIOBoringSSL/crypto/x509/internal.h +++ b/Sources/CNIOBoringSSL/crypto/x509/internal.h @@ -72,9 +72,6 @@ extern "C" { // Internal structures. -typedef struct X509_POLICY_CACHE_st X509_POLICY_CACHE; -typedef struct X509_POLICY_TREE_st X509_POLICY_TREE; - typedef struct X509_val_st { ASN1_TIME *notBefore; ASN1_TIME *notAfter; @@ -150,20 +147,17 @@ struct x509_st { CRYPTO_EX_DATA ex_data; // These contain copies of various extension values long ex_pathlen; - long ex_pcpathlen; - unsigned long ex_flags; - unsigned long ex_kusage; - unsigned long ex_xkusage; - unsigned long ex_nscert; + uint32_t ex_flags; + uint32_t ex_kusage; + uint32_t ex_xkusage; + uint32_t ex_nscert; ASN1_OCTET_STRING *skid; AUTHORITY_KEYID *akid; - X509_POLICY_CACHE *policy_cache; STACK_OF(DIST_POINT) *crldp; STACK_OF(GENERAL_NAME) *altname; NAME_CONSTRAINTS *nc; unsigned char cert_hash[SHA256_DIGEST_LENGTH]; X509_CERT_AUX *aux; - CRYPTO_BUFFER *buf; CRYPTO_MUTEX lock; } /* X509 */; @@ -233,7 +227,7 @@ struct X509_crl_st { struct X509_VERIFY_PARAM_st { char *name; - time_t check_time; // Time to use + int64_t check_time; // POSIX time to use unsigned long inh_flags; // Inheritance flags unsigned long flags; // Various verify flags int purpose; // purpose to check untrusted certificates @@ -350,9 +344,6 @@ struct x509_store_ctx_st { int valid; // if 0, rebuild chain int last_untrusted; // index of last untrusted cert STACK_OF(X509) *chain; // chain of X509s - built up and trusted - X509_POLICY_TREE *tree; // Valid policy tree - - int explicit_policy; // Require explicit policy value // When something goes wrong, this is why int error_depth; @@ -369,7 +360,7 @@ struct x509_store_ctx_st { CRYPTO_EX_DATA ex_data; } /* X509_STORE_CTX */; -ASN1_TYPE *ASN1_generate_v3(const char *str, X509V3_CTX *cnf); +ASN1_TYPE *ASN1_generate_v3(const char *str, const X509V3_CTX *cnf); int X509_CERT_AUX_print(BIO *bp, X509_CERT_AUX *x, int indent); @@ -410,6 +401,20 @@ int x509_digest_verify_init(EVP_MD_CTX *ctx, const X509_ALGOR *sigalg, EVP_PKEY *pkey); +// Path-building functions. + +// X509_policy_check checks certificate policies in |certs|. |user_policies| is +// the user-initial-policy-set. If |user_policies| is NULL or empty, it is +// interpreted as anyPolicy. |flags| is a set of |X509_V_FLAG_*| values to +// apply. It returns |X509_V_OK| on success and |X509_V_ERR_*| on error. It +// additionally sets |*out_current_cert| to the certificate where the error +// occurred. If the function succeeded, or the error applies to the entire +// chain, it sets |*out_current_cert| to NULL. +int X509_policy_check(const STACK_OF(X509) *certs, + const STACK_OF(ASN1_OBJECT) *user_policies, + unsigned long flags, X509 **out_current_cert); + + #if defined(__cplusplus) } // extern C #endif diff --git a/Sources/CNIOBoringSSL/crypto/x509/policy.c b/Sources/CNIOBoringSSL/crypto/x509/policy.c new file mode 100644 index 00000000..ba0789ef --- /dev/null +++ b/Sources/CNIOBoringSSL/crypto/x509/policy.c @@ -0,0 +1,790 @@ +/* Copyright (c) 2022, 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 + +#include + +#include +#include +#include +#include + +#include "../internal.h" +#include "../x509v3/internal.h" +#include "internal.h" + + +// This file computes the X.509 policy tree, as described in RFC 5280, section +// 6.1. It differs in that: +// +// (1) It does not track "qualifier_set". This is not needed as it is not +// output by this implementation. +// +// (2) It builds a directed acyclic graph, rather than a tree. When a given +// policy matches multiple parents, RFC 5280 makes a separate node for +// each parent. This representation condenses them into one node with +// multiple parents. Thus we refer to this structure as a "policy graph", +// rather than a "policy tree". +// +// (3) "expected_policy_set" is not tracked explicitly and built temporarily +// as part of building the graph. +// +// (4) anyPolicy nodes are not tracked explicitly. +// +// (5) Some pruning steps are deferred to when policies are evaluated, as a +// reachability pass. + +// An X509_POLICY_NODE is a node in the policy graph. It corresponds to a node +// from RFC 5280, section 6.1.2, step (a), but we store some fields differently. +typedef struct x509_policy_node_st { + // policy is the "valid_policy" field from RFC 5280. + ASN1_OBJECT *policy; + + // parent_policies, if non-empty, is the list of "valid_policy" values for all + // nodes which are a parent of this node. In this case, no entry in this list + // will be anyPolicy. This list is in no particular order and may contain + // duplicates if the corresponding certificate had duplicate mappings. + // + // If empty, this node has a single parent, anyPolicy. The node is then a root + // policies, and is in authorities-constrained-policy-set if it has a path to + // a leaf node. + // + // Note it is not possible for a policy to have both anyPolicy and a + // concrete policy as a parent. Section 6.1.3, step (d.1.ii) only runs if + // there was no match in step (d.1.i). We do not need to represent a parent + // list of, say, {anyPolicy, OID1, OID2}. + STACK_OF(ASN1_OBJECT) *parent_policies; + + // mapped is one if this node matches a policy mapping in the certificate and + // zero otherwise. + int mapped; + + // reachable is one if this node is reachable from some valid policy in the + // end-entity certificate. It is computed during |has_explicit_policy|. + int reachable; +} X509_POLICY_NODE; + +DEFINE_STACK_OF(X509_POLICY_NODE) + +// An X509_POLICY_LEVEL is the collection of nodes at the same depth in the +// policy graph. This structure can also be used to represent a level's +// "expected_policy_set" values. See |process_policy_mappings|. +typedef struct x509_policy_level_st { + // nodes is the list of nodes at this depth, except for the anyPolicy node, if + // any. This list is sorted by policy OID for efficient lookup. + STACK_OF(X509_POLICY_NODE) *nodes; + + // has_any_policy is one if there is an anyPolicy node at this depth, and zero + // otherwise. + int has_any_policy; +} X509_POLICY_LEVEL; + +DEFINE_STACK_OF(X509_POLICY_LEVEL) + +static int is_any_policy(const ASN1_OBJECT *obj) { + return OBJ_obj2nid(obj) == NID_any_policy; +} + +static void x509_policy_node_free(X509_POLICY_NODE *node) { + if (node != NULL) { + ASN1_OBJECT_free(node->policy); + sk_ASN1_OBJECT_pop_free(node->parent_policies, ASN1_OBJECT_free); + OPENSSL_free(node); + } +} + +static X509_POLICY_NODE *x509_policy_node_new(const ASN1_OBJECT *policy) { + assert(!is_any_policy(policy)); + X509_POLICY_NODE *node = OPENSSL_malloc(sizeof(X509_POLICY_NODE)); + if (node == NULL) { + return NULL; + } + OPENSSL_memset(node, 0, sizeof(X509_POLICY_NODE)); + node->policy = OBJ_dup(policy); + node->parent_policies = sk_ASN1_OBJECT_new_null(); + if (node->policy == NULL || node->parent_policies == NULL) { + x509_policy_node_free(node); + return NULL; + } + return node; +} + +static int x509_policy_node_cmp(const X509_POLICY_NODE *const *a, + const X509_POLICY_NODE *const *b) { + return OBJ_cmp((*a)->policy, (*b)->policy); +} + +static void x509_policy_level_free(X509_POLICY_LEVEL *level) { + if (level != NULL) { + sk_X509_POLICY_NODE_pop_free(level->nodes, x509_policy_node_free); + OPENSSL_free(level); + } +} + +static X509_POLICY_LEVEL *x509_policy_level_new(void) { + X509_POLICY_LEVEL *level = OPENSSL_malloc(sizeof(X509_POLICY_LEVEL)); + if (level == NULL) { + return NULL; + } + OPENSSL_memset(level, 0, sizeof(X509_POLICY_LEVEL)); + level->nodes = sk_X509_POLICY_NODE_new(x509_policy_node_cmp); + if (level->nodes == NULL) { + x509_policy_level_free(level); + return NULL; + } + return level; +} + +static int x509_policy_level_is_empty(const X509_POLICY_LEVEL *level) { + return !level->has_any_policy && sk_X509_POLICY_NODE_num(level->nodes) == 0; +} + +static void x509_policy_level_clear(X509_POLICY_LEVEL *level) { + level->has_any_policy = 0; + for (size_t i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++) { + x509_policy_node_free(sk_X509_POLICY_NODE_value(level->nodes, i)); + } + sk_X509_POLICY_NODE_zero(level->nodes); +} + +// x509_policy_level_find returns the node in |level| corresponding to |policy|, +// or NULL if none exists. +static X509_POLICY_NODE *x509_policy_level_find(X509_POLICY_LEVEL *level, + const ASN1_OBJECT *policy) { + assert(sk_X509_POLICY_NODE_is_sorted(level->nodes)); + X509_POLICY_NODE node; + node.policy = (ASN1_OBJECT *)policy; + size_t idx; + if (!sk_X509_POLICY_NODE_find(level->nodes, &idx, &node)) { + return NULL; + } + return sk_X509_POLICY_NODE_value(level->nodes, idx); +} + +// x509_policy_level_add_nodes adds the nodes in |nodes| to |level|. It returns +// one on success and zero on error. No policy in |nodes| may already be present +// in |level|. This function modifies |nodes| to avoid making a copy, but the +// caller is still responsible for releasing |nodes| itself. +// +// This function is used to add nodes to |level| in bulk, and avoid resorting +// |level| after each addition. +static int x509_policy_level_add_nodes(X509_POLICY_LEVEL *level, + STACK_OF(X509_POLICY_NODE) *nodes) { + for (size_t i = 0; i < sk_X509_POLICY_NODE_num(nodes); i++) { + X509_POLICY_NODE *node = sk_X509_POLICY_NODE_value(nodes, i); + if (!sk_X509_POLICY_NODE_push(level->nodes, node)) { + return 0; + } + sk_X509_POLICY_NODE_set(nodes, i, NULL); + } + sk_X509_POLICY_NODE_sort(level->nodes); + +#if !defined(NDEBUG) + // There should be no duplicate nodes. + for (size_t i = 1; i < sk_X509_POLICY_NODE_num(level->nodes); i++) { + assert(OBJ_cmp(sk_X509_POLICY_NODE_value(level->nodes, i - 1)->policy, + sk_X509_POLICY_NODE_value(level->nodes, i)->policy) != 0); + } +#endif + return 1; +} + +static int policyinfo_cmp(const POLICYINFO *const *a, + const POLICYINFO *const *b) { + return OBJ_cmp((*a)->policyid, (*b)->policyid); +} + +static int delete_if_not_in_policies(X509_POLICY_NODE *node, void *data) { + const CERTIFICATEPOLICIES *policies = data; + assert(sk_POLICYINFO_is_sorted(policies)); + POLICYINFO info; + info.policyid = node->policy; + if (sk_POLICYINFO_find(policies, NULL, &info)) { + return 0; + } + x509_policy_node_free(node); + return 1; +} + +// process_certificate_policies updates |level| to incorporate |x509|'s +// certificate policies extension. This implements steps (d) and (e) of RFC +// 5280, section 6.1.3. |level| must contain the previous level's +// "expected_policy_set" information. For all but the top-most level, this is +// the output of |process_policy_mappings|. |any_policy_allowed| specifies +// whether anyPolicy is allowed or inhibited, taking into account the exception +// for self-issued certificates. +static int process_certificate_policies(const X509 *x509, + X509_POLICY_LEVEL *level, + int any_policy_allowed) { + int ret = 0; + int critical; + STACK_OF(X509_POLICY_NODE) *new_nodes = NULL; + CERTIFICATEPOLICIES *policies = + X509_get_ext_d2i(x509, NID_certificate_policies, &critical, NULL); + if (policies == NULL) { + if (critical != -1) { + return 0; // Syntax error in the extension. + } + + // RFC 5280, section 6.1.3, step (e). + x509_policy_level_clear(level); + return 1; + } + + // certificatePolicies may not be empty. See RFC 5280, section 4.2.1.4. + // TODO(https://crbug.com/boringssl/443): Move this check into the parser. + if (sk_POLICYINFO_num(policies) == 0) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_POLICY_EXTENSION); + goto err; + } + + sk_POLICYINFO_set_cmp_func(policies, policyinfo_cmp); + sk_POLICYINFO_sort(policies); + int cert_has_any_policy = 0; + for (size_t i = 0; i < sk_POLICYINFO_num(policies); i++) { + const POLICYINFO *policy = sk_POLICYINFO_value(policies, i); + if (is_any_policy(policy->policyid)) { + cert_has_any_policy = 1; + } + if (i > 0 && OBJ_cmp(sk_POLICYINFO_value(policies, i - 1)->policyid, + policy->policyid) == 0) { + // Per RFC 5280, section 4.2.1.4, |policies| may not have duplicates. + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_POLICY_EXTENSION); + goto err; + } + } + + // This does the same thing as RFC 5280, section 6.1.3, step (d), though in + // a slighty different order. |level| currently contains "expected_policy_set" + // values of the previous level. See |process_policy_mappings| for details. + const int previous_level_has_any_policy = level->has_any_policy; + + // First, we handle steps (d.1.i) and (d.2). The net effect of these two steps + // is to intersect |level| with |policies|, ignoring anyPolicy if it is + // inhibited. + if (!cert_has_any_policy || !any_policy_allowed) { + sk_X509_POLICY_NODE_delete_if(level->nodes, delete_if_not_in_policies, + policies); + level->has_any_policy = 0; + } + + // Step (d.1.ii) may attach new nodes to the previous level's anyPolicy node. + if (previous_level_has_any_policy) { + new_nodes = sk_X509_POLICY_NODE_new_null(); + if (new_nodes == NULL) { + goto err; + } + for (size_t i = 0; i < sk_POLICYINFO_num(policies); i++) { + const POLICYINFO *policy = sk_POLICYINFO_value(policies, i); + // Though we've reordered the steps slightly, |policy| is in |level| if + // and only if it would have been a match in step (d.1.ii). + if (!is_any_policy(policy->policyid) && + x509_policy_level_find(level, policy->policyid) == NULL) { + X509_POLICY_NODE *node = x509_policy_node_new(policy->policyid); + if (node == NULL || // + !sk_X509_POLICY_NODE_push(new_nodes, node)) { + x509_policy_node_free(node); + goto err; + } + } + } + if (!x509_policy_level_add_nodes(level, new_nodes)) { + goto err; + } + } + + ret = 1; + +err: + sk_X509_POLICY_NODE_pop_free(new_nodes, x509_policy_node_free); + CERTIFICATEPOLICIES_free(policies); + return ret; +} + +static int compare_issuer_policy(const POLICY_MAPPING *const *a, + const POLICY_MAPPING *const *b) { + return OBJ_cmp((*a)->issuerDomainPolicy, (*b)->issuerDomainPolicy); +} + +static int compare_subject_policy(const POLICY_MAPPING *const *a, + const POLICY_MAPPING *const *b) { + return OBJ_cmp((*a)->subjectDomainPolicy, (*b)->subjectDomainPolicy); +} + +static int delete_if_mapped(X509_POLICY_NODE *node, void *data) { + const POLICY_MAPPINGS *mappings = data; + // |mappings| must have been sorted by |compare_issuer_policy|. + assert(sk_POLICY_MAPPING_is_sorted(mappings)); + POLICY_MAPPING mapping; + mapping.issuerDomainPolicy = node->policy; + if (!sk_POLICY_MAPPING_find(mappings, /*out_index=*/NULL, &mapping)) { + return 0; + } + x509_policy_node_free(node); + return 1; +} + +// process_policy_mappings processes the policy mappings extension of |cert|, +// whose corresponding graph level is |level|. |mapping_allowed| specifies +// whether policy mapping is inhibited at this point. On success, it returns an +// |X509_POLICY_LEVEL| containing the "expected_policy_set" for |level|. On +// error, it returns NULL. This implements steps (a) and (b) of RFC 5280, +// section 6.1.4. +// +// We represent the "expected_policy_set" as an |X509_POLICY_LEVEL|. +// |has_any_policy| indicates whether there is an anyPolicy node with +// "expected_policy_set" of {anyPolicy}. If a node with policy oid P1 contains +// P2 in its "expected_policy_set", the level will contain a node of policy P2 +// with P1 in |parent_policies|. +// +// This is equivalent to the |X509_POLICY_LEVEL| that would result if the next +// certificats contained anyPolicy. |process_certificate_policies| will filter +// this result down to compute the actual level. +static X509_POLICY_LEVEL *process_policy_mappings(const X509 *cert, + X509_POLICY_LEVEL *level, + int mapping_allowed) { + int ok = 0; + STACK_OF(X509_POLICY_NODE) *new_nodes = NULL; + X509_POLICY_LEVEL *next = NULL; + int critical; + POLICY_MAPPINGS *mappings = + X509_get_ext_d2i(cert, NID_policy_mappings, &critical, NULL); + if (mappings == NULL && critical != -1) { + // Syntax error in the policy mappings extension. + goto err; + } + + if (mappings != NULL) { + // PolicyMappings may not be empty. See RFC 5280, section 4.2.1.5. + // TODO(https://crbug.com/boringssl/443): Move this check into the parser. + if (sk_POLICY_MAPPING_num(mappings) == 0) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_POLICY_EXTENSION); + goto err; + } + + // RFC 5280, section 6.1.4, step (a). + for (size_t i = 0; i < sk_POLICY_MAPPING_num(mappings); i++) { + POLICY_MAPPING *mapping = sk_POLICY_MAPPING_value(mappings, i); + if (is_any_policy(mapping->issuerDomainPolicy) || + is_any_policy(mapping->subjectDomainPolicy)) { + goto err; + } + } + + // Sort to group by issuerDomainPolicy. + sk_POLICY_MAPPING_set_cmp_func(mappings, compare_issuer_policy); + sk_POLICY_MAPPING_sort(mappings); + + if (mapping_allowed) { + // Mark nodes as mapped, and add any nodes to |level| which may be needed + // as part of RFC 5280, section 6.1.4, step (b.1). + new_nodes = sk_X509_POLICY_NODE_new_null(); + if (new_nodes == NULL) { + goto err; + } + const ASN1_OBJECT *last_policy = NULL; + for (size_t i = 0; i < sk_POLICY_MAPPING_num(mappings); i++) { + const POLICY_MAPPING *mapping = sk_POLICY_MAPPING_value(mappings, i); + // There may be multiple mappings with the same |issuerDomainPolicy|. + if (last_policy != NULL && + OBJ_cmp(mapping->issuerDomainPolicy, last_policy) == 0) { + continue; + } + last_policy = mapping->issuerDomainPolicy; + + X509_POLICY_NODE *node = + x509_policy_level_find(level, mapping->issuerDomainPolicy); + if (node == NULL) { + if (!level->has_any_policy) { + continue; + } + node = x509_policy_node_new(mapping->issuerDomainPolicy); + if (node == NULL || // + !sk_X509_POLICY_NODE_push(new_nodes, node)) { + x509_policy_node_free(node); + goto err; + } + } + node->mapped = 1; + } + if (!x509_policy_level_add_nodes(level, new_nodes)) { + goto err; + } + } else { + // RFC 5280, section 6.1.4, step (b.2). If mapping is inhibited, delete + // all mapped nodes. + sk_X509_POLICY_NODE_delete_if(level->nodes, delete_if_mapped, mappings); + sk_POLICY_MAPPING_pop_free(mappings, POLICY_MAPPING_free); + mappings = NULL; + } + } + + // If a node was not mapped, it retains the original "explicit_policy_set" + // value, itself. Add those to |mappings|. + if (mappings == NULL) { + mappings = sk_POLICY_MAPPING_new_null(); + if (mappings == NULL) { + goto err; + } + } + for (size_t i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++) { + X509_POLICY_NODE *node = sk_X509_POLICY_NODE_value(level->nodes, i); + if (!node->mapped) { + POLICY_MAPPING *mapping = POLICY_MAPPING_new(); + if (mapping == NULL) { + goto err; + } + mapping->issuerDomainPolicy = OBJ_dup(node->policy); + mapping->subjectDomainPolicy = OBJ_dup(node->policy); + if (mapping->issuerDomainPolicy == NULL || + mapping->subjectDomainPolicy == NULL || + !sk_POLICY_MAPPING_push(mappings, mapping)) { + POLICY_MAPPING_free(mapping); + goto err; + } + } + } + + // Sort to group by subjectDomainPolicy. + sk_POLICY_MAPPING_set_cmp_func(mappings, compare_subject_policy); + sk_POLICY_MAPPING_sort(mappings); + + // Convert |mappings| to our "expected_policy_set" representation. + next = x509_policy_level_new(); + if (next == NULL) { + goto err; + } + next->has_any_policy = level->has_any_policy; + + X509_POLICY_NODE *last_node = NULL; + for (size_t i = 0; i < sk_POLICY_MAPPING_num(mappings); i++) { + POLICY_MAPPING *mapping = sk_POLICY_MAPPING_value(mappings, i); + // Skip mappings where |issuerDomainPolicy| does not appear in the graph. + if (!level->has_any_policy && + x509_policy_level_find(level, mapping->issuerDomainPolicy) == NULL) { + continue; + } + + if (last_node == NULL || + OBJ_cmp(last_node->policy, mapping->subjectDomainPolicy) != 0) { + last_node = x509_policy_node_new(mapping->subjectDomainPolicy); + if (last_node == NULL || + !sk_X509_POLICY_NODE_push(next->nodes, last_node)) { + x509_policy_node_free(last_node); + goto err; + } + } + + if (!sk_ASN1_OBJECT_push(last_node->parent_policies, + mapping->issuerDomainPolicy)) { + goto err; + } + mapping->issuerDomainPolicy = NULL; + } + + sk_X509_POLICY_NODE_sort(next->nodes); + ok = 1; + +err: + if (!ok) { + x509_policy_level_free(next); + next = NULL; + } + + sk_POLICY_MAPPING_pop_free(mappings, POLICY_MAPPING_free); + sk_X509_POLICY_NODE_pop_free(new_nodes, x509_policy_node_free); + return next; +} + +// apply_skip_certs, if |skip_certs| is non-NULL, sets |*value| to the minimum +// of its current value and |skip_certs|. It returns one on success and zero if +// |skip_certs| is negative. +static int apply_skip_certs(const ASN1_INTEGER *skip_certs, size_t *value) { + if (skip_certs == NULL) { + return 1; + } + + // TODO(https://crbug.com/boringssl/443): Move this check into the parser. + if (skip_certs->type & V_ASN1_NEG) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_POLICY_EXTENSION); + return 0; + } + + // If |skip_certs| does not fit in |uint64_t|, it must exceed |*value|. + uint64_t u64; + if (ASN1_INTEGER_get_uint64(&u64, skip_certs) && u64 < *value) { + *value = (size_t)u64; + } + ERR_clear_error(); + return 1; +} + +// process_policy_constraints updates |*explicit_policy|, |*policy_mapping|, and +// |*inhibit_any_policy| according to |x509|'s policy constraints and inhibit +// anyPolicy extensions. It returns one on success and zero on error. This +// implements steps (i) and (j) of RFC 5280, section 6.1.4. +static int process_policy_constraints(const X509 *x509, size_t *explicit_policy, + size_t *policy_mapping, + size_t *inhibit_any_policy) { + int critical; + POLICY_CONSTRAINTS *constraints = + X509_get_ext_d2i(x509, NID_policy_constraints, &critical, NULL); + if (constraints == NULL && critical != -1) { + return 0; + } + if (constraints != NULL) { + if (constraints->requireExplicitPolicy == NULL && + constraints->inhibitPolicyMapping == NULL) { + // Per RFC 5280, section 4.2.1.11, at least one of the fields must be + // present. + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_POLICY_EXTENSION); + POLICY_CONSTRAINTS_free(constraints); + return 0; + } + int ok = + apply_skip_certs(constraints->requireExplicitPolicy, explicit_policy) && + apply_skip_certs(constraints->inhibitPolicyMapping, policy_mapping); + POLICY_CONSTRAINTS_free(constraints); + if (!ok) { + return 0; + } + } + + ASN1_INTEGER *inhibit_any_policy_ext = + X509_get_ext_d2i(x509, NID_inhibit_any_policy, &critical, NULL); + if (inhibit_any_policy_ext == NULL && critical != -1) { + return 0; + } + int ok = apply_skip_certs(inhibit_any_policy_ext, inhibit_any_policy); + ASN1_INTEGER_free(inhibit_any_policy_ext); + return ok; +} + +// has_explicit_policy returns one if the set of authority-space policy OIDs +// |levels| has some non-empty intersection with |user_policies|, and zero +// otherwise. This mirrors the logic in RFC 5280, section 6.1.5, step (g). This +// function modifies |levels| and should only be called at the end of policy +// evaluation. +static int has_explicit_policy(STACK_OF(X509_POLICY_LEVEL) *levels, + const STACK_OF(ASN1_OBJECT) *user_policies) { + assert(user_policies == NULL || sk_ASN1_OBJECT_is_sorted(user_policies)); + + // Step (g.i). If the policy graph is empty, the intersection is empty. + size_t num_levels = sk_X509_POLICY_LEVEL_num(levels); + X509_POLICY_LEVEL *level = sk_X509_POLICY_LEVEL_value(levels, num_levels - 1); + if (x509_policy_level_is_empty(level)) { + return 0; + } + + // If |user_policies| is empty, we interpret it as having a single anyPolicy + // value. The caller may also have supplied anyPolicy explicitly. + int user_has_any_policy = sk_ASN1_OBJECT_num(user_policies) == 0; + for (size_t i = 0; i < sk_ASN1_OBJECT_num(user_policies); i++) { + if (is_any_policy(sk_ASN1_OBJECT_value(user_policies, i))) { + user_has_any_policy = 1; + break; + } + } + + // Step (g.ii). If the policy graph is not empty and the user set contains + // anyPolicy, the intersection is the entire (non-empty) graph. + if (user_has_any_policy) { + return 1; + } + + // Step (g.iii) does not delete anyPolicy nodes, so if the graph has + // anyPolicy, some explicit policy will survive. The actual intersection may + // synthesize some nodes in step (g.iii.3), but we do not return the policy + // list itself, so we skip actually computing this. + if (level->has_any_policy) { + return 1; + } + + // We defer pruning the tree, so as we look for nodes with parent anyPolicy, + // step (g.iii.1), we must limit to nodes reachable from the bottommost level. + // Start by marking each of those nodes as reachable. + for (size_t i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++) { + sk_X509_POLICY_NODE_value(level->nodes, i)->reachable = 1; + } + + for (size_t i = num_levels - 1; i < num_levels; i--) { + level = sk_X509_POLICY_LEVEL_value(levels, i); + for (size_t j = 0; j < sk_X509_POLICY_NODE_num(level->nodes); j++) { + X509_POLICY_NODE *node = sk_X509_POLICY_NODE_value(level->nodes, j); + if (!node->reachable) { + continue; + } + if (sk_ASN1_OBJECT_num(node->parent_policies) == 0) { + // |node|'s parent is anyPolicy and is part of "valid_policy_node_set". + // If it exists in |user_policies|, the intersection is non-empty and we + // can return immediately. + if (sk_ASN1_OBJECT_find(user_policies, /*out_index=*/NULL, + node->policy)) { + return 1; + } + } else if (i > 0) { + // |node|'s parents are concrete policies. Mark the parents reachable, + // to be inspected by the next loop iteration. + X509_POLICY_LEVEL *prev = sk_X509_POLICY_LEVEL_value(levels, i - 1); + for (size_t k = 0; k < sk_ASN1_OBJECT_num(node->parent_policies); k++) { + X509_POLICY_NODE *parent = x509_policy_level_find( + prev, sk_ASN1_OBJECT_value(node->parent_policies, k)); + if (parent != NULL) { + parent->reachable = 1; + } + } + } + } + } + + return 0; +} + +static int asn1_object_cmp(const ASN1_OBJECT *const *a, + const ASN1_OBJECT *const *b) { + return OBJ_cmp(*a, *b); +} + +int X509_policy_check(const STACK_OF(X509) *certs, + const STACK_OF(ASN1_OBJECT) *user_policies, + unsigned long flags, X509 **out_current_cert) { + *out_current_cert = NULL; + int ret = X509_V_ERR_OUT_OF_MEM; + X509_POLICY_LEVEL *level = NULL; + STACK_OF(X509_POLICY_LEVEL) *levels = NULL; + STACK_OF(ASN1_OBJECT) *user_policies_sorted = NULL; + size_t num_certs = sk_X509_num(certs); + + // Skip policy checking if the chain is just the trust anchor. + if (num_certs <= 1) { + return X509_V_OK; + } + + // See RFC 5280, section 6.1.2, steps (d) through (f). + size_t explicit_policy = + (flags & X509_V_FLAG_EXPLICIT_POLICY) ? 0 : num_certs + 1; + size_t inhibit_any_policy = + (flags & X509_V_FLAG_INHIBIT_ANY) ? 0 : num_certs + 1; + size_t policy_mapping = + (flags & X509_V_FLAG_INHIBIT_MAP) ? 0 : num_certs + 1; + + levels = sk_X509_POLICY_LEVEL_new_null(); + if (levels == NULL) { + goto err; + } + + for (size_t i = num_certs - 2; i < num_certs; i--) { + X509 *cert = sk_X509_value(certs, i); + if (!x509v3_cache_extensions(cert)) { + goto err; + } + const int is_self_issued = (cert->ex_flags & EXFLAG_SI) != 0; + + if (level == NULL) { + assert(i == num_certs - 2); + level = x509_policy_level_new(); + if (level == NULL) { + goto err; + } + level->has_any_policy = 1; + } + + // RFC 5280, section 6.1.3, steps (d) and (e). |any_policy_allowed| is + // computed as in step (d.2). + const int any_policy_allowed = + inhibit_any_policy > 0 || (i > 0 && is_self_issued); + if (!process_certificate_policies(cert, level, any_policy_allowed)) { + ret = X509_V_ERR_INVALID_POLICY_EXTENSION; + *out_current_cert = cert; + goto err; + } + + // RFC 5280, section 6.1.3, step (f). + if (explicit_policy == 0 && x509_policy_level_is_empty(level)) { + ret = X509_V_ERR_NO_EXPLICIT_POLICY; + goto err; + } + + // Insert into the list. + if (!sk_X509_POLICY_LEVEL_push(levels, level)) { + goto err; + } + X509_POLICY_LEVEL *current_level = level; + level = NULL; + + // If this is not the leaf certificate, we go to section 6.1.4. If it + // is the leaf certificate, we go to section 6.1.5 instead. + if (i != 0) { + // RFC 5280, section 6.1.4, steps (a) and (b). + level = process_policy_mappings(cert, current_level, policy_mapping > 0); + if (level == NULL) { + ret = X509_V_ERR_INVALID_POLICY_EXTENSION; + *out_current_cert = cert; + goto err; + } + } + + // RFC 5280, section 6.1.4, step (h-j) for non-leaves, and section 6.1.5, + // step (a-b) for leaves. In the leaf case, RFC 5280 says only to update + // |explicit_policy|, but |policy_mapping| and |inhibit_any_policy| are no + // longer read at this point, so we use the same process. + if (i == 0 || !is_self_issued) { + if (explicit_policy > 0) { + explicit_policy--; + } + if (policy_mapping > 0) { + policy_mapping--; + } + if (inhibit_any_policy > 0) { + inhibit_any_policy--; + } + } + if (!process_policy_constraints(cert, &explicit_policy, &policy_mapping, + &inhibit_any_policy)) { + ret = X509_V_ERR_INVALID_POLICY_EXTENSION; + *out_current_cert = cert; + goto err; + } + } + + // RFC 5280, section 6.1.5, step (g). We do not output the policy set, so it + // is only necessary to check if the user-constrained-policy-set is not empty. + if (explicit_policy == 0) { + // Build a sorted copy of |user_policies| for more efficient lookup. + if (user_policies != NULL) { + user_policies_sorted = sk_ASN1_OBJECT_dup(user_policies); + if (user_policies_sorted == NULL) { + goto err; + } + sk_ASN1_OBJECT_set_cmp_func(user_policies_sorted, asn1_object_cmp); + sk_ASN1_OBJECT_sort(user_policies_sorted); + } + + if (!has_explicit_policy(levels, user_policies_sorted)) { + ret = X509_V_ERR_NO_EXPLICIT_POLICY; + goto err; + } + } + + ret = X509_V_OK; + +err: + x509_policy_level_free(level); + // |user_policies_sorted|'s contents are owned by |user_policies|, so we do + // not use |sk_ASN1_OBJECT_pop_free|. + sk_ASN1_OBJECT_free(user_policies_sorted); + sk_X509_POLICY_LEVEL_pop_free(levels, x509_policy_level_free); + return ret; +} diff --git a/Sources/CNIOBoringSSL/crypto/x509/rsa_pss.c b/Sources/CNIOBoringSSL/crypto/x509/rsa_pss.c index 7f60ef26..3aed6858 100644 --- a/Sources/CNIOBoringSSL/crypto/x509/rsa_pss.c +++ b/Sources/CNIOBoringSSL/crypto/x509/rsa_pss.c @@ -202,7 +202,7 @@ int x509_rsa_ctx_to_pss(EVP_MD_CTX *ctx, X509_ALGOR *algor) { OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); return 0; } - int md_len = EVP_MD_size(sigmd); + int md_len = (int)EVP_MD_size(sigmd); if (saltlen == -1) { saltlen = md_len; } else if (saltlen != md_len) { diff --git a/Sources/CNIOBoringSSL/crypto/x509/x509_att.c b/Sources/CNIOBoringSSL/crypto/x509/x509_att.c index bbe51300..94dc7e87 100644 --- a/Sources/CNIOBoringSSL/crypto/x509/x509_att.c +++ b/Sources/CNIOBoringSSL/crypto/x509/x509_att.c @@ -1,4 +1,3 @@ -/* crypto/x509/x509_att.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -126,7 +125,7 @@ STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x, if (x == NULL) { OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER); - goto err2; + goto err; } if (*x == NULL) { @@ -138,7 +137,7 @@ STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x, } if ((new_attr = X509_ATTRIBUTE_dup(attr)) == NULL) { - goto err2; + goto err; } if (!sk_X509_ATTRIBUTE_push(sk, new_attr)) { goto err; @@ -148,8 +147,6 @@ STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x, } return sk; err: - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); -err2: if (new_attr != NULL) { X509_ATTRIBUTE_free(new_attr); } @@ -227,7 +224,6 @@ X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr, if ((attr == NULL) || (*attr == NULL)) { if ((ret = X509_ATTRIBUTE_new()) == NULL) { - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); return NULL; } } else { @@ -327,7 +323,6 @@ int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, } return 1; err: - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); ASN1_TYPE_free(ttmp); ASN1_STRING_free(stmp); return 0; diff --git a/Sources/CNIOBoringSSL/crypto/x509/x509_cmp.c b/Sources/CNIOBoringSSL/crypto/x509/x509_cmp.c index 4aee68f1..f0157254 100644 --- a/Sources/CNIOBoringSSL/crypto/x509/x509_cmp.c +++ b/Sources/CNIOBoringSSL/crypto/x509/x509_cmp.c @@ -1,4 +1,3 @@ -/* crypto/x509/x509_cmp.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -285,10 +284,11 @@ int X509_check_private_key(X509 *x, const EVP_PKEY *k) { // 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++) { + STACK_OF(X509) *ret = sk_X509_dup(chain); + if (ret == NULL) { + return NULL; + } + for (size_t i = 0; i < sk_X509_num(ret); i++) { X509_up_ref(sk_X509_value(ret, i)); } return ret; diff --git a/Sources/CNIOBoringSSL/crypto/x509/x509_d2.c b/Sources/CNIOBoringSSL/crypto/x509/x509_d2.c index 4dbf7519..768759e7 100644 --- a/Sources/CNIOBoringSSL/crypto/x509/x509_d2.c +++ b/Sources/CNIOBoringSSL/crypto/x509/x509_d2.c @@ -1,4 +1,3 @@ -/* crypto/x509/x509_d2.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * diff --git a/Sources/CNIOBoringSSL/crypto/x509/x509_def.c b/Sources/CNIOBoringSSL/crypto/x509/x509_def.c index a427ac8c..31f62709 100644 --- a/Sources/CNIOBoringSSL/crypto/x509/x509_def.c +++ b/Sources/CNIOBoringSSL/crypto/x509/x509_def.c @@ -1,4 +1,3 @@ -/* crypto/x509/x509_def.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * diff --git a/Sources/CNIOBoringSSL/crypto/x509/x509_ext.c b/Sources/CNIOBoringSSL/crypto/x509/x509_ext.c index 16c7ca5e..88e0c711 100644 --- a/Sources/CNIOBoringSSL/crypto/x509/x509_ext.c +++ b/Sources/CNIOBoringSSL/crypto/x509/x509_ext.c @@ -1,4 +1,3 @@ -/* crypto/x509/x509_ext.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * diff --git a/Sources/CNIOBoringSSL/crypto/x509/x509_lu.c b/Sources/CNIOBoringSSL/crypto/x509/x509_lu.c index 00368e4a..a827987c 100644 --- a/Sources/CNIOBoringSSL/crypto/x509/x509_lu.c +++ b/Sources/CNIOBoringSSL/crypto/x509/x509_lu.c @@ -1,4 +1,3 @@ -/* crypto/x509/x509_lu.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -141,25 +140,25 @@ int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name, return ctx->method->get_by_subject(ctx, type, name, ret) > 0; } -static int x509_object_cmp(const X509_OBJECT **a, const X509_OBJECT **b) { - int ret; - - ret = ((*a)->type - (*b)->type); +static int x509_object_cmp(const X509_OBJECT *a, const X509_OBJECT *b) { + int ret = a->type - b->type; if (ret) { return ret; } - switch ((*a)->type) { + switch (a->type) { case X509_LU_X509: - ret = X509_subject_name_cmp((*a)->data.x509, (*b)->data.x509); - break; + return X509_subject_name_cmp(a->data.x509, b->data.x509); case X509_LU_CRL: - ret = X509_CRL_cmp((*a)->data.crl, (*b)->data.crl); - break; + return X509_CRL_cmp(a->data.crl, b->data.crl); default: // abort(); return 0; } - return ret; +} + +static int x509_object_cmp_sk(const X509_OBJECT *const *a, + const X509_OBJECT *const *b) { + return x509_object_cmp(*a, *b); } X509_STORE *X509_STORE_new(void) { @@ -170,7 +169,7 @@ X509_STORE *X509_STORE_new(void) { } OPENSSL_memset(ret, 0, sizeof(*ret)); CRYPTO_MUTEX_init(&ret->objs_lock); - ret->objs = sk_X509_OBJECT_new(x509_object_cmp); + ret->objs = sk_X509_OBJECT_new(x509_object_cmp_sk); if (ret->objs == NULL) { goto err; } @@ -321,7 +320,6 @@ static int x509_store_add(X509_STORE *ctx, void *x, int is_crl) { X509_OBJECT *const obj = (X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT)); if (obj == NULL) { - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); return 0; } @@ -426,12 +424,10 @@ static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type, 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)) { + const X509_OBJECT *tobj = sk_X509_OBJECT_value(h, tidx); + if (x509_object_cmp(tobj, &stmp)) { break; } (*pnmatch)++; @@ -544,19 +540,17 @@ STACK_OF(X509_CRL) *X509_STORE_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm) { X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x) { - size_t idx, i; - X509_OBJECT *obj; - sk_X509_OBJECT_sort(h); + size_t idx; 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)) { + for (size_t i = idx; i < sk_X509_OBJECT_num(h); i++) { + X509_OBJECT *obj = sk_X509_OBJECT_value(h, i); + if (x509_object_cmp(obj, x)) { return NULL; } if (x->type == X509_LU_X509) { diff --git a/Sources/CNIOBoringSSL/crypto/x509/x509_obj.c b/Sources/CNIOBoringSSL/crypto/x509/x509_obj.c index 87f60452..2b8f103b 100644 --- a/Sources/CNIOBoringSSL/crypto/x509/x509_obj.c +++ b/Sources/CNIOBoringSSL/crypto/x509/x509_obj.c @@ -1,4 +1,3 @@ -/* crypto/x509/x509_obj.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -120,7 +119,7 @@ char *X509_NAME_oneline(const X509_NAME *a, char *buf, int len) { num = ne->value->length; if (num > NAME_ONELINE_MAX) { OPENSSL_PUT_ERROR(X509, X509_R_NAME_TOO_LONG); - goto end; + goto err; } q = ne->value->data; @@ -156,7 +155,7 @@ char *X509_NAME_oneline(const X509_NAME *a, char *buf, int len) { l += 1 + l1 + 1 + l2; if (l > NAME_ONELINE_MAX) { OPENSSL_PUT_ERROR(X509, X509_R_NAME_TOO_LONG); - goto end; + goto err; } if (b != NULL) { if (!BUF_MEM_grow(b, l + 1)) { @@ -202,8 +201,6 @@ char *X509_NAME_oneline(const X509_NAME *a, char *buf, int len) { } return p; err: - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); -end: BUF_MEM_free(b); return NULL; } diff --git a/Sources/CNIOBoringSSL/crypto/x509/x509_req.c b/Sources/CNIOBoringSSL/crypto/x509/x509_req.c index 7b07b29f..8c18dfe0 100644 --- a/Sources/CNIOBoringSSL/crypto/x509/x509_req.c +++ b/Sources/CNIOBoringSSL/crypto/x509/x509_req.c @@ -1,4 +1,3 @@ -/* crypto/x509/x509_req.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -65,6 +64,7 @@ #include #include +#include "../asn1/internal.h" #include "internal.h" @@ -99,15 +99,10 @@ int X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k) { OPENSSL_PUT_ERROR(X509, X509_R_KEY_TYPE_MISMATCH); break; case -2: - if (k->type == EVP_PKEY_EC) { + if (EVP_PKEY_id(k) == 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); } @@ -238,6 +233,6 @@ int X509_REQ_get_signature_nid(const X509_REQ *req) { } int i2d_re_X509_REQ_tbs(X509_REQ *req, unsigned char **pp) { - req->req_info->enc.modified = 1; + asn1_encoding_clear(&req->req_info->enc); return i2d_X509_REQ_INFO(req->req_info, pp); } diff --git a/Sources/CNIOBoringSSL/crypto/x509/x509_trs.c b/Sources/CNIOBoringSSL/crypto/x509/x509_trs.c index d12e5300..a840934b 100644 --- a/Sources/CNIOBoringSSL/crypto/x509/x509_trs.c +++ b/Sources/CNIOBoringSSL/crypto/x509/x509_trs.c @@ -63,7 +63,7 @@ #include "internal.h" -static int tr_cmp(const X509_TRUST **a, const X509_TRUST **b); +static int tr_cmp(const X509_TRUST *const *a, const X509_TRUST *const *b); static void trtable_free(X509_TRUST *p); static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags); @@ -97,7 +97,7 @@ static X509_TRUST trstandard[] = { 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 *const *a, const X509_TRUST *const *b) { return (*a)->trust - (*b)->trust; } @@ -152,7 +152,6 @@ int X509_TRUST_get_by_id(int id) { if (!trtable) { return -1; } - sk_X509_TRUST_sort(trtable); if (!sk_X509_TRUST_find(trtable, &idx, &tmp)) { return -1; } @@ -183,7 +182,6 @@ int X509_TRUST_add(int id, int flags, int (*ck)(X509_TRUST *, X509 *, int), // Need a new entry if (idx == -1) { if (!(trtmp = OPENSSL_malloc(sizeof(X509_TRUST)))) { - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); return 0; } trtmp->flags = X509_TRUST_DYNAMIC; @@ -194,7 +192,6 @@ int X509_TRUST_add(int id, int flags, int (*ck)(X509_TRUST *, X509 *, int), // Duplicate the supplied name. name_dup = OPENSSL_strdup(name); if (name_dup == NULL) { - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); if (idx == -1) { OPENSSL_free(trtmp); } @@ -218,16 +215,19 @@ int X509_TRUST_add(int id, int flags, int (*ck)(X509_TRUST *, X509 *, int), // If its a new entry manage the dynamic table if (idx == -1) { + // TODO(davidben): This should be locked. Alternatively, remove the dynamic + // registration mechanism entirely. The trouble is there no way to pass in + // the various parameters into an |X509_VERIFY_PARAM| directly. You can only + // register it in the global table and get an ID. 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; } + sk_X509_TRUST_sort(trtable); } return 1; } diff --git a/Sources/CNIOBoringSSL/crypto/x509/x509_v3.c b/Sources/CNIOBoringSSL/crypto/x509/x509_v3.c index 72b96b0f..b2bdb80d 100644 --- a/Sources/CNIOBoringSSL/crypto/x509/x509_v3.c +++ b/Sources/CNIOBoringSSL/crypto/x509/x509_v3.c @@ -148,6 +148,7 @@ STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x, X509_EXTENSION *new_ex = NULL; int n; STACK_OF(X509_EXTENSION) *sk = NULL; + int free_sk = 0; if (x == NULL) { OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER); @@ -158,6 +159,7 @@ STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x, if ((sk = sk_X509_EXTENSION_new_null()) == NULL) { goto err; } + free_sk = 1; } else { sk = *x; } @@ -180,10 +182,11 @@ STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x, } return sk; err: - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); err2: X509_EXTENSION_free(new_ex); - sk_X509_EXTENSION_free(sk); + if (free_sk) { + sk_X509_EXTENSION_free(sk); + } return NULL; } @@ -209,7 +212,6 @@ X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex, if ((ex == NULL) || (*ex == NULL)) { if ((ret = X509_EXTENSION_new()) == NULL) { - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); return NULL; } } else { @@ -250,7 +252,9 @@ int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit) { if (ex == NULL) { return 0; } - ex->critical = (crit) ? 0xFF : -1; + // The critical field is DEFAULT FALSE, so non-critical extensions should omit + // the value. + ex->critical = crit ? ASN1_BOOLEAN_TRUE : ASN1_BOOLEAN_NONE; return 1; } diff --git a/Sources/CNIOBoringSSL/crypto/x509/x509_vfy.c b/Sources/CNIOBoringSSL/crypto/x509/x509_vfy.c index 00f22e69..70c0a84f 100644 --- a/Sources/CNIOBoringSSL/crypto/x509/x509_vfy.c +++ b/Sources/CNIOBoringSSL/crypto/x509/x509_vfy.c @@ -205,7 +205,6 @@ int X509_verify_cert(X509_STORE_CTX *ctx) { // 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); ctx->error = X509_V_ERR_OUT_OF_MEM; goto end; } @@ -214,7 +213,6 @@ int X509_verify_cert(X509_STORE_CTX *ctx) { // 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); ctx->error = X509_V_ERR_OUT_OF_MEM; goto end; } @@ -262,7 +260,6 @@ int X509_verify_cert(X509_STORE_CTX *ctx) { xtmp = find_issuer(ctx, sktmp, x); if (xtmp != NULL) { if (!sk_X509_push(ctx->chain, xtmp)) { - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); ctx->error = X509_V_ERR_OUT_OF_MEM; ok = 0; goto end; @@ -358,7 +355,6 @@ int X509_verify_cert(X509_STORE_CTX *ctx) { x = xtmp; if (!sk_X509_push(ctx->chain, x)) { X509_free(xtmp); - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); ctx->error = X509_V_ERR_OUT_OF_MEM; ok = 0; goto end; @@ -451,7 +447,6 @@ int X509_verify_cert(X509_STORE_CTX *ctx) { // 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; @@ -468,14 +463,13 @@ int X509_verify_cert(X509_STORE_CTX *ctx) { } // Check name constraints - ok = check_name_constraints(ctx); if (!ok) { goto end; } - // If we get this far evaluate policies - if (!bad_chain && (ctx->param->flags & X509_V_FLAG_POLICY_CHECK)) { + // If we get this far, evaluate policies. + if (!bad_chain) { ok = ctx->check_policy(ctx); } @@ -543,35 +537,15 @@ static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) { // purpose static int check_chain_extensions(X509_STORE_CTX *ctx) { - int i, ok = 0, plen = 0; - X509 *x; - int proxy_path_length = 0; - int purpose; - int allow_proxy_certs; - - enum { - // ca_or_leaf allows either type of certificate so that direct use of - // self-signed certificates works. - ca_or_leaf, - must_be_ca, - must_not_be_ca, - } ca_requirement; - - // 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); - purpose = ctx->param->purpose; - } + int ok = 0, plen = 0; - ca_requirement = ca_or_leaf; + // If |ctx->parent| is set, this is CRL path validation. + int purpose = + ctx->parent == NULL ? ctx->param->purpose : X509_PURPOSE_CRL_SIGN; // Check all untrusted certificates - for (i = 0; i < ctx->last_untrusted; i++) { - int ret; - x = sk_X509_value(ctx->chain, i); + for (int i = 0; i < ctx->last_untrusted; i++) { + X509 *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; @@ -582,8 +556,10 @@ static int check_chain_extensions(X509_STORE_CTX *ctx) { goto end; } } - if (!allow_proxy_certs && (x->ex_flags & EXFLAG_PROXY)) { - ctx->error = X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED; + + int must_be_ca = i > 0; + if (must_be_ca && !X509_check_ca(x)) { + ctx->error = X509_V_ERR_INVALID_CA; ctx->error_depth = i; ctx->current_cert = x; ok = ctx->verify_cb(0, ctx); @@ -591,33 +567,9 @@ static int check_chain_extensions(X509_STORE_CTX *ctx) { goto end; } } - - switch (ca_requirement) { - case ca_or_leaf: - ret = 1; - break; - case must_not_be_ca: - if (X509_check_ca(x)) { - ret = 0; - ctx->error = X509_V_ERR_INVALID_NON_CA; - } else { - ret = 1; - } - break; - case must_be_ca: - if (!X509_check_ca(x)) { - ret = 0; - ctx->error = X509_V_ERR_INVALID_CA; - } else { - ret = 1; - } - break; - default: - // impossible. - ret = 0; - } - - if (ret == 0) { + if (ctx->param->purpose > 0 && + X509_check_purpose(x, purpose, must_be_ca) != 1) { + ctx->error = X509_V_ERR_INVALID_PURPOSE; ctx->error_depth = i; ctx->current_cert = x; ok = ctx->verify_cb(0, ctx); @@ -625,22 +577,9 @@ static int check_chain_extensions(X509_STORE_CTX *ctx) { goto end; } } - if (ctx->param->purpose > 0) { - ret = X509_check_purpose(x, purpose, ca_requirement == must_be_ca); - if (ret != 1) { - ret = 0; - ctx->error = X509_V_ERR_INVALID_PURPOSE; - ctx->error_depth = i; - ctx->current_cert = x; - ok = ctx->verify_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))) { + if (i > 1 && !(x->ex_flags & EXFLAG_SI) && x->ex_pathlen != -1 && + plen > x->ex_pathlen + 1) { ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED; ctx->error_depth = i; ctx->current_cert = x; @@ -653,24 +592,6 @@ static int check_chain_extensions(X509_STORE_CTX *ctx) { 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 = ctx->verify_cb(0, ctx); - if (!ok) { - goto end; - } - } - proxy_path_length++; - ca_requirement = must_not_be_ca; - } else { - ca_requirement = must_be_ca; - } } ok = 1; end: @@ -978,14 +899,14 @@ static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify) { if (notify) { ctx->current_crl = crl; } - time_t *ptime; + int64_t ptime; if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) { - ptime = &ctx->param->check_time; + ptime = ctx->param->check_time; } else { - ptime = NULL; + ptime = time(NULL); } - int i = X509_cmp_time(X509_CRL_get0_lastUpdate(crl), ptime); + int i = X509_cmp_time_posix(X509_CRL_get0_lastUpdate(crl), ptime); if (i == 0) { if (!notify) { return 0; @@ -1007,7 +928,7 @@ static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify) { } if (X509_CRL_get0_nextUpdate(crl)) { - i = X509_cmp_time(X509_CRL_get0_nextUpdate(crl), ptime); + i = X509_cmp_time_posix(X509_CRL_get0_nextUpdate(crl), ptime); if (i == 0) { if (!notify) { @@ -1689,41 +1610,20 @@ static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x) { } static int check_policy(X509_STORE_CTX *ctx) { - int ret; + // TODO(davidben): Why do we disable policy validation for CRL paths? if (ctx->parent) { return 1; } - // TODO(davidben): Historically, outputs of the |X509_policy_check| were saved - // on |ctx| and accessible via the public API. This has since been removed, so - // remove the fields from |X509_STORE_CTX|. - 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); - ctx->error = X509_V_ERR_OUT_OF_MEM; - 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; - } + + X509 *current_cert = NULL; + int ret = X509_policy_check(ctx->chain, ctx->param->policies, + ctx->param->flags, ¤t_cert); + if (ret != X509_V_OK) { + ctx->current_cert = current_cert; + ctx->error = ret; + if (ret == X509_V_ERR_OUT_OF_MEM) { + 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); } @@ -1746,14 +1646,14 @@ static int check_cert_time(X509_STORE_CTX *ctx, X509 *x) { return 1; } - time_t *ptime; + int64_t ptime; if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) { - ptime = &ctx->param->check_time; + ptime = ctx->param->check_time; } else { - ptime = NULL; + ptime = time(NULL); } - int i = X509_cmp_time(X509_get_notBefore(x), ptime); + int i = X509_cmp_time_posix(X509_get_notBefore(x), ptime); if (i == 0) { ctx->error = X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD; ctx->current_cert = x; @@ -1770,7 +1670,7 @@ static int check_cert_time(X509_STORE_CTX *ctx, X509 *x) { } } - i = X509_cmp_time(X509_get_notAfter(x), ptime); + i = X509_cmp_time_posix(X509_get_notAfter(x), ptime); if (i == 0) { ctx->error = X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD; ctx->current_cert = x; @@ -1873,17 +1773,21 @@ static int internal_verify(X509_STORE_CTX *ctx) { } int X509_cmp_current_time(const ASN1_TIME *ctm) { - return X509_cmp_time(ctm, NULL); + return X509_cmp_time_posix(ctm, time(NULL)); } int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time) { + int64_t compare_time = (cmp_time == NULL) ? time(NULL) : *cmp_time; + return X509_cmp_time_posix(ctm, compare_time); +} + +int X509_cmp_time_posix(const ASN1_TIME *ctm, int64_t cmp_time) { int64_t ctm_time; if (!ASN1_TIME_to_posix(ctm, &ctm_time)) { return 0; } - int64_t compare_time = (cmp_time == NULL) ? time(NULL) : *cmp_time; // The return value 0 is reserved for errors. - return (ctm_time - compare_time <= 0) ? -1 : 1; + return (ctm_time - cmp_time <= 0) ? -1 : 1; } ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long offset_sec) { @@ -1896,12 +1800,12 @@ ASN1_TIME *X509_time_adj(ASN1_TIME *s, long offset_sec, time_t *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; + int64_t t = 0; if (in_tm) { t = *in_tm; } else { - time(&t); + t = time(NULL); } return ASN1_TIME_adj(s, t, offset_day, offset_sec); @@ -2012,7 +1916,6 @@ X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer, EVP_PKEY *skey, return crl; memerr: - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); if (crl) { X509_CRL_free(crl); } @@ -2163,7 +2066,6 @@ 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; } X509_STORE_CTX_zero(ctx); @@ -2283,7 +2185,6 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, } OPENSSL_memset(ctx, 0, sizeof(X509_STORE_CTX)); - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); return 0; } @@ -2313,10 +2214,6 @@ void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx) { } 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; @@ -2333,12 +2230,19 @@ void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags) { X509_VERIFY_PARAM_set_flags(ctx->param, flags); } +void X509_STORE_CTX_set_time_posix(X509_STORE_CTX *ctx, unsigned long flags, + int64_t t) { + X509_VERIFY_PARAM_set_time_posix(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); + X509_STORE_CTX_set_time_posix(ctx, flags, t); } -X509 *X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx) { return ctx->cert; } +X509 *X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx) { + return ctx->cert; +} void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, int (*verify_cb)(int, X509_STORE_CTX *)) { diff --git a/Sources/CNIOBoringSSL/crypto/x509/x509_vpm.c b/Sources/CNIOBoringSSL/crypto/x509/x509_vpm.c index ef5eaab5..0b27171b 100644 --- a/Sources/CNIOBoringSSL/crypto/x509/x509_vpm.c +++ b/Sources/CNIOBoringSSL/crypto/x509/x509_vpm.c @@ -72,8 +72,6 @@ #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); } #define string_stack_free(sk) sk_OPENSSL_STRING_pop_free(sk, str_free) @@ -279,7 +277,8 @@ int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest, dest->hosts = NULL; } if (src->hosts) { - dest->hosts = sk_OPENSSL_STRING_deep_copy(src->hosts, str_copy, str_free); + dest->hosts = + sk_OPENSSL_STRING_deep_copy(src->hosts, OPENSSL_strdup, str_free); if (dest->hosts == NULL) { return 0; } @@ -351,9 +350,6 @@ int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name) { 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; } @@ -379,11 +375,15 @@ void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth) { param->depth = depth; } -void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t) { +void X509_VERIFY_PARAM_set_time_posix(X509_VERIFY_PARAM *param, int64_t t) { param->check_time = t; param->flags |= X509_V_FLAG_USE_CHECK_TIME; } +void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t) { + X509_VERIFY_PARAM_set_time_posix(param, t); +} + int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, ASN1_OBJECT *policy) { if (!param->policies) { @@ -399,38 +399,23 @@ int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, } int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, - STACK_OF(ASN1_OBJECT) *policies) { - size_t i; - ASN1_OBJECT *oid, *doid; + const STACK_OF(ASN1_OBJECT) *policies) { if (!param) { return 0; } - if (param->policies) { - sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free); - } + sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free); if (!policies) { param->policies = NULL; return 1; } - param->policies = sk_ASN1_OBJECT_new_null(); + param->policies = + sk_ASN1_OBJECT_deep_copy(policies, OBJ_dup, ASN1_OBJECT_free); 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; } @@ -556,76 +541,11 @@ static const X509_VERIFY_PARAM default_table[] = { 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); -} - -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; - - sk_X509_VERIFY_PARAM_sort(param_table); - 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; -} - -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); -} - 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; - sk_X509_VERIFY_PARAM_sort(param_table); - 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++) { + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(default_table); 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; -} diff --git a/Sources/CNIOBoringSSL/crypto/x509/x509cset.c b/Sources/CNIOBoringSSL/crypto/x509/x509cset.c index 57c39b30..62246fce 100644 --- a/Sources/CNIOBoringSSL/crypto/x509/x509cset.c +++ b/Sources/CNIOBoringSSL/crypto/x509/x509cset.c @@ -59,6 +59,7 @@ #include #include +#include "../asn1/internal.h" #include "../internal.h" #include "internal.h" @@ -132,7 +133,7 @@ int X509_CRL_set1_nextUpdate(X509_CRL *x, const ASN1_TIME *tm) { int X509_CRL_sort(X509_CRL *c) { // Sort the data so it will be written in serial number order. sk_X509_REVOKED_sort(c->crl->revoked); - c->crl->enc.modified = 1; + asn1_encoding_clear(&c->crl->enc); return 1; } @@ -241,7 +242,7 @@ const STACK_OF(X509_EXTENSION) *X509_REVOKED_get0_extensions( } int i2d_re_X509_CRL_tbs(X509_CRL *crl, unsigned char **outp) { - crl->crl->enc.modified = 1; + asn1_encoding_clear(&crl->crl->enc); return i2d_X509_CRL_INFO(crl->crl, outp); } diff --git a/Sources/CNIOBoringSSL/crypto/x509/x509name.c b/Sources/CNIOBoringSSL/crypto/x509/x509name.c index 80cd3c82..ede0b222 100644 --- a/Sources/CNIOBoringSSL/crypto/x509/x509name.c +++ b/Sources/CNIOBoringSSL/crypto/x509/x509name.c @@ -263,7 +263,6 @@ int X509_NAME_add_entry(X509_NAME *name, const X509_NAME_ENTRY *entry, int loc, } 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) { diff --git a/Sources/CNIOBoringSSL/crypto/x509/x509spki.c b/Sources/CNIOBoringSSL/crypto/x509/x509spki.c index 4565a11a..5120b87c 100644 --- a/Sources/CNIOBoringSSL/crypto/x509/x509spki.c +++ b/Sources/CNIOBoringSSL/crypto/x509/x509spki.c @@ -77,7 +77,7 @@ EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x) { // 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, ossl_ssize_t len) { unsigned char *spki_der; const unsigned char *p; size_t spki_len; @@ -90,7 +90,6 @@ NETSCAPE_SPKI *NETSCAPE_SPKI_b64_decode(const char *str, int len) { 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, @@ -119,13 +118,11 @@ char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *spki) { } 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; diff --git a/Sources/CNIOBoringSSL/crypto/x509/x_all.c b/Sources/CNIOBoringSSL/crypto/x509/x_all.c index cf6b1509..5932c262 100644 --- a/Sources/CNIOBoringSSL/crypto/x509/x_all.c +++ b/Sources/CNIOBoringSSL/crypto/x509/x_all.c @@ -66,6 +66,7 @@ #include #include +#include "../asn1/internal.h" #include "internal.h" @@ -84,37 +85,37 @@ int X509_REQ_verify(X509_REQ *req, EVP_PKEY *pkey) { } int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md) { - x->cert_info->enc.modified = 1; + asn1_encoding_clear(&x->cert_info->enc); 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; + asn1_encoding_clear(&x->cert_info->enc); 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) { - x->req_info->enc.modified = 1; + asn1_encoding_clear(&x->req_info->enc); 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) { - x->req_info->enc.modified = 1; + asn1_encoding_clear(&x->req_info->enc); 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; + asn1_encoding_clear(&x->crl->enc); 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; + asn1_encoding_clear(&x->crl->enc); return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CRL_INFO), x->crl->sig_alg, x->sig_alg, x->signature, x->crl, ctx); } @@ -129,22 +130,6 @@ int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *spki, EVP_PKEY *pkey) { spki->signature, spki->spkac, pkey)); } -X509 *d2i_X509_fp(FILE *fp, X509 **x509) { - return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509), fp, x509); -} - -int i2d_X509_fp(FILE *fp, X509 *x509) { - return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509), fp, x509); -} - -X509 *d2i_X509_bio(BIO *bp, X509 **x509) { - return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509), bp, x509); -} - -int i2d_X509_bio(BIO *bp, X509 *x509) { - return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509), bp, x509); -} - X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl) { return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl); } @@ -200,6 +185,9 @@ int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req) { return ret; \ } +IMPLEMENT_D2I_FP(X509, d2i_X509_fp, d2i_X509_bio); +IMPLEMENT_I2D_FP(X509, i2d_X509_fp, i2d_X509_bio); + IMPLEMENT_D2I_FP(RSA, d2i_RSAPrivateKey_fp, d2i_RSAPrivateKey_bio) IMPLEMENT_I2D_FP(RSA, i2d_RSAPrivateKey_fp, i2d_RSAPrivateKey_bio) @@ -234,6 +222,9 @@ IMPLEMENT_I2D_FP(RSA, i2d_RSA_PUBKEY_fp, i2d_RSA_PUBKEY_bio) return ret; \ } +IMPLEMENT_D2I_BIO(X509, d2i_X509_bio, d2i_X509) +IMPLEMENT_I2D_BIO(X509, i2d_X509_bio, i2d_X509) + IMPLEMENT_D2I_BIO(RSA, d2i_RSAPrivateKey_bio, d2i_RSAPrivateKey) IMPLEMENT_I2D_BIO(RSA, i2d_RSAPrivateKey_bio, i2d_RSAPrivateKey) @@ -277,9 +268,18 @@ int X509_pubkey_digest(const X509 *data, const EVP_MD *type, unsigned char *md, 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_digest(const X509 *x509, const EVP_MD *md, uint8_t *out, + unsigned *out_len) { + uint8_t *der = NULL; + // TODO(https://crbug.com/boringssl/407): This function is not const-correct. + int der_len = i2d_X509((X509 *)x509, &der); + if (der_len < 0) { + return 0; + } + + int ret = EVP_Digest(der, der_len, out, out_len, md, NULL); + OPENSSL_free(der); + return ret; } int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type, unsigned char *md, diff --git a/Sources/CNIOBoringSSL/crypto/x509/x_crl.c b/Sources/CNIOBoringSSL/crypto/x509/x_crl.c index 1faf0672..14c3bed7 100644 --- a/Sources/CNIOBoringSSL/crypto/x509/x_crl.c +++ b/Sources/CNIOBoringSSL/crypto/x509/x_crl.c @@ -67,10 +67,12 @@ #include +#include "../asn1/internal.h" #include "../internal.h" #include "internal.h" -static int X509_REVOKED_cmp(const X509_REVOKED **a, const X509_REVOKED **b); +static int X509_REVOKED_cmp(const X509_REVOKED *const *a, + const X509_REVOKED *const *b); static int setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp); ASN1_SEQUENCE(X509_REVOKED) = { @@ -360,7 +362,8 @@ 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) { +static int X509_REVOKED_cmp(const X509_REVOKED *const *a, + const X509_REVOKED *const *b) { return ASN1_STRING_cmp((*a)->serialNumber, (*b)->serialNumber); } @@ -371,10 +374,9 @@ int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev) { 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; + asn1_encoding_clear(&inf->enc); return 1; } diff --git a/Sources/CNIOBoringSSL/crypto/x509/x_info.c b/Sources/CNIOBoringSSL/crypto/x509/x_info.c index 88276548..ce4499e9 100644 --- a/Sources/CNIOBoringSSL/crypto/x509/x_info.c +++ b/Sources/CNIOBoringSSL/crypto/x509/x_info.c @@ -66,7 +66,6 @@ X509_INFO *X509_INFO_new(void) { ret = (X509_INFO *)OPENSSL_malloc(sizeof(X509_INFO)); if (ret == NULL) { - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); return NULL; } diff --git a/Sources/CNIOBoringSSL/crypto/x509/x_name.c b/Sources/CNIOBoringSSL/crypto/x509/x_name.c index a6981d02..1d951cdf 100644 --- a/Sources/CNIOBoringSSL/crypto/x509/x_name.c +++ b/Sources/CNIOBoringSSL/crypto/x509/x_name.c @@ -80,11 +80,11 @@ DEFINE_STACK_OF(STACK_OF_X509_NAME_ENTRY) #define X509_NAME_MAX (1024 * 1024) 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); + long len, const ASN1_ITEM *it, int 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); 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); @@ -120,13 +120,11 @@ ASN1_ITEM_TEMPLATE_END(X509_NAME_INTERNAL) // 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, - NULL, }; IMPLEMENT_EXTERN_ASN1(X509_NAME, V_ASN1_SEQUENCE, x509_name_ff) @@ -154,7 +152,6 @@ static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it) { return 1; memerr: - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); if (ret) { if (ret->entries) { sk_X509_NAME_ENTRY_free(ret->entries); @@ -189,8 +186,8 @@ static void local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne) { } 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) { + long len, const ASN1_ITEM *it, int opt, + ASN1_TLC *ctx) { const unsigned char *p = *in, *q; STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = NULL; X509_NAME *nm = NULL; @@ -207,8 +204,8 @@ static int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in, // Get internal representation of Name ASN1_VALUE *intname_val = NULL; ret = ASN1_item_ex_d2i(&intname_val, &p, len, - ASN1_ITEM_rptr(X509_NAME_INTERNAL), tag, aclass, opt, - ctx); + ASN1_ITEM_rptr(X509_NAME_INTERNAL), /*tag=*/-1, + /*aclass=*/0, opt, /*buf=*/NULL); if (ret <= 0) { return ret; } @@ -258,7 +255,7 @@ static int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in, } static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, - const ASN1_ITEM *it, int tag, int aclass) { + const ASN1_ITEM *it) { X509_NAME *a = (X509_NAME *)*val; if (a->modified && (!x509_name_encode(a) || !x509_name_canon(a))) { return -1; @@ -281,23 +278,23 @@ static int x509_name_encode(X509_NAME *a) { STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = sk_STACK_OF_X509_NAME_ENTRY_new_null(); if (!intname) { - goto memerr; + 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 memerr; + goto err; } if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries)) { sk_X509_NAME_ENTRY_free(entries); - goto memerr; + goto err; } set = entry->set; } if (!sk_X509_NAME_ENTRY_push(entries, entry)) { - goto memerr; + goto err; } } ASN1_VALUE *intname_val = (ASN1_VALUE *)intname; @@ -307,7 +304,7 @@ static int x509_name_encode(X509_NAME *a) { goto err; } if (!BUF_MEM_grow(a->bytes, len)) { - goto memerr; + goto err; } p = (unsigned char *)a->bytes->data; if (ASN1_item_ex_i2d(&intname_val, &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), @@ -317,8 +314,6 @@ static int x509_name_encode(X509_NAME *a) { sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname, local_sk_X509_NAME_ENTRY_free); a->modified = 0; return 1; -memerr: - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); err: sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname, local_sk_X509_NAME_ENTRY_free); return 0; @@ -443,12 +438,10 @@ static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in) { 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. + // Convert string in place to canonical form. // Ignore leading spaces - while ((len > 0) && !(*from & 0x80) && isspace(*from)) { + while ((len > 0) && OPENSSL_isspace(*from)) { from++; len--; } @@ -456,7 +449,7 @@ static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in) { to = from + len; // Ignore trailing spaces - while ((len > 0) && !(to[-1] & 0x80) && isspace(to[-1])) { + while ((len > 0) && OPENSSL_isspace(to[-1])) { to--; len--; } @@ -465,13 +458,8 @@ static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in) { i = 0; while (i < len) { - // If MSB set just copy across - if (*from & 0x80) { - *to++ = *from++; - i++; - } // Collapse multiple spaces - else if (isspace(*from)) { + if (OPENSSL_isspace(*from)) { // Copy one space across *to++ = ' '; // Ignore subsequent spaces. Note: don't need to check len here @@ -480,7 +468,7 @@ static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in) { do { from++; i++; - } while (!(*from & 0x80) && isspace(*from)); + } while (OPENSSL_isspace(*from)); } else { *to++ = OPENSSL_tolower(*from); from++; diff --git a/Sources/CNIOBoringSSL/crypto/x509/x_pkey.c b/Sources/CNIOBoringSSL/crypto/x509/x_pkey.c index 2e1edca3..f35be5bd 100644 --- a/Sources/CNIOBoringSSL/crypto/x509/x_pkey.c +++ b/Sources/CNIOBoringSSL/crypto/x509/x_pkey.c @@ -69,7 +69,6 @@ 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; } OPENSSL_memset(ret, 0, sizeof(X509_PKEY)); diff --git a/Sources/CNIOBoringSSL/crypto/x509/x_sig.c b/Sources/CNIOBoringSSL/crypto/x509/x_sig.c index 91c6cfba..5d6c2ba1 100644 --- a/Sources/CNIOBoringSSL/crypto/x509/x_sig.c +++ b/Sources/CNIOBoringSSL/crypto/x509/x_sig.c @@ -1,4 +1,3 @@ -/* crypto/asn1/x_sig.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * diff --git a/Sources/CNIOBoringSSL/crypto/x509/x_spki.c b/Sources/CNIOBoringSSL/crypto/x509/x_spki.c index 2f69ef81..d0d11400 100644 --- a/Sources/CNIOBoringSSL/crypto/x509/x_spki.c +++ b/Sources/CNIOBoringSSL/crypto/x509/x_spki.c @@ -1,4 +1,3 @@ -/* crypto/asn1/x_spki.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * diff --git a/Sources/CNIOBoringSSL/crypto/x509/x_val.c b/Sources/CNIOBoringSSL/crypto/x509/x_val.c index 06f3799e..6269f0e3 100644 --- a/Sources/CNIOBoringSSL/crypto/x509/x_val.c +++ b/Sources/CNIOBoringSSL/crypto/x509/x_val.c @@ -1,4 +1,3 @@ -/* crypto/asn1/x_val.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * diff --git a/Sources/CNIOBoringSSL/crypto/x509/x_x509.c b/Sources/CNIOBoringSSL/crypto/x509/x_x509.c index a74bc977..6fcda085 100644 --- a/Sources/CNIOBoringSSL/crypto/x509/x_x509.c +++ b/Sources/CNIOBoringSSL/crypto/x509/x_x509.c @@ -1,4 +1,3 @@ -/* crypto/asn1/x_x509.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -68,6 +67,8 @@ #include #include +#include "../asn1/internal.h" +#include "../bytestring/internal.h" #include "../internal.h" #include "internal.h" @@ -87,115 +88,289 @@ ASN1_SEQUENCE_enc(X509_CINF, enc, 0) = { } ASN1_SEQUENCE_END_enc(X509_CINF, X509_CINF) IMPLEMENT_ASN1_FUNCTIONS(X509_CINF) -// X509 top level structure needs a bit of customisation - -extern void policy_cache_free(X509_POLICY_CACHE *cache); - -static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, - void *exarg) { - X509 *ret = (X509 *)*pval; - - switch (operation) { - case ASN1_OP_NEW_POST: - ret->ex_flags = 0; - ret->ex_pathlen = -1; - ret->skid = NULL; - ret->akid = NULL; - ret->aux = NULL; - ret->crldp = NULL; - ret->buf = NULL; - CRYPTO_new_ex_data(&ret->ex_data); - CRYPTO_MUTEX_init(&ret->lock); - break; - - case ASN1_OP_D2I_PRE: - CRYPTO_BUFFER_free(ret->buf); - ret->buf = NULL; - break; - - case ASN1_OP_D2I_POST: { - // The version must be one of v1(0), v2(1), or v3(2). - long version = X509_VERSION_1; - if (ret->cert_info->version != NULL) { - version = ASN1_INTEGER_get(ret->cert_info->version); - // TODO(https://crbug.com/boringssl/364): |X509_VERSION_1| should - // also be rejected here. This means an explicitly-encoded X.509v1 - // version. v1 is DEFAULT, so DER requires it be omitted. - if (version < X509_VERSION_1 || version > X509_VERSION_3) { - OPENSSL_PUT_ERROR(X509, X509_R_INVALID_VERSION); - return 0; - } - } - // Per RFC 5280, section 4.1.2.8, these fields require v2 or v3. - if (version == X509_VERSION_1 && (ret->cert_info->issuerUID != NULL || - ret->cert_info->subjectUID != NULL)) { - OPENSSL_PUT_ERROR(X509, X509_R_INVALID_FIELD_FOR_VERSION); - return 0; - } +// x509_new_null returns a new |X509| object where the |cert_info|, |sig_alg|, +// and |signature| fields are not yet filled in. +static X509 *x509_new_null(void) { + X509 *ret = OPENSSL_malloc(sizeof(X509)); + if (ret == NULL) { + return NULL; + } + OPENSSL_memset(ret, 0, sizeof(X509)); - // Per RFC 5280, section 4.1.2.9, extensions require v3. - if (version != X509_VERSION_3 && ret->cert_info->extensions != NULL) { - OPENSSL_PUT_ERROR(X509, X509_R_INVALID_FIELD_FOR_VERSION); - return 0; - } + ret->references = 1; + ret->ex_pathlen = -1; + CRYPTO_new_ex_data(&ret->ex_data); + CRYPTO_MUTEX_init(&ret->lock); + return ret; +} + +X509 *X509_new(void) { + X509 *ret = x509_new_null(); + if (ret == NULL) { + return NULL; + } + + ret->cert_info = X509_CINF_new(); + ret->sig_alg = X509_ALGOR_new(); + ret->signature = ASN1_BIT_STRING_new(); + if (ret->cert_info == NULL || ret->sig_alg == NULL || + ret->signature == NULL) { + X509_free(ret); + return NULL; + } + + return ret; +} + +void X509_free(X509 *x509) { + if (x509 == NULL || !CRYPTO_refcount_dec_and_test_zero(&x509->references)) { + return; + } + + CRYPTO_free_ex_data(&g_ex_data_class, x509, &x509->ex_data); + + X509_CINF_free(x509->cert_info); + X509_ALGOR_free(x509->sig_alg); + ASN1_BIT_STRING_free(x509->signature); + ASN1_OCTET_STRING_free(x509->skid); + AUTHORITY_KEYID_free(x509->akid); + CRL_DIST_POINTS_free(x509->crldp); + GENERAL_NAMES_free(x509->altname); + NAME_CONSTRAINTS_free(x509->nc); + X509_CERT_AUX_free(x509->aux); + CRYPTO_MUTEX_cleanup(&x509->lock); + + OPENSSL_free(x509); +} + +static X509 *x509_parse(CBS *cbs, CRYPTO_BUFFER *buf) { + CBS cert, tbs, sigalg, sig; + if (!CBS_get_asn1(cbs, &cert, CBS_ASN1_SEQUENCE) || + // Bound the length to comfortably fit in an int. Lengths in this + // module often omit overflow checks. + CBS_len(&cert) > INT_MAX / 2 || + !CBS_get_asn1_element(&cert, &tbs, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1_element(&cert, &sigalg, CBS_ASN1_SEQUENCE)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return NULL; + } - break; + // For just the signature field, we accept non-minimal BER lengths, though not + // indefinite-length encoding. See b/18228011. + // + // TODO(crbug.com/boringssl/354): Switch the affected callers to convert the + // certificate before parsing and then remove this workaround. + CBS_ASN1_TAG tag; + size_t header_len; + int indefinite; + if (!CBS_get_any_ber_asn1_element(&cert, &sig, &tag, &header_len, + /*out_ber_found=*/NULL, + &indefinite) || + tag != CBS_ASN1_BITSTRING || indefinite || // + !CBS_skip(&sig, header_len) || // + CBS_len(&cert) != 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return NULL; + } + + X509 *ret = x509_new_null(); + if (ret == NULL) { + return NULL; + } + + // TODO(crbug.com/boringssl/443): When the rest of the library is decoupled + // from the tasn_*.c implementation, replace this with |CBS|-based functions. + const uint8_t *inp = CBS_data(&tbs); + if (ASN1_item_ex_d2i((ASN1_VALUE **)&ret->cert_info, &inp, CBS_len(&tbs), + ASN1_ITEM_rptr(X509_CINF), /*tag=*/-1, + /*aclass=*/0, /*opt=*/0, buf) <= 0 || + inp != CBS_data(&tbs) + CBS_len(&tbs)) { + goto err; + } + + inp = CBS_data(&sigalg); + ret->sig_alg = d2i_X509_ALGOR(NULL, &inp, CBS_len(&sigalg)); + if (ret->sig_alg == NULL || inp != CBS_data(&sigalg) + CBS_len(&sigalg)) { + goto err; + } + + inp = CBS_data(&sig); + ret->signature = c2i_ASN1_BIT_STRING(NULL, &inp, CBS_len(&sig)); + if (ret->signature == NULL || inp != CBS_data(&sig) + CBS_len(&sig)) { + goto err; + } + + // The version must be one of v1(0), v2(1), or v3(2). + long version = X509_VERSION_1; + if (ret->cert_info->version != NULL) { + version = ASN1_INTEGER_get(ret->cert_info->version); + // TODO(https://crbug.com/boringssl/364): |X509_VERSION_1| should + // also be rejected here. This means an explicitly-encoded X.509v1 + // version. v1 is DEFAULT, so DER requires it be omitted. + if (version < X509_VERSION_1 || version > X509_VERSION_3) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_VERSION); + goto err; } + } - case ASN1_OP_FREE_POST: - CRYPTO_MUTEX_cleanup(&ret->lock); - 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); - CRYPTO_BUFFER_free(ret->buf); - break; + // Per RFC 5280, section 4.1.2.8, these fields require v2 or v3. + if (version == X509_VERSION_1 && (ret->cert_info->issuerUID != NULL || + ret->cert_info->subjectUID != NULL)) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_FIELD_FOR_VERSION); + goto err; } - return 1; + // Per RFC 5280, section 4.1.2.9, extensions require v3. + if (version != X509_VERSION_3 && ret->cert_info->extensions != NULL) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_FIELD_FOR_VERSION); + goto err; + } + + return ret; + +err: + X509_free(ret); + return NULL; +} + +X509 *d2i_X509(X509 **out, const uint8_t **inp, long len) { + X509 *ret = NULL; + if (len < 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BUFFER_TOO_SMALL); + goto err; + } + + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + ret = x509_parse(&cbs, NULL); + if (ret == NULL) { + goto err; + } + + *inp = CBS_data(&cbs); + +err: + if (out != NULL) { + X509_free(*out); + *out = ret; + } + return ret; } -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_SEQUENCE_END_ref(X509, X509) +int i2d_X509(X509 *x509, uint8_t **outp) { + if (x509 == NULL) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_VALUE); + return -1; + } + + CBB cbb, cert; + if (!CBB_init(&cbb, 64) || // + !CBB_add_asn1(&cbb, &cert, CBS_ASN1_SEQUENCE)) { + goto err; + } -IMPLEMENT_ASN1_FUNCTIONS(X509) + // TODO(crbug.com/boringssl/443): When the rest of the library is decoupled + // from the tasn_*.c implementation, replace this with |CBS|-based functions. + uint8_t *out; + int len = i2d_X509_CINF(x509->cert_info, NULL); + if (len < 0 || // + !CBB_add_space(&cert, &out, (size_t)len) || + i2d_X509_CINF(x509->cert_info, &out) != len) { + goto err; + } -IMPLEMENT_ASN1_DUP_FUNCTION(X509) + len = i2d_X509_ALGOR(x509->sig_alg, NULL); + if (len < 0 || // + !CBB_add_space(&cert, &out, (size_t)len) || + i2d_X509_ALGOR(x509->sig_alg, &out) != len) { + goto err; + } -X509 *X509_parse_from_buffer(CRYPTO_BUFFER *buf) { - if (CRYPTO_BUFFER_len(buf) > LONG_MAX) { - OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + len = i2d_ASN1_BIT_STRING(x509->signature, NULL); + if (len < 0 || // + !CBB_add_space(&cert, &out, (size_t)len) || + i2d_ASN1_BIT_STRING(x509->signature, &out) != len) { + goto err; + } + + return CBB_finish_i2d(&cbb, outp); + +err: + CBB_cleanup(&cbb); + return -1; +} + +static int x509_new_cb(ASN1_VALUE **pval, const ASN1_ITEM *it) { + *pval = (ASN1_VALUE *)X509_new(); + return *pval != NULL; +} + +static void x509_free_cb(ASN1_VALUE **pval, const ASN1_ITEM *it) { + X509_free((X509 *)*pval); + *pval = NULL; +} + +static int x509_d2i_cb(ASN1_VALUE **pval, const unsigned char **in, long len, + const ASN1_ITEM *it, int opt, ASN1_TLC *ctx) { + if (len < 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BUFFER_TOO_SMALL); return 0; } - X509 *x509 = X509_new(); - if (x509 == NULL) { - return NULL; + CBS cbs; + CBS_init(&cbs, *in, len); + if (opt && !CBS_peek_asn1_tag(&cbs, CBS_ASN1_SEQUENCE)) { + return -1; + } + + X509 *ret = x509_parse(&cbs, NULL); + if (ret == NULL) { + return 0; } - x509->cert_info->enc.alias_only_on_next_parse = 1; + *in = CBS_data(&cbs); + X509_free((X509 *)*pval); + *pval = (ASN1_VALUE *)ret; + return 1; +} + +static int x509_i2d_cb(ASN1_VALUE **pval, unsigned char **out, + const ASN1_ITEM *it) { + return i2d_X509((X509 *)*pval, out); +} - const uint8_t *inp = CRYPTO_BUFFER_data(buf); - X509 *x509p = x509; - X509 *ret = d2i_X509(&x509p, &inp, CRYPTO_BUFFER_len(buf)); - if (ret == NULL || - inp - CRYPTO_BUFFER_data(buf) != (ptrdiff_t)CRYPTO_BUFFER_len(buf)) { - X509_free(x509p); +static const ASN1_EXTERN_FUNCS x509_extern_funcs = { + x509_new_cb, + x509_free_cb, + /*asn1_ex_clear=*/NULL, + x509_d2i_cb, + x509_i2d_cb, +}; + +IMPLEMENT_EXTERN_ASN1(X509, V_ASN1_SEQUENCE, x509_extern_funcs) + +X509 *X509_dup(X509 *x509) { + uint8_t *der = NULL; + int len = i2d_X509(x509, &der); + if (len < 0) { return NULL; } - assert(x509p == x509); - assert(ret == x509); - CRYPTO_BUFFER_up_ref(buf); - ret->buf = buf; + const uint8_t *inp = der; + X509 *ret = d2i_X509(NULL, &inp, len); + OPENSSL_free(der); + return ret; +} + +X509 *X509_parse_from_buffer(CRYPTO_BUFFER *buf) { + CBS cbs; + CBS_init(&cbs, CRYPTO_BUFFER_data(buf), CRYPTO_BUFFER_len(buf)); + X509 *ret = x509_parse(&cbs, buf); + if (ret == NULL || CBS_len(&cbs) != 0) { + X509_free(ret); + return NULL; + } return ret; } @@ -329,7 +504,7 @@ int i2d_X509_AUX(X509 *a, unsigned char **pp) { } int i2d_re_X509_tbs(X509 *x509, unsigned char **outp) { - x509->cert_info->enc.modified = 1; + asn1_encoding_clear(&x509->cert_info->enc); return i2d_X509_CINF(x509->cert_info, outp); } diff --git a/Sources/CNIOBoringSSL/crypto/x509/x_x509a.c b/Sources/CNIOBoringSSL/crypto/x509/x_x509a.c index 13f71754..d8fae293 100644 --- a/Sources/CNIOBoringSSL/crypto/x509/x_x509a.c +++ b/Sources/CNIOBoringSSL/crypto/x509/x_x509a.c @@ -90,7 +90,7 @@ static X509_CERT_AUX *aux_get(X509 *x) { return x->aux; } -int X509_alias_set1(X509 *x, const unsigned char *name, int len) { +int X509_alias_set1(X509 *x, const unsigned char *name, ossl_ssize_t len) { X509_CERT_AUX *aux; // TODO(davidben): Empty aliases are not meaningful in PKCS#12, and the // getters cannot quite represent them. Also erase the object if |len| is @@ -112,7 +112,7 @@ int X509_alias_set1(X509 *x, const unsigned char *name, int len) { return ASN1_STRING_set(aux->alias, name, len); } -int X509_keyid_set1(X509 *x, const unsigned char *id, int len) { +int X509_keyid_set1(X509 *x, const unsigned char *id, ossl_ssize_t len) { X509_CERT_AUX *aux; // TODO(davidben): Empty key IDs are not meaningful in PKCS#12, and the // getters cannot quite represent them. Also erase the object if |len| is diff --git a/Sources/CNIOBoringSSL/crypto/x509v3/ext_dat.h b/Sources/CNIOBoringSSL/crypto/x509v3/ext_dat.h index 24914310..0d327699 100644 --- a/Sources/CNIOBoringSSL/crypto/x509v3/ext_dat.h +++ b/Sources/CNIOBoringSSL/crypto/x509v3/ext_dat.h @@ -69,7 +69,7 @@ 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_crl_hold; 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; @@ -116,7 +116,6 @@ static const X509V3_EXT_METHOD *const standard_exts[] = { #ifndef OPENSSL_NO_OCSP &v3_crl_hold, #endif - &v3_pci, &v3_name_constraints, &v3_policy_mappings, &v3_inhibit_anyp, diff --git a/Sources/CNIOBoringSSL/crypto/x509v3/internal.h b/Sources/CNIOBoringSSL/crypto/x509v3/internal.h index ce909dad..2f8a8d07 100644 --- a/Sources/CNIOBoringSSL/crypto/x509v3/internal.h +++ b/Sources/CNIOBoringSSL/crypto/x509v3/internal.h @@ -90,11 +90,11 @@ OPENSSL_EXPORT char *x509v3_bytes_to_hex(const uint8_t *in, size_t len); // // This function was historically named |string_to_hex| in OpenSSL. Despite the // name, |string_to_hex| converted from hex. -unsigned char *x509v3_hex_to_bytes(const char *str, long *len); +unsigned char *x509v3_hex_to_bytes(const char *str, size_t *len); -// x509v3_name_cmp returns zero if |name| is equal to |cmp| or begins with |cmp| -// followed by '.'. Otherwise, it returns a non-zero number. -int x509v3_name_cmp(const char *name, const char *cmp); +// x509v3_conf_name_matches returns one if |name| is equal to |cmp| or begins +// with |cmp| followed by '.', and zero otherwise. +int x509v3_conf_name_matches(const char *name, const char *cmp); // x509v3_looks_like_dns_name returns one if |in| looks like a DNS name and zero // otherwise. @@ -104,7 +104,7 @@ OPENSSL_EXPORT int x509v3_looks_like_dns_name(const unsigned char *in, // x509v3_cache_extensions fills in a number of fields relating to X.509 // extensions in |x|. It returns one on success and zero if some extensions were // invalid. -int x509v3_cache_extensions(X509 *x); +OPENSSL_EXPORT int x509v3_cache_extensions(X509 *x); // x509v3_a2i_ipadd decodes |ipasc| as an IPv4 or IPv6 address. IPv6 addresses // use colon-separated syntax while IPv4 addresses use dotted decimal syntax. If @@ -127,162 +127,67 @@ typedef struct { int x509V3_add_value_asn1_string(const char *name, const ASN1_STRING *value, STACK_OF(CONF_VALUE) **extlist); - -// Internal structures - -// This structure and the field names correspond to the Policy 'node' of -// RFC 3280. 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. - -typedef struct X509_POLICY_DATA_st X509_POLICY_DATA; -typedef struct X509_POLICY_LEVEL_st X509_POLICY_LEVEL; -typedef struct X509_POLICY_NODE_st X509_POLICY_NODE; - -DEFINE_STACK_OF(X509_POLICY_DATA) - -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. - -#define POLICY_DATA_FLAG_MAPPED 0x1 - -// 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 - -// AND with flags to see if any mapping has occurred - -#define POLICY_DATA_FLAG_MAP_MASK 0x3 - -// qualifiers are shared and shouldn't be freed - -#define POLICY_DATA_FLAG_SHARED_QUALIFIERS 0x4 - -// Parent node is an extra node and should be freed - -#define POLICY_DATA_FLAG_EXTRA_NODE 0x8 - -// Corresponding CertificatePolicies is critical - -#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 - -// 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; -}; - -DEFINE_STACK_OF(X509_POLICY_NODE) - -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 - -// Useful macros - -#define node_data_critical(data) ((data)->flags & POLICY_DATA_FLAG_CRITICAL) -#define node_critical(node) node_data_critical((node)->data) - -// Internal functions - -void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent); - -int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy, - STACK_OF(X509) *certs, STACK_OF(ASN1_OBJECT) *policy_oids, - unsigned int flags); - -void X509_policy_tree_free(X509_POLICY_TREE *tree); - -X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, const ASN1_OBJECT *id, - int crit); -void policy_data_free(X509_POLICY_DATA *data); - -X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache, - 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); - -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); - -X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *sk, - const ASN1_OBJECT *id); - -X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level, - X509_POLICY_DATA *data, - X509_POLICY_NODE *parent, - X509_POLICY_TREE *tree); -void policy_node_free(X509_POLICY_NODE *node); -int policy_node_match(const X509_POLICY_LEVEL *lvl, - const X509_POLICY_NODE *node, const ASN1_OBJECT *oid); - -const X509_POLICY_CACHE *policy_cache_set(X509 *x); +// X509V3_NAME_from_section adds attributes to |nm| by interpreting the +// key/value pairs in |dn_sk|. It returns one on success and zero on error. +// |chtype|, which should be one of |MBSTRING_*| constants, determines the +// character encoding used to interpret values. +int X509V3_NAME_from_section(X509_NAME *nm, const STACK_OF(CONF_VALUE) *dn_sk, + int chtype); + +// X509V3_bool_from_string decodes |str| as a boolean. On success, it returns +// one and sets |*out_bool| to resulting value. Otherwise, it returns zero. +int X509V3_bool_from_string(const char *str, ASN1_BOOLEAN *out_bool); + +// X509V3_get_value_bool decodes |value| as a boolean. On success, it returns +// one and sets |*out_bool| to the resulting value. Otherwise, it returns zero. +int X509V3_get_value_bool(const CONF_VALUE *value, ASN1_BOOLEAN *out_bool); + +// X509V3_get_value_int decodes |value| as an integer. On success, it returns +// one and sets |*aint| to the resulting value. Otherwise, it returns zero. If +// |*aint| was non-NULL at the start of the function, it frees the previous +// value before writing a new one. +int X509V3_get_value_int(const CONF_VALUE *value, ASN1_INTEGER **aint); + +// X509V3_get_section behaves like |NCONF_get_section| but queries |ctx|'s +// config database. +const STACK_OF(CONF_VALUE) *X509V3_get_section(const X509V3_CTX *ctx, + const char *section); + +// X509V3_add_value appends a |CONF_VALUE| containing |name| and |value| to +// |*extlist|. It returns one on success and zero on error. If |*extlist| is +// NULL, it sets |*extlist| to a newly-allocated |STACK_OF(CONF_VALUE)| +// containing the result. Either |name| or |value| may be NULL to omit the +// field. +// +// On failure, if |*extlist| was NULL, |*extlist| will remain NULL when the +// function returns. +int X509V3_add_value(const char *name, const char *value, + STACK_OF(CONF_VALUE) **extlist); + +// X509V3_add_value_bool behaves like |X509V3_add_value| but stores the value +// "TRUE" if |asn1_bool| is non-zero and "FALSE" otherwise. +int X509V3_add_value_bool(const char *name, int asn1_bool, + STACK_OF(CONF_VALUE) **extlist); + +// X509V3_add_value_bool behaves like |X509V3_add_value| but stores a string +// representation of |aint|. Note this string representation may be decimal or +// hexadecimal, depending on the size of |aint|. +int X509V3_add_value_int(const char *name, const ASN1_INTEGER *aint, + STACK_OF(CONF_VALUE) **extlist); + +STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line); + +#define X509V3_conf_err(val) \ + ERR_add_error_data(6, "section:", (val)->section, ",name:", (val)->name, \ + ",value:", (val)->value); + +// GENERAL_NAME_cmp returns zero if |a| and |b| are equal and a non-zero +// value otherwise. Note this function does not provide a comparison suitable +// for sorting. +// +// This function is exported for testing. +OPENSSL_EXPORT int GENERAL_NAME_cmp(const GENERAL_NAME *a, + const GENERAL_NAME *b); #if defined(__cplusplus) diff --git a/Sources/CNIOBoringSSL/crypto/x509v3/pcy_cache.c b/Sources/CNIOBoringSSL/crypto/x509v3/pcy_cache.c deleted file mode 100644 index c05f25e6..00000000 --- a/Sources/CNIOBoringSSL/crypto/x509v3/pcy_cache.c +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2004. - */ -/* ==================================================================== - * Copyright (c) 2004 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 -#include -#include -#include -#include - -#include "../internal.h" -#include "../x509/internal.h" -#include "internal.h" - -static int policy_data_cmp(const X509_POLICY_DATA **a, - 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. - -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. - sk_X509_POLICY_DATA_sort(cache->data); - 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; -} - -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. -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; - - CRYPTO_STATIC_MUTEX_lock_read(&g_x509_policy_cache_lock); - cache = x->policy_cache; - CRYPTO_STATIC_MUTEX_unlock_read(&g_x509_policy_cache_lock); - - 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_write(&g_x509_policy_cache_lock); - - 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; - sk_X509_POLICY_DATA_sort(cache->data); - 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); -} - -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; -} diff --git a/Sources/CNIOBoringSSL/crypto/x509v3/pcy_data.c b/Sources/CNIOBoringSSL/crypto/x509v3/pcy_data.c deleted file mode 100644 index e723d68a..00000000 --- a/Sources/CNIOBoringSSL/crypto/x509v3/pcy_data.c +++ /dev/null @@ -1,134 +0,0 @@ -/* pcy_data.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2004. - */ -/* ==================================================================== - * Copyright (c) 2004 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 -#include -#include -#include - -#include "internal.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); -} - -// 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 RFC 3280: 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) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - ASN1_OBJECT_free(id); - return NULL; - } - ret->expected_policy_set = sk_ASN1_OBJECT_new_null(); - if (!ret->expected_policy_set) { - OPENSSL_free(ret); - ASN1_OBJECT_free(id); - return NULL; - } - - if (crit) { - ret->flags = POLICY_DATA_FLAG_CRITICAL; - } else { - ret->flags = 0; - } - - if (id) { - ret->valid_policy = id; - } else { - ret->valid_policy = policy->policyid; - policy->policyid = NULL; - } - - if (policy) { - ret->qualifier_set = policy->qualifiers; - policy->qualifiers = NULL; - } else { - ret->qualifier_set = NULL; - } - - return ret; -} diff --git a/Sources/CNIOBoringSSL/crypto/x509v3/pcy_map.c b/Sources/CNIOBoringSSL/crypto/x509v3/pcy_map.c deleted file mode 100644 index 1b7f06c0..00000000 --- a/Sources/CNIOBoringSSL/crypto/x509v3/pcy_map.c +++ /dev/null @@ -1,129 +0,0 @@ -/* pcy_map.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2004. - */ -/* ==================================================================== - * Copyright (c) 2004 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 -#include -#include - -#include "../x509/internal.h" -#include "internal.h" - -// 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; - } - - // 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; - } - - 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/Sources/CNIOBoringSSL/crypto/x509v3/pcy_node.c b/Sources/CNIOBoringSSL/crypto/x509v3/pcy_node.c deleted file mode 100644 index 2f44dd48..00000000 --- a/Sources/CNIOBoringSSL/crypto/x509v3/pcy_node.c +++ /dev/null @@ -1,187 +0,0 @@ -/* pcy_node.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2004. - */ -/* ==================================================================== - * Copyright (c) 2004 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 -#include -#include -#include -#include - -#include "internal.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); -} - -STACK_OF(X509_POLICY_NODE) *policy_node_cmp_new(void) { - return sk_X509_POLICY_NODE_new(node_cmp); -} - -X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *nodes, - const ASN1_OBJECT *id) { - X509_POLICY_DATA n; - X509_POLICY_NODE l; - size_t idx; - - n.valid_policy = (ASN1_OBJECT *)id; - l.data = &n; - - sk_X509_POLICY_NODE_sort(nodes); - if (!sk_X509_POLICY_NODE_find(nodes, &idx, &l)) { - return NULL; - } - - 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; -} - -X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level, - X509_POLICY_DATA *data, - X509_POLICY_NODE *parent, - X509_POLICY_TREE *tree) { - X509_POLICY_NODE *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); } - -// 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; -} diff --git a/Sources/CNIOBoringSSL/crypto/x509v3/pcy_tree.c b/Sources/CNIOBoringSSL/crypto/x509v3/pcy_tree.c deleted file mode 100644 index 2c7a05c2..00000000 --- a/Sources/CNIOBoringSSL/crypto/x509v3/pcy_tree.c +++ /dev/null @@ -1,829 +0,0 @@ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2004. - */ -/* ==================================================================== - * Copyright (c) 2004 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 - -#include -#include -#include -#include -#include -#include - -#include "../internal.h" -#include "../x509/internal.h" -#include "internal.h" - -// Enable this to print out the complete policy tree at various point during -// evaluation. - -// #define OPENSSL_POLICY_DEBUG - -#ifdef OPENSSL_POLICY_DEBUG - -static void expected_print(BIO *err, X509_POLICY_LEVEL *lev, - X509_POLICY_NODE *node, int indent) { - 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); -} -#else - -#define tree_print(a, b, c) // - -#endif - -//- -// Initialize policy tree. Return values: -// 0 Some internal error occurred. -// -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); - -#if 0 - // 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; - } - - OPENSSL_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); - X509_up_ref(x); - level->cert = 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, - 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 RFC 3280 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. -#if 0 - 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 RFC 3280 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; -} - -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; -} - -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; - } - -#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; - } -#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 -// 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 RFC 3280 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 { - sk_X509_POLICY_NODE_sort(*pnodes); - 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; -} - -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; -} - -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; -} - -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) { - if (!tree) { - return; - } - - sk_X509_POLICY_NODE_free(tree->auth_policies); - sk_X509_POLICY_NODE_pop_free(tree->user_policies, exnode_free); - - for (int i = 0; i < tree->nlevel; i++) { - X509_POLICY_LEVEL *curr = &tree->levels[i]; - X509_free(curr->cert); - sk_X509_POLICY_NODE_pop_free(curr->nodes, policy_node_free); - policy_node_free(curr->anyPolicy); - } - - 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; - int calc_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); - - switch (ret) { - // Tree empty requireExplicit False: OK - case 2: - return 1; - - // Some internal error - case -1: - return -1; - - // Some internal error - case 0: - return 0; - - // Tree empty requireExplicit True: Error - - case 6: - *pexplicit_policy = 1; - return -2; - - // Tree OK requireExplicit True: OK and continue - case 5: - *pexplicit_policy = 1; - break; - - // 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; - } - - if (!tree) { - goto error; - } - ret = tree_evaluate(tree); - - tree_print("tree_evaluate()", tree, NULL); - - 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; - } - } - - // Tree is not empty: continue - - calc_ret = tree_calculate_authority_set(tree, &auth_nodes); - - if (!calc_ret) { - goto error; - } - - ret = tree_calculate_user_set(tree, policy_oids, auth_nodes); - - if (calc_ret == 2) { - sk_X509_POLICY_NODE_free(auth_nodes); - } - - if (!ret) { - goto error; - } - - - if (tree) { - *ptree = tree; - } - - if (*pexplicit_policy) { - if (tree->flags & POLICY_FLAG_ANY_POLICY) { - nodes = tree->auth_policies; - } else { - nodes = tree->user_policies; - } - if (sk_X509_POLICY_NODE_num(nodes) <= 0) { - return -2; - } - } - - return 1; - -error: - X509_policy_tree_free(tree); - return 0; -} diff --git a/Sources/CNIOBoringSSL/crypto/x509v3/v3_akey.c b/Sources/CNIOBoringSSL/crypto/x509v3/v3_akey.c index 6c31715e..35f0a362 100644 --- a/Sources/CNIOBoringSSL/crypto/x509v3/v3_akey.c +++ b/Sources/CNIOBoringSSL/crypto/x509v3/v3_akey.c @@ -1,4 +1,3 @@ -/* v3_akey.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 1999. @@ -72,7 +71,8 @@ static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID( const X509V3_EXT_METHOD *method, void *ext, STACK_OF(CONF_VALUE) *extlist); static void *v2i_AUTHORITY_KEYID(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values); + const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *values); const X509V3_EXT_METHOD v3_akey_id = { NID_authority_key_identifier, @@ -132,22 +132,20 @@ static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID( // is always included. static void *v2i_AUTHORITY_KEYID(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *values) { + const X509V3_CTX *ctx, + const 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 *cert; + const X509 *cert; AUTHORITY_KEYID *akeyid; - for (i = 0; i < sk_CONF_VALUE_num(values); i++) { - cnf = sk_CONF_VALUE_value(values, i); + for (size_t i = 0; i < sk_CONF_VALUE_num(values); i++) { + const CONF_VALUE *cnf = sk_CONF_VALUE_value(values, i); if (!strcmp(cnf->name, "keyid")) { keyid = 1; if (cnf->value && !strcmp(cnf->value, "always")) { @@ -166,7 +164,7 @@ static void *v2i_AUTHORITY_KEYID(const X509V3_EXT_METHOD *method, } if (!ctx || !ctx->issuer_cert) { - if (ctx && (ctx->flags == CTX_TEST)) { + if (ctx && (ctx->flags == X509V3_CTX_TEST)) { return AUTHORITY_KEYID_new(); } OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_ISSUER_CERTIFICATE); @@ -189,7 +187,7 @@ static void *v2i_AUTHORITY_KEYID(const X509V3_EXT_METHOD *method, if ((issuer && !ikeyid) || (issuer == 2)) { isname = X509_NAME_dup(X509_get_issuer_name(cert)); - serial = ASN1_INTEGER_dup(X509_get_serialNumber(cert)); + serial = ASN1_INTEGER_dup(X509_get0_serialNumber(cert)); if (!isname || !serial) { OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS); goto err; @@ -203,7 +201,6 @@ static void *v2i_AUTHORITY_KEYID(const X509V3_EXT_METHOD *method, 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; diff --git a/Sources/CNIOBoringSSL/crypto/x509v3/v3_akeya.c b/Sources/CNIOBoringSSL/crypto/x509v3/v3_akeya.c index 40dcb884..d32d07f9 100644 --- a/Sources/CNIOBoringSSL/crypto/x509v3/v3_akeya.c +++ b/Sources/CNIOBoringSSL/crypto/x509v3/v3_akeya.c @@ -1,4 +1,3 @@ -/* v3_akey_asn1.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 1999. diff --git a/Sources/CNIOBoringSSL/crypto/x509v3/v3_alt.c b/Sources/CNIOBoringSSL/crypto/x509v3/v3_alt.c index 3e059bf8..e3c9e6b1 100644 --- a/Sources/CNIOBoringSSL/crypto/x509v3/v3_alt.c +++ b/Sources/CNIOBoringSSL/crypto/x509v3/v3_alt.c @@ -1,4 +1,3 @@ -/* v3_alt.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project. @@ -68,14 +67,18 @@ #include "internal.h" -static void *v2i_subject_alt(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval); -static void *v2i_issuer_alt(const 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, const char *value, X509V3_CTX *ctx); -static int do_dirname(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx); +static void *v2i_subject_alt(const X509V3_EXT_METHOD *method, + const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *nval); +static void *v2i_issuer_alt(const X509V3_EXT_METHOD *method, + const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *nval); +static int copy_email(const X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p); +static int copy_issuer(const X509V3_CTX *ctx, GENERAL_NAMES *gens); +static int do_othername(GENERAL_NAME *gen, const char *value, + const X509V3_CTX *ctx); +static int do_dirname(GENERAL_NAME *gen, const char *value, + const X509V3_CTX *ctx); static STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES_cb( const X509V3_EXT_METHOD *method, void *ext, STACK_OF(CONF_VALUE) *ret) { @@ -94,11 +97,11 @@ const X509V3_EXT_METHOD v3_alt[] = { }; STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(const X509V3_EXT_METHOD *method, - GENERAL_NAMES *gens, + const GENERAL_NAMES *gens, STACK_OF(CONF_VALUE) *ret) { int ret_was_null = ret == NULL; for (size_t i = 0; i < sk_GENERAL_NAME_num(gens); i++) { - GENERAL_NAME *gen = sk_GENERAL_NAME_value(gens, i); + const GENERAL_NAME *gen = sk_GENERAL_NAME_value(gens, i); STACK_OF(CONF_VALUE) *tmp = i2v_GENERAL_NAME(method, gen, ret); if (tmp == NULL) { if (ret_was_null) { @@ -115,7 +118,7 @@ STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(const X509V3_EXT_METHOD *method, } STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(const X509V3_EXT_METHOD *method, - GENERAL_NAME *gen, + const GENERAL_NAME *gen, STACK_OF(CONF_VALUE) *ret) { // Note the error-handling for this function relies on there being at most // one |X509V3_add_value| call. If there were two and the second failed, we @@ -204,9 +207,7 @@ STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(const X509V3_EXT_METHOD *method, return ret; } -int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen) { - unsigned char *p; - int i; +int GENERAL_NAME_print(BIO *out, const GENERAL_NAME *gen) { switch (gen->type) { case GEN_OTHERNAME: BIO_printf(out, "othername:"); @@ -241,13 +242,13 @@ int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen) { X509_NAME_print_ex(out, gen->d.dirn, 0, XN_FLAG_ONELINE); break; - case GEN_IPADD: - p = gen->d.ip->data; + case GEN_IPADD: { + const unsigned char *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++) { + for (int i = 0; i < 8; i++) { uint16_t v = ((uint16_t)p[0] << 8) | p[1]; BIO_printf(out, ":%X", v); p += 2; @@ -258,6 +259,7 @@ int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen) { break; } break; + } case GEN_RID: BIO_printf(out, "Registered ID"); @@ -267,28 +269,26 @@ int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen) { return 1; } -static void *v2i_issuer_alt(const X509V3_EXT_METHOD *method, 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); +static void *v2i_issuer_alt(const X509V3_EXT_METHOD *method, + const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *nval) { + GENERAL_NAMES *gens = sk_GENERAL_NAME_new_null(); + if (gens == NULL) { return NULL; } - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { - cnf = sk_CONF_VALUE_value(nval, i); - if (!x509v3_name_cmp(cnf->name, "issuer") && cnf->value && + for (size_t i = 0; i < sk_CONF_VALUE_num(nval); i++) { + const CONF_VALUE *cnf = sk_CONF_VALUE_value(nval, i); + if (x509v3_conf_name_matches(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))) { + GENERAL_NAME *gen = v2i_GENERAL_NAME(method, ctx, cnf); + if (gen == NULL || !sk_GENERAL_NAME_push(gens, gen)) { + GENERAL_NAME_free(gen); goto err; } - sk_GENERAL_NAME_push(gens, gen); } } return gens; @@ -299,8 +299,8 @@ static void *v2i_issuer_alt(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, // Append subject altname of issuer to issuer alt name of subject -static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens) { - if (ctx && (ctx->flags == CTX_TEST)) { +static int copy_issuer(const X509V3_CTX *ctx, GENERAL_NAMES *gens) { + if (ctx && (ctx->flags == X509V3_CTX_TEST)) { return 1; } if (!ctx || !ctx->issuer_cert) { @@ -324,7 +324,6 @@ static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens) { for (size_t j = 0; j < sk_GENERAL_NAME_num(ialt); j++) { GENERAL_NAME *gen = sk_GENERAL_NAME_value(ialt, j); if (!sk_GENERAL_NAME_push(gens, gen)) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); goto err; } // Ownership of |gen| has moved from |ialt| to |gens|. @@ -338,33 +337,31 @@ static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens) { return ret; } -static void *v2i_subject_alt(const X509V3_EXT_METHOD *method, 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); +static void *v2i_subject_alt(const X509V3_EXT_METHOD *method, + const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *nval) { + GENERAL_NAMES *gens = sk_GENERAL_NAME_new_null(); + if (gens == NULL) { return NULL; } - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { - cnf = sk_CONF_VALUE_value(nval, i); - if (!x509v3_name_cmp(cnf->name, "email") && cnf->value && + for (size_t i = 0; i < sk_CONF_VALUE_num(nval); i++) { + const CONF_VALUE *cnf = sk_CONF_VALUE_value(nval, i); + if (x509v3_conf_name_matches(cnf->name, "email") && cnf->value && !strcmp(cnf->value, "copy")) { if (!copy_email(ctx, gens, 0)) { goto err; } - } else if (!x509v3_name_cmp(cnf->name, "email") && cnf->value && + } else if (x509v3_conf_name_matches(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))) { + GENERAL_NAME *gen = v2i_GENERAL_NAME(method, ctx, cnf); + if (gen == NULL || !sk_GENERAL_NAME_push(gens, gen)) { + GENERAL_NAME_free(gen); goto err; } - sk_GENERAL_NAME_push(gens, gen); } } return gens; @@ -375,13 +372,13 @@ static void *v2i_subject_alt(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, // 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) { +static int copy_email(const 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) { + if (ctx != NULL && ctx->flags == X509V3_CTX_TEST) { return 1; } if (!ctx || (!ctx->subject_cert && !ctx->subject_req)) { @@ -406,14 +403,12 @@ static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p) { 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; @@ -428,21 +423,19 @@ static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p) { } GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method, - 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); + const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *nval) { + GENERAL_NAMES *gens = sk_GENERAL_NAME_new_null(); + if (gens == NULL) { 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))) { + for (size_t i = 0; i < sk_CONF_VALUE_num(nval); i++) { + const CONF_VALUE *cnf = sk_CONF_VALUE_value(nval, i); + GENERAL_NAME *gen = v2i_GENERAL_NAME(method, ctx, cnf); + if (gen == NULL || !sk_GENERAL_NAME_push(gens, gen)) { + GENERAL_NAME_free(gen); goto err; } - sk_GENERAL_NAME_push(gens, gen); } return gens; err: @@ -450,28 +443,26 @@ GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method, return NULL; } -GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, - CONF_VALUE *cnf) { +GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, + const X509V3_CTX *ctx, const 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, const char *value, int is_nc) { - char is_string = 0; - GENERAL_NAME *gen = NULL; - + const X509V3_EXT_METHOD *method, + const X509V3_CTX *ctx, int gen_type, + const char *value, int is_nc) { if (!value) { OPENSSL_PUT_ERROR(X509V3, X509V3_R_MISSING_VALUE); return NULL; } + GENERAL_NAME *gen = NULL; if (out) { gen = out; } else { gen = GENERAL_NAME_new(); if (gen == NULL) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); return NULL; } } @@ -479,9 +470,16 @@ GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, switch (gen_type) { case GEN_URI: case GEN_EMAIL: - case GEN_DNS: - is_string = 1; + case GEN_DNS: { + ASN1_IA5STRING *str = ASN1_IA5STRING_new(); + if (str == NULL || !ASN1_STRING_set(str, value, strlen(value))) { + ASN1_STRING_free(str); + goto err; + } + gen->type = gen_type; + gen->d.ia5 = str; break; + } case GEN_RID: { ASN1_OBJECT *obj; @@ -490,10 +488,13 @@ GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, ERR_add_error_data(2, "value=", value); goto err; } + gen->type = GEN_RID; gen->d.rid = obj; - } break; + break; + } case GEN_IPADD: + gen->type = GEN_IPADD; if (is_nc) { gen->d.ip = a2i_IPADDRESS_NC(value); } else { @@ -524,16 +525,6 @@ GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, goto err; } - if (is_string) { - if (!(gen->d.ia5 = 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: @@ -545,32 +536,29 @@ GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, 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; - + const X509V3_CTX *ctx, const CONF_VALUE *cnf, + int is_nc) { + const char *name = cnf->name; + const char *value = cnf->value; if (!value) { OPENSSL_PUT_ERROR(X509V3, X509V3_R_MISSING_VALUE); return NULL; } - if (!x509v3_name_cmp(name, "email")) { + int type; + if (x509v3_conf_name_matches(name, "email")) { type = GEN_EMAIL; - } else if (!x509v3_name_cmp(name, "URI")) { + } else if (x509v3_conf_name_matches(name, "URI")) { type = GEN_URI; - } else if (!x509v3_name_cmp(name, "DNS")) { + } else if (x509v3_conf_name_matches(name, "DNS")) { type = GEN_DNS; - } else if (!x509v3_name_cmp(name, "RID")) { + } else if (x509v3_conf_name_matches(name, "RID")) { type = GEN_RID; - } else if (!x509v3_name_cmp(name, "IP")) { + } else if (x509v3_conf_name_matches(name, "IP")) { type = GEN_IPADD; - } else if (!x509v3_name_cmp(name, "dirName")) { + } else if (x509v3_conf_name_matches(name, "dirName")) { type = GEN_DIRNAME; - } else if (!x509v3_name_cmp(name, "otherName")) { + } else if (x509v3_conf_name_matches(name, "otherName")) { type = GEN_OTHERNAME; } else { OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNSUPPORTED_OPTION); @@ -581,44 +569,52 @@ GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out, return a2i_GENERAL_NAME(out, method, ctx, type, value, is_nc); } -static int do_othername(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx) { - char *objtmp = NULL; - const char *p; - int objlen; - if (!(p = strchr(value, ';'))) { +static int do_othername(GENERAL_NAME *gen, const char *value, + const X509V3_CTX *ctx) { + const char *semicolon = strchr(value, ';'); + if (semicolon == NULL) { 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))) { + + OTHERNAME *name = OTHERNAME_new(); + if (name == NULL) { return 0; } - objlen = p - value; - objtmp = OPENSSL_malloc(objlen + 1); + + char *objtmp = OPENSSL_strndup(value, semicolon - value); if (objtmp == NULL) { - return 0; + goto err; } - OPENSSL_strlcpy(objtmp, value, objlen + 1); - gen->d.otherName->type_id = OBJ_txt2obj(objtmp, 0); + ASN1_OBJECT_free(name->type_id); + name->type_id = OBJ_txt2obj(objtmp, /*dont_search_names=*/0); OPENSSL_free(objtmp); - if (!gen->d.otherName->type_id) { - return 0; + if (name->type_id == NULL) { + goto err; + } + + ASN1_TYPE_free(name->value); + name->value = ASN1_generate_v3(semicolon + 1, ctx); + if (name->value == NULL) { + goto err; } + + gen->type = GEN_OTHERNAME; + gen->d.otherName = name; return 1; + +err: + OTHERNAME_free(name); + return 0; } -static int do_dirname(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx) { +static int do_dirname(GENERAL_NAME *gen, const char *value, + const 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); + const STACK_OF(CONF_VALUE) *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); @@ -628,6 +624,7 @@ static int do_dirname(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx) { if (!X509V3_NAME_from_section(nm, sk, MBSTRING_ASC)) { goto err; } + gen->type = GEN_DIRNAME; gen->d.dirn = nm; ret = 1; @@ -635,6 +632,5 @@ static int do_dirname(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx) { if (!ret) { X509_NAME_free(nm); } - X509V3_section_free(ctx, sk); return ret; } diff --git a/Sources/CNIOBoringSSL/crypto/x509v3/v3_bcons.c b/Sources/CNIOBoringSSL/crypto/x509v3/v3_bcons.c index 2415d4ba..948882b4 100644 --- a/Sources/CNIOBoringSSL/crypto/x509v3/v3_bcons.c +++ b/Sources/CNIOBoringSSL/crypto/x509v3/v3_bcons.c @@ -1,4 +1,3 @@ -/* v3_bcons.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 1999. @@ -65,11 +64,14 @@ #include #include +#include "internal.h" + + static STACK_OF(CONF_VALUE) *i2v_BASIC_CONSTRAINTS( const X509V3_EXT_METHOD *method, void *ext, STACK_OF(CONF_VALUE) *extlist); static void *v2i_BASIC_CONSTRAINTS(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *values); + const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *values); const X509V3_EXT_METHOD v3_bcons = { NID_basic_constraints, @@ -104,17 +106,14 @@ static STACK_OF(CONF_VALUE) *i2v_BASIC_CONSTRAINTS( } static void *v2i_BASIC_CONSTRAINTS(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *values) { + const X509V3_CTX *ctx, + const 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); + for (size_t i = 0; i < sk_CONF_VALUE_num(values); i++) { + const CONF_VALUE *val = sk_CONF_VALUE_value(values, i); if (!strcmp(val->name, "CA")) { if (!X509V3_get_value_bool(val, &bcons->ca)) { goto err; diff --git a/Sources/CNIOBoringSSL/crypto/x509v3/v3_bitst.c b/Sources/CNIOBoringSSL/crypto/x509v3/v3_bitst.c index 5f8d84f3..8f1e2b26 100644 --- a/Sources/CNIOBoringSSL/crypto/x509v3/v3_bitst.c +++ b/Sources/CNIOBoringSSL/crypto/x509v3/v3_bitst.c @@ -1,4 +1,3 @@ -/* v3_bitst.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 1999. @@ -102,21 +101,18 @@ static STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING( } static void *v2i_ASN1_BIT_STRING(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) { - CONF_VALUE *val; + const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *nval) { ASN1_BIT_STRING *bs; - size_t i; - const BIT_STRING_BITNAME *bnam; if (!(bs = 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 (size_t i = 0; i < sk_CONF_VALUE_num(nval); i++) { + const CONF_VALUE *val = sk_CONF_VALUE_value(nval, i); + const BIT_STRING_BITNAME *bnam; 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); ASN1_BIT_STRING_free(bs); return NULL; } diff --git a/Sources/CNIOBoringSSL/crypto/x509v3/v3_conf.c b/Sources/CNIOBoringSSL/crypto/x509v3/v3_conf.c index 3460c3fe..0f8170d2 100644 --- a/Sources/CNIOBoringSSL/crypto/x509v3/v3_conf.c +++ b/Sources/CNIOBoringSSL/crypto/x509v3/v3_conf.c @@ -1,4 +1,3 @@ -/* v3_conf.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 1999. @@ -58,6 +57,7 @@ // extension creation utilities #include +#include #include #include @@ -74,28 +74,32 @@ static int v3_check_critical(const char **value); static int v3_check_generic(const char **value); -static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid, - int crit, const char *value); +static X509_EXTENSION *do_ext_nconf(const CONF *conf, const X509V3_CTX *ctx, + int ext_nid, int crit, const char *value); static X509_EXTENSION *v3_generic_extension(const char *ext, const char *value, int crit, int type, - X509V3_CTX *ctx); + const 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(const char *value, X509V3_CTX *ctx, - long *ext_len); -// CONF *conf: Config file -// char *name: Name -// char *value: Value -X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, const char *name, - const char *value) { - int crit; - int ext_type; - X509_EXTENSION *ret; - crit = v3_check_critical(&value); - if ((ext_type = v3_check_generic(&value))) { +static unsigned char *generic_asn1(const char *value, const X509V3_CTX *ctx, + size_t *ext_len); + +X509_EXTENSION *X509V3_EXT_nconf(const CONF *conf, const X509V3_CTX *ctx, + const char *name, const char *value) { + // If omitted, fill in an empty |X509V3_CTX|. + X509V3_CTX ctx_tmp; + if (ctx == NULL) { + X509V3_set_ctx(&ctx_tmp, NULL, NULL, NULL, NULL, 0); + X509V3_set_nconf(&ctx_tmp, conf); + ctx = &ctx_tmp; + } + + int crit = v3_check_critical(&value); + int ext_type = v3_check_generic(&value); + if (ext_type != 0) { return v3_generic_extension(name, value, crit, ext_type, ctx); } - ret = do_ext_nconf(conf, ctx, OBJ_sn2nid(name), crit, value); + X509_EXTENSION *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); @@ -103,14 +107,19 @@ X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, const char *name, return ret; } -// CONF *conf: Config file -// char *value: Value -X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, - const char *value) { - int crit; - int ext_type; - crit = v3_check_critical(&value); - if ((ext_type = v3_check_generic(&value))) { +X509_EXTENSION *X509V3_EXT_nconf_nid(const CONF *conf, const X509V3_CTX *ctx, + int ext_nid, const char *value) { + // If omitted, fill in an empty |X509V3_CTX|. + X509V3_CTX ctx_tmp; + if (ctx == NULL) { + X509V3_set_ctx(&ctx_tmp, NULL, NULL, NULL, NULL, 0); + X509V3_set_nconf(&ctx_tmp, conf); + ctx = &ctx_tmp; + } + + int crit = v3_check_critical(&value); + int ext_type = v3_check_generic(&value); + if (ext_type != 0) { return v3_generic_extension(OBJ_nid2sn(ext_nid), value, crit, ext_type, ctx); } @@ -119,11 +128,12 @@ X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, // CONF *conf: Config file // char *value: Value -static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid, - int crit, const char *value) { +static X509_EXTENSION *do_ext_nconf(const CONF *conf, const X509V3_CTX *ctx, + int ext_nid, int crit, const char *value) { const X509V3_EXT_METHOD *method; X509_EXTENSION *ext; - STACK_OF(CONF_VALUE) *nval; + const STACK_OF(CONF_VALUE) *nval; + STACK_OF(CONF_VALUE) *nval_owned = NULL; void *ext_struc; if (ext_nid == NID_undef) { OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_EXTENSION_NAME); @@ -136,22 +146,26 @@ static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid, // Now get internal extension representation based on type if (method->v2i) { if (*value == '@') { + // TODO(davidben): This is the only place where |X509V3_EXT_nconf|'s + // |conf| parameter is used. All other codepaths use the copy inside + // |ctx|. Should this be switched and then the parameter ignored? + if (conf == NULL) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_CONFIG_DATABASE); + return NULL; + } nval = NCONF_get_section(conf, value + 1); } else { - nval = X509V3_parse_list(value); + nval_owned = X509V3_parse_list(value); + nval = nval_owned; } if (nval == NULL || 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); - if (*value != '@') { - sk_CONF_VALUE_pop_free(nval, X509V3_conf_free); - } + sk_CONF_VALUE_pop_free(nval_owned, X509V3_conf_free); return NULL; } ext_struc = method->v2i(method, ctx, nval); - if (*value != '@') { - sk_CONF_VALUE_pop_free(nval, X509V3_conf_free); - } + sk_CONF_VALUE_pop_free(nval_owned, X509V3_conf_free); if (!ext_struc) { return NULL; } @@ -160,7 +174,11 @@ static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid, return NULL; } } else if (method->r2i) { - if (!ctx->db || !ctx->db_meth) { + // TODO(davidben): Should this check be removed? This matches OpenSSL, but + // r2i-based extensions do not necessarily require a config database. The + // two built-in extensions only use it some of the time, and already handle + // |X509V3_get_section| returning NULL. + if (!ctx->db) { OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_CONFIG_DATABASE); return NULL; } @@ -184,43 +202,38 @@ static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid, static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid, int crit, void *ext_struc) { + // Convert the extension's internal representation to DER. 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; + return NULL; } } else { - unsigned char *p; + // TODO(davidben): Remove support for the "old-style" ASN.1 callbacks. Every + // |X509V3_EXT_METHOD|, both inside and outside the library, has an + // |ASN1_ITEM|, and this codepath is missing handling. ext_len = method->i2d(ext_struc, NULL); if (!(ext_der = OPENSSL_malloc(ext_len))) { - goto merr; + return NULL; } - p = ext_der; + unsigned char *p = ext_der; method->i2d(ext_struc, &p); } - if (!(ext_oct = 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; + ASN1_OCTET_STRING *ext_oct = ASN1_OCTET_STRING_new(); + if (ext_oct == NULL) { + OPENSSL_free(ext_der); + return NULL; } - ASN1_OCTET_STRING_free(ext_oct); + ASN1_STRING_set0(ext_oct, ext_der, ext_len); + X509_EXTENSION *ext = + X509_EXTENSION_create_by_NID(NULL, ext_nid, crit, ext_oct); + 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 @@ -241,7 +254,7 @@ static int v3_check_critical(const char **value) { return 0; } p += 9; - while (isspace((unsigned char)*p)) { + while (OPENSSL_isspace((unsigned char)*p)) { p++; } *value = p; @@ -262,7 +275,7 @@ static int v3_check_generic(const char **value) { return 0; } - while (isspace((unsigned char)*p)) { + while (OPENSSL_isspace((unsigned char)*p)) { p++; } *value = p; @@ -272,9 +285,9 @@ static int v3_check_generic(const char **value) { // Create a generic extension: for now just handle DER type static X509_EXTENSION *v3_generic_extension(const char *ext, const char *value, int crit, int gen_type, - X509V3_CTX *ctx) { + const X509V3_CTX *ctx) { unsigned char *ext_der = NULL; - long ext_len = 0; + size_t ext_len = 0; ASN1_OBJECT *obj = NULL; ASN1_OCTET_STRING *oct = NULL; X509_EXTENSION *extension = NULL; @@ -296,13 +309,17 @@ static X509_EXTENSION *v3_generic_extension(const char *ext, const char *value, goto err; } - if (!(oct = ASN1_OCTET_STRING_new())) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + if (ext_len > INT_MAX) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_OVERFLOW); + goto err; + } + + oct = ASN1_OCTET_STRING_new(); + if (oct == NULL) { goto err; } - oct->data = ext_der; - oct->length = ext_len; + ASN1_STRING_set0(oct, ext_der, (int)ext_len); ext_der = NULL; extension = X509_EXTENSION_create_by_OBJ(NULL, obj, crit, oct); @@ -314,48 +331,49 @@ static X509_EXTENSION *v3_generic_extension(const char *ext, const char *value, return extension; } -static unsigned char *generic_asn1(const char *value, X509V3_CTX *ctx, - long *ext_len) { - ASN1_TYPE *typ; - unsigned char *ext_der = NULL; - typ = ASN1_generate_v3(value, ctx); +static unsigned char *generic_asn1(const char *value, const X509V3_CTX *ctx, + size_t *ext_len) { + ASN1_TYPE *typ = ASN1_generate_v3(value, ctx); if (typ == NULL) { return NULL; } - *ext_len = i2d_ASN1_TYPE(typ, &ext_der); + unsigned char *ext_der = NULL; + int len = i2d_ASN1_TYPE(typ, &ext_der); ASN1_TYPE_free(typ); + if (len < 0) { + return NULL; + } + *ext_len = len; 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, const char *section, +int X509V3_EXT_add_nconf_sk(const CONF *conf, const X509V3_CTX *ctx, + const 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))) { + const STACK_OF(CONF_VALUE) *nval = NCONF_get_section(conf, section); + if (nval == NULL) { 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))) { + for (size_t i = 0; i < sk_CONF_VALUE_num(nval); i++) { + const CONF_VALUE *val = sk_CONF_VALUE_value(nval, i); + X509_EXTENSION *ext = X509V3_EXT_nconf(conf, ctx, val->name, val->value); + int ok = ext != NULL && // + (sk == NULL || X509v3_add_ext(sk, ext, -1) != NULL); + X509_EXTENSION_free(ext); + if (!ok) { 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, const char *section, - X509 *cert) { +int X509V3_EXT_add_nconf(const CONF *conf, const X509V3_CTX *ctx, + const char *section, X509 *cert) { STACK_OF(X509_EXTENSION) **sk = NULL; if (cert) { sk = &cert->cert_info->extensions; @@ -365,8 +383,8 @@ int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, // Same as above but for a CRL -int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, - X509_CRL *crl) { +int X509V3_EXT_CRL_add_nconf(const CONF *conf, const X509V3_CTX *ctx, + const char *section, X509_CRL *crl) { STACK_OF(X509_EXTENSION) **sk = NULL; if (crl) { sk = &crl->crl->extensions; @@ -376,8 +394,8 @@ int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, // Add extensions to certificate request -int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, - X509_REQ *req) { +int X509V3_EXT_REQ_add_nconf(const CONF *conf, const X509V3_CTX *ctx, + const char *section, X509_REQ *req) { STACK_OF(X509_EXTENSION) *extlist = NULL, **sk = NULL; int i; if (req) { @@ -394,71 +412,22 @@ int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, // Config database functions -char *X509V3_get_string(X509V3_CTX *ctx, const char *name, - const 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, const char *section) { - if (!ctx->db || !ctx->db_meth || !ctx->db_meth->get_section) { +const STACK_OF(CONF_VALUE) *X509V3_get_section(const X509V3_CTX *ctx, + const char *section) { + if (ctx->db == NULL) { 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); - } -} - -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); - } -} - -static char *nconf_get_string(void *db, const char *section, - const char *value) { - // TODO(fork): This returns a non-const pointer because |X509V3_CONF_METHOD| - // allows |get_string| to return caller-owned pointers, provided they're - // freed by |free_string|. |nconf_method| leaves |free_string| NULL, and - // there are no other implementations of |X509V3_CONF_METHOD|, so this can - // be simplified if we make it private. - return (char *)NCONF_get_string(db, section, value); + return NCONF_get_section(ctx->db, section); } -static STACK_OF(CONF_VALUE) *nconf_get_section(void *db, const char *section) { - return NCONF_get_section(db, section); -} - -static const X509V3_CONF_METHOD nconf_method = {nconf_get_string, - nconf_get_section, NULL, NULL}; - -void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf) { - ctx->db_meth = &nconf_method; +void X509V3_set_nconf(X509V3_CTX *ctx, const CONF *conf) { ctx->db = conf; } -void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subj, X509_REQ *req, - X509_CRL *crl, int flags) { +void X509V3_set_ctx(X509V3_CTX *ctx, const X509 *issuer, const X509 *subj, + const X509_REQ *req, const X509_CRL *crl, int flags) { + OPENSSL_memset(ctx, 0, sizeof(*ctx)); ctx->issuer_cert = issuer; ctx->subject_cert = subj; ctx->crl = crl; diff --git a/Sources/CNIOBoringSSL/crypto/x509v3/v3_cpols.c b/Sources/CNIOBoringSSL/crypto/x509v3/v3_cpols.c index d7a6746c..bd6ccf6e 100644 --- a/Sources/CNIOBoringSSL/crypto/x509v3/v3_cpols.c +++ b/Sources/CNIOBoringSSL/crypto/x509v3/v3_cpols.c @@ -1,4 +1,3 @@ -/* v3_cpols.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 1999. @@ -75,16 +74,19 @@ static int i2r_certpol(const X509V3_EXT_METHOD *method, void *ext, BIO *out, int indent); -static void *r2i_certpol(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, +static void *r2i_certpol(const X509V3_EXT_METHOD *method, const X509V3_CTX *ctx, const char *value); static void print_qualifiers(BIO *out, const STACK_OF(POLICYQUALINFO) *quals, int indent); static void print_notice(BIO *out, const USERNOTICE *notice, int indent); -static POLICYINFO *policy_section(X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *polstrs, int ia5org); -static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *unot, int ia5org); -static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos); +static POLICYINFO *policy_section(const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *polstrs, + int ia5org); +static POLICYQUALINFO *notice_section(const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *unot, + int ia5org); +static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, + const STACK_OF(CONF_VALUE) *nos); const X509V3_EXT_METHOD v3_cpols = { NID_certificate_policies, @@ -147,41 +149,32 @@ ASN1_SEQUENCE(NOTICEREF) = { IMPLEMENT_ASN1_FUNCTIONS_const(NOTICEREF) -static void *r2i_certpol(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, +static void *r2i_certpol(const X509V3_EXT_METHOD *method, const X509V3_CTX *ctx, const 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(); + STACK_OF(POLICYINFO) *pols = sk_POLICYINFO_new_null(); if (pols == NULL) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); return NULL; } - vals = X509V3_parse_list(value); + STACK_OF(CONF_VALUE) *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); + int ia5org = 0; + for (size_t i = 0; i < sk_CONF_VALUE_num(vals); i++) { + const CONF_VALUE *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; + POLICYINFO *pol; + const char *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); + const STACK_OF(CONF_VALUE) *polsect = X509V3_get_section(ctx, pstr + 1); if (!polsect) { OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SECTION); @@ -189,19 +182,18 @@ static void *r2i_certpol(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, 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))) { + ASN1_OBJECT *pobj = OBJ_txt2obj(cnf->name, 0); + if (pobj == NULL) { 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; } @@ -209,7 +201,6 @@ static void *r2i_certpol(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, } if (!sk_POLICYINFO_push(pols, pol)) { POLICYINFO_free(pol); - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); goto err; } } @@ -221,17 +212,16 @@ static void *r2i_certpol(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, return NULL; } -static POLICYINFO *policy_section(X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *polstrs, int ia5org) { - size_t i; - CONF_VALUE *cnf; +static POLICYINFO *policy_section(const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *polstrs, + int ia5org) { POLICYINFO *pol; POLICYQUALINFO *qual; if (!(pol = POLICYINFO_new())) { - goto merr; + goto err; } - for (i = 0; i < sk_CONF_VALUE_num(polstrs); i++) { - cnf = sk_CONF_VALUE_value(polstrs, i); + for (size_t i = 0; i < sk_CONF_VALUE_num(polstrs); i++) { + const CONF_VALUE *cnf = sk_CONF_VALUE_value(polstrs, i); if (!strcmp(cnf->name, "policyIdentifier")) { ASN1_OBJECT *pobj; if (!(pobj = OBJ_txt2obj(cnf->value, 0))) { @@ -241,15 +231,15 @@ static POLICYINFO *policy_section(X509V3_CTX *ctx, } pol->policyid = pobj; - } else if (!x509v3_name_cmp(cnf->name, "CPS")) { + } else if (x509v3_conf_name_matches(cnf->name, "CPS")) { if (!pol->qualifiers) { pol->qualifiers = sk_POLICYQUALINFO_new_null(); } if (!(qual = POLICYQUALINFO_new())) { - goto merr; + goto err; } if (!sk_POLICYQUALINFO_push(pol->qualifiers, qual)) { - goto merr; + goto err; } qual->pqualid = OBJ_nid2obj(NID_id_qt_cps); if (qual->pqualid == NULL) { @@ -261,24 +251,22 @@ static POLICYINFO *policy_section(X509V3_CTX *ctx, goto err; } if (!ASN1_STRING_set(qual->d.cpsuri, cnf->value, strlen(cnf->value))) { - goto merr; + goto err; } - } else if (!x509v3_name_cmp(cnf->name, "userNotice")) { - STACK_OF(CONF_VALUE) *unot; + } else if (x509v3_conf_name_matches(cnf->name, "userNotice")) { 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); + const STACK_OF(CONF_VALUE) *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; } @@ -286,7 +274,7 @@ static POLICYINFO *policy_section(X509V3_CTX *ctx, pol->qualifiers = sk_POLICYQUALINFO_new_null(); } if (!sk_POLICYQUALINFO_push(pol->qualifiers, qual)) { - goto merr; + goto err; } } else { OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OPTION); @@ -302,52 +290,47 @@ static POLICYINFO *policy_section(X509V3_CTX *ctx, 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) { - size_t i; - int ret; - CONF_VALUE *cnf; - USERNOTICE * not ; +static POLICYQUALINFO *notice_section(const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *unot, + int ia5org) { + USERNOTICE *notice; POLICYQUALINFO *qual; if (!(qual = POLICYQUALINFO_new())) { - goto merr; + goto err; } qual->pqualid = 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; + if (!(notice = USERNOTICE_new())) { + goto err; } - qual->d.usernotice = not ; - for (i = 0; i < sk_CONF_VALUE_num(unot); i++) { - cnf = sk_CONF_VALUE_value(unot, i); + qual->d.usernotice = notice; + for (size_t i = 0; i < sk_CONF_VALUE_num(unot); i++) { + const CONF_VALUE *cnf = sk_CONF_VALUE_value(unot, i); if (!strcmp(cnf->name, "explicitText")) { - not ->exptext = ASN1_VISIBLESTRING_new(); - if (not ->exptext == NULL) { - goto merr; + notice->exptext = ASN1_VISIBLESTRING_new(); + if (notice->exptext == NULL) { + goto err; } - if (!ASN1_STRING_set(not ->exptext, cnf->value, strlen(cnf->value))) { - goto merr; + if (!ASN1_STRING_set(notice->exptext, cnf->value, strlen(cnf->value))) { + goto err; } } else if (!strcmp(cnf->name, "organization")) { NOTICEREF *nref; - if (!not ->noticeref) { + if (!notice->noticeref) { if (!(nref = NOTICEREF_new())) { - goto merr; + goto err; } - not ->noticeref = nref; + notice->noticeref = nref; } else { - nref = not ->noticeref; + nref = notice->noticeref; } if (ia5org) { nref->organization->type = V_ASN1_IA5STRING; @@ -356,26 +339,27 @@ static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, } if (!ASN1_STRING_set(nref->organization, cnf->value, strlen(cnf->value))) { - goto merr; + goto err; } } else if (!strcmp(cnf->name, "noticeNumbers")) { NOTICEREF *nref; STACK_OF(CONF_VALUE) *nos; - if (!not ->noticeref) { + if (!notice->noticeref) { if (!(nref = NOTICEREF_new())) { - goto merr; + goto err; } - not ->noticeref = nref; + notice->noticeref = nref; } else { - nref = not ->noticeref; + nref = notice->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); + sk_CONF_VALUE_pop_free(nos, X509V3_conf_free); goto err; } - ret = nref_nos(nref->noticenos, nos); + int ret = nref_nos(nref->noticenos, nos); sk_CONF_VALUE_pop_free(nos, X509V3_conf_free); if (!ret) { goto err; @@ -387,46 +371,34 @@ static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, } } - if (not ->noticeref && - (!not ->noticeref->noticenos || !not ->noticeref->organization)) { + if (notice->noticeref && + (!notice->noticeref->noticenos || !notice->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))) { +static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, + const STACK_OF(CONF_VALUE) *nos) { + for (size_t i = 0; i < sk_CONF_VALUE_num(nos); i++) { + const CONF_VALUE *cnf = sk_CONF_VALUE_value(nos, i); + ASN1_INTEGER *aint = s2i_ASN1_INTEGER(NULL, cnf->name); + if (aint == NULL) { OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NUMBER); - goto err; + return 0; } if (!sk_ASN1_INTEGER_push(nnums, aint)) { - goto merr; + ASN1_INTEGER_free(aint); + return 0; } } return 1; - -merr: - ASN1_INTEGER_free(aint); - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - -err: - return 0; } static int i2r_certpol(const X509V3_EXT_METHOD *method, void *ext, BIO *out, @@ -503,19 +475,3 @@ static void print_notice(BIO *out, const USERNOTICE *notice, int indent) { notice->exptext->length, 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, ""); - } -} diff --git a/Sources/CNIOBoringSSL/crypto/x509v3/v3_crld.c b/Sources/CNIOBoringSSL/crypto/x509v3/v3_crld.c index 681bf614..a3a858aa 100644 --- a/Sources/CNIOBoringSSL/crypto/x509v3/v3_crld.c +++ b/Sources/CNIOBoringSSL/crypto/x509v3/v3_crld.c @@ -1,4 +1,3 @@ -/* v3_crld.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 1999. @@ -70,8 +69,8 @@ #include "internal.h" -static void *v2i_crld(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval); +static void *v2i_crld(const X509V3_EXT_METHOD *method, const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *nval); static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out, int indent); @@ -109,59 +108,68 @@ const X509V3_EXT_METHOD v3_freshest_crl = { NULL, }; -static STACK_OF(GENERAL_NAME) *gnames_from_sectname(X509V3_CTX *ctx, +static STACK_OF(GENERAL_NAME) *gnames_from_sectname(const X509V3_CTX *ctx, char *sect) { - STACK_OF(CONF_VALUE) *gnsect; - STACK_OF(GENERAL_NAME) *gens; + const STACK_OF(CONF_VALUE) *gnsect; + STACK_OF(CONF_VALUE) *gnsect_owned = NULL; if (*sect == '@') { gnsect = X509V3_get_section(ctx, sect + 1); } else { - gnsect = X509V3_parse_list(sect); + gnsect_owned = X509V3_parse_list(sect); + gnsect = gnsect_owned; } 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); - } + STACK_OF(GENERAL_NAME) *gens = v2i_GENERAL_NAMES(NULL, ctx, gnsect); + sk_CONF_VALUE_pop_free(gnsect_owned, X509V3_conf_free); return gens; } -static int set_dist_point_name(DIST_POINT_NAME **pdp, X509V3_CTX *ctx, - CONF_VALUE *cnf) { +// set_dist_point_name decodes a DistributionPointName from |cnf| and writes the +// result in |*pdp|. It returns 1 on success, -1 on error, and 0 if |cnf| used +// an unrecognized input type. The zero return can be used by callers to support +// additional syntax. +static int set_dist_point_name(DIST_POINT_NAME **pdp, const X509V3_CTX *ctx, + const CONF_VALUE *cnf) { STACK_OF(GENERAL_NAME) *fnm = NULL; STACK_OF(X509_NAME_ENTRY) *rnm = NULL; if (!strncmp(cnf->name, "fullname", 9)) { + // If |cnf| comes from |X509V3_parse_list|, which is possible for a v2i + // function, |cnf->value| may be NULL. + if (cnf->value == NULL) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_MISSING_VALUE); + return -1; + } 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) { + // If |cnf| comes from |X509V3_parse_list|, which is possible for a v2i + // function, |cnf->value| may be NULL. + if (cnf->value == NULL) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_MISSING_VALUE); return -1; } - dnsect = X509V3_get_section(ctx, cnf->value); + const STACK_OF(CONF_VALUE) *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); + X509_NAME *nm = X509_NAME_new(); + if (!nm) { + return -1; + } + int ret = X509V3_NAME_from_section(nm, dnsect, MBSTRING_ASC); 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 + // There can only be one RDN in nameRelativeToCRLIssuer. 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; @@ -207,27 +215,26 @@ static const BIT_STRING_BITNAME reason_flags[] = { {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) { +static int set_reasons(ASN1_BIT_STRING **preas, const char *value) { + if (*preas) { + // Duplicate "reasons" or "onlysomereasons" key. + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_VALUE); return 0; } - if (*preas) { + int ret = 0; + STACK_OF(CONF_VALUE) *rsk = X509V3_parse_list(value); + if (!rsk) { return 0; } - for (i = 0; i < sk_CONF_VALUE_num(rsk); i++) { - bnam = sk_CONF_VALUE_value(rsk, i)->name; + for (size_t i = 0; i < sk_CONF_VALUE_num(rsk); i++) { + const char *bnam = sk_CONF_VALUE_value(rsk, i)->name; if (!*preas) { *preas = ASN1_BIT_STRING_new(); if (!*preas) { goto err; } } + const BIT_STRING_BITNAME *pbn; for (pbn = reason_flags; pbn->lname; pbn++) { if (!strcmp(pbn->sname, bnam)) { if (!ASN1_BIT_STRING_set_bit(*preas, pbn->bitnum, 1)) { @@ -270,19 +277,16 @@ static int print_reasons(BIO *out, const char *rname, ASN1_BIT_STRING *rflags, return 1; } -static DIST_POINT *crldp_from_section(X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval) { - size_t i; - CONF_VALUE *cnf; +static DIST_POINT *crldp_from_section(const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *nval) { 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); + for (size_t i = 0; i < sk_CONF_VALUE_num(nval); i++) { + const CONF_VALUE *cnf = sk_CONF_VALUE_value(nval, i); + int ret = set_dist_point_name(&point->distpoint, ctx, cnf); if (ret > 0) { continue; } @@ -294,6 +298,7 @@ static DIST_POINT *crldp_from_section(X509V3_CTX *ctx, goto err; } } else if (!strcmp(cnf->name, "CRLissuer")) { + GENERAL_NAMES_free(point->CRLissuer); point->CRLissuer = gnames_from_sectname(ctx, cnf->value); if (!point->CRLissuer) { goto err; @@ -308,54 +313,50 @@ static DIST_POINT *crldp_from_section(X509V3_CTX *ctx, return NULL; } -static void *v2i_crld(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval) { +static void *v2i_crld(const X509V3_EXT_METHOD *method, const X509V3_CTX *ctx, + const 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; + goto err; } - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + for (size_t i = 0; i < sk_CONF_VALUE_num(nval); i++) { DIST_POINT *point; - cnf = sk_CONF_VALUE_value(nval, i); + const CONF_VALUE *cnf = sk_CONF_VALUE_value(nval, i); if (!cnf->value) { - STACK_OF(CONF_VALUE) *dpsect; - dpsect = X509V3_get_section(ctx, cnf->name); + const STACK_OF(CONF_VALUE) *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; + goto err; } } else { if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) { goto err; } if (!(gens = GENERAL_NAMES_new())) { - goto merr; + goto err; } if (!sk_GENERAL_NAME_push(gens, gen)) { - goto merr; + goto err; } gen = NULL; if (!(point = DIST_POINT_new())) { - goto merr; + goto err; } if (!sk_DIST_POINT_push(crld, point)) { DIST_POINT_free(point); - goto merr; + goto err; } if (!(point->distpoint = DIST_POINT_NAME_new())) { - goto merr; + goto err; } point->distpoint->name.fullname = gens; point->distpoint->type = 0; @@ -364,8 +365,6 @@ static void *v2i_crld(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, } return crld; -merr: - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); err: GENERAL_NAME_free(gen); GENERAL_NAMES_free(gens); @@ -390,14 +389,12 @@ static int dpn_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, } -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_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_CHOICE_END_cb(DIST_POINT_NAME, DIST_POINT_NAME, type) - - IMPLEMENT_ASN1_FUNCTIONS(DIST_POINT_NAME) +IMPLEMENT_ASN1_FUNCTIONS(DIST_POINT_NAME) ASN1_SEQUENCE(DIST_POINT) = { ASN1_EXP_OPT(DIST_POINT, distpoint, DIST_POINT_NAME, 0), @@ -426,8 +423,8 @@ IMPLEMENT_ASN1_FUNCTIONS(ISSUING_DIST_POINT) static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out, int indent); -static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval); +static void *v2i_idp(const X509V3_EXT_METHOD *method, const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *nval); const X509V3_EXT_METHOD v3_idp = { NID_issuing_distribution_point, @@ -446,22 +443,17 @@ const X509V3_EXT_METHOD v3_idp = { 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(); +static void *v2i_idp(const X509V3_EXT_METHOD *method, const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *nval) { + ISSUING_DIST_POINT *idp = ISSUING_DIST_POINT_new(); if (!idp) { - goto merr; + goto err; } - 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); + for (size_t i = 0; i < sk_CONF_VALUE_num(nval); i++) { + const CONF_VALUE *cnf = sk_CONF_VALUE_value(nval, i); + const char *name = cnf->name; + const char *val = cnf->value; + int ret = set_dist_point_name(&idp->distpoint, ctx, cnf); if (ret > 0) { continue; } @@ -496,8 +488,6 @@ static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, } return idp; -merr: - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); err: ISSUING_DIST_POINT_free(idp); return NULL; diff --git a/Sources/CNIOBoringSSL/crypto/x509v3/v3_enum.c b/Sources/CNIOBoringSSL/crypto/x509v3/v3_enum.c index 4a128766..b318af62 100644 --- a/Sources/CNIOBoringSSL/crypto/x509v3/v3_enum.c +++ b/Sources/CNIOBoringSSL/crypto/x509v3/v3_enum.c @@ -1,4 +1,3 @@ -/* v3_enum.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 1999. diff --git a/Sources/CNIOBoringSSL/crypto/x509v3/v3_extku.c b/Sources/CNIOBoringSSL/crypto/x509v3/v3_extku.c index 6ead258f..041fb3da 100644 --- a/Sources/CNIOBoringSSL/crypto/x509v3/v3_extku.c +++ b/Sources/CNIOBoringSSL/crypto/x509v3/v3_extku.c @@ -1,4 +1,3 @@ -/* v3_extku.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 1999. @@ -63,9 +62,12 @@ #include #include +#include "internal.h" + + static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval); + const X509V3_CTX *ctx, + const 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); @@ -112,12 +114,10 @@ IMPLEMENT_ASN1_FUNCTIONS_const(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) { - 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); + const EXTENDED_KEY_USAGE *eku = a; + for (size_t i = 0; i < sk_ASN1_OBJECT_num(eku); i++) { + const ASN1_OBJECT *obj = sk_ASN1_OBJECT_value(eku, i); + char obj_tmp[80]; i2t_ASN1_OBJECT(obj_tmp, 80, obj); X509V3_add_value(NULL, obj_tmp, &ext_list); } @@ -125,33 +125,30 @@ static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE( } static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval) { - 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); + const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *nval) { + EXTENDED_KEY_USAGE *extku = sk_ASN1_OBJECT_new_null(); + if (extku == NULL) { return NULL; } - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { - val = sk_CONF_VALUE_value(nval, i); + for (size_t i = 0; i < sk_CONF_VALUE_num(nval); i++) { + const CONF_VALUE *val = sk_CONF_VALUE_value(nval, i); + const char *extval; if (val->value) { extval = val->value; } else { extval = val->name; } - if (!(objtmp = OBJ_txt2obj(extval, 0))) { + ASN1_OBJECT *obj = OBJ_txt2obj(extval, 0); + if (obj == NULL || !sk_ASN1_OBJECT_push(extku, obj)) { + ASN1_OBJECT_free(obj); 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/Sources/CNIOBoringSSL/crypto/x509v3/v3_genn.c b/Sources/CNIOBoringSSL/crypto/x509v3/v3_genn.c index 581356c9..1b5c506e 100644 --- a/Sources/CNIOBoringSSL/crypto/x509v3/v3_genn.c +++ b/Sources/CNIOBoringSSL/crypto/x509v3/v3_genn.c @@ -1,4 +1,3 @@ -/* v3_genn.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 1999. @@ -62,6 +61,8 @@ #include #include +#include "internal.h" + ASN1_SEQUENCE(OTHERNAME) = { ASN1_SIMPLE(OTHERNAME, type_id, ASN1_OBJECT), @@ -122,6 +123,22 @@ static int edipartyname_cmp(const EDIPARTYNAME *a, const EDIPARTYNAME *b) { return ASN1_STRING_cmp(a->partyName, b->partyName); } +// Returns 0 if they are equal, != 0 otherwise. +static int othername_cmp(const OTHERNAME *a, const 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; +} + // Returns 0 if they are equal, != 0 otherwise. int GENERAL_NAME_cmp(const GENERAL_NAME *a, const GENERAL_NAME *b) { if (!a || !b || a->type != b->type) { @@ -130,13 +147,13 @@ int GENERAL_NAME_cmp(const GENERAL_NAME *a, const GENERAL_NAME *b) { switch (a->type) { case GEN_X400: - return ASN1_TYPE_cmp(a->d.x400Address, b->d.x400Address); + return ASN1_STRING_cmp(a->d.x400Address, b->d.x400Address); case GEN_EDIPARTY: return edipartyname_cmp(a->d.ediPartyName, b->d.ediPartyName); case GEN_OTHERNAME: - return OTHERNAME_cmp(a->d.otherName, b->d.otherName); + return othername_cmp(a->d.otherName, b->d.otherName); case GEN_EMAIL: case GEN_DNS: @@ -156,22 +173,6 @@ int GENERAL_NAME_cmp(const GENERAL_NAME *a, const GENERAL_NAME *b) { return -1; } -// 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; -} - void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value) { switch (type) { case GEN_X400: diff --git a/Sources/CNIOBoringSSL/crypto/x509v3/v3_ia5.c b/Sources/CNIOBoringSSL/crypto/x509v3/v3_ia5.c index 2e54e210..28f8902d 100644 --- a/Sources/CNIOBoringSSL/crypto/x509v3/v3_ia5.c +++ b/Sources/CNIOBoringSSL/crypto/x509v3/v3_ia5.c @@ -1,4 +1,3 @@ -/* v3_ia5.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 1999. @@ -77,7 +76,6 @@ static char *i2s_ASN1_IA5STRING(const X509V3_EXT_METHOD *method, void *ext) { return NULL; } if (!(tmp = OPENSSL_malloc(ia5->length + 1))) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); return NULL; } OPENSSL_memcpy(tmp, ia5->data, ia5->length); @@ -86,7 +84,7 @@ static char *i2s_ASN1_IA5STRING(const X509V3_EXT_METHOD *method, void *ext) { } static void *s2i_ASN1_IA5STRING(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, const char *str) { + const X509V3_CTX *ctx, const char *str) { ASN1_IA5STRING *ia5; if (!str) { OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_ARGUMENT); @@ -101,7 +99,6 @@ static void *s2i_ASN1_IA5STRING(const X509V3_EXT_METHOD *method, } return ia5; err: - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); return NULL; } diff --git a/Sources/CNIOBoringSSL/crypto/x509v3/v3_info.c b/Sources/CNIOBoringSSL/crypto/x509v3/v3_info.c index 1e25b284..7c76a0fd 100644 --- a/Sources/CNIOBoringSSL/crypto/x509v3/v3_info.c +++ b/Sources/CNIOBoringSSL/crypto/x509v3/v3_info.c @@ -1,4 +1,3 @@ -/* v3_info.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 1999. @@ -71,8 +70,8 @@ static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS( const X509V3_EXT_METHOD *method, void *ext, STACK_OF(CONF_VALUE) *ret); static void *v2i_AUTHORITY_INFO_ACCESS(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval); + const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *nval); const X509V3_EXT_METHOD v3_info = { NID_info_access, @@ -158,7 +157,6 @@ static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS( return tret; err: - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); if (ret == NULL && tret != NULL) { sk_CONF_VALUE_pop_free(tret, X509V3_conf_free); } @@ -166,39 +164,34 @@ static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS( } static void *v2i_AUTHORITY_INFO_ACCESS(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval) { + const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *nval) { AUTHORITY_INFO_ACCESS *ainfo = NULL; ACCESS_DESCRIPTION *acc; - char *objtmp, *ptmp; if (!(ainfo = sk_ACCESS_DESCRIPTION_new_null())) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); return NULL; } for (size_t i = 0; i < sk_CONF_VALUE_num(nval); i++) { - CONF_VALUE *cnf = sk_CONF_VALUE_value(nval, i); + const CONF_VALUE *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, ';'); + char *ptmp = strchr(cnf->name, ';'); if (!ptmp) { OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SYNTAX); goto err; } - int objlen = ptmp - cnf->name; CONF_VALUE ctmp; 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); + char *objtmp = OPENSSL_strndup(cnf->name, ptmp - cnf->name); + if (objtmp == NULL) { goto err; } - OPENSSL_strlcpy(objtmp, cnf->name, objlen + 1); acc->method = OBJ_txt2obj(objtmp, 0); if (!acc->method) { OPENSSL_PUT_ERROR(X509V3, X509V3_R_BAD_OBJECT); diff --git a/Sources/CNIOBoringSSL/crypto/x509v3/v3_int.c b/Sources/CNIOBoringSSL/crypto/x509v3/v3_int.c index 04820b5c..ada69ce6 100644 --- a/Sources/CNIOBoringSSL/crypto/x509v3/v3_int.c +++ b/Sources/CNIOBoringSSL/crypto/x509v3/v3_int.c @@ -1,4 +1,3 @@ -/* v3_int.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 1999. @@ -65,7 +64,7 @@ static char *i2s_ASN1_INTEGER_cb(const X509V3_EXT_METHOD *method, void *ext) { return i2s_ASN1_INTEGER(method, ext); } -static void *s2i_asn1_int(const X509V3_EXT_METHOD *meth, X509V3_CTX *ctx, +static void *s2i_asn1_int(const X509V3_EXT_METHOD *meth, const X509V3_CTX *ctx, const char *value) { return s2i_ASN1_INTEGER(meth, value); } diff --git a/Sources/CNIOBoringSSL/crypto/x509v3/v3_lib.c b/Sources/CNIOBoringSSL/crypto/x509v3/v3_lib.c index 8df23e06..a3cb6417 100644 --- a/Sources/CNIOBoringSSL/crypto/x509v3/v3_lib.c +++ b/Sources/CNIOBoringSSL/crypto/x509v3/v3_lib.c @@ -1,4 +1,3 @@ -/* v3_lib.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 1999. @@ -73,22 +72,22 @@ 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 *const *a, + const X509V3_EXT_METHOD *const *b) { return ((*a)->ext_nid - (*b)->ext_nid); } int X509V3_EXT_add(X509V3_EXT_METHOD *ext) { + // TODO(davidben): This should be locked. Also check for duplicates. 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; } + sk_X509V3_EXT_METHOD_sort(ext_list); return 1; } @@ -116,7 +115,6 @@ const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid) { return NULL; } - sk_X509V3_EXT_METHOD_sort(ext_list); if (!sk_X509V3_EXT_METHOD_find(ext_list, &idx, &tmp)) { return NULL; } @@ -169,7 +167,6 @@ int X509V3_EXT_add_alias(int nid_to, int nid_from) { } if (!(tmpext = (X509V3_EXT_METHOD *)OPENSSL_malloc(sizeof(X509V3_EXT_METHOD)))) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); return 0; } *tmpext = *ext; diff --git a/Sources/CNIOBoringSSL/crypto/x509v3/v3_ncons.c b/Sources/CNIOBoringSSL/crypto/x509v3/v3_ncons.c index 9683785d..679951eb 100644 --- a/Sources/CNIOBoringSSL/crypto/x509v3/v3_ncons.c +++ b/Sources/CNIOBoringSSL/crypto/x509v3/v3_ncons.c @@ -1,4 +1,3 @@ -/* v3_ncons.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project. @@ -70,7 +69,8 @@ static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); + const X509V3_CTX *ctx, + const 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, @@ -120,18 +120,18 @@ 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; + const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *nval) { STACK_OF(GENERAL_SUBTREE) **ptree = NULL; NAME_CONSTRAINTS *ncons = NULL; GENERAL_SUBTREE *sub = NULL; ncons = NAME_CONSTRAINTS_new(); if (!ncons) { - goto memerr; + goto err; } - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { - val = sk_CONF_VALUE_value(nval, i); + for (size_t i = 0; i < sk_CONF_VALUE_num(nval); i++) { + const CONF_VALUE *val = sk_CONF_VALUE_value(nval, i); + CONF_VALUE tval; if (!strncmp(val->name, "permitted", 9) && val->name[9]) { ptree = &ncons->permittedSubtrees; tval.name = val->name + 10; @@ -151,15 +151,13 @@ static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, *ptree = sk_GENERAL_SUBTREE_new_null(); } if (!*ptree || !sk_GENERAL_SUBTREE_push(*ptree, sub)) { - goto memerr; + goto err; } sub = NULL; } return ncons; -memerr: - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); err: NAME_CONSTRAINTS_free(ncons); GENERAL_SUBTREE_free(sub); diff --git a/Sources/CNIOBoringSSL/crypto/x509v3/v3_ocsp.c b/Sources/CNIOBoringSSL/crypto/x509v3/v3_ocsp.c index 5d7c680c..ff07b7e5 100644 --- a/Sources/CNIOBoringSSL/crypto/x509v3/v3_ocsp.c +++ b/Sources/CNIOBoringSSL/crypto/x509v3/v3_ocsp.c @@ -20,8 +20,8 @@ static int i2r_ocsp_acutoff(const X509V3_EXT_METHOD *method, void *nonce, static int i2r_ocsp_nocheck(const X509V3_EXT_METHOD *method, void *nocheck, BIO *out, int indent); -static void *s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, - const char *str); +static void *s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method, + const X509V3_CTX *ctx, const char *str); const X509V3_EXT_METHOD v3_crl_invdate = { NID_invalidity_date, @@ -75,7 +75,7 @@ static int i2r_ocsp_nocheck(const X509V3_EXT_METHOD *method, void *nocheck, return 1; } -static void *s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, - const char *str) { +static void *s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method, + const X509V3_CTX *ctx, const char *str) { return ASN1_NULL_new(); } diff --git a/Sources/CNIOBoringSSL/crypto/x509v3/v3_pci.c b/Sources/CNIOBoringSSL/crypto/x509v3/v3_pci.c deleted file mode 100644 index 81991a48..00000000 --- a/Sources/CNIOBoringSSL/crypto/x509v3/v3_pci.c +++ /dev/null @@ -1,287 +0,0 @@ -/* v3_pci.c -*- mode:C; c-file-style: "eay" -*- */ -/* - * 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). - * 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. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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 - -#include -#include -#include -#include -#include - -#include "../internal.h" -#include "internal.h" - - -static int i2r_pci(const X509V3_EXT_METHOD *method, void *ext, BIO *out, - int indent); -static void *r2i_pci(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, - const 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, - i2r_pci, - r2i_pci, - NULL, -}; - -static int i2r_pci(const X509V3_EXT_METHOD *method, void *ext, BIO *out, - int indent) { - const PROXY_CERT_INFO_EXTENSION *pci = ext; - 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->length, - 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; - - 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 = x509v3_hex_to_bytes(val->value + 4, &val_len); - - 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; - OPENSSL_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, "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; - OPENSSL_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 void *r2i_pci(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, - const 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; - - 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; - } - - 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; -} diff --git a/Sources/CNIOBoringSSL/crypto/x509v3/v3_pcia.c b/Sources/CNIOBoringSSL/crypto/x509v3/v3_pcia.c deleted file mode 100644 index 57762a3f..00000000 --- a/Sources/CNIOBoringSSL/crypto/x509v3/v3_pcia.c +++ /dev/null @@ -1,55 +0,0 @@ -/* v3_pcia.c -*- mode:C; c-file-style: "eay" -*- */ -/* - * 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). - * 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. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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 -#include -#include - - -ASN1_SEQUENCE(PROXY_POLICY) = { - ASN1_SIMPLE(PROXY_POLICY, policyLanguage, ASN1_OBJECT), - ASN1_OPT(PROXY_POLICY, policy, ASN1_OCTET_STRING), -} ASN1_SEQUENCE_END(PROXY_POLICY) - -IMPLEMENT_ASN1_FUNCTIONS_const(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_SEQUENCE_END(PROXY_CERT_INFO_EXTENSION) - -IMPLEMENT_ASN1_FUNCTIONS_const(PROXY_CERT_INFO_EXTENSION) diff --git a/Sources/CNIOBoringSSL/crypto/x509v3/v3_pcons.c b/Sources/CNIOBoringSSL/crypto/x509v3/v3_pcons.c index c311d333..ae0f27f0 100644 --- a/Sources/CNIOBoringSSL/crypto/x509v3/v3_pcons.c +++ b/Sources/CNIOBoringSSL/crypto/x509v3/v3_pcons.c @@ -1,4 +1,3 @@ -/* v3_pcons.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project. @@ -65,12 +64,15 @@ #include #include +#include "internal.h" + + 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); + const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *values); const X509V3_EXT_METHOD v3_policy_constraints = { NID_policy_constraints, @@ -97,7 +99,7 @@ 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) { - POLICY_CONSTRAINTS *pcons = a; + const POLICY_CONSTRAINTS *pcons = a; X509V3_add_value_int("Require Explicit Policy", pcons->requireExplicitPolicy, &extlist); X509V3_add_value_int("Inhibit Policy Mapping", pcons->inhibitPolicyMapping, @@ -106,17 +108,14 @@ static STACK_OF(CONF_VALUE) *i2v_POLICY_CONSTRAINTS( } static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *values) { + const X509V3_CTX *ctx, + const 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); + for (size_t i = 0; i < sk_CONF_VALUE_num(values); i++) { + const CONF_VALUE *val = sk_CONF_VALUE_value(values, i); if (!strcmp(val->name, "requireExplicitPolicy")) { if (!X509V3_get_value_int(val, &pcons->requireExplicitPolicy)) { goto err; diff --git a/Sources/CNIOBoringSSL/crypto/x509v3/v3_pmaps.c b/Sources/CNIOBoringSSL/crypto/x509v3/v3_pmaps.c index 3b1e32dc..ff51cfc7 100644 --- a/Sources/CNIOBoringSSL/crypto/x509v3/v3_pmaps.c +++ b/Sources/CNIOBoringSSL/crypto/x509v3/v3_pmaps.c @@ -1,4 +1,3 @@ -/* v3_pmaps.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project. @@ -63,8 +62,12 @@ #include #include +#include "internal.h" + + static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); + const X509V3_CTX *ctx, + const 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); @@ -98,13 +101,10 @@ 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) { - 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); + const POLICY_MAPPINGS *pmaps = a; + for (size_t i = 0; i < sk_POLICY_MAPPING_num(pmaps); i++) { + const POLICY_MAPPING *pmap = sk_POLICY_MAPPING_value(pmaps, i); + char obj_tmp1[80], obj_tmp2[80]; 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); @@ -113,43 +113,38 @@ static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS( } static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) { - 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); + const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *nval) { + POLICY_MAPPINGS *pmaps = sk_POLICY_MAPPING_new_null(); + if (pmaps == NULL) { return NULL; } - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { - val = sk_CONF_VALUE_value(nval, i); + for (size_t i = 0; i < sk_CONF_VALUE_num(nval); i++) { + const CONF_VALUE *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; + goto err; + } + + POLICY_MAPPING *pmap = POLICY_MAPPING_new(); + if (pmap == NULL || !sk_POLICY_MAPPING_push(pmaps, pmap)) { + POLICY_MAPPING_free(pmap); + goto err; } - obj1 = OBJ_txt2obj(val->name, 0); - obj2 = OBJ_txt2obj(val->value, 0); - if (!obj1 || !obj2) { - sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free); + + pmap->issuerDomainPolicy = OBJ_txt2obj(val->name, 0); + pmap->subjectDomainPolicy = OBJ_txt2obj(val->value, 0); + if (!pmap->issuerDomainPolicy || !pmap->subjectDomainPolicy) { OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER); X509V3_conf_err(val); - return NULL; + goto err; } - 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; + +err: + sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free); + return NULL; } diff --git a/Sources/CNIOBoringSSL/crypto/x509v3/v3_prn.c b/Sources/CNIOBoringSSL/crypto/x509v3/v3_prn.c index 13f91d06..6a0f5248 100644 --- a/Sources/CNIOBoringSSL/crypto/x509v3/v3_prn.c +++ b/Sources/CNIOBoringSSL/crypto/x509v3/v3_prn.c @@ -1,4 +1,3 @@ -/* v3_prn.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 1999. diff --git a/Sources/CNIOBoringSSL/crypto/x509v3/v3_purp.c b/Sources/CNIOBoringSSL/crypto/x509v3/v3_purp.c index e4b8e816..25d41f0a 100644 --- a/Sources/CNIOBoringSSL/crypto/x509v3/v3_purp.c +++ b/Sources/CNIOBoringSSL/crypto/x509v3/v3_purp.c @@ -1,4 +1,3 @@ -/* v3_purp.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 2001. @@ -96,7 +95,7 @@ static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x, 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); -static int xp_cmp(const X509_PURPOSE **a, const X509_PURPOSE **b); +static int xp_cmp(const X509_PURPOSE *const *a, const X509_PURPOSE *const *b); static void xptable_free(X509_PURPOSE *p); static X509_PURPOSE xstandard[] = { @@ -127,7 +126,7 @@ static X509_PURPOSE xstandard[] = { static STACK_OF(X509_PURPOSE) *xptable = NULL; -static int xp_cmp(const X509_PURPOSE **a, const X509_PURPOSE **b) { +static int xp_cmp(const X509_PURPOSE *const *a, const X509_PURPOSE *const *b) { return (*a)->purpose - (*b)->purpose; } @@ -202,7 +201,6 @@ int X509_PURPOSE_get_by_id(int purpose) { return -1; } - sk_X509_PURPOSE_sort(xptable); if (!sk_X509_PURPOSE_find(xptable, &idx, &tmp)) { return -1; } @@ -225,7 +223,6 @@ int X509_PURPOSE_add(int id, int trust, int flags, // Need a new entry if (idx == -1) { if (!(ptmp = OPENSSL_malloc(sizeof(X509_PURPOSE)))) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); return 0; } ptmp->flags = X509_PURPOSE_DYNAMIC; @@ -237,7 +234,6 @@ int X509_PURPOSE_add(int id, int trust, int flags, name_dup = OPENSSL_strdup(name); sname_dup = OPENSSL_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); } @@ -270,16 +266,19 @@ int X509_PURPOSE_add(int id, int trust, int flags, // If its a new entry manage the dynamic table if (idx == -1) { + // TODO(davidben): This should be locked. Alternatively, remove the dynamic + // registration mechanism entirely. The trouble is there no way to pass in + // the various parameters into an |X509_VERIFY_PARAM| directly. You can only + // register it in the global table and get an ID. 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; } + sk_X509_PURPOSE_sort(xptable); } return 1; } @@ -335,7 +334,6 @@ int X509_supported_extension(const X509_EXTENSION *ex) { 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 @@ -401,7 +399,6 @@ static int setup_crldp(X509 *x) { int 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; @@ -454,23 +451,6 @@ int x509v3_cache_extensions(X509 *x) { } else if (j != -1) { x->ex_flags |= EXFLAG_INVALID; } - // Handle proxy certificates - if ((pci = X509_get_ext_d2i(x, NID_proxyCertInfo, &j, 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; - } else if (j != -1) { - x->ex_flags |= EXFLAG_INVALID; - } // Handle key usage if ((usage = X509_get_ext_d2i(x, NID_key_usage, &j, NULL))) { if (usage->length > 0) { @@ -802,11 +782,7 @@ int X509_check_issued(X509 *issuer, X509 *subject) { } } - if (subject->ex_flags & EXFLAG_PROXY) { - if (ku_reject(issuer, KU_DIGITAL_SIGNATURE)) { - return X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE; - } - } else if (ku_reject(issuer, KU_KEY_CERT_SIGN)) { + if (ku_reject(issuer, KU_KEY_CERT_SIGN)) { return X509_V_ERR_KEYUSAGE_NO_CERTSIGN; } return X509_V_OK; diff --git a/Sources/CNIOBoringSSL/crypto/x509v3/v3_skey.c b/Sources/CNIOBoringSSL/crypto/x509v3/v3_skey.c index 2540afa5..a769f1df 100644 --- a/Sources/CNIOBoringSSL/crypto/x509v3/v3_skey.c +++ b/Sources/CNIOBoringSSL/crypto/x509v3/v3_skey.c @@ -1,4 +1,3 @@ -/* v3_skey.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 1999. @@ -55,12 +54,14 @@ * (eay@cryptsoft.com). This product includes software written by Tim * Hudson (tjh@cryptsoft.com). */ +#include #include #include #include #include #include +#include #include #include "../x509/internal.h" @@ -73,23 +74,28 @@ char *i2s_ASN1_OCTET_STRING(const X509V3_EXT_METHOD *method, } ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, const char *str) { - ASN1_OCTET_STRING *oct; - long length; - - if (!(oct = ASN1_OCTET_STRING_new())) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + const X509V3_CTX *ctx, + const char *str) { + size_t len; + uint8_t *data = x509v3_hex_to_bytes(str, &len); + if (data == NULL) { return NULL; } - - if (!(oct->data = x509v3_hex_to_bytes(str, &length))) { - ASN1_OCTET_STRING_free(oct); - return NULL; + if (len > INT_MAX) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_OVERFLOW); + goto err; } - oct->length = length; - + ASN1_OCTET_STRING *oct = ASN1_OCTET_STRING_new(); + if (oct == NULL) { + goto err; + } + ASN1_STRING_set0(oct, data, (int)len); return oct; + +err: + OPENSSL_free(data); + return NULL; } static char *i2s_ASN1_OCTET_STRING_cb(const X509V3_EXT_METHOD *method, @@ -97,7 +103,7 @@ static char *i2s_ASN1_OCTET_STRING_cb(const X509V3_EXT_METHOD *method, return i2s_ASN1_OCTET_STRING(method, ext); } -static void *s2i_skey_id(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, +static void *s2i_skey_id(const X509V3_EXT_METHOD *method, const X509V3_CTX *ctx, const char *str) { ASN1_OCTET_STRING *oct; ASN1_BIT_STRING *pk; @@ -109,11 +115,10 @@ static void *s2i_skey_id(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, } if (!(oct = ASN1_OCTET_STRING_new())) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); return NULL; } - if (ctx && (ctx->flags == CTX_TEST)) { + if (ctx && (ctx->flags == X509V3_CTX_TEST)) { return oct; } @@ -138,7 +143,6 @@ static void *s2i_skey_id(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, } if (!ASN1_OCTET_STRING_set(oct, pkey_dig, diglen)) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); goto err; } diff --git a/Sources/CNIOBoringSSL/crypto/x509v3/v3_utl.c b/Sources/CNIOBoringSSL/crypto/x509v3/v3_utl.c index 2a44022d..bf2fa17d 100644 --- a/Sources/CNIOBoringSSL/crypto/x509v3/v3_utl.c +++ b/Sources/CNIOBoringSSL/crypto/x509v3/v3_utl.c @@ -1,4 +1,3 @@ -/* v3_utl.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project. @@ -76,7 +75,7 @@ static char *strip_spaces(char *name); -static int sk_strcmp(const char **a, const char **b); +static int sk_strcmp(const char *const *a, const char *const *b); static STACK_OF(OPENSSL_STRING) *get_email(const X509_NAME *name, const GENERAL_NAMES *gens); static void str_free(OPENSSL_STRING str); @@ -97,7 +96,7 @@ static int x509V3_add_len_value(const char *name, const char *value, char *tname = NULL, *tvalue = NULL; int extlist_was_null = *extlist == NULL; if (name && !(tname = OPENSSL_strdup(name))) { - goto malloc_err; + goto err; } if (!omit_value) { // |CONF_VALUE| cannot represent strings with NULs. @@ -107,24 +106,22 @@ static int x509V3_add_len_value(const char *name, const char *value, } tvalue = OPENSSL_strndup(value, value_len); if (tvalue == NULL) { - goto malloc_err; + goto err; } } if (!(vtmp = CONF_VALUE_new())) { - goto malloc_err; + goto err; } if (!*extlist && !(*extlist = sk_CONF_VALUE_new_null())) { - goto malloc_err; + goto err; } vtmp->section = NULL; vtmp->name = tname; vtmp->value = tvalue; if (!sk_CONF_VALUE_push(*extlist, vtmp)) { - goto malloc_err; + goto err; } return 1; -malloc_err: - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); err: if (extlist_was_null) { sk_CONF_VALUE_free(*extlist); @@ -142,11 +139,6 @@ int X509V3_add_value(const char *name, const char *value, /*omit_value=*/value == NULL, extlist); } -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); -} - int x509V3_add_value_asn1_string(const char *name, const ASN1_STRING *value, STACK_OF(CONF_VALUE) **extlist) { return x509V3_add_len_value(name, (const char *)value->data, value->length, @@ -173,14 +165,6 @@ int X509V3_add_value_bool(const char *name, int asn1_bool, return X509V3_add_value(name, "FALSE", extlist); } -int X509V3_add_value_bool_nf(const char *name, int asn1_bool, - STACK_OF(CONF_VALUE) **extlist) { - if (asn1_bool) { - return X509V3_add_value(name, "TRUE", extlist); - } - return 1; -} - static char *bignum_to_string(const BIGNUM *bn) { char *tmp, *ret; size_t len; @@ -200,7 +184,6 @@ static char *bignum_to_string(const BIGNUM *bn) { len = strlen(tmp) + 3; ret = OPENSSL_malloc(len); if (ret == NULL) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); OPENSSL_free(tmp); return NULL; } @@ -226,7 +209,6 @@ char *i2s_ASN1_ENUMERATED(const X509V3_EXT_METHOD *method, } if (!(bntmp = ASN1_ENUMERATED_to_BN(a, NULL)) || !(strtmp = bignum_to_string(bntmp))) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); } BN_free(bntmp); return strtmp; @@ -240,7 +222,6 @@ char *i2s_ASN1_INTEGER(const X509V3_EXT_METHOD *method, const ASN1_INTEGER *a) { } if (!(bntmp = ASN1_INTEGER_to_BN(a, NULL)) || !(strtmp = bignum_to_string(bntmp))) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); } BN_free(bntmp); return strtmp; @@ -274,6 +255,16 @@ ASN1_INTEGER *s2i_ASN1_INTEGER(const X509V3_EXT_METHOD *method, if (ishex) { ret = BN_hex2bn(&bn, value); } else { + // Decoding from decimal scales quadratically in the input length. Bound the + // largest decimal input we accept in the config parser. 8,192 decimal + // digits allows values up to 27,213 bits. Ths exceeds the largest RSA, DSA, + // or DH modulus we support, and those are not usefully represented in + // decimal. + if (strlen(value) > 8192) { + BN_free(bn); + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NUMBER); + return 0; + } ret = BN_dec2bn(&bn, value); } @@ -314,23 +305,33 @@ int X509V3_add_value_int(const char *name, const ASN1_INTEGER *aint, return ret; } -int X509V3_get_value_bool(const 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; +int X509V3_bool_from_string(const char *str, ASN1_BOOLEAN *out_bool) { + if (!strcmp(str, "TRUE") || !strcmp(str, "true") || !strcmp(str, "Y") || + !strcmp(str, "y") || !strcmp(str, "YES") || !strcmp(str, "yes")) { + *out_bool = ASN1_BOOLEAN_TRUE; 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; + } + if (!strcmp(str, "FALSE") || !strcmp(str, "false") || !strcmp(str, "N") || + !strcmp(str, "n") || !strcmp(str, "NO") || !strcmp(str, "no")) { + *out_bool = ASN1_BOOLEAN_FALSE; return 1; } -err: OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_BOOLEAN_STRING); + return 0; +} + +int X509V3_get_value_bool(const CONF_VALUE *value, ASN1_BOOLEAN *out_bool) { + const char *btmp = value->value; + if (btmp == NULL) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_BOOLEAN_STRING); + goto err; + } + if (!X509V3_bool_from_string(btmp, out_bool)) { + goto err; + } + return 1; + +err: X509V3_conf_err(value); return 0; } @@ -341,6 +342,7 @@ int X509V3_get_value_int(const CONF_VALUE *value, ASN1_INTEGER **aint) { X509V3_conf_err(value); return 0; } + ASN1_INTEGER_free(*aint); *aint = itmp; return 1; } @@ -359,7 +361,6 @@ STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line) { // We are going to modify the line so copy it first linebuf = OPENSSL_strdup(line); if (linebuf == NULL) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); goto err; } state = HDR_NAME; @@ -446,14 +447,14 @@ static char *strip_spaces(char *name) { char *p, *q; // Skip over leading spaces p = name; - while (*p && isspace((unsigned char)*p)) { + while (*p && OPENSSL_isspace((unsigned char)*p)) { p++; } if (!*p) { return NULL; } q = p + strlen(p) - 1; - while ((q != p) && isspace((unsigned char)*q)) { + while ((q != p) && OPENSSL_isspace((unsigned char)*q)) { q--; } if (p != q) { @@ -489,14 +490,14 @@ char *x509v3_bytes_to_hex(const uint8_t *in, size_t len) { return (char *)ret; err: - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); CBB_cleanup(&cbb); return NULL; } -unsigned char *x509v3_hex_to_bytes(const char *str, long *len) { +unsigned char *x509v3_hex_to_bytes(const char *str, size_t *len) { unsigned char *hexbuf, *q; unsigned char ch, cl, *p; + uint8_t high, low; if (!str) { OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_ARGUMENT); return NULL; @@ -515,28 +516,13 @@ unsigned char *x509v3_hex_to_bytes(const char *str, long *len) { OPENSSL_free(hexbuf); return NULL; } - - if ((ch >= '0') && (ch <= '9')) { - ch -= '0'; - } else if ((ch >= 'a') && (ch <= 'f')) { - ch -= 'a' - 10; - } else if ((ch >= 'A') && (ch <= 'F')) { - ch -= 'A' - 10; - } else { + if (!OPENSSL_fromxdigit(&high, ch)) { goto badhex; } - - if ((cl >= '0') && (cl <= '9')) { - cl -= '0'; - } else if ((cl >= 'a') && (cl <= 'f')) { - cl -= 'a' - 10; - } else if ((cl >= 'A') && (cl <= 'F')) { - cl -= 'A' - 10; - } else { + if (!OPENSSL_fromxdigit(&low, cl)) { goto badhex; } - - *q++ = (ch << 4) | cl; + *q++ = (high << 4) | low; } if (len) { @@ -547,7 +533,6 @@ unsigned char *x509v3_hex_to_bytes(const char *str, long *len) { err: OPENSSL_free(hexbuf); - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); return NULL; badhex: @@ -556,21 +541,19 @@ unsigned char *x509v3_hex_to_bytes(const char *str, long *len) { return NULL; } -int x509v3_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 == '.')) { +int x509v3_conf_name_matches(const char *name, const char *cmp) { + // |name| must begin with |cmp|. + size_t len = strlen(cmp); + if (strncmp(name, cmp, len) != 0) { return 0; } - return 1; + // |name| must either be equal to |cmp| or begin with |cmp|, followed by '.'. + return name[len] == '\0' || name[len] == '.'; } -static int sk_strcmp(const char **a, const char **b) { return strcmp(*a, *b); } +static int sk_strcmp(const char *const *a, const char *const *b) { + return strcmp(*a, *b); +} STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x) { GENERAL_NAMES *gens; @@ -717,13 +700,7 @@ static int equal_nocase(const unsigned char *pattern, size_t pattern_len, 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) { + if (OPENSSL_tolower(l) != OPENSSL_tolower(r)) { return 0; } } @@ -813,8 +790,7 @@ static int wildcard_match(const unsigned char *prefix, size_t prefix_len, // Check that the part matched by the wildcard contains only // permitted characters and only matches a single label. for (p = wildcard_start; p != wildcard_end; ++p) { - if (!(('0' <= *p && *p <= '9') || ('A' <= *p && *p <= 'Z') || - ('a' <= *p && *p <= 'z') || *p == '-')) { + if (!OPENSSL_isalnum(*p) && *p != '-') { return 0; } } @@ -850,8 +826,7 @@ static const unsigned char *valid_star(const unsigned char *p, size_t len, } star = &p[i]; state &= ~LABEL_START; - } else if (('a' <= p[i] && p[i] <= 'z') || ('A' <= p[i] && p[i] <= 'Z') || - ('0' <= p[i] && p[i] <= '9')) { + } else if (OPENSSL_isalnum(p[i])) { if ((state & LABEL_START) != 0 && len - i >= 4 && OPENSSL_strncasecmp((char *)&p[i], "xn--", 4) == 0) { state |= LABEL_IDNA; @@ -925,8 +900,7 @@ int x509v3_looks_like_dns_name(const unsigned char *in, size_t len) { size_t label_start = 0; for (size_t i = 0; i < len; i++) { unsigned char c = in[i]; - if ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || - (c >= 'A' && c <= 'Z') || (c == '-' && i > label_start) || + if (OPENSSL_isalnum(c) || (c == '-' && i > label_start) || // These are not valid characters in hostnames, but commonly found // in deployments outside the Web PKI. c == '_' || c == ':') { @@ -1335,38 +1309,28 @@ static int ipv6_hex(unsigned char *out, const char *in, size_t inlen) { } uint16_t num = 0; while (inlen--) { - unsigned char 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 { + uint8_t val; + if (!OPENSSL_fromxdigit(&val, *in++)) { return 0; } + num = (num << 4) | val; } 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; +int X509V3_NAME_from_section(X509_NAME *nm, const STACK_OF(CONF_VALUE) *dn_sk, + int chtype) { 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; + for (size_t i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) { + const CONF_VALUE *v = sk_CONF_VALUE_value(dn_sk, i); + const char *type = v->name; // Skip past any leading X. X: X, etc to allow for multiple instances - for (p = type; *p; p++) { + for (const char *p = type; *p; p++) { if ((*p == ':') || (*p == ',') || (*p == '.')) { p++; if (*p) { @@ -1375,6 +1339,7 @@ int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE) *dn_sk, break; } } + int mval; if (*type == '+') { mval = -1; type++; diff --git a/Sources/CNIOBoringSSL/hash.txt b/Sources/CNIOBoringSSL/hash.txt index ef533e98..9766498e 100644 --- a/Sources/CNIOBoringSSL/hash.txt +++ b/Sources/CNIOBoringSSL/hash.txt @@ -1 +1 @@ -This directory is derived from BoringSSL cloned from https://boringssl.googlesource.com/boringssl at revision b819f7e9392d25db6705a6bd3c92be3bb91775e2 +This directory is derived from BoringSSL cloned from https://boringssl.googlesource.com/boringssl at revision abfd5ebc87ddca0fab9fca067c9d7edbc355eae8 diff --git a/Sources/CNIOBoringSSL/include/CNIOBoringSSL.h b/Sources/CNIOBoringSSL/include/CNIOBoringSSL.h index a81cb690..2254e030 100644 --- a/Sources/CNIOBoringSSL/include/CNIOBoringSSL.h +++ b/Sources/CNIOBoringSSL/include/CNIOBoringSSL.h @@ -44,6 +44,7 @@ #include "CNIOBoringSSL_hpke.h" #include "CNIOBoringSSL_hrss.h" #include "CNIOBoringSSL_kdf.h" +#include "CNIOBoringSSL_kyber.h" #include "CNIOBoringSSL_md4.h" #include "CNIOBoringSSL_md5.h" #include "CNIOBoringSSL_obj_mac.h" @@ -62,6 +63,7 @@ #include "CNIOBoringSSL_siphash.h" #include "CNIOBoringSSL_srtp.h" #include "CNIOBoringSSL_ssl.h" +#include "CNIOBoringSSL_time.h" #include "CNIOBoringSSL_trust_token.h" #include "CNIOBoringSSL_type_check.h" #include "CNIOBoringSSL_x509_vfy.h" diff --git a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_asn1.h b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_asn1.h index 84d36ce7..01f85862 100644 --- a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_asn1.h +++ b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_asn1.h @@ -55,8 +55,8 @@ * [including the GNU Public Licence.] */ -#ifndef HEADER_ASN1_H -#define HEADER_ASN1_H +#ifndef OPENSSL_HEADER_ASN1_H +#define OPENSSL_HEADER_ASN1_H #include "CNIOBoringSSL_base.h" @@ -213,38 +213,10 @@ OPENSSL_EXPORT const char *ASN1_tag2str(int tag); // // Note: If |out| and |*out| are both non-NULL, the object at |*out| is not // updated in-place. Instead, it is freed, and the pointer is updated to the -// new object. This differs from OpenSSL, which behaves more like -// |d2i_SAMPLE_with_reuse|. Callers are recommended to set |out| to NULL and -// instead use the return value. +// new object. This differs from OpenSSL. Callers are recommended to set |out| +// to NULL and instead use the return value. SAMPLE *d2i_SAMPLE(SAMPLE **out, const uint8_t **inp, long len); -// d2i_SAMPLE_with_reuse parses a structure from up to |len| bytes at |*inp|. On -// success, it advances |*inp| by the number of bytes read and returns a -// non-NULL pointer to an object containing the parsed structure. The object is -// determined from |out| as follows: -// -// If |out| is NULL, the function places the result in a newly-allocated -// |SAMPLE| object and returns it. This mode is recommended. -// -// If |out| is non-NULL, but |*out| is NULL, the function also places the result -// in a newly-allocated |SAMPLE| object. It sets |*out| to this object and also -// returns it. -// -// If |out| and |*out| are both non-NULL, the function updates the object at -// |*out| in-place with the result and returns |*out|. -// -// If any of the above fail, the function returns NULL. -// -// This function does not reject trailing data in the input. This allows the -// caller to parse a sequence of concatenated structures. Callers parsing only -// one structure should check for trailing data by comparing the updated |*inp| -// with the end of the input. -// -// WARNING: Callers should not rely on the in-place update mode. It often -// produces the wrong result or breaks the type's internal invariants. Future -// revisions of BoringSSL may standardize on the |d2i_SAMPLE| behavior. -SAMPLE *d2i_SAMPLE_with_reuse(SAMPLE **out, const uint8_t **inp, long len); - // i2d_SAMPLE marshals |in|. On error, it returns a negative value. On success, // it returns the length of the result and outputs it via |outp| as follows: // @@ -348,8 +320,8 @@ OPENSSL_EXPORT ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it); OPENSSL_EXPORT void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it); // ASN1_item_d2i parses the ASN.1 type |it| from up to |len| bytes at |*inp|. -// It behaves like |d2i_SAMPLE_with_reuse|, except that |out| and the return -// value are cast to |ASN1_VALUE| pointers. +// It behaves like |d2i_SAMPLE|, except that |out| and the return value are cast +// to |ASN1_VALUE| pointers. // // TODO(https://crbug.com/boringssl/444): C strict aliasing forbids type-punning // |T*| and |ASN1_VALUE*| the way this function signature does. When that bug is @@ -447,10 +419,22 @@ OPENSSL_EXPORT ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, // integer type. FALSE is zero, TRUE is 0xff, and an omitted OPTIONAL BOOLEAN is // -1. +// ASN1_BOOLEAN_FALSE is FALSE as an |ASN1_BOOLEAN|. +#define ASN1_BOOLEAN_FALSE 0 + +// ASN1_BOOLEAN_TRUE is TRUE as an |ASN1_BOOLEAN|. Some code incorrectly uses +// 1, so prefer |b != ASN1_BOOLEAN_FALSE| over |b == ASN1_BOOLEAN_TRUE|. +#define ASN1_BOOLEAN_TRUE 0xff + +// ASN1_BOOLEAN_NONE, in contexts where the |ASN1_BOOLEAN| represents an +// OPTIONAL BOOLEAN, is an omitted value. Using this value in other contexts is +// undefined and may be misinterpreted as TRUE. +#define ASN1_BOOLEAN_NONE (-1) + // d2i_ASN1_BOOLEAN parses a DER-encoded ASN.1 BOOLEAN from up to |len| bytes at // |*inp|. On success, it advances |*inp| by the number of bytes read and // returns the result. If |out| is non-NULL, it additionally writes the result -// to |*out|. On error, it returns -1. +// to |*out|. On error, it returns |ASN1_BOOLEAN_NONE|. // // This function does not reject trailing data in the input. This allows the // caller to parse a sequence of concatenated structures. Callers parsing only @@ -459,9 +443,6 @@ OPENSSL_EXPORT ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, // // WARNING: This function's is slightly different from other |d2i_*| functions // because |ASN1_BOOLEAN| is not a pointer type. -// -// TODO(https://crbug.com/boringssl/354): This function currently also accepts -// BER, but this will be removed in the future. OPENSSL_EXPORT ASN1_BOOLEAN d2i_ASN1_BOOLEAN(ASN1_BOOLEAN *out, const unsigned char **inp, long len); @@ -472,7 +453,8 @@ OPENSSL_EXPORT int i2d_ASN1_BOOLEAN(ASN1_BOOLEAN a, unsigned char **outp); // The following |ASN1_ITEM|s have ASN.1 type BOOLEAN and C type |ASN1_BOOLEAN|. // |ASN1_TBOOLEAN| and |ASN1_FBOOLEAN| must be marked OPTIONAL. When omitted, -// they are parsed as TRUE and FALSE, respectively, rather than -1. +// they are parsed as TRUE and FALSE, respectively, rather than +// |ASN1_BOOLEAN_NONE|. DECLARE_ASN1_ITEM(ASN1_BOOLEAN) DECLARE_ASN1_ITEM(ASN1_TBOOLEAN) DECLARE_ASN1_ITEM(ASN1_FBOOLEAN) @@ -485,31 +467,39 @@ DECLARE_ASN1_ITEM(ASN1_FBOOLEAN) // |ASN1_STRING|, to represent most values. // An asn1_string_st (aka |ASN1_STRING|) represents a value of a string-like -// ASN.1 type. It contains a type field, and a byte string data field with a +// ASN.1 type. It contains a |type| field, and a byte string |data| field with a // type-specific representation. // -// When representing a string value, the type field is one of -// |V_ASN1_OCTET_STRING|, |V_ASN1_UTF8STRING|, |V_ASN1_NUMERICSTRING|, -// |V_ASN1_PRINTABLESTRING|, |V_ASN1_T61STRING|, |V_ASN1_VIDEOTEXSTRING|, -// |V_ASN1_IA5STRING|, |V_ASN1_GRAPHICSTRING|, |V_ASN1_ISO64STRING|, -// |V_ASN1_VISIBLESTRING|, |V_ASN1_GENERALSTRING|, |V_ASN1_UNIVERSALSTRING|, or -// |V_ASN1_BMPSTRING|. The data contains the byte representation of of the +// If |type| is one of |V_ASN1_OCTET_STRING|, |V_ASN1_UTF8STRING|, +// |V_ASN1_NUMERICSTRING|, |V_ASN1_PRINTABLESTRING|, |V_ASN1_T61STRING|, +// |V_ASN1_VIDEOTEXSTRING|, |V_ASN1_IA5STRING|, |V_ASN1_GRAPHICSTRING|, +// |V_ASN1_ISO64STRING|, |V_ASN1_VISIBLESTRING|, |V_ASN1_GENERALSTRING|, +// |V_ASN1_UNIVERSALSTRING|, or |V_ASN1_BMPSTRING|, the object represents an +// ASN.1 string type. The data contains the byte representation of the // string. // -// When representing a BIT STRING value, the type field is |V_ASN1_BIT_STRING|. -// See bit string documentation below for how the data and flags are used. +// If |type| is |V_ASN1_BIT_STRING|, the object represents a BIT STRING value. +// See bit string documentation below for the data and flags. // -// When representing an INTEGER or ENUMERATED value, the type field is one of -// |V_ASN1_INTEGER|, |V_ASN1_NEG_INTEGER|, |V_ASN1_ENUMERATED|, or -// |V_ASN1_NEG_ENUMERATED|. See integer documentation below for details. +// If |type| is one of |V_ASN1_INTEGER|, |V_ASN1_NEG_INTEGER|, +// |V_ASN1_ENUMERATED|, or |V_ASN1_NEG_ENUMERATED|, the object represents an +// INTEGER or ENUMERATED value. See integer documentation below for details. // -// When representing a GeneralizedTime or UTCTime value, the type field is -// |V_ASN1_GENERALIZEDTIME| or |V_ASN1_UTCTIME|, respectively. The data contains -// the DER encoding of the value. For example, the UNIX epoch would be +// If |type| is |V_ASN1_GENERALIZEDTIME| or |V_ASN1_UTCTIME|, the object +// represents a GeneralizedTime or UTCTime value, respectively. The data +// contains the DER encoding of the value. For example, the UNIX epoch would be // "19700101000000Z" for a GeneralizedTime and "700101000000Z" for a UTCTime. // -// |ASN1_STRING|, when stored in an |ASN1_TYPE|, may also represent an element -// with tag not directly supported by this library. See |ASN1_TYPE| for details. +// If |type| is |V_ASN1_SEQUENCE|, |V_ASN1_SET|, or |V_ASN1_OTHER|, the object +// represents a SEQUENCE, SET, or arbitrary ASN.1 value, respectively. Unlike +// the above cases, the data contains the DER encoding of the entire structure, +// including the header. If the value is explicitly or implicitly tagged, this +// too will be reflected in the data field. As this case handles unknown types, +// the contents are not checked when parsing or serializing. +// +// Other values of |type| do not represent a valid ASN.1 value, though +// default-constructed objects may set |type| to -1. Such objects cannot be +// serialized. // // |ASN1_STRING| additionally has the following typedefs: |ASN1_BIT_STRING|, // |ASN1_BMPSTRING|, |ASN1_ENUMERATED|, |ASN1_GENERALIZEDTIME|, @@ -526,15 +516,14 @@ DECLARE_ASN1_ITEM(ASN1_FBOOLEAN) // |ASN1_STRING_length|. // // If a function returns an |ASN1_STRING| where the typedef or ASN.1 structure -// implies constraints on the type field, callers may assume that the type field -// is correct. However, if a function takes an |ASN1_STRING| as input, callers -// must ensure the type field matches. These invariants are not captured by the -// C type system and may not be checked at runtime. For example, callers may -// assume the output of |X509_get0_serialNumber| has type |V_ASN1_INTEGER| or -// |V_ASN1_NEG_INTEGER|. Callers must not pass a string of type -// |V_ASN1_OCTET_STRING| to |X509_set_serialNumber|. Doing so may break -// invariants on the |X509| object and break the |X509_get0_serialNumber| -// invariant. +// implies constraints on |type|, callers may assume that |type| is correct. +// However, if a function takes an |ASN1_STRING| as input, callers must ensure +// |type| matches. These invariants are not captured by the C type system and +// may not be checked at runtime. For example, callers may assume the output of +// |X509_get0_serialNumber| has type |V_ASN1_INTEGER| or |V_ASN1_NEG_INTEGER|. +// Callers must not pass a string of type |V_ASN1_OCTET_STRING| to +// |X509_set_serialNumber|. Doing so may break invariants on the |X509| object +// and break the |X509_get0_serialNumber| invariant. // // TODO(https://crbug.com/boringssl/445): This is very unfriendly. Getting the // type field wrong should not cause memory errors, but it may do strange @@ -608,7 +597,8 @@ OPENSSL_EXPORT int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b); // |data|. It returns one on success and zero on error. If |data| is NULL, it // updates the length and allocates the buffer as needed, but does not // initialize the contents. -OPENSSL_EXPORT int ASN1_STRING_set(ASN1_STRING *str, const void *data, int len); +OPENSSL_EXPORT int ASN1_STRING_set(ASN1_STRING *str, const void *data, + ossl_ssize_t len); // ASN1_STRING_set0 sets the contents of |str| to |len| bytes from |data|. It // takes ownership of |data|, which must have been allocated with @@ -640,10 +630,7 @@ OPENSSL_EXPORT void ASN1_VISIBLESTRING_free(ASN1_VISIBLESTRING *str); // The following functions parse up to |len| bytes from |*inp| as a // DER-encoded ASN.1 value of the corresponding type, as described in -// |d2i_SAMPLE_with_reuse|. -// -// TODO(https://crbug.com/boringssl/354): This function currently also accepts -// BER, but this will be removed in the future. +// |d2i_SAMPLE|. OPENSSL_EXPORT ASN1_BMPSTRING *d2i_ASN1_BMPSTRING(ASN1_BMPSTRING **out, const uint8_t **inp, long len); @@ -832,7 +819,7 @@ OPENSSL_EXPORT ASN1_STRING *DIRECTORYSTRING_new(void); OPENSSL_EXPORT void DIRECTORYSTRING_free(ASN1_STRING *str); // d2i_DIRECTORYSTRING parses up to |len| bytes from |*inp| as a DER-encoded -// X.509 DirectoryString (RFC 5280), as described in |d2i_SAMPLE_with_reuse|. +// X.509 DirectoryString (RFC 5280), as described in |d2i_SAMPLE|. // // TODO(https://crbug.com/boringssl/354): This function currently also accepts // BER, but this will be removed in the future. @@ -865,7 +852,7 @@ OPENSSL_EXPORT ASN1_STRING *DISPLAYTEXT_new(void); OPENSSL_EXPORT void DISPLAYTEXT_free(ASN1_STRING *str); // d2i_DISPLAYTEXT parses up to |len| bytes from |*inp| as a DER-encoded X.509 -// DisplayText (RFC 5280), as described in |d2i_SAMPLE_with_reuse|. +// DisplayText (RFC 5280), as described in |d2i_SAMPLE|. // // TODO(https://crbug.com/boringssl/354): This function currently also accepts // BER, but this will be removed in the future. @@ -926,10 +913,7 @@ OPENSSL_EXPORT ASN1_BIT_STRING *ASN1_BIT_STRING_new(void); OPENSSL_EXPORT void ASN1_BIT_STRING_free(ASN1_BIT_STRING *str); // d2i_ASN1_BIT_STRING parses up to |len| bytes from |*inp| as a DER-encoded -// ASN.1 BIT STRING, as described in |d2i_SAMPLE_with_reuse|. -// -// TODO(https://crbug.com/boringssl/354): This function currently also accepts -// BER, but this will be removed in the future. +// ASN.1 BIT STRING, as described in |d2i_SAMPLE|. OPENSSL_EXPORT ASN1_BIT_STRING *d2i_ASN1_BIT_STRING(ASN1_BIT_STRING **out, const uint8_t **inp, long len); @@ -941,11 +925,7 @@ OPENSSL_EXPORT int i2d_ASN1_BIT_STRING(const ASN1_BIT_STRING *in, // c2i_ASN1_BIT_STRING decodes |len| bytes from |*inp| as the contents of a // DER-encoded BIT STRING, excluding the tag and length. It behaves like -// |d2i_SAMPLE_with_reuse| except, on success, it always consumes all |len| -// bytes. -// -// TODO(https://crbug.com/boringssl/354): This function currently also accepts -// BER, but this will be removed in the future. +// |d2i_SAMPLE| except, on success, it always consumes all |len| bytes. OPENSSL_EXPORT ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **out, const uint8_t **inp, long len); @@ -985,7 +965,8 @@ OPENSSL_EXPORT int ASN1_BIT_STRING_num_bytes(const ASN1_BIT_STRING *str, // TODO(davidben): Maybe it should? Wrapping a byte string in a bit string is a // common use case. OPENSSL_EXPORT int ASN1_BIT_STRING_set(ASN1_BIT_STRING *str, - const unsigned char *d, int length); + const unsigned char *d, + ossl_ssize_t length); // ASN1_BIT_STRING_set_bit sets bit |n| of |str| to one if |value| is non-zero // and zero if |value| is zero, resizing |str| as needed. It then truncates @@ -1036,10 +1017,7 @@ OPENSSL_EXPORT void ASN1_INTEGER_free(ASN1_INTEGER *str); OPENSSL_EXPORT ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x); // d2i_ASN1_INTEGER parses up to |len| bytes from |*inp| as a DER-encoded -// ASN.1 INTEGER, as described in |d2i_SAMPLE_with_reuse|. -// -// TODO(https://crbug.com/boringssl/354): This function currently also accepts -// BER, but this will be removed in the future. +// ASN.1 INTEGER, as described in |d2i_SAMPLE|. OPENSSL_EXPORT ASN1_INTEGER *d2i_ASN1_INTEGER(ASN1_INTEGER **out, const uint8_t **inp, long len); @@ -1049,11 +1027,7 @@ OPENSSL_EXPORT int i2d_ASN1_INTEGER(const ASN1_INTEGER *in, uint8_t **outp); // c2i_ASN1_INTEGER decodes |len| bytes from |*inp| as the contents of a // DER-encoded INTEGER, excluding the tag and length. It behaves like -// |d2i_SAMPLE_with_reuse| except, on success, it always consumes all |len| -// bytes. -// -// TODO(https://crbug.com/boringssl/354): This function currently also accepts -// some invalid inputs, but this will be removed in the future. +// |d2i_SAMPLE| except, on success, it always consumes all |len| bytes. OPENSSL_EXPORT ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **in, const uint8_t **outp, long len); @@ -1121,10 +1095,7 @@ OPENSSL_EXPORT ASN1_ENUMERATED *ASN1_ENUMERATED_new(void); OPENSSL_EXPORT void ASN1_ENUMERATED_free(ASN1_ENUMERATED *str); // d2i_ASN1_ENUMERATED parses up to |len| bytes from |*inp| as a DER-encoded -// ASN.1 ENUMERATED, as described in |d2i_SAMPLE_with_reuse|. -// -// TODO(https://crbug.com/boringssl/354): This function currently also accepts -// BER, but this will be removed in the future. +// ASN.1 ENUMERATED, as described in |d2i_SAMPLE|. OPENSSL_EXPORT ASN1_ENUMERATED *d2i_ASN1_ENUMERATED(ASN1_ENUMERATED **out, const uint8_t **inp, long len); @@ -1199,7 +1170,7 @@ OPENSSL_EXPORT ASN1_UTCTIME *ASN1_UTCTIME_new(void); OPENSSL_EXPORT void ASN1_UTCTIME_free(ASN1_UTCTIME *str); // d2i_ASN1_UTCTIME parses up to |len| bytes from |*inp| as a DER-encoded -// ASN.1 UTCTime, as described in |d2i_SAMPLE_with_reuse|. +// ASN.1 UTCTime, as described in |d2i_SAMPLE|. // // TODO(https://crbug.com/boringssl/354): This function currently also accepts // BER, but this will be removed in the future. @@ -1217,20 +1188,23 @@ DECLARE_ASN1_ITEM(ASN1_UTCTIME) // ASN1_UTCTIME_check returns one if |a| is a valid UTCTime and zero otherwise. OPENSSL_EXPORT int ASN1_UTCTIME_check(const ASN1_UTCTIME *a); -// ASN1_UTCTIME_set represents |t| as a UTCTime and writes the result to |s|. It -// returns |s| on success and NULL on error. If |s| is NULL, it returns a -// newly-allocated |ASN1_UTCTIME| instead. +// ASN1_UTCTIME_set represents |posix_time| as a UTCTime and writes the result +// to |s|. It returns |s| on success and NULL on error. If |s| is NULL, it +// returns a newly-allocated |ASN1_UTCTIME| instead. // // Note this function may fail if the time is out of range for UTCTime. -OPENSSL_EXPORT ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t); +OPENSSL_EXPORT ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, + int64_t posix_time); -// ASN1_UTCTIME_adj adds |offset_day| days and |offset_sec| seconds to |t| and -// writes the result to |s| as a UTCTime. It returns |s| on success and NULL on -// error. If |s| is NULL, it returns a newly-allocated |ASN1_UTCTIME| instead. +// ASN1_UTCTIME_adj adds |offset_day| days and |offset_sec| seconds to +// |posix_time| and writes the result to |s| as a UTCTime. It returns |s| on +// success and NULL on error. If |s| is NULL, it returns a newly-allocated +// |ASN1_UTCTIME| instead. // // Note this function may fail if the time overflows or is out of range for // UTCTime. -OPENSSL_EXPORT ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t, +OPENSSL_EXPORT ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, + int64_t posix_time, int offset_day, long offset_sec); // ASN1_UTCTIME_set_string sets |s| to a UTCTime whose contents are a copy of @@ -1253,10 +1227,7 @@ OPENSSL_EXPORT ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_new(void); OPENSSL_EXPORT void ASN1_GENERALIZEDTIME_free(ASN1_GENERALIZEDTIME *str); // d2i_ASN1_GENERALIZEDTIME parses up to |len| bytes from |*inp| as a -// DER-encoded ASN.1 GeneralizedTime, as described in |d2i_SAMPLE_with_reuse|. -// -// TODO(https://crbug.com/boringssl/354): This function currently also accepts -// BER, but this will be removed in the future. +// DER-encoded ASN.1 GeneralizedTime, as described in |d2i_SAMPLE|. OPENSSL_EXPORT ASN1_GENERALIZEDTIME *d2i_ASN1_GENERALIZEDTIME( ASN1_GENERALIZEDTIME **out, const uint8_t **inp, long len); @@ -1273,23 +1244,24 @@ DECLARE_ASN1_ITEM(ASN1_GENERALIZEDTIME) // zero otherwise. OPENSSL_EXPORT int ASN1_GENERALIZEDTIME_check(const ASN1_GENERALIZEDTIME *a); -// ASN1_GENERALIZEDTIME_set represents |t| as a GeneralizedTime and writes the -// result to |s|. It returns |s| on success and NULL on error. If |s| is NULL, -// it returns a newly-allocated |ASN1_GENERALIZEDTIME| instead. +// ASN1_GENERALIZEDTIME_set represents |posix_time| as a GeneralizedTime and +// writes the result to |s|. It returns |s| on success and NULL on error. If |s| +// is NULL, it returns a newly-allocated |ASN1_GENERALIZEDTIME| instead. // // Note this function may fail if the time is out of range for GeneralizedTime. OPENSSL_EXPORT ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set( - ASN1_GENERALIZEDTIME *s, time_t t); + ASN1_GENERALIZEDTIME *s, int64_t posix_time); // ASN1_GENERALIZEDTIME_adj adds |offset_day| days and |offset_sec| seconds to -// |t| and writes the result to |s| as a GeneralizedTime. It returns |s| on -// success and NULL on error. If |s| is NULL, it returns a newly-allocated -// |ASN1_GENERALIZEDTIME| instead. +// |posix_time| and writes the result to |s| as a GeneralizedTime. It returns +// |s| on success and NULL on error. If |s| is NULL, it returns a +// newly-allocated |ASN1_GENERALIZEDTIME| instead. // // Note this function may fail if the time overflows or is out of range for // GeneralizedTime. OPENSSL_EXPORT ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj( - ASN1_GENERALIZEDTIME *s, time_t t, int offset_day, long offset_sec); + ASN1_GENERALIZEDTIME *s, int64_t posix_time, int offset_day, + long offset_sec); // ASN1_GENERALIZEDTIME_set_string sets |s| to a GeneralizedTime whose contents // are a copy of |str|. It returns one on success and zero on error or if |str| @@ -1311,7 +1283,7 @@ OPENSSL_EXPORT ASN1_TIME *ASN1_TIME_new(void); OPENSSL_EXPORT void ASN1_TIME_free(ASN1_TIME *str); // d2i_ASN1_TIME parses up to |len| bytes from |*inp| as a DER-encoded X.509 -// Time (RFC 5280), as described in |d2i_SAMPLE_with_reuse|. +// Time (RFC 5280), as described in |d2i_SAMPLE|. // // TODO(https://crbug.com/boringssl/354): This function currently also accepts // BER, but this will be removed in the future. @@ -1339,24 +1311,29 @@ DECLARE_ASN1_ITEM(ASN1_TIME) OPENSSL_EXPORT int ASN1_TIME_diff(int *out_days, int *out_seconds, const ASN1_TIME *from, const ASN1_TIME *to); -// ASN1_TIME_set represents |t| as a GeneralizedTime or UTCTime and writes -// the result to |s|. As in RFC 5280, section 4.1.2.5, it uses UTCTime when the -// time fits and GeneralizedTime otherwise. It returns |s| on success and NULL -// on error. If |s| is NULL, it returns a newly-allocated |ASN1_TIME| instead. +// ASN1_TIME_set_posix represents |posix_time| as a GeneralizedTime or UTCTime +// and writes the result to |s|. As in RFC 5280, section 4.1.2.5, it uses +// UTCTime when the time fits and GeneralizedTime otherwise. It returns |s| on +// success and NULL on error. If |s| is NULL, it returns a newly-allocated +// |ASN1_TIME| instead. // // Note this function may fail if the time is out of range for GeneralizedTime. -OPENSSL_EXPORT ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t); +OPENSSL_EXPORT ASN1_TIME *ASN1_TIME_set_posix(ASN1_TIME *s, int64_t posix_time); + +// ASN1_TIME_set is exactly the same as |ASN1_TIME_set_posix| but with a +// time_t as input for compatibility. +OPENSSL_EXPORT ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t time); // ASN1_TIME_adj adds |offset_day| days and |offset_sec| seconds to -// |t| and writes the result to |s|. As in RFC 5280, section 4.1.2.5, it uses -// UTCTime when the time fits and GeneralizedTime otherwise. It returns |s| on -// success and NULL on error. If |s| is NULL, it returns a newly-allocated -// |ASN1_GENERALIZEDTIME| instead. +// |posix_time| and writes the result to |s|. As in RFC 5280, section 4.1.2.5, +// it uses UTCTime when the time fits and GeneralizedTime otherwise. It returns +// |s| on success and NULL on error. If |s| is NULL, it returns a +// newly-allocated |ASN1_GENERALIZEDTIME| instead. // // Note this function may fail if the time overflows or is out of range for // GeneralizedTime. -OPENSSL_EXPORT ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t, int offset_day, - long offset_sec); +OPENSSL_EXPORT ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, int64_t posix_time, + int offset_day, long offset_sec); // ASN1_TIME_check returns one if |t| is a valid UTCTime or GeneralizedTime, and // zero otherwise. |t|'s type determines which check is performed. This @@ -1404,9 +1381,6 @@ OPENSSL_EXPORT void ASN1_NULL_free(ASN1_NULL *null); // d2i_ASN1_NULL parses a DER-encoded ASN.1 NULL value from up to |len| bytes // at |*inp|, as described in |d2i_SAMPLE|. -// -// TODO(https://crbug.com/boringssl/354): This function currently also accepts -// BER, but this will be removed in the future. OPENSSL_EXPORT ASN1_NULL *d2i_ASN1_NULL(ASN1_NULL **out, const uint8_t **inp, long len); @@ -1441,7 +1415,7 @@ DEFINE_STACK_OF(ASN1_OBJECT) // TODO(davidben): Should we just ignore all those parameters? NIDs and names // are only relevant for |ASN1_OBJECT|s in the obj.h table. OPENSSL_EXPORT ASN1_OBJECT *ASN1_OBJECT_create(int nid, const uint8_t *data, - int len, const char *sn, + size_t len, const char *sn, const char *ln); // ASN1_OBJECT_free releases memory associated with |a|. If |a| is a static @@ -1449,21 +1423,17 @@ OPENSSL_EXPORT ASN1_OBJECT *ASN1_OBJECT_create(int nid, const uint8_t *data, OPENSSL_EXPORT void ASN1_OBJECT_free(ASN1_OBJECT *a); // d2i_ASN1_OBJECT parses a DER-encoded ASN.1 OBJECT IDENTIFIER from up to |len| -// bytes at |*inp|, as described in |d2i_SAMPLE_with_reuse|. -// -// TODO(https://crbug.com/boringssl/354): This function currently also accepts -// BER, but this will be removed in the future. +// bytes at |*inp|, as described in |d2i_SAMPLE|. OPENSSL_EXPORT ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **out, const uint8_t **inp, long len); // i2d_ASN1_OBJECT marshals |in| as a DER-encoded ASN.1 OBJECT IDENTIFIER, as // described in |i2d_SAMPLE|. -OPENSSL_EXPORT int i2d_ASN1_OBJECT(const ASN1_OBJECT *a, uint8_t **outp); +OPENSSL_EXPORT int i2d_ASN1_OBJECT(const ASN1_OBJECT *in, uint8_t **outp); // c2i_ASN1_OBJECT decodes |len| bytes from |*inp| as the contents of a // DER-encoded OBJECT IDENTIFIER, excluding the tag and length. It behaves like -// |d2i_SAMPLE_with_reuse| except, on success, it always consumes all |len| -// bytes. +// |d2i_SAMPLE| except, on success, it always consumes all |len| bytes. OPENSSL_EXPORT ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **out, const uint8_t **inp, long len); @@ -1505,15 +1475,14 @@ DECLARE_ASN1_ITEM(ASN1_OBJECT) // |ASN1_BOOLEAN|. // // If |type| is |V_ASN1_SEQUENCE|, |V_ASN1_SET|, or |V_ASN1_OTHER|, the tag is -// SEQUENCE, SET, or some non-universal tag, respectively. |value| is an -// |ASN1_STRING| containing the entire element, including the tag and length. -// The |ASN1_STRING|'s |type| field matches the containing |ASN1_TYPE|'s |type|. -// -// Other positive values of |type|, up to |V_ASN1_MAX_UNIVERSAL|, correspond to -// universal primitive tags not directly supported by this library. |value| is -// an |ASN1_STRING| containing the body of the element, excluding the tag -// and length. The |ASN1_STRING|'s |type| field matches the containing -// |ASN1_TYPE|'s |type|. +// SEQUENCE, SET, or some arbitrary tag, respectively. |value| uses the +// corresponding |ASN1_STRING| representation. Although any type may be +// represented in |V_ASN1_OTHER|, the parser will always return the more +// specific encoding when available. +// +// Other values of |type| do not represent a valid ASN.1 value, though +// default-constructed objects may set |type| to -1. Such objects cannot be +// serialized. struct asn1_type_st { int type; union { @@ -1553,10 +1522,10 @@ OPENSSL_EXPORT ASN1_TYPE *ASN1_TYPE_new(void); OPENSSL_EXPORT void ASN1_TYPE_free(ASN1_TYPE *a); // d2i_ASN1_TYPE parses up to |len| bytes from |*inp| as an ASN.1 value of any -// type, as described in |d2i_SAMPLE_with_reuse|. Note this function only -// validates primitive, universal types supported by this library. Values of -// type |V_ASN1_SEQUENCE|, |V_ASN1_SET|, |V_ASN1_OTHER|, or an unsupported -// primitive type must be validated by the caller when interpreting. +// type, as described in |d2i_SAMPLE|. Note this function only validates +// primitive, universal types supported by this library. Values of type +// |V_ASN1_SEQUENCE|, |V_ASN1_SET|, |V_ASN1_OTHER|, or an unsupported primitive +// type must be validated by the caller when interpreting. // // TODO(https://crbug.com/boringssl/354): This function currently also accepts // BER, but this will be removed in the future. @@ -1600,9 +1569,9 @@ OPENSSL_EXPORT int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b); typedef STACK_OF(ASN1_TYPE) ASN1_SEQUENCE_ANY; // d2i_ASN1_SEQUENCE_ANY parses up to |len| bytes from |*inp| as a DER-encoded -// ASN.1 SEQUENCE OF ANY structure, as described in |d2i_SAMPLE_with_reuse|. The -// resulting |ASN1_SEQUENCE_ANY| owns its contents and thus must be released -// with |sk_ASN1_TYPE_pop_free| and |ASN1_TYPE_free|, not |sk_ASN1_TYPE_free|. +// ASN.1 SEQUENCE OF ANY structure, as described in |d2i_SAMPLE|. The resulting +// |ASN1_SEQUENCE_ANY| owns its contents and thus must be released with +// |sk_ASN1_TYPE_pop_free| and |ASN1_TYPE_free|, not |sk_ASN1_TYPE_free|. // // TODO(https://crbug.com/boringssl/354): This function currently also accepts // BER, but this will be removed in the future. @@ -1616,7 +1585,7 @@ OPENSSL_EXPORT int i2d_ASN1_SEQUENCE_ANY(const ASN1_SEQUENCE_ANY *in, uint8_t **outp); // d2i_ASN1_SET_ANY parses up to |len| bytes from |*inp| as a DER-encoded ASN.1 -// SET OF ANY structure, as described in |d2i_SAMPLE_with_reuse|. The resulting +// SET OF ANY structure, as described in |d2i_SAMPLE|. The resulting // |ASN1_SEQUENCE_ANY| owns its contents and thus must be released with // |sk_ASN1_TYPE_pop_free| and |ASN1_TYPE_free|, not |sk_ASN1_TYPE_free|. // @@ -1765,13 +1734,11 @@ OPENSSL_EXPORT int i2t_ASN1_OBJECT(char *buf, int buf_len, // |*out_length|, |*out_tag|, and |*out_class| to the element's length, tag // number, and tag class, respectively, // -// Unlike OpenSSL, this function does not support indefinite-length elements. +// Unlike OpenSSL, this function only supports DER. Indefinite and non-minimal +// lengths are rejected. // // This function is difficult to use correctly. Use |CBS_get_asn1| and related // functions from bytestring.h. -// -// TODO(https://crbug.com/boringssl/354): Remove support for non-minimal -// lengths. OPENSSL_EXPORT int ASN1_get_object(const unsigned char **inp, long *out_length, int *out_tag, int *out_class, long max_len); @@ -1847,15 +1814,6 @@ OPENSSL_EXPORT int ASN1_object_size(int constructed, int length, int tag); // Deprecated functions. -// ASN1_PRINTABLE_type interprets |len| bytes from |s| as a Latin-1 string. It -// returns the first of |V_ASN1_PRINTABLESTRING|, |V_ASN1_IA5STRING|, or -// |V_ASN1_T61STRING| that can represent every character. If |len| is negative, -// |strlen(s)| is used instead. -// -// TODO(davidben): Remove this once all copies of Conscrypt have been updated -// past https://github.com/google/conscrypt/pull/1032. -OPENSSL_EXPORT int ASN1_PRINTABLE_type(const unsigned char *s, int len); - // ASN1_STRING_set_default_mask does nothing. OPENSSL_EXPORT void ASN1_STRING_set_default_mask(unsigned long mask); @@ -1937,7 +1895,7 @@ OPENSSL_EXPORT void ASN1_PRINTABLE_free(ASN1_STRING *str); // d2i_ASN1_PRINTABLE parses up to |len| bytes from |*inp| as a DER-encoded // CHOICE of an ad-hoc subset of string-like types, as described in -// |d2i_SAMPLE_with_reuse|. +// |d2i_SAMPLE|. // // Do not use this. Despite, the name it has no connection to PrintableString or // printable characters. See https://crbug.com/boringssl/412. @@ -2102,4 +2060,4 @@ BSSL_NAMESPACE_END #define ASN1_R_WRONG_INTEGER_TYPE 195 #define ASN1_R_INVALID_INTEGER 196 -#endif +#endif // OPENSSL_HEADER_ASN1_H diff --git a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_asn1t.h b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_asn1t.h index f391f7de..cc7faf70 100644 --- a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_asn1t.h +++ b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_asn1t.h @@ -54,13 +54,13 @@ * Hudson (tjh@cryptsoft.com). * */ -#ifndef HEADER_ASN1T_H -#define HEADER_ASN1T_H +#ifndef OPENSSL_HEADER_ASN1T_H +#define OPENSSL_HEADER_ASN1T_H #include "CNIOBoringSSL_base.h" #include "CNIOBoringSSL_asn1.h" -#ifdef __cplusplus +#if defined(__cplusplus) extern "C" { #endif @@ -244,11 +244,6 @@ typedef struct ASN1_TLC_st ASN1_TLC; (flags), (tag), offsetof(stname, field),\ #field, ASN1_ITEM_ref(type) } -/* used when the structure is combined with the parent */ - -#define ASN1_EX_COMBINE(flags, tag, type) { \ - (flags)|ASN1_TFLG_COMBINE, (tag), 0, NULL, ASN1_ITEM_ref(type) } - /* implicit and explicit helper macros */ #define ASN1_IMP_EX(stname, field, type, tag, ex) \ @@ -348,8 +343,8 @@ typedef struct ASN1_TLC_st ASN1_TLC; */ struct ASN1_TEMPLATE_st { -unsigned long flags; /* Various flags */ -long tag; /* tag, not used if no tagging */ +uint32_t flags; /* Various flags */ +int tag; /* tag, not used if no tagging */ unsigned long offset; /* Offset of this field in structure */ const char *field_name; /* Field name */ ASN1_ITEM_EXP *item; /* Relevant ASN1_ITEM or ASN1_ADB */ @@ -366,7 +361,7 @@ typedef struct ASN1_ADB_st ASN1_ADB; typedef struct asn1_must_be_null_st ASN1_MUST_BE_NULL; struct ASN1_ADB_st { - unsigned long flags; /* Various flags */ + uint32_t flags; /* Various flags */ unsigned long offset; /* Offset of selector field */ ASN1_MUST_BE_NULL *unused; const ASN1_ADB_TABLE *tbl; /* Table of possible types */ @@ -441,21 +436,11 @@ struct ASN1_ADB_TABLE_st { #define ASN1_TFLG_ADB_OID (0x1<<8) -/* This flag means a parent structure is passed - * instead of the field: this is useful is a - * SEQUENCE is being combined with a CHOICE for - * example. Since this means the structure and - * item name will differ we need to use the - * ASN1_CHOICE_END_name() macro for example. - */ - -#define ASN1_TFLG_COMBINE (0x1<<10) - /* This is the actual ASN1 item itself */ struct ASN1_ITEM_st { char itype; /* The item type, primitive, SEQUENCE, CHOICE or extern */ -long utype; /* underlying type */ +int utype; /* underlying type */ const ASN1_TEMPLATE *templates; /* If SEQUENCE or CHOICE this contains the contents */ long tcount; /* Number of templates if SEQUENCE or CHOICE */ const void *funcs; /* functions that handle this type */ @@ -512,35 +497,6 @@ const char *sname; /* Structure name */ /* Deprecated tag and length cache */ struct ASN1_TLC_st; -/* Typedefs for ASN1 function pointers */ - -typedef ASN1_VALUE * ASN1_new_func(void); -typedef void ASN1_free_func(ASN1_VALUE *a); -typedef ASN1_VALUE * ASN1_d2i_func(ASN1_VALUE **a, const unsigned char ** in, long length); -typedef int ASN1_i2d_func(ASN1_VALUE * a, unsigned char **in); - -typedef int ASN1_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it, - int tag, int aclass, char opt, ASN1_TLC *ctx); - -typedef int ASN1_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass); -typedef int ASN1_ex_new_func(ASN1_VALUE **pval, const ASN1_ITEM *it); -typedef void ASN1_ex_free_func(ASN1_VALUE **pval, const ASN1_ITEM *it); - -typedef int ASN1_ex_print_func(BIO *out, ASN1_VALUE **pval, - int indent, const char *fname, - const ASN1_PCTX *pctx); - -typedef struct ASN1_EXTERN_FUNCS_st { - void *app_data; - ASN1_ex_new_func *asn1_ex_new; - ASN1_ex_free_func *asn1_ex_free; - ASN1_ex_free_func *asn1_ex_clear; - ASN1_ex_d2i *asn1_ex_d2i; - ASN1_ex_i2d *asn1_ex_i2d; - /* asn1_ex_print is unused. */ - ASN1_ex_print_func *asn1_ex_print; -} ASN1_EXTERN_FUNCS; - /* This is the ASN1_AUX structure: it handles various * miscellaneous requirements. For example the use of * reference counts and an informational callback. @@ -563,7 +519,7 @@ typedef int ASN1_aux_cb(int operation, ASN1_VALUE **in, const ASN1_ITEM *it, typedef struct ASN1_AUX_st { void *app_data; - int flags; + uint32_t flags; int ref_offset; /* Offset of reference value */ ASN1_aux_cb *asn1_cb; int enc_offset; /* Offset of ASN1_ENCODING structure */ @@ -702,7 +658,9 @@ DECLARE_ASN1_ITEM(ASN1_SEQUENCE) DEFINE_STACK_OF(ASN1_VALUE) -#ifdef __cplusplus -} -#endif + +#if defined(__cplusplus) +} // extern "C" #endif + +#endif // OPENSSL_HEADER_ASN1T_H diff --git a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_base.h b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_base.h index 9ec2bf53..7adeaf7a 100644 --- a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_base.h +++ b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_base.h @@ -101,9 +101,6 @@ extern "C" { #elif defined(__ARMEL__) || defined(_M_ARM) #define OPENSSL_32_BIT #define OPENSSL_ARM -#elif (defined(__PPC64__) || defined(__powerpc64__)) && defined(_LITTLE_ENDIAN) -#define OPENSSL_64_BIT -#define OPENSSL_PPC64LE #elif defined(__MIPSEL__) && !defined(__LP64__) #define OPENSSL_32_BIT #define OPENSSL_MIPS @@ -201,7 +198,7 @@ extern "C" { // A consumer may use this symbol in the preprocessor to temporarily build // against multiple revisions of BoringSSL at the same time. It is not // recommended to do so for longer than is necessary. -#define BORINGSSL_API_VERSION 18 +#define BORINGSSL_API_VERSION 19 #if defined(BORINGSSL_SHARED_LIBRARY) @@ -331,6 +328,19 @@ enum ssl_verify_result_t BORINGSSL_ENUM_INT; #define BORINGSSL_ENUM_INT #endif +// ossl_ssize_t is a signed type which is large enough to fit the size of any +// valid memory allocation. We prefer using |size_t|, but sometimes we need a +// signed type for OpenSSL API compatibility. This type can be used in such +// cases to avoid overflow. +// +// Not all |size_t| values fit in |ossl_ssize_t|, but all |size_t| values that +// are sizes of or indices into C objects, can be converted without overflow. +typedef ptrdiff_t ossl_ssize_t; + +// CBS_ASN1_TAG is the type used by |CBS| and |CBB| for ASN.1 tags. See that +// header for details. This type is defined in base.h as a forward declaration. +typedef uint32_t CBS_ASN1_TAG; + // CRYPTO_THREADID is a dummy value. typedef int CRYPTO_THREADID; @@ -414,9 +424,7 @@ typedef struct evp_hpke_ctx_st EVP_HPKE_CTX; typedef struct evp_hpke_kdf_st EVP_HPKE_KDF; typedef struct evp_hpke_kem_st EVP_HPKE_KEM; typedef struct evp_hpke_key_st EVP_HPKE_KEY; -typedef struct evp_pkey_asn1_method_st EVP_PKEY_ASN1_METHOD; typedef struct evp_pkey_ctx_st EVP_PKEY_CTX; -typedef struct evp_pkey_method_st EVP_PKEY_METHOD; typedef struct evp_pkey_st EVP_PKEY; typedef struct hmac_ctx_st HMAC_CTX; typedef struct md4_state_st MD4_CTX; @@ -521,8 +529,8 @@ namespace internal { template struct DeleterImpl {}; -template struct Deleter { + template void operator()(T *ptr) { // Rather than specialize Deleter for each type, we specialize // DeleterImpl. This allows bssl::UniquePtr to be used while only @@ -606,7 +614,7 @@ class StackAllocatedMovable { // bssl::UniquePtr rsa(RSA_new()); // bssl::UniquePtr bio(BIO_new(BIO_s_mem())); template -using UniquePtr = std::unique_ptr>; +using UniquePtr = std::unique_ptr; #define BORINGSSL_MAKE_UP_REF(type, up_ref_func) \ inline UniquePtr UpRef(type *v) { \ diff --git a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_bio.h b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_bio.h index a031d4e3..3f84d6b1 100644 --- a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_bio.h +++ b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_bio.h @@ -107,14 +107,14 @@ OPENSSL_EXPORT int BIO_up_ref(BIO *bio); // bytes read, zero on EOF, or a negative number on error. OPENSSL_EXPORT int BIO_read(BIO *bio, void *data, int len); -// BIO_gets "reads a line" from |bio| and puts at most |size| bytes into |buf|. -// It returns the number of bytes read or a negative number on error. The -// phrase "reads a line" is in quotes in the previous sentence because the -// exact operation depends on the BIO's method. For example, a digest BIO will -// return the digest in response to a |BIO_gets| call. -// -// TODO(fork): audit the set of BIOs that we end up needing. If all actually -// return a line for this call, remove the warning above. +// BIO_gets reads a line from |bio| and writes at most |size| bytes into |buf|. +// It returns the number of bytes read or a negative number on error. This +// function's output always includes a trailing NUL byte, so it will read at +// most |size - 1| bytes. +// +// If the function read a complete line, the output will include the newline +// character, '\n'. If no newline was found before |size - 1| bytes or EOF, it +// outputs the bytes which were available. OPENSSL_EXPORT int BIO_gets(BIO *bio, char *buf, int size); // BIO_write writes |len| bytes from |data| to |bio|. It returns the number of @@ -328,7 +328,7 @@ OPENSSL_EXPORT int BIO_printf(BIO *bio, const char *format, ...) OPENSSL_EXPORT int BIO_indent(BIO *bio, unsigned indent, unsigned max_indent); // BIO_hexdump writes a hex dump of |data| to |bio|. Each line will be indented -// by |indent| spaces. +// by |indent| spaces. It returns one on success and zero otherwise. OPENSSL_EXPORT int BIO_hexdump(BIO *bio, const uint8_t *data, size_t len, unsigned indent); @@ -383,7 +383,7 @@ OPENSSL_EXPORT const BIO_METHOD *BIO_s_mem(void); // // 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(const void *buf, int len); +OPENSSL_EXPORT BIO *BIO_new_mem_buf(const void *buf, ossl_ssize_t 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 diff --git a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_bn.h b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_bn.h index c91ea1d0..0e71b2c5 100644 --- a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_bn.h +++ b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_bn.h @@ -136,7 +136,16 @@ extern "C" { // BN provides support for working with arbitrary sized integers. For example, // although the largest integer supported by the compiler might be 64 bits, BN -// will allow you to work with numbers until you run out of memory. +// will allow you to work with much larger numbers. +// +// This library is developed for use inside BoringSSL, and uses implementation +// strategies that may not be ideal for other applications. Non-cryptographic +// uses should use a more general-purpose integer library, especially if +// performance-sensitive. +// +// Many functions in BN scale quadratically or higher in the bit length of their +// input. Callers at this layer are assumed to have capped input sizes within +// their performance tolerances. // BN_ULONG is the native word size when working with big integers. @@ -284,6 +293,10 @@ OPENSSL_EXPORT int BN_hex2bn(BIGNUM **outp, const char *in); // BN_bn2dec returns an allocated string that contains a NUL-terminated, // decimal representation of |bn|. If |bn| is negative, the first char in the // resulting string will be '-'. Returns NULL on allocation failure. +// +// Converting an arbitrarily large integer to decimal is quadratic in the bit +// length of |a|. This function assumes the caller has capped the input within +// performance tolerances. OPENSSL_EXPORT char *BN_bn2dec(const BIGNUM *a); // BN_dec2bn parses the leading decimal number from |in|, which may be @@ -292,6 +305,10 @@ OPENSSL_EXPORT char *BN_bn2dec(const BIGNUM *a); // decimal number and stores it in |*outp|. If |*outp| is NULL then it // allocates a new BIGNUM and updates |*outp|. It returns the number of bytes // of |in| processed or zero on error. +// +// Converting an arbitrarily large integer to decimal is quadratic in the bit +// length of |a|. This function assumes the caller has capped the input within +// performance tolerances. OPENSSL_EXPORT int BN_dec2bn(BIGNUM **outp, const char *in); // BN_asc2bn acts like |BN_dec2bn| or |BN_hex2bn| depending on whether |in| @@ -817,8 +834,9 @@ OPENSSL_EXPORT BIGNUM *BN_mod_inverse(BIGNUM *out, const BIGNUM *a, // Note this function may incorrectly report |a| has no inverse if the random // blinding value has no inverse. It should only be used when |n| has few // non-invertible elements, such as an RSA modulus. -int BN_mod_inverse_blinded(BIGNUM *out, int *out_no_inverse, const BIGNUM *a, - const BN_MONT_CTX *mont, BN_CTX *ctx); +OPENSSL_EXPORT int BN_mod_inverse_blinded(BIGNUM *out, int *out_no_inverse, + const BIGNUM *a, + const BN_MONT_CTX *mont, BN_CTX *ctx); // BN_mod_inverse_odd sets |out| equal to |a|^-1, mod |n|. |a| must be // non-negative and must be less than |n|. |n| must be odd. This function @@ -856,15 +874,6 @@ OPENSSL_EXPORT void BN_MONT_CTX_free(BN_MONT_CTX *mont); OPENSSL_EXPORT BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, const BN_MONT_CTX *from); -// 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|. It returns one on success and zero on error. Note -// this function assumes |mod| is public. -// -// 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. |a| is // assumed to be in the range [0, n), where |n| is the Montgomery modulus. It // returns one on success or zero on error. diff --git a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_boringssl_prefix_symbols.h b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_boringssl_prefix_symbols.h index 19874334..21bedeb2 100644 --- a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_boringssl_prefix_symbols.h +++ b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_boringssl_prefix_symbols.h @@ -103,7 +103,6 @@ #define ASN1_PRINTABLE_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_PRINTABLE_free) #define ASN1_PRINTABLE_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_PRINTABLE_it) #define ASN1_PRINTABLE_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_PRINTABLE_new) -#define ASN1_PRINTABLE_type BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_PRINTABLE_type) #define ASN1_SEQUENCE_ANY_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_SEQUENCE_ANY_it) #define ASN1_SEQUENCE_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_SEQUENCE_it) #define ASN1_SET_ANY_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_SET_ANY_it) @@ -141,6 +140,7 @@ #define ASN1_TIME_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_TIME_new) #define ASN1_TIME_print BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_TIME_print) #define ASN1_TIME_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_TIME_set) +#define ASN1_TIME_set_posix BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_TIME_set_posix) #define ASN1_TIME_set_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_TIME_set_string) #define ASN1_TIME_to_generalizedtime BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_TIME_to_generalizedtime) #define ASN1_TIME_to_posix BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_TIME_to_posix) @@ -453,6 +453,9 @@ #define BN_usub BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_usub) #define BN_value_one BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_value_one) #define BN_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_zero) +#define BORINGSSL_keccak BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BORINGSSL_keccak) +#define BORINGSSL_keccak_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BORINGSSL_keccak_init) +#define BORINGSSL_keccak_squeeze BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BORINGSSL_keccak_squeeze) #define BORINGSSL_self_test BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BORINGSSL_self_test) #define BUF_MEM_append BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BUF_MEM_append) #define BUF_MEM_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BUF_MEM_free) @@ -530,6 +533,7 @@ #define CBS_get_u32 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_get_u32) #define CBS_get_u32le BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_get_u32le) #define CBS_get_u64 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_get_u64) +#define CBS_get_u64_decimal BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_get_u64_decimal) #define CBS_get_u64le BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_get_u64le) #define CBS_get_u8 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_get_u8) #define CBS_get_u8_length_prefixed BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_get_u8_length_prefixed) @@ -538,6 +542,7 @@ #define CBS_is_unsigned_asn1_integer BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_is_unsigned_asn1_integer) #define CBS_is_valid_asn1_bitstring BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_is_valid_asn1_bitstring) #define CBS_is_valid_asn1_integer BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_is_valid_asn1_integer) +#define CBS_is_valid_asn1_oid BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_is_valid_asn1_oid) #define CBS_len BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_len) #define CBS_mem_equal BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_mem_equal) #define CBS_parse_generalized_time BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_parse_generalized_time) @@ -600,7 +605,7 @@ #define CRYPTO_cleanup_all_ex_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_cleanup_all_ex_data) #define CRYPTO_ctr128_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_ctr128_encrypt) #define CRYPTO_ctr128_encrypt_ctr32 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_ctr128_encrypt_ctr32) -#define CRYPTO_fork_detect_ignore_madv_wipeonfork_for_testing BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_fork_detect_ignore_madv_wipeonfork_for_testing) +#define CRYPTO_fork_detect_force_madv_wipeonfork_for_testing BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_fork_detect_force_madv_wipeonfork_for_testing) #define CRYPTO_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_free) #define CRYPTO_free_ex_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_free_ex_data) #define CRYPTO_gcm128_aad BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_gcm128_aad) @@ -832,9 +837,13 @@ #define EC_KEY_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_new) #define EC_KEY_new_by_curve_name BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_new_by_curve_name) #define EC_KEY_new_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_new_method) +#define EC_KEY_oct2key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_oct2key) +#define EC_KEY_oct2priv BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_oct2priv) #define EC_KEY_parse_curve_name BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_parse_curve_name) #define EC_KEY_parse_parameters BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_parse_parameters) #define EC_KEY_parse_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_parse_private_key) +#define EC_KEY_priv2buf BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_priv2buf) +#define EC_KEY_priv2oct BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_priv2oct) #define EC_KEY_set_asn1_flag BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_set_asn1_flag) #define EC_KEY_set_conv_form BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_set_conv_form) #define EC_KEY_set_enc_flags BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_set_enc_flags) @@ -860,6 +869,7 @@ #define EC_POINT_mul BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_POINT_mul) #define EC_POINT_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_POINT_new) #define EC_POINT_oct2point BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_POINT_oct2point) +#define EC_POINT_point2buf BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_POINT_point2buf) #define EC_POINT_point2cbb BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_POINT_point2cbb) #define EC_POINT_point2oct BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_POINT_point2oct) #define EC_POINT_set_affine_coordinates BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_POINT_set_affine_coordinates) @@ -869,6 +879,8 @@ #define EC_curve_nid2nist BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_curve_nid2nist) #define EC_curve_nist2nid BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_curve_nist2nid) #define EC_get_builtin_curves BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_get_builtin_curves) +#define EC_hash_to_curve_p256_xmd_sha256_sswu BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_hash_to_curve_p256_xmd_sha256_sswu) +#define EC_hash_to_curve_p384_xmd_sha384_sswu BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_hash_to_curve_p384_xmd_sha384_sswu) #define ED25519_keypair BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ED25519_keypair) #define ED25519_keypair_from_seed BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ED25519_keypair_from_seed) #define ED25519_sign BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ED25519_sign) @@ -884,6 +896,8 @@ #define ENGINE_register_all_complete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ENGINE_register_all_complete) #define ENGINE_set_ECDSA_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ENGINE_set_ECDSA_method) #define ENGINE_set_RSA_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ENGINE_set_RSA_method) +#define ERR_GET_LIB BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_GET_LIB) +#define ERR_GET_REASON BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_GET_REASON) #define ERR_SAVE_STATE_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_SAVE_STATE_free) #define ERR_add_error_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_add_error_data) #define ERR_add_error_dataf BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_add_error_dataf) @@ -1303,6 +1317,16 @@ #define ISSUING_DIST_POINT_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ISSUING_DIST_POINT_free) #define ISSUING_DIST_POINT_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ISSUING_DIST_POINT_it) #define ISSUING_DIST_POINT_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ISSUING_DIST_POINT_new) +#define KYBER_decap BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, KYBER_decap) +#define KYBER_encap BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, KYBER_encap) +#define KYBER_encap_external_entropy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, KYBER_encap_external_entropy) +#define KYBER_generate_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, KYBER_generate_key) +#define KYBER_generate_key_external_entropy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, KYBER_generate_key_external_entropy) +#define KYBER_marshal_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, KYBER_marshal_private_key) +#define KYBER_marshal_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, KYBER_marshal_public_key) +#define KYBER_parse_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, KYBER_parse_private_key) +#define KYBER_parse_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, KYBER_parse_public_key) +#define KYBER_public_from_private BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, KYBER_public_from_private) #define MD4 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MD4) #define MD4_Final BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MD4_Final) #define MD4_Init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MD4_Init) @@ -1361,6 +1385,7 @@ #define OBJ_txt2obj BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OBJ_txt2obj) #define OPENSSL_add_all_algorithms_conf BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_add_all_algorithms_conf) #define OPENSSL_armcap_P BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_armcap_P) +#define OPENSSL_asprintf BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_asprintf) #define OPENSSL_built_in_curves BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_built_in_curves) #define OPENSSL_cleanse BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_cleanse) #define OPENSSL_cleanup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_cleanup) @@ -1368,6 +1393,7 @@ #define OPENSSL_config BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_config) #define OPENSSL_cpuid_setup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_cpuid_setup) #define OPENSSL_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_free) +#define OPENSSL_fromxdigit BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_fromxdigit) #define OPENSSL_get_armcap_pointer_for_test BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_get_armcap_pointer_for_test) #define OPENSSL_gmtime BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_gmtime) #define OPENSSL_gmtime_adj BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_gmtime_adj) @@ -1376,6 +1402,11 @@ #define OPENSSL_ia32cap_P BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_ia32cap_P) #define OPENSSL_init_crypto BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_init_crypto) #define OPENSSL_init_ssl BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_init_ssl) +#define OPENSSL_isalnum BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_isalnum) +#define OPENSSL_isalpha BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_isalpha) +#define OPENSSL_isdigit BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_isdigit) +#define OPENSSL_isspace BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_isspace) +#define OPENSSL_isxdigit BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_isxdigit) #define OPENSSL_lh_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_lh_delete) #define OPENSSL_lh_doall_arg BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_lh_doall_arg) #define OPENSSL_lh_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_lh_free) @@ -1404,7 +1435,8 @@ #define OPENSSL_timegm BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_timegm) #define OPENSSL_tm_to_posix BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_tm_to_posix) #define OPENSSL_tolower BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_tolower) -#define OTHERNAME_cmp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OTHERNAME_cmp) +#define OPENSSL_vasprintf BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_vasprintf) +#define OPENSSL_vasprintf_internal BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_vasprintf_internal) #define OTHERNAME_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OTHERNAME_free) #define OTHERNAME_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OTHERNAME_it) #define OTHERNAME_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OTHERNAME_new) @@ -1421,10 +1453,8 @@ #define PEM_X509_INFO_read_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_X509_INFO_read_bio) #define PEM_bytes_read_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_bytes_read_bio) #define PEM_def_callback BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_def_callback) -#define PEM_dek_info BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_dek_info) #define PEM_do_header BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_do_header) #define PEM_get_EVP_CIPHER_INFO BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_get_EVP_CIPHER_INFO) -#define PEM_proc_type BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_proc_type) #define PEM_read BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_read) #define PEM_read_DHparams BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_read_DHparams) #define PEM_read_DSAPrivateKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_read_DSAPrivateKey) @@ -1517,6 +1547,7 @@ #define PKCS12_get_key_and_certs BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PKCS12_get_key_and_certs) #define PKCS12_parse BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PKCS12_parse) #define PKCS12_verify_mac BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PKCS12_verify_mac) +#define PKCS1_MGF1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PKCS1_MGF1) #define PKCS5_PBKDF2_HMAC BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PKCS5_PBKDF2_HMAC) #define PKCS5_PBKDF2_HMAC_SHA1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PKCS5_PBKDF2_HMAC_SHA1) #define PKCS5_pbe2_decrypt_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PKCS5_pbe2_decrypt_init) @@ -1557,12 +1588,6 @@ #define POLICY_MAPPING_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, POLICY_MAPPING_free) #define POLICY_MAPPING_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, POLICY_MAPPING_it) #define POLICY_MAPPING_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, POLICY_MAPPING_new) -#define PROXY_CERT_INFO_EXTENSION_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PROXY_CERT_INFO_EXTENSION_free) -#define PROXY_CERT_INFO_EXTENSION_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PROXY_CERT_INFO_EXTENSION_it) -#define PROXY_CERT_INFO_EXTENSION_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PROXY_CERT_INFO_EXTENSION_new) -#define PROXY_POLICY_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PROXY_POLICY_free) -#define PROXY_POLICY_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PROXY_POLICY_it) -#define PROXY_POLICY_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PROXY_POLICY_new) #define RAND_OpenSSL BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RAND_OpenSSL) #define RAND_SSLeay BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RAND_SSLeay) #define RAND_add BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RAND_add) @@ -1622,11 +1647,9 @@ #define RSA_padding_add_PKCS1_OAEP_mgf1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_padding_add_PKCS1_OAEP_mgf1) #define RSA_padding_add_PKCS1_PSS_mgf1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_padding_add_PKCS1_PSS_mgf1) #define RSA_padding_add_PKCS1_type_1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_padding_add_PKCS1_type_1) -#define RSA_padding_add_PKCS1_type_2 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_padding_add_PKCS1_type_2) #define RSA_padding_add_none BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_padding_add_none) #define RSA_padding_check_PKCS1_OAEP_mgf1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_padding_check_PKCS1_OAEP_mgf1) #define RSA_padding_check_PKCS1_type_1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_padding_check_PKCS1_type_1) -#define RSA_padding_check_PKCS1_type_2 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_padding_check_PKCS1_type_2) #define RSA_parse_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_parse_private_key) #define RSA_parse_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_parse_public_key) #define RSA_print BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_print) @@ -1634,7 +1657,6 @@ #define RSA_private_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_private_encrypt) #define RSA_private_key_from_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_private_key_from_bytes) #define RSA_private_key_to_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_private_key_to_bytes) -#define RSA_private_transform BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_private_transform) #define RSA_public_decrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_public_decrypt) #define RSA_public_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_public_encrypt) #define RSA_public_key_from_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_public_key_from_bytes) @@ -1699,7 +1721,6 @@ #define SSL_CIPHER_get_name BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CIPHER_get_name) #define SSL_CIPHER_get_prf_nid BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CIPHER_get_prf_nid) #define SSL_CIPHER_get_protocol_id BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CIPHER_get_protocol_id) -#define SSL_CIPHER_get_rfc_name BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CIPHER_get_rfc_name) #define SSL_CIPHER_get_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CIPHER_get_value) #define SSL_CIPHER_get_version BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CIPHER_get_version) #define SSL_CIPHER_is_aead BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CIPHER_is_aead) @@ -2187,6 +2208,7 @@ #define SSL_used_hello_retry_request BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_used_hello_retry_request) #define SSL_version BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_version) #define SSL_want BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_want) +#define SSL_was_key_usage_invalid BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_was_key_usage_invalid) #define SSL_write BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_write) #define SSLeay BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSLeay) #define SSLeay_version BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSLeay_version) @@ -2208,6 +2230,7 @@ #define TLSv1_server_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TLSv1_server_method) #define TRUST_TOKEN_CLIENT_add_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TRUST_TOKEN_CLIENT_add_key) #define TRUST_TOKEN_CLIENT_begin_issuance BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TRUST_TOKEN_CLIENT_begin_issuance) +#define TRUST_TOKEN_CLIENT_begin_issuance_over_message BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TRUST_TOKEN_CLIENT_begin_issuance_over_message) #define TRUST_TOKEN_CLIENT_begin_redemption BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TRUST_TOKEN_CLIENT_begin_redemption) #define TRUST_TOKEN_CLIENT_finish_issuance BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TRUST_TOKEN_CLIENT_finish_issuance) #define TRUST_TOKEN_CLIENT_finish_redemption BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TRUST_TOKEN_CLIENT_finish_redemption) @@ -2219,7 +2242,7 @@ #define TRUST_TOKEN_ISSUER_issue BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TRUST_TOKEN_ISSUER_issue) #define TRUST_TOKEN_ISSUER_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TRUST_TOKEN_ISSUER_new) #define TRUST_TOKEN_ISSUER_redeem BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TRUST_TOKEN_ISSUER_redeem) -#define TRUST_TOKEN_ISSUER_redeem_raw BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TRUST_TOKEN_ISSUER_redeem_raw) +#define TRUST_TOKEN_ISSUER_redeem_over_message BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TRUST_TOKEN_ISSUER_redeem_over_message) #define TRUST_TOKEN_ISSUER_set_metadata_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TRUST_TOKEN_ISSUER_set_metadata_key) #define TRUST_TOKEN_ISSUER_set_srr_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TRUST_TOKEN_ISSUER_set_srr_key) #define TRUST_TOKEN_PRETOKEN_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TRUST_TOKEN_PRETOKEN_free) @@ -2231,6 +2254,8 @@ #define TRUST_TOKEN_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TRUST_TOKEN_free) #define TRUST_TOKEN_generate_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TRUST_TOKEN_generate_key) #define TRUST_TOKEN_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TRUST_TOKEN_new) +#define TRUST_TOKEN_pst_v1_pmb BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TRUST_TOKEN_pst_v1_pmb) +#define TRUST_TOKEN_pst_v1_voprf BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TRUST_TOKEN_pst_v1_voprf) #define USERNOTICE_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, USERNOTICE_free) #define USERNOTICE_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, USERNOTICE_it) #define USERNOTICE_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, USERNOTICE_new) @@ -2260,21 +2285,17 @@ #define X509V3_add_standard_extensions BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_add_standard_extensions) #define X509V3_add_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_add_value) #define X509V3_add_value_bool BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_add_value_bool) -#define X509V3_add_value_bool_nf BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_add_value_bool_nf) #define X509V3_add_value_int BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_add_value_int) -#define X509V3_add_value_uchar BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_add_value_uchar) +#define X509V3_bool_from_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_bool_from_string) #define X509V3_conf_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_conf_free) #define X509V3_extensions_print BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_extensions_print) #define X509V3_get_d2i BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_get_d2i) #define X509V3_get_section BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_get_section) -#define X509V3_get_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_get_string) #define X509V3_get_value_bool BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_get_value_bool) #define X509V3_get_value_int BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_get_value_int) #define X509V3_parse_list BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_parse_list) -#define X509V3_section_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_section_free) #define X509V3_set_ctx BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_set_ctx) #define X509V3_set_nconf BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_set_nconf) -#define X509V3_string_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_string_free) #define X509_ALGOR_cmp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_ALGOR_cmp) #define X509_ALGOR_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_ALGOR_dup) #define X509_ALGOR_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_ALGOR_free) @@ -2421,7 +2442,6 @@ #define X509_OBJECT_up_ref_count BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_OBJECT_up_ref_count) #define X509_PKEY_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PKEY_free) #define X509_PKEY_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PKEY_new) -#define X509_POLICY_NODE_print BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_POLICY_NODE_print) #define X509_PUBKEY_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PUBKEY_free) #define X509_PUBKEY_get BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PUBKEY_get) #define X509_PUBKEY_get0_param BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PUBKEY_get0_param) @@ -2536,6 +2556,7 @@ #define X509_STORE_CTX_set_flags BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_set_flags) #define X509_STORE_CTX_set_purpose BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_set_purpose) #define X509_STORE_CTX_set_time BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_set_time) +#define X509_STORE_CTX_set_time_posix BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_set_time_posix) #define X509_STORE_CTX_set_trust BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_set_trust) #define X509_STORE_CTX_set_verify_cb BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_set_verify_cb) #define X509_STORE_CTX_trusted_stack BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_trusted_stack) @@ -2593,14 +2614,11 @@ #define X509_VAL_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VAL_it) #define X509_VAL_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VAL_new) #define X509_VERIFY_PARAM_add0_policy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_add0_policy) -#define X509_VERIFY_PARAM_add0_table BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_add0_table) #define X509_VERIFY_PARAM_add1_host BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_add1_host) #define X509_VERIFY_PARAM_clear_flags BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_clear_flags) #define X509_VERIFY_PARAM_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_free) -#define X509_VERIFY_PARAM_get0 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_get0) #define X509_VERIFY_PARAM_get0_name BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_get0_name) #define X509_VERIFY_PARAM_get0_peername BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_get0_peername) -#define X509_VERIFY_PARAM_get_count BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_get_count) #define X509_VERIFY_PARAM_get_depth BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_get_depth) #define X509_VERIFY_PARAM_get_flags BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_get_flags) #define X509_VERIFY_PARAM_inherit BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_inherit) @@ -2618,8 +2636,8 @@ #define X509_VERIFY_PARAM_set_hostflags BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set_hostflags) #define X509_VERIFY_PARAM_set_purpose BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set_purpose) #define X509_VERIFY_PARAM_set_time BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set_time) +#define X509_VERIFY_PARAM_set_time_posix BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set_time_posix) #define X509_VERIFY_PARAM_set_trust BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set_trust) -#define X509_VERIFY_PARAM_table_cleanup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_table_cleanup) #define X509_add1_ext_i2d BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_add1_ext_i2d) #define X509_add1_reject_object BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_add1_reject_object) #define X509_add1_trust_object BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_add1_trust_object) @@ -2640,6 +2658,7 @@ #define X509_cmp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_cmp) #define X509_cmp_current_time BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_cmp_current_time) #define X509_cmp_time BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_cmp_time) +#define X509_cmp_time_posix BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_cmp_time_posix) #define X509_delete_ext BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_delete_ext) #define X509_digest BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_digest) #define X509_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_dup) @@ -2703,7 +2722,6 @@ #define X509_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_new) #define X509_parse_from_buffer BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_parse_from_buffer) #define X509_policy_check BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_policy_check) -#define X509_policy_tree_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_policy_tree_free) #define X509_print BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_print) #define X509_print_ex BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_print_ex) #define X509_print_ex_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_print_ex_fp) @@ -2772,6 +2790,8 @@ #define aes256gcmsiv_enc_msg_x8 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, aes256gcmsiv_enc_msg_x8) #define aes256gcmsiv_kdf BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, aes256gcmsiv_kdf) #define aes_ctr_set_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, aes_ctr_set_key) +#define aes_gcm_dec_kernel BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, aes_gcm_dec_kernel) +#define aes_gcm_enc_kernel BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, aes_gcm_enc_kernel) #define aes_hw_cbc_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, aes_hw_cbc_encrypt) #define aes_hw_ctr32_encrypt_blocks BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, aes_hw_ctr32_encrypt_blocks) #define aes_hw_decrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, aes_hw_decrypt) @@ -2797,15 +2817,16 @@ #define asn1_enc_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_enc_init) #define asn1_enc_restore BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_enc_restore) #define asn1_enc_save BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_enc_save) +#define asn1_encoding_clear BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_encoding_clear) #define asn1_generalizedtime_to_tm BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_generalizedtime_to_tm) #define asn1_get_choice_selector BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_get_choice_selector) #define asn1_get_field_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_get_field_ptr) #define asn1_get_string_table_for_testing BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_get_string_table_for_testing) #define asn1_is_printable BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_is_printable) -#define asn1_item_combine_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_item_combine_free) #define asn1_refcount_dec_and_test_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_refcount_dec_and_test_zero) #define asn1_refcount_set_one BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_refcount_set_one) #define asn1_set_choice_selector BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_set_choice_selector) +#define asn1_type_cleanup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_type_cleanup) #define asn1_type_value_as_pointer BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_type_value_as_pointer) #define asn1_utctime_to_tm BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_utctime_to_tm) #define beeu_mod_inverse_vartime BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, beeu_mod_inverse_vartime) @@ -2816,6 +2837,7 @@ #define bio_socket_nbio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bio_socket_nbio) #define bn_abs_sub_consttime BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_abs_sub_consttime) #define bn_add_words BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_add_words) +#define bn_assert_fits_in_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_assert_fits_in_bytes) #define bn_big_endian_to_words BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_big_endian_to_words) #define bn_copy_words BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_copy_words) #define bn_div_consttime BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_div_consttime) @@ -2978,8 +3000,6 @@ #define d2i_PKCS8_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_PKCS8_fp) #define d2i_POLICYINFO BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_POLICYINFO) #define d2i_POLICYQUALINFO BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_POLICYQUALINFO) -#define d2i_PROXY_CERT_INFO_EXTENSION BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_PROXY_CERT_INFO_EXTENSION) -#define d2i_PROXY_POLICY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_PROXY_POLICY) #define d2i_PUBKEY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_PUBKEY) #define d2i_PUBKEY_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_PUBKEY_bio) #define d2i_PUBKEY_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_PUBKEY_fp) @@ -3026,11 +3046,13 @@ #define d2i_X509_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_fp) #define dh_compute_key_padded_no_self_test BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, dh_compute_key_padded_no_self_test) #define dsa_asn1_meth BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, dsa_asn1_meth) -#define dsa_check_parameters BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, dsa_check_parameters) +#define dsa_check_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, dsa_check_key) #define ec_GFp_mont_add BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_GFp_mont_add) #define ec_GFp_mont_dbl BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_GFp_mont_dbl) +#define ec_GFp_mont_felem_exp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_GFp_mont_felem_exp) #define ec_GFp_mont_felem_from_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_GFp_mont_felem_from_bytes) #define ec_GFp_mont_felem_mul BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_GFp_mont_felem_mul) +#define ec_GFp_mont_felem_reduce BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_GFp_mont_felem_reduce) #define ec_GFp_mont_felem_sqr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_GFp_mont_felem_sqr) #define ec_GFp_mont_felem_to_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_GFp_mont_felem_to_bytes) #define ec_GFp_mont_group_finish BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_GFp_mont_group_finish) @@ -3077,12 +3099,16 @@ #define ec_get_x_coordinate_as_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_get_x_coordinate_as_bytes) #define ec_get_x_coordinate_as_scalar BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_get_x_coordinate_as_scalar) #define ec_group_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_group_new) +#define ec_hash_to_curve_p256_xmd_sha256_sswu BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_hash_to_curve_p256_xmd_sha256_sswu) +#define ec_hash_to_curve_p384_xmd_sha384_sswu BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_hash_to_curve_p384_xmd_sha384_sswu) #define ec_hash_to_curve_p384_xmd_sha512_sswu_draft07 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_hash_to_curve_p384_xmd_sha512_sswu_draft07) +#define ec_hash_to_scalar_p384_xmd_sha384 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_hash_to_scalar_p384_xmd_sha384) #define ec_hash_to_scalar_p384_xmd_sha512_draft07 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_hash_to_scalar_p384_xmd_sha512_draft07) #define ec_init_precomp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_init_precomp) #define ec_jacobian_to_affine BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_jacobian_to_affine) #define ec_jacobian_to_affine_batch BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_jacobian_to_affine_batch) #define ec_pkey_meth BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_pkey_meth) +#define ec_point_byte_len BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_point_byte_len) #define ec_point_from_uncompressed BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_point_from_uncompressed) #define ec_point_mul_no_self_test BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_point_mul_no_self_test) #define ec_point_mul_scalar BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_point_mul_scalar) @@ -3236,8 +3262,6 @@ #define i2d_PKCS8_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_PKCS8_fp) #define i2d_POLICYINFO BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_POLICYINFO) #define i2d_POLICYQUALINFO BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_POLICYQUALINFO) -#define i2d_PROXY_CERT_INFO_EXTENSION BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_PROXY_CERT_INFO_EXTENSION) -#define i2d_PROXY_POLICY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_PROXY_POLICY) #define i2d_PUBKEY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_PUBKEY) #define i2d_PUBKEY_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_PUBKEY_bio) #define i2d_PUBKEY_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_PUBKEY_fp) @@ -3299,8 +3323,6 @@ #define kOpenSSLReasonStringData BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, kOpenSSLReasonStringData) #define kOpenSSLReasonValues BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, kOpenSSLReasonValues) #define kOpenSSLReasonValuesLen BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, kOpenSSLReasonValuesLen) -#define level_add_node BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, level_add_node) -#define level_find_node BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, level_find_node) #define md4_block_data_order BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, md4_block_data_order) #define md5_block_asm_data_order BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, md5_block_asm_data_order) #define o2i_ECPublicKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, o2i_ECPublicKey) @@ -3328,24 +3350,25 @@ #define pmbtoken_exp2_read BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, pmbtoken_exp2_read) #define pmbtoken_exp2_sign BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, pmbtoken_exp2_sign) #define pmbtoken_exp2_unblind BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, pmbtoken_exp2_unblind) -#define policy_cache_find_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, policy_cache_find_data) -#define policy_cache_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, policy_cache_free) -#define policy_cache_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, policy_cache_set) -#define policy_cache_set_mapping BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, policy_cache_set_mapping) -#define policy_data_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, policy_data_free) -#define policy_data_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, policy_data_new) -#define policy_node_cmp_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, policy_node_cmp_new) -#define policy_node_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, policy_node_free) -#define policy_node_match BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, policy_node_match) +#define pmbtoken_pst1_blind BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, pmbtoken_pst1_blind) +#define pmbtoken_pst1_client_key_from_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, pmbtoken_pst1_client_key_from_bytes) +#define pmbtoken_pst1_derive_key_from_secret BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, pmbtoken_pst1_derive_key_from_secret) +#define pmbtoken_pst1_generate_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, pmbtoken_pst1_generate_key) +#define pmbtoken_pst1_get_h_for_testing BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, pmbtoken_pst1_get_h_for_testing) +#define pmbtoken_pst1_issuer_key_from_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, pmbtoken_pst1_issuer_key_from_bytes) +#define pmbtoken_pst1_read BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, pmbtoken_pst1_read) +#define pmbtoken_pst1_sign BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, pmbtoken_pst1_sign) +#define pmbtoken_pst1_unblind BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, pmbtoken_pst1_unblind) #define poly_Rq_mul BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, poly_Rq_mul) #define rand_fork_unsafe_buffering_enabled BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rand_fork_unsafe_buffering_enabled) #define rsa_asn1_meth BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsa_asn1_meth) #define rsa_check_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsa_check_public_key) -#define rsa_default_decrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsa_default_decrypt) #define rsa_default_private_transform BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsa_default_private_transform) #define rsa_default_sign_raw BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsa_default_sign_raw) #define rsa_default_size BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsa_default_size) #define rsa_pkey_meth BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsa_pkey_meth) +#define rsa_private_transform BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsa_private_transform) +#define rsa_private_transform_no_self_test BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsa_private_transform_no_self_test) #define rsa_sign_no_self_test BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsa_sign_no_self_test) #define rsa_verify_no_self_test BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsa_verify_no_self_test) #define rsa_verify_raw_no_self_test BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsa_verify_raw_no_self_test) @@ -3400,6 +3423,7 @@ #define sk_X509_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_value) #define sk_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_deep_copy) #define sk_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_delete) +#define sk_delete_if BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_delete_if) #define sk_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_delete_ptr) #define sk_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_dup) #define sk_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_find) @@ -3419,7 +3443,6 @@ #define sk_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_sort) #define sk_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_value) #define sk_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_zero) -#define tree_find_sk BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, tree_find_sk) #define v2i_GENERAL_NAME BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, v2i_GENERAL_NAME) #define v2i_GENERAL_NAMES BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, v2i_GENERAL_NAMES) #define v2i_GENERAL_NAME_ex BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, v2i_GENERAL_NAME_ex) @@ -3443,7 +3466,6 @@ #define v3_nscert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, v3_nscert) #define v3_ocsp_accresp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, v3_ocsp_accresp) #define v3_ocsp_nocheck BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, v3_ocsp_nocheck) -#define v3_pci BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, v3_pci) #define v3_policy_constraints BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, v3_policy_constraints) #define v3_policy_mappings BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, v3_policy_mappings) #define v3_sinfo BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, v3_sinfo) @@ -3456,6 +3478,14 @@ #define voprf_exp2_read BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, voprf_exp2_read) #define voprf_exp2_sign BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, voprf_exp2_sign) #define voprf_exp2_unblind BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, voprf_exp2_unblind) +#define voprf_pst1_blind BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, voprf_pst1_blind) +#define voprf_pst1_client_key_from_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, voprf_pst1_client_key_from_bytes) +#define voprf_pst1_derive_key_from_secret BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, voprf_pst1_derive_key_from_secret) +#define voprf_pst1_generate_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, voprf_pst1_generate_key) +#define voprf_pst1_issuer_key_from_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, voprf_pst1_issuer_key_from_bytes) +#define voprf_pst1_read BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, voprf_pst1_read) +#define voprf_pst1_sign BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, voprf_pst1_sign) +#define voprf_pst1_unblind BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, voprf_pst1_unblind) #define vpaes_cbc_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, vpaes_cbc_encrypt) #define vpaes_ctr32_encrypt_blocks BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, vpaes_ctr32_encrypt_blocks) #define vpaes_decrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, vpaes_decrypt) @@ -3484,9 +3514,9 @@ #define x509v3_a2i_ipadd BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509v3_a2i_ipadd) #define x509v3_bytes_to_hex BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509v3_bytes_to_hex) #define x509v3_cache_extensions BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509v3_cache_extensions) +#define x509v3_conf_name_matches BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509v3_conf_name_matches) #define x509v3_hex_to_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509v3_hex_to_bytes) #define x509v3_looks_like_dns_name BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509v3_looks_like_dns_name) -#define x509v3_name_cmp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509v3_name_cmp) #define sk_TRUST_TOKEN_PRETOKEN_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_PRETOKEN_call_free_func) #define sk_TRUST_TOKEN_PRETOKEN_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_PRETOKEN_call_copy_func) #define sk_TRUST_TOKEN_PRETOKEN_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_PRETOKEN_call_cmp_func) @@ -3556,52 +3586,6 @@ #define sk_BIGNUM_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIGNUM_is_sorted) #define sk_BIGNUM_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIGNUM_set_cmp_func) #define sk_BIGNUM_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIGNUM_deep_copy) -#define sk_X509_POLICY_DATA_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_call_free_func) -#define sk_X509_POLICY_DATA_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_call_copy_func) -#define sk_X509_POLICY_DATA_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_call_cmp_func) -#define sk_X509_POLICY_DATA_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_new) -#define sk_X509_POLICY_DATA_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_new_null) -#define sk_X509_POLICY_DATA_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_num) -#define sk_X509_POLICY_DATA_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_zero) -#define sk_X509_POLICY_DATA_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_value) -#define sk_X509_POLICY_DATA_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_set) -#define sk_X509_POLICY_DATA_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_free) -#define sk_X509_POLICY_DATA_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_pop_free) -#define sk_X509_POLICY_DATA_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_insert) -#define sk_X509_POLICY_DATA_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_delete) -#define sk_X509_POLICY_DATA_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_delete_ptr) -#define sk_X509_POLICY_DATA_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_find) -#define sk_X509_POLICY_DATA_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_shift) -#define sk_X509_POLICY_DATA_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_push) -#define sk_X509_POLICY_DATA_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_pop) -#define sk_X509_POLICY_DATA_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_dup) -#define sk_X509_POLICY_DATA_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_sort) -#define sk_X509_POLICY_DATA_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_is_sorted) -#define sk_X509_POLICY_DATA_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_set_cmp_func) -#define sk_X509_POLICY_DATA_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_deep_copy) -#define sk_X509_POLICY_NODE_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_call_free_func) -#define sk_X509_POLICY_NODE_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_call_copy_func) -#define sk_X509_POLICY_NODE_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_call_cmp_func) -#define sk_X509_POLICY_NODE_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_new) -#define sk_X509_POLICY_NODE_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_new_null) -#define sk_X509_POLICY_NODE_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_num) -#define sk_X509_POLICY_NODE_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_zero) -#define sk_X509_POLICY_NODE_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_value) -#define sk_X509_POLICY_NODE_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_set) -#define sk_X509_POLICY_NODE_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_free) -#define sk_X509_POLICY_NODE_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_pop_free) -#define sk_X509_POLICY_NODE_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_insert) -#define sk_X509_POLICY_NODE_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_delete) -#define sk_X509_POLICY_NODE_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_delete_ptr) -#define sk_X509_POLICY_NODE_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_find) -#define sk_X509_POLICY_NODE_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_shift) -#define sk_X509_POLICY_NODE_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_push) -#define sk_X509_POLICY_NODE_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_pop) -#define sk_X509_POLICY_NODE_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_dup) -#define sk_X509_POLICY_NODE_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_sort) -#define sk_X509_POLICY_NODE_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_is_sorted) -#define sk_X509_POLICY_NODE_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_set_cmp_func) -#define sk_X509_POLICY_NODE_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_deep_copy) #define sk_STACK_OF_X509_NAME_ENTRY_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_STACK_OF_X509_NAME_ENTRY_call_free_func) #define sk_STACK_OF_X509_NAME_ENTRY_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_STACK_OF_X509_NAME_ENTRY_call_copy_func) #define sk_STACK_OF_X509_NAME_ENTRY_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_STACK_OF_X509_NAME_ENTRY_call_cmp_func) @@ -3671,6 +3655,52 @@ #define sk_BY_DIR_ENTRY_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_ENTRY_is_sorted) #define sk_BY_DIR_ENTRY_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_ENTRY_set_cmp_func) #define sk_BY_DIR_ENTRY_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_ENTRY_deep_copy) +#define sk_X509_POLICY_NODE_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_call_free_func) +#define sk_X509_POLICY_NODE_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_call_copy_func) +#define sk_X509_POLICY_NODE_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_call_cmp_func) +#define sk_X509_POLICY_NODE_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_new) +#define sk_X509_POLICY_NODE_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_new_null) +#define sk_X509_POLICY_NODE_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_num) +#define sk_X509_POLICY_NODE_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_zero) +#define sk_X509_POLICY_NODE_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_value) +#define sk_X509_POLICY_NODE_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_set) +#define sk_X509_POLICY_NODE_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_free) +#define sk_X509_POLICY_NODE_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_pop_free) +#define sk_X509_POLICY_NODE_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_insert) +#define sk_X509_POLICY_NODE_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_delete) +#define sk_X509_POLICY_NODE_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_delete_ptr) +#define sk_X509_POLICY_NODE_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_find) +#define sk_X509_POLICY_NODE_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_shift) +#define sk_X509_POLICY_NODE_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_push) +#define sk_X509_POLICY_NODE_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_pop) +#define sk_X509_POLICY_NODE_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_dup) +#define sk_X509_POLICY_NODE_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_sort) +#define sk_X509_POLICY_NODE_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_is_sorted) +#define sk_X509_POLICY_NODE_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_set_cmp_func) +#define sk_X509_POLICY_NODE_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_deep_copy) +#define sk_X509_POLICY_LEVEL_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_LEVEL_call_free_func) +#define sk_X509_POLICY_LEVEL_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_LEVEL_call_copy_func) +#define sk_X509_POLICY_LEVEL_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_LEVEL_call_cmp_func) +#define sk_X509_POLICY_LEVEL_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_LEVEL_new) +#define sk_X509_POLICY_LEVEL_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_LEVEL_new_null) +#define sk_X509_POLICY_LEVEL_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_LEVEL_num) +#define sk_X509_POLICY_LEVEL_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_LEVEL_zero) +#define sk_X509_POLICY_LEVEL_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_LEVEL_value) +#define sk_X509_POLICY_LEVEL_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_LEVEL_set) +#define sk_X509_POLICY_LEVEL_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_LEVEL_free) +#define sk_X509_POLICY_LEVEL_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_LEVEL_pop_free) +#define sk_X509_POLICY_LEVEL_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_LEVEL_insert) +#define sk_X509_POLICY_LEVEL_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_LEVEL_delete) +#define sk_X509_POLICY_LEVEL_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_LEVEL_delete_ptr) +#define sk_X509_POLICY_LEVEL_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_LEVEL_find) +#define sk_X509_POLICY_LEVEL_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_LEVEL_shift) +#define sk_X509_POLICY_LEVEL_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_LEVEL_push) +#define sk_X509_POLICY_LEVEL_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_LEVEL_pop) +#define sk_X509_POLICY_LEVEL_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_LEVEL_dup) +#define sk_X509_POLICY_LEVEL_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_LEVEL_sort) +#define sk_X509_POLICY_LEVEL_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_LEVEL_is_sorted) +#define sk_X509_POLICY_LEVEL_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_LEVEL_set_cmp_func) +#define sk_X509_POLICY_LEVEL_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_LEVEL_deep_copy) #define sk_X509_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_call_free_func) #define sk_X509_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_call_copy_func) #define sk_X509_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_call_cmp_func) diff --git a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_boringssl_prefix_symbols_asm.h b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_boringssl_prefix_symbols_asm.h index 41647ac4..c8353256 100644 --- a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_boringssl_prefix_symbols_asm.h +++ b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_boringssl_prefix_symbols_asm.h @@ -108,7 +108,6 @@ #define _ASN1_PRINTABLE_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_PRINTABLE_free) #define _ASN1_PRINTABLE_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_PRINTABLE_it) #define _ASN1_PRINTABLE_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_PRINTABLE_new) -#define _ASN1_PRINTABLE_type BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_PRINTABLE_type) #define _ASN1_SEQUENCE_ANY_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_SEQUENCE_ANY_it) #define _ASN1_SEQUENCE_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_SEQUENCE_it) #define _ASN1_SET_ANY_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_SET_ANY_it) @@ -146,6 +145,7 @@ #define _ASN1_TIME_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_TIME_new) #define _ASN1_TIME_print BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_TIME_print) #define _ASN1_TIME_set BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_TIME_set) +#define _ASN1_TIME_set_posix BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_TIME_set_posix) #define _ASN1_TIME_set_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_TIME_set_string) #define _ASN1_TIME_to_generalizedtime BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_TIME_to_generalizedtime) #define _ASN1_TIME_to_posix BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_TIME_to_posix) @@ -458,6 +458,9 @@ #define _BN_usub BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_usub) #define _BN_value_one BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_value_one) #define _BN_zero BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_zero) +#define _BORINGSSL_keccak BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BORINGSSL_keccak) +#define _BORINGSSL_keccak_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BORINGSSL_keccak_init) +#define _BORINGSSL_keccak_squeeze BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BORINGSSL_keccak_squeeze) #define _BORINGSSL_self_test BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BORINGSSL_self_test) #define _BUF_MEM_append BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BUF_MEM_append) #define _BUF_MEM_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BUF_MEM_free) @@ -535,6 +538,7 @@ #define _CBS_get_u32 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_get_u32) #define _CBS_get_u32le BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_get_u32le) #define _CBS_get_u64 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_get_u64) +#define _CBS_get_u64_decimal BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_get_u64_decimal) #define _CBS_get_u64le BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_get_u64le) #define _CBS_get_u8 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_get_u8) #define _CBS_get_u8_length_prefixed BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_get_u8_length_prefixed) @@ -543,6 +547,7 @@ #define _CBS_is_unsigned_asn1_integer BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_is_unsigned_asn1_integer) #define _CBS_is_valid_asn1_bitstring BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_is_valid_asn1_bitstring) #define _CBS_is_valid_asn1_integer BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_is_valid_asn1_integer) +#define _CBS_is_valid_asn1_oid BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_is_valid_asn1_oid) #define _CBS_len BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_len) #define _CBS_mem_equal BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_mem_equal) #define _CBS_parse_generalized_time BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_parse_generalized_time) @@ -605,7 +610,7 @@ #define _CRYPTO_cleanup_all_ex_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_cleanup_all_ex_data) #define _CRYPTO_ctr128_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_ctr128_encrypt) #define _CRYPTO_ctr128_encrypt_ctr32 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_ctr128_encrypt_ctr32) -#define _CRYPTO_fork_detect_ignore_madv_wipeonfork_for_testing BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_fork_detect_ignore_madv_wipeonfork_for_testing) +#define _CRYPTO_fork_detect_force_madv_wipeonfork_for_testing BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_fork_detect_force_madv_wipeonfork_for_testing) #define _CRYPTO_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_free) #define _CRYPTO_free_ex_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_free_ex_data) #define _CRYPTO_gcm128_aad BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_gcm128_aad) @@ -837,9 +842,13 @@ #define _EC_KEY_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_new) #define _EC_KEY_new_by_curve_name BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_new_by_curve_name) #define _EC_KEY_new_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_new_method) +#define _EC_KEY_oct2key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_oct2key) +#define _EC_KEY_oct2priv BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_oct2priv) #define _EC_KEY_parse_curve_name BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_parse_curve_name) #define _EC_KEY_parse_parameters BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_parse_parameters) #define _EC_KEY_parse_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_parse_private_key) +#define _EC_KEY_priv2buf BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_priv2buf) +#define _EC_KEY_priv2oct BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_priv2oct) #define _EC_KEY_set_asn1_flag BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_set_asn1_flag) #define _EC_KEY_set_conv_form BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_set_conv_form) #define _EC_KEY_set_enc_flags BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_set_enc_flags) @@ -865,6 +874,7 @@ #define _EC_POINT_mul BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_POINT_mul) #define _EC_POINT_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_POINT_new) #define _EC_POINT_oct2point BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_POINT_oct2point) +#define _EC_POINT_point2buf BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_POINT_point2buf) #define _EC_POINT_point2cbb BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_POINT_point2cbb) #define _EC_POINT_point2oct BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_POINT_point2oct) #define _EC_POINT_set_affine_coordinates BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_POINT_set_affine_coordinates) @@ -874,6 +884,8 @@ #define _EC_curve_nid2nist BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_curve_nid2nist) #define _EC_curve_nist2nid BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_curve_nist2nid) #define _EC_get_builtin_curves BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_get_builtin_curves) +#define _EC_hash_to_curve_p256_xmd_sha256_sswu BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_hash_to_curve_p256_xmd_sha256_sswu) +#define _EC_hash_to_curve_p384_xmd_sha384_sswu BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_hash_to_curve_p384_xmd_sha384_sswu) #define _ED25519_keypair BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ED25519_keypair) #define _ED25519_keypair_from_seed BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ED25519_keypair_from_seed) #define _ED25519_sign BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ED25519_sign) @@ -889,6 +901,8 @@ #define _ENGINE_register_all_complete BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ENGINE_register_all_complete) #define _ENGINE_set_ECDSA_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ENGINE_set_ECDSA_method) #define _ENGINE_set_RSA_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ENGINE_set_RSA_method) +#define _ERR_GET_LIB BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_GET_LIB) +#define _ERR_GET_REASON BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_GET_REASON) #define _ERR_SAVE_STATE_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_SAVE_STATE_free) #define _ERR_add_error_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_add_error_data) #define _ERR_add_error_dataf BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_add_error_dataf) @@ -1308,6 +1322,16 @@ #define _ISSUING_DIST_POINT_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ISSUING_DIST_POINT_free) #define _ISSUING_DIST_POINT_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ISSUING_DIST_POINT_it) #define _ISSUING_DIST_POINT_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ISSUING_DIST_POINT_new) +#define _KYBER_decap BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, KYBER_decap) +#define _KYBER_encap BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, KYBER_encap) +#define _KYBER_encap_external_entropy BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, KYBER_encap_external_entropy) +#define _KYBER_generate_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, KYBER_generate_key) +#define _KYBER_generate_key_external_entropy BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, KYBER_generate_key_external_entropy) +#define _KYBER_marshal_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, KYBER_marshal_private_key) +#define _KYBER_marshal_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, KYBER_marshal_public_key) +#define _KYBER_parse_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, KYBER_parse_private_key) +#define _KYBER_parse_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, KYBER_parse_public_key) +#define _KYBER_public_from_private BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, KYBER_public_from_private) #define _MD4 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, MD4) #define _MD4_Final BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, MD4_Final) #define _MD4_Init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, MD4_Init) @@ -1366,6 +1390,7 @@ #define _OBJ_txt2obj BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OBJ_txt2obj) #define _OPENSSL_add_all_algorithms_conf BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_add_all_algorithms_conf) #define _OPENSSL_armcap_P BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_armcap_P) +#define _OPENSSL_asprintf BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_asprintf) #define _OPENSSL_built_in_curves BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_built_in_curves) #define _OPENSSL_cleanse BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_cleanse) #define _OPENSSL_cleanup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_cleanup) @@ -1373,6 +1398,7 @@ #define _OPENSSL_config BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_config) #define _OPENSSL_cpuid_setup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_cpuid_setup) #define _OPENSSL_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_free) +#define _OPENSSL_fromxdigit BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_fromxdigit) #define _OPENSSL_get_armcap_pointer_for_test BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_get_armcap_pointer_for_test) #define _OPENSSL_gmtime BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_gmtime) #define _OPENSSL_gmtime_adj BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_gmtime_adj) @@ -1381,6 +1407,11 @@ #define _OPENSSL_ia32cap_P BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_ia32cap_P) #define _OPENSSL_init_crypto BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_init_crypto) #define _OPENSSL_init_ssl BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_init_ssl) +#define _OPENSSL_isalnum BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_isalnum) +#define _OPENSSL_isalpha BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_isalpha) +#define _OPENSSL_isdigit BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_isdigit) +#define _OPENSSL_isspace BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_isspace) +#define _OPENSSL_isxdigit BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_isxdigit) #define _OPENSSL_lh_delete BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_lh_delete) #define _OPENSSL_lh_doall_arg BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_lh_doall_arg) #define _OPENSSL_lh_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_lh_free) @@ -1409,7 +1440,8 @@ #define _OPENSSL_timegm BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_timegm) #define _OPENSSL_tm_to_posix BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_tm_to_posix) #define _OPENSSL_tolower BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_tolower) -#define _OTHERNAME_cmp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OTHERNAME_cmp) +#define _OPENSSL_vasprintf BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_vasprintf) +#define _OPENSSL_vasprintf_internal BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_vasprintf_internal) #define _OTHERNAME_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OTHERNAME_free) #define _OTHERNAME_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OTHERNAME_it) #define _OTHERNAME_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OTHERNAME_new) @@ -1426,10 +1458,8 @@ #define _PEM_X509_INFO_read_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_X509_INFO_read_bio) #define _PEM_bytes_read_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_bytes_read_bio) #define _PEM_def_callback BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_def_callback) -#define _PEM_dek_info BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_dek_info) #define _PEM_do_header BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_do_header) #define _PEM_get_EVP_CIPHER_INFO BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_get_EVP_CIPHER_INFO) -#define _PEM_proc_type BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_proc_type) #define _PEM_read BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_read) #define _PEM_read_DHparams BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_read_DHparams) #define _PEM_read_DSAPrivateKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_read_DSAPrivateKey) @@ -1522,6 +1552,7 @@ #define _PKCS12_get_key_and_certs BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PKCS12_get_key_and_certs) #define _PKCS12_parse BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PKCS12_parse) #define _PKCS12_verify_mac BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PKCS12_verify_mac) +#define _PKCS1_MGF1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PKCS1_MGF1) #define _PKCS5_PBKDF2_HMAC BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PKCS5_PBKDF2_HMAC) #define _PKCS5_PBKDF2_HMAC_SHA1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PKCS5_PBKDF2_HMAC_SHA1) #define _PKCS5_pbe2_decrypt_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PKCS5_pbe2_decrypt_init) @@ -1562,12 +1593,6 @@ #define _POLICY_MAPPING_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, POLICY_MAPPING_free) #define _POLICY_MAPPING_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, POLICY_MAPPING_it) #define _POLICY_MAPPING_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, POLICY_MAPPING_new) -#define _PROXY_CERT_INFO_EXTENSION_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PROXY_CERT_INFO_EXTENSION_free) -#define _PROXY_CERT_INFO_EXTENSION_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PROXY_CERT_INFO_EXTENSION_it) -#define _PROXY_CERT_INFO_EXTENSION_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PROXY_CERT_INFO_EXTENSION_new) -#define _PROXY_POLICY_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PROXY_POLICY_free) -#define _PROXY_POLICY_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PROXY_POLICY_it) -#define _PROXY_POLICY_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PROXY_POLICY_new) #define _RAND_OpenSSL BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RAND_OpenSSL) #define _RAND_SSLeay BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RAND_SSLeay) #define _RAND_add BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RAND_add) @@ -1627,11 +1652,9 @@ #define _RSA_padding_add_PKCS1_OAEP_mgf1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_padding_add_PKCS1_OAEP_mgf1) #define _RSA_padding_add_PKCS1_PSS_mgf1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_padding_add_PKCS1_PSS_mgf1) #define _RSA_padding_add_PKCS1_type_1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_padding_add_PKCS1_type_1) -#define _RSA_padding_add_PKCS1_type_2 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_padding_add_PKCS1_type_2) #define _RSA_padding_add_none BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_padding_add_none) #define _RSA_padding_check_PKCS1_OAEP_mgf1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_padding_check_PKCS1_OAEP_mgf1) #define _RSA_padding_check_PKCS1_type_1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_padding_check_PKCS1_type_1) -#define _RSA_padding_check_PKCS1_type_2 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_padding_check_PKCS1_type_2) #define _RSA_parse_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_parse_private_key) #define _RSA_parse_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_parse_public_key) #define _RSA_print BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_print) @@ -1639,7 +1662,6 @@ #define _RSA_private_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_private_encrypt) #define _RSA_private_key_from_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_private_key_from_bytes) #define _RSA_private_key_to_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_private_key_to_bytes) -#define _RSA_private_transform BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_private_transform) #define _RSA_public_decrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_public_decrypt) #define _RSA_public_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_public_encrypt) #define _RSA_public_key_from_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_public_key_from_bytes) @@ -1704,7 +1726,6 @@ #define _SSL_CIPHER_get_name BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CIPHER_get_name) #define _SSL_CIPHER_get_prf_nid BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CIPHER_get_prf_nid) #define _SSL_CIPHER_get_protocol_id BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CIPHER_get_protocol_id) -#define _SSL_CIPHER_get_rfc_name BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CIPHER_get_rfc_name) #define _SSL_CIPHER_get_value BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CIPHER_get_value) #define _SSL_CIPHER_get_version BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CIPHER_get_version) #define _SSL_CIPHER_is_aead BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CIPHER_is_aead) @@ -2192,6 +2213,7 @@ #define _SSL_used_hello_retry_request BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_used_hello_retry_request) #define _SSL_version BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_version) #define _SSL_want BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_want) +#define _SSL_was_key_usage_invalid BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_was_key_usage_invalid) #define _SSL_write BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_write) #define _SSLeay BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSLeay) #define _SSLeay_version BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSLeay_version) @@ -2213,6 +2235,7 @@ #define _TLSv1_server_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TLSv1_server_method) #define _TRUST_TOKEN_CLIENT_add_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TRUST_TOKEN_CLIENT_add_key) #define _TRUST_TOKEN_CLIENT_begin_issuance BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TRUST_TOKEN_CLIENT_begin_issuance) +#define _TRUST_TOKEN_CLIENT_begin_issuance_over_message BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TRUST_TOKEN_CLIENT_begin_issuance_over_message) #define _TRUST_TOKEN_CLIENT_begin_redemption BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TRUST_TOKEN_CLIENT_begin_redemption) #define _TRUST_TOKEN_CLIENT_finish_issuance BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TRUST_TOKEN_CLIENT_finish_issuance) #define _TRUST_TOKEN_CLIENT_finish_redemption BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TRUST_TOKEN_CLIENT_finish_redemption) @@ -2224,7 +2247,7 @@ #define _TRUST_TOKEN_ISSUER_issue BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TRUST_TOKEN_ISSUER_issue) #define _TRUST_TOKEN_ISSUER_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TRUST_TOKEN_ISSUER_new) #define _TRUST_TOKEN_ISSUER_redeem BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TRUST_TOKEN_ISSUER_redeem) -#define _TRUST_TOKEN_ISSUER_redeem_raw BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TRUST_TOKEN_ISSUER_redeem_raw) +#define _TRUST_TOKEN_ISSUER_redeem_over_message BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TRUST_TOKEN_ISSUER_redeem_over_message) #define _TRUST_TOKEN_ISSUER_set_metadata_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TRUST_TOKEN_ISSUER_set_metadata_key) #define _TRUST_TOKEN_ISSUER_set_srr_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TRUST_TOKEN_ISSUER_set_srr_key) #define _TRUST_TOKEN_PRETOKEN_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TRUST_TOKEN_PRETOKEN_free) @@ -2236,6 +2259,8 @@ #define _TRUST_TOKEN_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TRUST_TOKEN_free) #define _TRUST_TOKEN_generate_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TRUST_TOKEN_generate_key) #define _TRUST_TOKEN_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TRUST_TOKEN_new) +#define _TRUST_TOKEN_pst_v1_pmb BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TRUST_TOKEN_pst_v1_pmb) +#define _TRUST_TOKEN_pst_v1_voprf BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TRUST_TOKEN_pst_v1_voprf) #define _USERNOTICE_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, USERNOTICE_free) #define _USERNOTICE_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, USERNOTICE_it) #define _USERNOTICE_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, USERNOTICE_new) @@ -2265,21 +2290,17 @@ #define _X509V3_add_standard_extensions BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_add_standard_extensions) #define _X509V3_add_value BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_add_value) #define _X509V3_add_value_bool BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_add_value_bool) -#define _X509V3_add_value_bool_nf BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_add_value_bool_nf) #define _X509V3_add_value_int BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_add_value_int) -#define _X509V3_add_value_uchar BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_add_value_uchar) +#define _X509V3_bool_from_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_bool_from_string) #define _X509V3_conf_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_conf_free) #define _X509V3_extensions_print BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_extensions_print) #define _X509V3_get_d2i BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_get_d2i) #define _X509V3_get_section BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_get_section) -#define _X509V3_get_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_get_string) #define _X509V3_get_value_bool BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_get_value_bool) #define _X509V3_get_value_int BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_get_value_int) #define _X509V3_parse_list BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_parse_list) -#define _X509V3_section_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_section_free) #define _X509V3_set_ctx BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_set_ctx) #define _X509V3_set_nconf BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_set_nconf) -#define _X509V3_string_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_string_free) #define _X509_ALGOR_cmp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_ALGOR_cmp) #define _X509_ALGOR_dup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_ALGOR_dup) #define _X509_ALGOR_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_ALGOR_free) @@ -2426,7 +2447,6 @@ #define _X509_OBJECT_up_ref_count BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_OBJECT_up_ref_count) #define _X509_PKEY_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PKEY_free) #define _X509_PKEY_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PKEY_new) -#define _X509_POLICY_NODE_print BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_POLICY_NODE_print) #define _X509_PUBKEY_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PUBKEY_free) #define _X509_PUBKEY_get BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PUBKEY_get) #define _X509_PUBKEY_get0_param BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PUBKEY_get0_param) @@ -2541,6 +2561,7 @@ #define _X509_STORE_CTX_set_flags BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_set_flags) #define _X509_STORE_CTX_set_purpose BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_set_purpose) #define _X509_STORE_CTX_set_time BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_set_time) +#define _X509_STORE_CTX_set_time_posix BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_set_time_posix) #define _X509_STORE_CTX_set_trust BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_set_trust) #define _X509_STORE_CTX_set_verify_cb BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_set_verify_cb) #define _X509_STORE_CTX_trusted_stack BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_trusted_stack) @@ -2598,14 +2619,11 @@ #define _X509_VAL_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VAL_it) #define _X509_VAL_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VAL_new) #define _X509_VERIFY_PARAM_add0_policy BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_add0_policy) -#define _X509_VERIFY_PARAM_add0_table BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_add0_table) #define _X509_VERIFY_PARAM_add1_host BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_add1_host) #define _X509_VERIFY_PARAM_clear_flags BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_clear_flags) #define _X509_VERIFY_PARAM_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_free) -#define _X509_VERIFY_PARAM_get0 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_get0) #define _X509_VERIFY_PARAM_get0_name BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_get0_name) #define _X509_VERIFY_PARAM_get0_peername BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_get0_peername) -#define _X509_VERIFY_PARAM_get_count BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_get_count) #define _X509_VERIFY_PARAM_get_depth BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_get_depth) #define _X509_VERIFY_PARAM_get_flags BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_get_flags) #define _X509_VERIFY_PARAM_inherit BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_inherit) @@ -2623,8 +2641,8 @@ #define _X509_VERIFY_PARAM_set_hostflags BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set_hostflags) #define _X509_VERIFY_PARAM_set_purpose BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set_purpose) #define _X509_VERIFY_PARAM_set_time BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set_time) +#define _X509_VERIFY_PARAM_set_time_posix BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set_time_posix) #define _X509_VERIFY_PARAM_set_trust BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set_trust) -#define _X509_VERIFY_PARAM_table_cleanup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_table_cleanup) #define _X509_add1_ext_i2d BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_add1_ext_i2d) #define _X509_add1_reject_object BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_add1_reject_object) #define _X509_add1_trust_object BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_add1_trust_object) @@ -2645,6 +2663,7 @@ #define _X509_cmp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_cmp) #define _X509_cmp_current_time BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_cmp_current_time) #define _X509_cmp_time BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_cmp_time) +#define _X509_cmp_time_posix BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_cmp_time_posix) #define _X509_delete_ext BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_delete_ext) #define _X509_digest BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_digest) #define _X509_dup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_dup) @@ -2708,7 +2727,6 @@ #define _X509_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_new) #define _X509_parse_from_buffer BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_parse_from_buffer) #define _X509_policy_check BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_policy_check) -#define _X509_policy_tree_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_policy_tree_free) #define _X509_print BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_print) #define _X509_print_ex BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_print_ex) #define _X509_print_ex_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_print_ex_fp) @@ -2777,6 +2795,8 @@ #define _aes256gcmsiv_enc_msg_x8 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, aes256gcmsiv_enc_msg_x8) #define _aes256gcmsiv_kdf BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, aes256gcmsiv_kdf) #define _aes_ctr_set_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, aes_ctr_set_key) +#define _aes_gcm_dec_kernel BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, aes_gcm_dec_kernel) +#define _aes_gcm_enc_kernel BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, aes_gcm_enc_kernel) #define _aes_hw_cbc_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, aes_hw_cbc_encrypt) #define _aes_hw_ctr32_encrypt_blocks BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, aes_hw_ctr32_encrypt_blocks) #define _aes_hw_decrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, aes_hw_decrypt) @@ -2802,15 +2822,16 @@ #define _asn1_enc_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_enc_init) #define _asn1_enc_restore BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_enc_restore) #define _asn1_enc_save BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_enc_save) +#define _asn1_encoding_clear BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_encoding_clear) #define _asn1_generalizedtime_to_tm BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_generalizedtime_to_tm) #define _asn1_get_choice_selector BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_get_choice_selector) #define _asn1_get_field_ptr BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_get_field_ptr) #define _asn1_get_string_table_for_testing BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_get_string_table_for_testing) #define _asn1_is_printable BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_is_printable) -#define _asn1_item_combine_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_item_combine_free) #define _asn1_refcount_dec_and_test_zero BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_refcount_dec_and_test_zero) #define _asn1_refcount_set_one BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_refcount_set_one) #define _asn1_set_choice_selector BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_set_choice_selector) +#define _asn1_type_cleanup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_type_cleanup) #define _asn1_type_value_as_pointer BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_type_value_as_pointer) #define _asn1_utctime_to_tm BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_utctime_to_tm) #define _beeu_mod_inverse_vartime BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, beeu_mod_inverse_vartime) @@ -2821,6 +2842,7 @@ #define _bio_socket_nbio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bio_socket_nbio) #define _bn_abs_sub_consttime BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_abs_sub_consttime) #define _bn_add_words BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_add_words) +#define _bn_assert_fits_in_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_assert_fits_in_bytes) #define _bn_big_endian_to_words BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_big_endian_to_words) #define _bn_copy_words BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_copy_words) #define _bn_div_consttime BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_div_consttime) @@ -2983,8 +3005,6 @@ #define _d2i_PKCS8_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_PKCS8_fp) #define _d2i_POLICYINFO BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_POLICYINFO) #define _d2i_POLICYQUALINFO BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_POLICYQUALINFO) -#define _d2i_PROXY_CERT_INFO_EXTENSION BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_PROXY_CERT_INFO_EXTENSION) -#define _d2i_PROXY_POLICY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_PROXY_POLICY) #define _d2i_PUBKEY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_PUBKEY) #define _d2i_PUBKEY_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_PUBKEY_bio) #define _d2i_PUBKEY_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_PUBKEY_fp) @@ -3031,11 +3051,13 @@ #define _d2i_X509_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_fp) #define _dh_compute_key_padded_no_self_test BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, dh_compute_key_padded_no_self_test) #define _dsa_asn1_meth BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, dsa_asn1_meth) -#define _dsa_check_parameters BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, dsa_check_parameters) +#define _dsa_check_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, dsa_check_key) #define _ec_GFp_mont_add BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_GFp_mont_add) #define _ec_GFp_mont_dbl BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_GFp_mont_dbl) +#define _ec_GFp_mont_felem_exp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_GFp_mont_felem_exp) #define _ec_GFp_mont_felem_from_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_GFp_mont_felem_from_bytes) #define _ec_GFp_mont_felem_mul BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_GFp_mont_felem_mul) +#define _ec_GFp_mont_felem_reduce BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_GFp_mont_felem_reduce) #define _ec_GFp_mont_felem_sqr BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_GFp_mont_felem_sqr) #define _ec_GFp_mont_felem_to_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_GFp_mont_felem_to_bytes) #define _ec_GFp_mont_group_finish BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_GFp_mont_group_finish) @@ -3082,12 +3104,16 @@ #define _ec_get_x_coordinate_as_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_get_x_coordinate_as_bytes) #define _ec_get_x_coordinate_as_scalar BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_get_x_coordinate_as_scalar) #define _ec_group_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_group_new) +#define _ec_hash_to_curve_p256_xmd_sha256_sswu BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_hash_to_curve_p256_xmd_sha256_sswu) +#define _ec_hash_to_curve_p384_xmd_sha384_sswu BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_hash_to_curve_p384_xmd_sha384_sswu) #define _ec_hash_to_curve_p384_xmd_sha512_sswu_draft07 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_hash_to_curve_p384_xmd_sha512_sswu_draft07) +#define _ec_hash_to_scalar_p384_xmd_sha384 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_hash_to_scalar_p384_xmd_sha384) #define _ec_hash_to_scalar_p384_xmd_sha512_draft07 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_hash_to_scalar_p384_xmd_sha512_draft07) #define _ec_init_precomp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_init_precomp) #define _ec_jacobian_to_affine BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_jacobian_to_affine) #define _ec_jacobian_to_affine_batch BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_jacobian_to_affine_batch) #define _ec_pkey_meth BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_pkey_meth) +#define _ec_point_byte_len BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_point_byte_len) #define _ec_point_from_uncompressed BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_point_from_uncompressed) #define _ec_point_mul_no_self_test BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_point_mul_no_self_test) #define _ec_point_mul_scalar BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_point_mul_scalar) @@ -3241,8 +3267,6 @@ #define _i2d_PKCS8_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_PKCS8_fp) #define _i2d_POLICYINFO BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_POLICYINFO) #define _i2d_POLICYQUALINFO BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_POLICYQUALINFO) -#define _i2d_PROXY_CERT_INFO_EXTENSION BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_PROXY_CERT_INFO_EXTENSION) -#define _i2d_PROXY_POLICY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_PROXY_POLICY) #define _i2d_PUBKEY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_PUBKEY) #define _i2d_PUBKEY_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_PUBKEY_bio) #define _i2d_PUBKEY_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_PUBKEY_fp) @@ -3304,8 +3328,6 @@ #define _kOpenSSLReasonStringData BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, kOpenSSLReasonStringData) #define _kOpenSSLReasonValues BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, kOpenSSLReasonValues) #define _kOpenSSLReasonValuesLen BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, kOpenSSLReasonValuesLen) -#define _level_add_node BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, level_add_node) -#define _level_find_node BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, level_find_node) #define _md4_block_data_order BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, md4_block_data_order) #define _md5_block_asm_data_order BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, md5_block_asm_data_order) #define _o2i_ECPublicKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, o2i_ECPublicKey) @@ -3333,24 +3355,25 @@ #define _pmbtoken_exp2_read BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, pmbtoken_exp2_read) #define _pmbtoken_exp2_sign BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, pmbtoken_exp2_sign) #define _pmbtoken_exp2_unblind BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, pmbtoken_exp2_unblind) -#define _policy_cache_find_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, policy_cache_find_data) -#define _policy_cache_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, policy_cache_free) -#define _policy_cache_set BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, policy_cache_set) -#define _policy_cache_set_mapping BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, policy_cache_set_mapping) -#define _policy_data_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, policy_data_free) -#define _policy_data_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, policy_data_new) -#define _policy_node_cmp_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, policy_node_cmp_new) -#define _policy_node_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, policy_node_free) -#define _policy_node_match BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, policy_node_match) +#define _pmbtoken_pst1_blind BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, pmbtoken_pst1_blind) +#define _pmbtoken_pst1_client_key_from_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, pmbtoken_pst1_client_key_from_bytes) +#define _pmbtoken_pst1_derive_key_from_secret BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, pmbtoken_pst1_derive_key_from_secret) +#define _pmbtoken_pst1_generate_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, pmbtoken_pst1_generate_key) +#define _pmbtoken_pst1_get_h_for_testing BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, pmbtoken_pst1_get_h_for_testing) +#define _pmbtoken_pst1_issuer_key_from_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, pmbtoken_pst1_issuer_key_from_bytes) +#define _pmbtoken_pst1_read BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, pmbtoken_pst1_read) +#define _pmbtoken_pst1_sign BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, pmbtoken_pst1_sign) +#define _pmbtoken_pst1_unblind BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, pmbtoken_pst1_unblind) #define _poly_Rq_mul BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, poly_Rq_mul) #define _rand_fork_unsafe_buffering_enabled BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rand_fork_unsafe_buffering_enabled) #define _rsa_asn1_meth BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsa_asn1_meth) #define _rsa_check_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsa_check_public_key) -#define _rsa_default_decrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsa_default_decrypt) #define _rsa_default_private_transform BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsa_default_private_transform) #define _rsa_default_sign_raw BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsa_default_sign_raw) #define _rsa_default_size BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsa_default_size) #define _rsa_pkey_meth BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsa_pkey_meth) +#define _rsa_private_transform BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsa_private_transform) +#define _rsa_private_transform_no_self_test BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsa_private_transform_no_self_test) #define _rsa_sign_no_self_test BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsa_sign_no_self_test) #define _rsa_verify_no_self_test BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsa_verify_no_self_test) #define _rsa_verify_raw_no_self_test BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsa_verify_raw_no_self_test) @@ -3405,6 +3428,7 @@ #define _sk_X509_value BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_X509_value) #define _sk_deep_copy BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_deep_copy) #define _sk_delete BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_delete) +#define _sk_delete_if BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_delete_if) #define _sk_delete_ptr BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_delete_ptr) #define _sk_dup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_dup) #define _sk_find BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_find) @@ -3424,7 +3448,6 @@ #define _sk_sort BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_sort) #define _sk_value BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_value) #define _sk_zero BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_zero) -#define _tree_find_sk BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, tree_find_sk) #define _v2i_GENERAL_NAME BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, v2i_GENERAL_NAME) #define _v2i_GENERAL_NAMES BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, v2i_GENERAL_NAMES) #define _v2i_GENERAL_NAME_ex BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, v2i_GENERAL_NAME_ex) @@ -3448,7 +3471,6 @@ #define _v3_nscert BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, v3_nscert) #define _v3_ocsp_accresp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, v3_ocsp_accresp) #define _v3_ocsp_nocheck BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, v3_ocsp_nocheck) -#define _v3_pci BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, v3_pci) #define _v3_policy_constraints BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, v3_policy_constraints) #define _v3_policy_mappings BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, v3_policy_mappings) #define _v3_sinfo BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, v3_sinfo) @@ -3461,6 +3483,14 @@ #define _voprf_exp2_read BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, voprf_exp2_read) #define _voprf_exp2_sign BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, voprf_exp2_sign) #define _voprf_exp2_unblind BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, voprf_exp2_unblind) +#define _voprf_pst1_blind BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, voprf_pst1_blind) +#define _voprf_pst1_client_key_from_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, voprf_pst1_client_key_from_bytes) +#define _voprf_pst1_derive_key_from_secret BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, voprf_pst1_derive_key_from_secret) +#define _voprf_pst1_generate_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, voprf_pst1_generate_key) +#define _voprf_pst1_issuer_key_from_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, voprf_pst1_issuer_key_from_bytes) +#define _voprf_pst1_read BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, voprf_pst1_read) +#define _voprf_pst1_sign BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, voprf_pst1_sign) +#define _voprf_pst1_unblind BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, voprf_pst1_unblind) #define _vpaes_cbc_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, vpaes_cbc_encrypt) #define _vpaes_ctr32_encrypt_blocks BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, vpaes_ctr32_encrypt_blocks) #define _vpaes_decrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, vpaes_decrypt) @@ -3489,7 +3519,7 @@ #define _x509v3_a2i_ipadd BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509v3_a2i_ipadd) #define _x509v3_bytes_to_hex BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509v3_bytes_to_hex) #define _x509v3_cache_extensions BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509v3_cache_extensions) +#define _x509v3_conf_name_matches BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509v3_conf_name_matches) #define _x509v3_hex_to_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509v3_hex_to_bytes) #define _x509v3_looks_like_dns_name BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509v3_looks_like_dns_name) -#define _x509v3_name_cmp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509v3_name_cmp) #endif diff --git a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_bytestring.h b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_bytestring.h index c2a91b55..1f5255c0 100644 --- a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_bytestring.h +++ b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_bytestring.h @@ -160,6 +160,13 @@ OPENSSL_EXPORT int CBS_get_u24_length_prefixed(CBS *cbs, CBS *out); // one. Otherwise, it returns zero and leaves |cbs| unmodified. OPENSSL_EXPORT int CBS_get_until_first(CBS *cbs, CBS *out, uint8_t c); +// CBS_get_u64_decimal reads a decimal integer from |cbs| and writes it to +// |*out|. It stops reading at the end of the string, or the first non-digit +// character. It returns one on success and zero on error. This function behaves +// analogously to |strtoul| except it does not accept empty inputs, leading +// zeros, or negative values. +OPENSSL_EXPORT int CBS_get_u64_decimal(CBS *cbs, uint64_t *out); + // Parsing ASN.1 // @@ -169,8 +176,8 @@ OPENSSL_EXPORT int CBS_get_until_first(CBS *cbs, CBS *out, uint8_t c); // SEQUENCE, branching on CHOICEs or OPTIONAL fields, checking for trailing // data, and handling explict vs. implicit tagging. // -// Tags are represented as |unsigned| values in memory. The upper few bits store -// the class and constructed bit, and the remaining bits store the tag +// Tags are represented as |CBS_ASN1_TAG| values in memory. The upper few bits +// store the class and constructed bit, and the remaining bits store the tag // number. Note this differs from the DER serialization, to support tag numbers // beyond 31. Consumers must use the constants defined below to decompose or // assemble tags. @@ -231,31 +238,33 @@ OPENSSL_EXPORT int CBS_get_until_first(CBS *cbs, CBS *out, uint8_t c); // including tag and length bytes) and advances |cbs| over it. The ASN.1 // element must match |tag_value|. It returns one on success and zero // on error. -OPENSSL_EXPORT int CBS_get_asn1(CBS *cbs, CBS *out, unsigned tag_value); +OPENSSL_EXPORT int CBS_get_asn1(CBS *cbs, CBS *out, CBS_ASN1_TAG tag_value); // CBS_get_asn1_element acts like |CBS_get_asn1| but |out| will include the // ASN.1 header bytes too. -OPENSSL_EXPORT int CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned tag_value); +OPENSSL_EXPORT int CBS_get_asn1_element(CBS *cbs, CBS *out, + CBS_ASN1_TAG tag_value); // CBS_peek_asn1_tag looks ahead at the next ASN.1 tag and returns one // if the next ASN.1 element on |cbs| would have tag |tag_value|. If // |cbs| is empty or the tag does not match, it returns zero. Note: if // it returns one, CBS_get_asn1 may still fail if the rest of the // element is malformed. -OPENSSL_EXPORT int CBS_peek_asn1_tag(const CBS *cbs, unsigned tag_value); +OPENSSL_EXPORT int CBS_peek_asn1_tag(const CBS *cbs, CBS_ASN1_TAG tag_value); // CBS_get_any_asn1 sets |*out| to contain the next ASN.1 element from |*cbs| // (not including tag and length bytes), sets |*out_tag| to the tag number, and // advances |*cbs|. It returns one on success and zero on error. Either of |out| // and |out_tag| may be NULL to ignore the value. -OPENSSL_EXPORT int CBS_get_any_asn1(CBS *cbs, CBS *out, unsigned *out_tag); +OPENSSL_EXPORT int CBS_get_any_asn1(CBS *cbs, CBS *out, + CBS_ASN1_TAG *out_tag); // CBS_get_any_asn1_element sets |*out| to contain the next ASN.1 element from // |*cbs| (including header bytes) and advances |*cbs|. It sets |*out_tag| to // the tag number and |*out_header_len| to the length of the ASN.1 header. Each // of |out|, |out_tag|, and |out_header_len| may be NULL to ignore the value. OPENSSL_EXPORT int CBS_get_any_asn1_element(CBS *cbs, CBS *out, - unsigned *out_tag, + CBS_ASN1_TAG *out_tag, size_t *out_header_len); // CBS_get_any_ber_asn1_element acts the same as |CBS_get_any_asn1_element| but @@ -271,7 +280,7 @@ OPENSSL_EXPORT int CBS_get_any_asn1_element(CBS *cbs, CBS *out, // element. Callers parsing indefinite-length encoding must check for EOC // separately. OPENSSL_EXPORT int CBS_get_any_ber_asn1_element(CBS *cbs, CBS *out, - unsigned *out_tag, + CBS_ASN1_TAG *out_tag, size_t *out_header_len, int *out_ber_found, int *out_indefinite); @@ -297,7 +306,7 @@ OPENSSL_EXPORT int CBS_get_asn1_bool(CBS *cbs, int *out); // one, otherwise zero. It returns one on success, whether or not the element // was present, and zero on decode failure. OPENSSL_EXPORT int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, - unsigned tag); + CBS_ASN1_TAG tag); // CBS_get_optional_asn1_octet_string gets an optional // explicitly-tagged OCTET STRING from |cbs|. If present, it sets @@ -307,7 +316,7 @@ OPENSSL_EXPORT int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, // present, and zero on decode failure. OPENSSL_EXPORT int CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, int *out_present, - unsigned tag); + CBS_ASN1_TAG tag); // CBS_get_optional_asn1_uint64 gets an optional explicitly-tagged // INTEGER from |cbs|. If present, it sets |*out| to the @@ -315,7 +324,7 @@ OPENSSL_EXPORT int CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, // on success, whether or not the element was present, and zero on // decode failure. OPENSSL_EXPORT int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, - unsigned tag, + CBS_ASN1_TAG tag, uint64_t default_value); // CBS_get_optional_asn1_bool gets an optional, explicitly-tagged BOOLEAN from @@ -323,7 +332,8 @@ OPENSSL_EXPORT int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, // boolean. Otherwise, it sets |*out| to |default_value|. It returns one on // success, whether or not the element was present, and zero on decode // failure. -OPENSSL_EXPORT int CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned tag, +OPENSSL_EXPORT int CBS_get_optional_asn1_bool(CBS *cbs, int *out, + CBS_ASN1_TAG tag, int default_value); // CBS_is_valid_asn1_bitstring returns one if |cbs| is a valid ASN.1 BIT STRING @@ -346,11 +356,19 @@ OPENSSL_EXPORT int CBS_is_valid_asn1_integer(const CBS *cbs, // ASN.1 INTEGER body and zero otherwise. OPENSSL_EXPORT int CBS_is_unsigned_asn1_integer(const CBS *cbs); +// CBS_is_valid_asn1_oid returns one if |cbs| is a valid DER-encoded ASN.1 +// OBJECT IDENTIFIER contents (not including the element framing) and zero +// otherwise. This function tolerates arbitrarily large OID components. +OPENSSL_EXPORT int CBS_is_valid_asn1_oid(const CBS *cbs); + // CBS_asn1_oid_to_text interprets |cbs| as DER-encoded ASN.1 OBJECT IDENTIFIER // contents (not including the element framing) and returns the ASCII // representation (e.g., "1.2.840.113554.4.1.72585") in a newly-allocated // string, or NULL on failure. The caller must release the result with // |OPENSSL_free|. +// +// This function may fail if |cbs| is an invalid OBJECT IDENTIFIER, or if any +// OID components are too large. OPENSSL_EXPORT char *CBS_asn1_oid_to_text(const CBS *cbs); @@ -502,7 +520,7 @@ OPENSSL_EXPORT int CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents); // CBB_add_asn1 sets |*out_contents| to a |CBB| into which the contents of an // ASN.1 object can be written. The |tag| argument will be used as the tag for // the object. It returns one on success or zero on error. -OPENSSL_EXPORT int CBB_add_asn1(CBB *cbb, CBB *out_contents, unsigned tag); +OPENSSL_EXPORT int CBB_add_asn1(CBB *cbb, CBB *out_contents, CBS_ASN1_TAG tag); // CBB_add_bytes appends |len| bytes from |data| to |cbb|. It returns one on // success and zero otherwise. @@ -574,7 +592,7 @@ OPENSSL_EXPORT int CBB_add_asn1_uint64(CBB *cbb, uint64_t value); // |tag| as the tag instead of INTEGER. This is useful if the INTEGER type uses // implicit tagging. OPENSSL_EXPORT int CBB_add_asn1_uint64_with_tag(CBB *cbb, uint64_t value, - unsigned tag); + CBS_ASN1_TAG tag); // CBB_add_asn1_int64 writes an ASN.1 INTEGER into |cbb| using |CBB_add_asn1| // and writes |value| in its contents. It returns one on success and zero on @@ -585,7 +603,7 @@ OPENSSL_EXPORT int CBB_add_asn1_int64(CBB *cbb, int64_t value); // as the tag instead of INTEGER. This is useful if the INTEGER type uses // implicit tagging. OPENSSL_EXPORT int CBB_add_asn1_int64_with_tag(CBB *cbb, int64_t value, - unsigned tag); + CBS_ASN1_TAG tag); // CBB_add_asn1_octet_string writes an ASN.1 OCTET STRING into |cbb| with the // given contents. It returns one on success and zero on error. diff --git a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_cipher.h b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_cipher.h index 3e66a0be..c23407cf 100644 --- a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_cipher.h +++ b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_cipher.h @@ -214,26 +214,6 @@ OPENSSL_EXPORT int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, OPENSSL_EXPORT int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len); -// EVP_Cipher performs a one-shot encryption/decryption operation for non-AEAD -// ciphers. No partial blocks are maintained between calls. However, any -// internal cipher state is still updated. For CBC-mode ciphers, the IV is -// updated to the final ciphertext block. For stream ciphers, the stream is -// advanced past the bytes used. It returns one on success and zero otherwise. -// -// WARNING: This function behaves completely differently on AEAD ciphers, such -// as |EVP_aes_128_gcm|. Rather than being a one-shot operation, it behaves like -// |EVP_CipherUpdate| or |EVP_CipherFinal_ex|, depending on whether |in| is -// NULL. It also instead returns the number of bytes written or -1 on error. -// This behavior is deprecated. Use |EVP_CipherUpdate| or |EVP_CipherFinal_ex| -// instead. -// -// TODO(davidben): The normal ciphers currently never fail, even if, e.g., -// |in_len| is not a multiple of the block size for CBC-mode decryption. The -// input just gets rounded up while the output gets truncated. This should -// either be officially documented or fail. -OPENSSL_EXPORT int EVP_Cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, - const uint8_t *in, size_t in_len); - // EVP_CipherUpdate calls either |EVP_EncryptUpdate| or |EVP_DecryptUpdate| // depending on how |ctx| has been setup. OPENSSL_EXPORT int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, @@ -361,6 +341,12 @@ OPENSSL_EXPORT int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, #define EVP_CIPH_GCM_MODE 0x6 #define EVP_CIPH_XTS_MODE 0x7 +// The following values are never returned from |EVP_CIPHER_mode| and are +// included only to make it easier to compile code with BoringSSL. +#define EVP_CIPH_CCM_MODE 0x8 +#define EVP_CIPH_OCB_MODE 0x9 +#define EVP_CIPH_WRAP_MODE 0xa + // Cipher flags (for |EVP_CIPHER_flags|). @@ -432,6 +418,30 @@ OPENSSL_EXPORT int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, uint8_t *out, OPENSSL_EXPORT int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len); +// EVP_Cipher historically exposed an internal implementation detail of |ctx| +// and should not be used. Use |EVP_CipherUpdate| and |EVP_CipherFinal_ex| +// instead. +// +// If |ctx|'s cipher does not have the |EVP_CIPH_FLAG_CUSTOM_CIPHER| flag, it +// encrypts or decrypts |in_len| bytes from |in| and writes the resulting +// |in_len| bytes to |out|. It returns one on success and zero on error. +// |in_len| must be a multiple of the cipher's block size, or the behavior is +// undefined. +// +// TODO(davidben): Rather than being undefined (it'll often round the length up +// and likely read past the buffer), just fail the operation. +// +// If |ctx|'s cipher has the |EVP_CIPH_FLAG_CUSTOM_CIPHER| flag, it runs in one +// of two modes: If |in| is non-NULL, it behaves like |EVP_CipherUpdate|. If +// |in| is NULL, it behaves like |EVP_CipherFinal_ex|. In both cases, it returns +// |*out_len| on success and -1 on error. +// +// WARNING: The two possible calling conventions of this function signal errors +// incompatibly. In the first, zero indicates an error. In the second, zero +// indicates success with zero bytes of output. +OPENSSL_EXPORT int EVP_Cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, + const uint8_t *in, size_t in_len); + // EVP_add_cipher_alias does nothing and returns one. OPENSSL_EXPORT int EVP_add_cipher_alias(const char *a, const char *b); @@ -445,6 +455,12 @@ OPENSSL_EXPORT const EVP_CIPHER *EVP_get_cipherbyname(const char *name); // These AEADs are deprecated AES-GCM implementations that set // |EVP_CIPH_FLAG_CUSTOM_CIPHER|. Use |EVP_aead_aes_128_gcm| and // |EVP_aead_aes_256_gcm| instead. +// +// WARNING: Although these APIs allow streaming an individual AES-GCM operation, +// this is not secure. Until calling |EVP_DecryptFinal_ex|, the tag has not yet +// been checked and output released by |EVP_DecryptUpdate| is unauthenticated +// and easily manipulated by attackers. Callers must buffer the output and may +// not act on it until the entire operation is complete. OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_128_gcm(void); OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_gcm(void); @@ -496,9 +512,6 @@ OPENSSL_EXPORT const EVP_CIPHER *EVP_cast5_cbc(void); // The following flags do nothing and are included only to make it easier to // compile code with BoringSSL. -#define EVP_CIPH_CCM_MODE (-1) -#define EVP_CIPH_OCB_MODE (-2) -#define EVP_CIPH_WRAP_MODE (-3) #define EVP_CIPHER_CTX_FLAG_WRAP_ALLOW 0 // EVP_CIPHER_CTX_set_flags does nothing. diff --git a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_conf.h b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_conf.h index 6eeb02d8..d4fca56b 100644 --- a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_conf.h +++ b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_conf.h @@ -110,8 +110,8 @@ OPENSSL_EXPORT int NCONF_load_bio(CONF *conf, BIO *bio, long *out_error_line); // NCONF_get_section returns a stack of values for a given section in |conf|. // If |section| is NULL, the default section is returned. It returns NULL on // error. -OPENSSL_EXPORT STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf, - const char *section); +OPENSSL_EXPORT const STACK_OF(CONF_VALUE) *NCONF_get_section( + const CONF *conf, const char *section); // NCONF_get_string returns the value of the key |name|, in section |section|. // The |section| argument may be NULL to indicate the default section. It diff --git a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_crypto.h b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_crypto.h index 91a71e33..c37eee35 100644 --- a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_crypto.h +++ b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_crypto.h @@ -75,10 +75,6 @@ OPENSSL_EXPORT void CRYPTO_pre_sandbox_init(void); #if defined(OPENSSL_ARM) && defined(OPENSSL_LINUX) && \ !defined(OPENSSL_STATIC_ARMCAP) -// 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); - // CRYPTO_needs_hwcap2_workaround returns one if the ARMv8 AArch32 AT_HWCAP2 // workaround was needed. See https://crbug.com/boringssl/46. OPENSSL_EXPORT int CRYPTO_needs_hwcap2_workaround(void); @@ -193,6 +189,12 @@ OPENSSL_EXPORT uint32_t FIPS_version(void); // the current BoringSSL and zero otherwise. OPENSSL_EXPORT int FIPS_query_algorithm_status(const char *algorithm); +#if defined(OPENSSL_ARM) && defined(OPENSSL_LINUX) && \ + !defined(OPENSSL_STATIC_ARMCAP) +// CRYPTO_has_broken_NEON returns zero. +OPENSSL_EXPORT int CRYPTO_has_broken_NEON(void); +#endif + #if defined(__cplusplus) } // extern C diff --git a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ctrdrbg.h b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ctrdrbg.h index 3cfdc8e9..c4b622ec 100644 --- a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ctrdrbg.h +++ b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ctrdrbg.h @@ -71,6 +71,12 @@ OPENSSL_EXPORT void CTR_DRBG_clear(CTR_DRBG_STATE *drbg); #if defined(__cplusplus) } // extern C + +extern "C++" { +BSSL_NAMESPACE_BEGIN +BORINGSSL_MAKE_DELETER(CTR_DRBG_STATE, CTR_DRBG_free) +BSSL_NAMESPACE_END +} // extern C++ #endif #endif // OPENSSL_HEADER_CTRDRBG_H diff --git a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_dsa.h b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_dsa.h index c6eb7405..ab09dded 100644 --- a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_dsa.h +++ b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_dsa.h @@ -442,5 +442,6 @@ BSSL_NAMESPACE_END #define DSA_R_DECODE_ERROR 105 #define DSA_R_ENCODE_ERROR 106 #define DSA_R_INVALID_PARAMETERS 107 +#define DSA_R_TOO_MANY_ITERATIONS 108 #endif // OPENSSL_HEADER_DSA_H diff --git a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ec.h b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ec.h index 2add64dd..7c50126a 100644 --- a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ec.h +++ b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ec.h @@ -253,13 +253,23 @@ OPENSSL_EXPORT int EC_POINT_set_affine_coordinates(const EC_GROUP *group, BN_CTX *ctx); // EC_POINT_point2oct serialises |point| into the X9.62 form given by |form| -// into, at most, |len| bytes at |buf|. It returns the number of bytes written -// or zero on error if |buf| is non-NULL, else the number of bytes needed. The -// |ctx| argument may be used if not NULL. +// into, at most, |max_out| bytes at |buf|. It returns the number of bytes +// written or zero on error if |buf| is non-NULL, else the number of bytes +// needed. The |ctx| argument may be used if not NULL. OPENSSL_EXPORT size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form, - uint8_t *buf, size_t len, BN_CTX *ctx); + uint8_t *buf, size_t max_out, + BN_CTX *ctx); + +// EC_POINT_point2buf serialises |point| into the X9.62 form given by |form| to +// a newly-allocated buffer and sets |*out_buf| to point to it. It returns the +// length of the result on success or zero on error. The caller must release +// |*out_buf| with |OPENSSL_free| when done. +OPENSSL_EXPORT size_t EC_POINT_point2buf(const EC_GROUP *group, + const EC_POINT *point, + point_conversion_form_t form, + uint8_t **out_buf, 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. @@ -309,6 +319,31 @@ OPENSSL_EXPORT int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *m, BN_CTX *ctx); +// Hash-to-curve. +// +// The following functions implement primitives from +// draft-irtf-cfrg-hash-to-curve-16. The |dst| parameter in each function is the +// domain separation tag and must be unique for each protocol and between the +// |hash_to_curve| and |hash_to_scalar| variants. See section 3.1 of the spec +// for additional guidance on this parameter. + +// EC_hash_to_curve_p256_xmd_sha256_sswu hashes |msg| to a point on |group| and +// writes the result to |out|, implementing the P256_XMD:SHA-256_SSWU_RO_ suite +// from draft-irtf-cfrg-hash-to-curve-16. It returns one on success and zero on +// error. +OPENSSL_EXPORT int EC_hash_to_curve_p256_xmd_sha256_sswu( + const EC_GROUP *group, EC_POINT *out, const uint8_t *dst, size_t dst_len, + const uint8_t *msg, size_t msg_len); + +// EC_hash_to_curve_p384_xmd_sha384_sswu hashes |msg| to a point on |group| and +// writes the result to |out|, implementing the P384_XMD:SHA-384_SSWU_RO_ suite +// from draft-irtf-cfrg-hash-to-curve-16. It returns one on success and zero on +// error. +OPENSSL_EXPORT int EC_hash_to_curve_p384_xmd_sha384_sswu( + const EC_GROUP *group, EC_POINT *out, const uint8_t *dst, size_t dst_len, + const uint8_t *msg, size_t msg_len); + + // Deprecated functions. // EC_GROUP_new_curve_GFp creates a new, arbitrary elliptic curve group based diff --git a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ec_key.h b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ec_key.h index 085fa733..14b25111 100644 --- a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ec_key.h +++ b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ec_key.h @@ -179,12 +179,38 @@ OPENSSL_EXPORT int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, const BIGNUM *x, const BIGNUM *y); -// EC_KEY_key2buf encodes the public key in |key| to an allocated octet string -// and sets |*out_buf| to point to it. It returns the length of the encoded -// octet string or zero if an error occurred. +// EC_KEY_oct2key decodes |len| bytes from |in| as an EC public key in X9.62 +// form. |key| must already have a group configured. On success, it sets the +// public key in |key| to the result and returns one. Otherwise, it returns +// zero. +OPENSSL_EXPORT int EC_KEY_oct2key(EC_KEY *key, const uint8_t *in, size_t len, + BN_CTX *ctx); + +// EC_KEY_key2buf behaves like |EC_POINT_point2buf|, except it encodes the +// public key in |key|. OPENSSL_EXPORT size_t EC_KEY_key2buf(const EC_KEY *key, point_conversion_form_t form, - unsigned char **out_buf, BN_CTX *ctx); + uint8_t **out_buf, BN_CTX *ctx); + +// EC_KEY_oct2priv decodes a big-endian, zero-padded integer from |len| bytes +// from |in| and sets |key|'s private key to the result. It returns one on +// success and zero on error. The input must be padded to the size of |key|'s +// group order. +OPENSSL_EXPORT int EC_KEY_oct2priv(EC_KEY *key, const uint8_t *in, size_t len); + +// EC_KEY_priv2oct serializes |key|'s private key as a big-endian integer, +// zero-padded to the size of |key|'s group order and writes the result to at +// most |max_out| bytes of |out|. It returns the number of bytes written on +// success and zero on error. If |out| is NULL, it returns the number of bytes +// needed without writing anything. +OPENSSL_EXPORT size_t EC_KEY_priv2oct(const EC_KEY *key, uint8_t *out, + size_t max_out); + +// EC_KEY_priv2buf behaves like |EC_KEY_priv2oct| but sets |*out_buf| to a +// newly-allocated buffer containing the result. It returns the size of the +// result on success and zero on error. The caller must release |*out_buf| with +// |OPENSSL_free| when done. +OPENSSL_EXPORT size_t EC_KEY_priv2buf(const EC_KEY *key, uint8_t **out_buf); // Key generation. @@ -335,7 +361,7 @@ OPENSSL_EXPORT EC_KEY *o2i_ECPublicKey(EC_KEY **out_key, const uint8_t **inp, long len); // i2o_ECPublicKey marshals an EC point from |key|, as described in -// |i2d_SAMPLE|. +// |i2d_SAMPLE|, except it returns zero on error instead of a negative value. // // Use |EC_POINT_point2cbb| instead. OPENSSL_EXPORT int i2o_ECPublicKey(const EC_KEY *key, unsigned char **outp); diff --git a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ecdsa.h b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ecdsa.h index b1459b0a..7ea89057 100644 --- a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ecdsa.h +++ b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ecdsa.h @@ -232,5 +232,6 @@ BSSL_NAMESPACE_END #define ECDSA_R_NOT_IMPLEMENTED 103 #define ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED 104 #define ECDSA_R_ENCODE_ERROR 105 +#define ECDSA_R_TOO_MANY_ITERATIONS 106 #endif // OPENSSL_HEADER_ECDSA_H diff --git a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_err.h b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_err.h index 3841e50e..567c192c 100644 --- a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_err.h +++ b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_err.h @@ -163,12 +163,16 @@ OPENSSL_EXPORT void ERR_free_strings(void); // ERR_GET_LIB returns the library code for the error. This is one of // the |ERR_LIB_*| values. -#define ERR_GET_LIB(packed_error) ((int)(((packed_error) >> 24) & 0xff)) +OPENSSL_INLINE int ERR_GET_LIB(uint32_t packed_error) { + return (int)((packed_error >> 24) & 0xff); +} // ERR_GET_REASON returns the reason code for the error. This is one of // library-specific |LIB_R_*| values where |LIB| is the library (see // |ERR_GET_LIB|). Note that reason codes are specific to the library. -#define ERR_GET_REASON(packed_error) ((int)((packed_error) & 0xfff)) +OPENSSL_INLINE int ERR_GET_REASON(uint32_t packed_error) { + return (int)(packed_error & 0xfff); +} // ERR_get_error gets the packed error code for the least recent error and // removes that error from the queue. If there are no errors in the queue then @@ -184,8 +188,12 @@ OPENSSL_EXPORT uint32_t ERR_get_error_line(const char **file, int *line); #define ERR_FLAG_STRING 1 // ERR_FLAG_MALLOCED is passed into |ERR_set_error_data| to indicate that |data| -// was allocated with |OPENSSL_malloc|. It is never returned from -// |ERR_get_error_line_data|. +// was allocated with |OPENSSL_malloc|. +// +// It is, separately, returned in |*flags| from |ERR_get_error_line_data| to +// indicate that |*data| has a non-static lifetime, but this lifetime is still +// managed by the library. The caller must not call |OPENSSL_free| or |free| on +// |data|. #define ERR_FLAG_MALLOCED 2 // ERR_get_error_line_data acts like |ERR_get_error_line|, but also returns the @@ -411,7 +419,10 @@ OPENSSL_EXPORT char *ERR_error_string(uint32_t packed_error, char *buf); #define ERR_ERROR_STRING_BUF_LEN 120 // ERR_GET_FUNC returns zero. BoringSSL errors do not report a function code. -#define ERR_GET_FUNC(packed_error) 0 +OPENSSL_INLINE int ERR_GET_FUNC(uint32_t packed_error) { + (void)packed_error; + return 0; +} // ERR_TXT_* are provided for compatibility with code that assumes that it's // using OpenSSL. diff --git a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_evp.h b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_evp.h index e4f8c1ee..2ea88d57 100644 --- a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_evp.h +++ b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_evp.h @@ -936,7 +936,10 @@ OPENSSL_EXPORT int EVP_PKEY_CTX_set_ec_param_enc(EVP_PKEY_CTX *ctx, // EVP_PKEY_set1_tls_encodedpoint replaces |pkey| with a public key encoded by // |in|. It returns one on success and zero on error. // -// This function only works on X25519 keys. +// If |pkey| is an EC key, the format is an X9.62 point and |pkey| must already +// have an EC group configured. If it is an X25519 key, it is the 32-byte X25519 +// public key representation. This function is not supported for other key types +// and will fail. OPENSSL_EXPORT int EVP_PKEY_set1_tls_encodedpoint(EVP_PKEY *pkey, const uint8_t *in, size_t len); @@ -946,7 +949,10 @@ OPENSSL_EXPORT int EVP_PKEY_set1_tls_encodedpoint(EVP_PKEY *pkey, // |OPENSSL_free| to release this buffer. The function returns the length of the // buffer on success and zero on error. // -// This function only works on X25519 keys. +// If |pkey| is an EC key, the format is an X9.62 point with uncompressed +// coordinates. If it is an X25519 key, it is the 32-byte X25519 public key +// representation. This function is not supported for other key types and will +// fail. OPENSSL_EXPORT size_t EVP_PKEY_get1_tls_encodedpoint(const EVP_PKEY *pkey, uint8_t **out_ptr); @@ -1050,29 +1056,6 @@ OPENSSL_EXPORT int EVP_PKEY_CTX_set_dsa_paramgen_q_bits(EVP_PKEY_CTX *ctx, ERR_put_error(ERR_LIB_EVP, 0, reason, __FILE__, __LINE__) -// Private structures. - -struct evp_pkey_st { - CRYPTO_refcount_t references; - - // type contains one of the EVP_PKEY_* values or NID_undef and determines - // which element (if any) of the |pkey| union is valid. - int type; - - union { - void *ptr; - RSA *rsa; - DSA *dsa; - DH *dh; - EC_KEY *ec; - } pkey; - - // ameth contains a pointer to a method table that contains many ASN.1 - // methods for the key type. - const EVP_PKEY_ASN1_METHOD *ameth; -} /* EVP_PKEY */; - - #if defined(__cplusplus) } // extern C diff --git a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ex_data.h b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ex_data.h index e6602a69..030fe16a 100644 --- a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ex_data.h +++ b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ex_data.h @@ -145,7 +145,7 @@ OPENSSL_EXPORT int TYPE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_free *free_func); // TYPE_set_ex_data sets an extra data pointer on |t|. The |index| argument -// should have been returned from a previous call to |TYPE_get_ex_new_index|. +// must have been returned from a previous call to |TYPE_get_ex_new_index|. OPENSSL_EXPORT int TYPE_set_ex_data(TYPE *t, int index, void *arg); // TYPE_get_ex_data returns an extra data pointer for |t|, or NULL if no such diff --git a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_kyber.h b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_kyber.h new file mode 100644 index 00000000..5c060373 --- /dev/null +++ b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_kyber.h @@ -0,0 +1,128 @@ +/* Copyright (c) 2023, 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_KYBER_H +#define OPENSSL_HEADER_KYBER_H + +#include "CNIOBoringSSL_base.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Kyber768. + + +// KYBER_public_key contains a Kyber768 public key. The contents of this +// object should never leave the address space since the format is unstable. +struct KYBER_public_key { + union { + uint8_t bytes[512 * (3 + 9) + 32 + 32]; + uint16_t alignment; + } opaque; +}; + +// KYBER_private_key contains a Kyber768 private key. The contents of this +// object should never leave the address space since the format is unstable. +struct KYBER_private_key { + union { + uint8_t bytes[512 * (3 + 3 + 9) + 32 + 32 + 32]; + uint16_t alignment; + } opaque; +}; + +// KYBER_PUBLIC_KEY_BYTES is the number of bytes in an encoded Kyber768 public +// key. +#define KYBER_PUBLIC_KEY_BYTES 1184 + +// KYBER_generate_key generates a random public/private key pair, writes the +// encoded public key to |out_encoded_public_key| and sets |out_private_key| to +// the private key. +OPENSSL_EXPORT void KYBER_generate_key( + uint8_t out_encoded_public_key[KYBER_PUBLIC_KEY_BYTES], + struct KYBER_private_key *out_private_key); + +// KYBER_public_from_private sets |*out_public_key| to the public key that +// corresponds to |private_key|. (This is faster than parsing the output of +// |KYBER_generate_key| if, for some reason, you need to encapsulate to a key +// that was just generated.) +OPENSSL_EXPORT void KYBER_public_from_private( + struct KYBER_public_key *out_public_key, + const struct KYBER_private_key *private_key); + +// KYBER_CIPHERTEXT_BYTES is number of bytes in the Kyber768 ciphertext. +#define KYBER_CIPHERTEXT_BYTES 1088 + +// KYBER_encap encrypts a random secret key of length |out_shared_secret_len| to +// |public_key|, writes the ciphertext to |ciphertext|, and writes the random +// key to |out_shared_secret|. The party calling |KYBER_decap| must already know +// the correct value of |out_shared_secret_len|. +OPENSSL_EXPORT void KYBER_encap(uint8_t out_ciphertext[KYBER_CIPHERTEXT_BYTES], + uint8_t *out_shared_secret, + size_t out_shared_secret_len, + const struct KYBER_public_key *public_key); + +// KYBER_decap decrypts a key of length |out_shared_secret_len| from +// |ciphertext| using |private_key| and writes it to |out_shared_secret|. If +// |ciphertext| is invalid, |out_shared_secret| is filled with a key that +// will always be the same for the same |ciphertext| and |private_key|, but +// which appears to be random unless one has access to |private_key|. These +// alternatives occur in constant time. Any subsequent symmetric encryption +// using |out_shared_secret| must use an authenticated encryption scheme in +// order to discover the decapsulation failure. +OPENSSL_EXPORT void KYBER_decap( + uint8_t *out_shared_secret, size_t out_shared_secret_len, + const uint8_t ciphertext[KYBER_CIPHERTEXT_BYTES], + const struct KYBER_private_key *private_key); + + +// Serialisation of keys. + +// KYBER_marshal_public_key serializes |public_key| to |out| in the standard +// format for Kyber public keys. It returns one on success or zero on allocation +// error. +OPENSSL_EXPORT int KYBER_marshal_public_key( + CBB *out, const struct KYBER_public_key *public_key); + +// KYBER_parse_public_key parses a public key, in the format generated by +// |KYBER_marshal_public_key|, from |in| and writes the result to +// |out_public_key|. It returns one on success or zero on parse error or if +// there are trailing bytes in |in|. +OPENSSL_EXPORT int KYBER_parse_public_key( + struct KYBER_public_key *out_public_key, CBS *in); + +// KYBER_marshal_private_key serializes |private_key| to |out| in the standard +// format for Kyber private keys. It returns one on success or zero on +// allocation error. +OPENSSL_EXPORT int KYBER_marshal_private_key( + CBB *out, const struct KYBER_private_key *private_key); + +// KYBER_PRIVATE_KEY_BYTES is the length of the data produced by +// |KYBER_marshal_private_key|. +#define KYBER_PRIVATE_KEY_BYTES 2400 + +// KYBER_parse_private_key parses a private key, in the format generated by +// |KYBER_marshal_private_key|, from |in| and writes the result to +// |out_private_key|. It returns one on success or zero on parse error or if +// there are trailing bytes in |in|. +OPENSSL_EXPORT int KYBER_parse_private_key( + struct KYBER_private_key *out_private_key, CBS *in); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_KYBER_H diff --git a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_mem.h b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_mem.h index 50e4b3a1..2bb7429d 100644 --- a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_mem.h +++ b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_mem.h @@ -75,17 +75,26 @@ extern "C" { // unless stated otherwise. -// OPENSSL_malloc acts like a regular |malloc|. +#ifndef _BORINGSSL_PROHIBIT_OPENSSL_MALLOC +// OPENSSL_malloc is similar to a regular |malloc|, but allocates additional +// private data. The resulting pointer must be freed with |OPENSSL_free|. In +// the case of a malloc failure, prior to returning NULL |OPENSSL_malloc| will +// push |ERR_R_MALLOC_FAILURE| onto the openssl error stack. OPENSSL_EXPORT void *OPENSSL_malloc(size_t size); +#endif // !_BORINGSSL_PROHIBIT_OPENSSL_MALLOC // OPENSSL_free does nothing if |ptr| is NULL. Otherwise it zeros out the -// memory allocated at |ptr| and frees it. +// memory allocated at |ptr| and frees it along with the private data. +// It must only be used on on |ptr| values obtained from |OPENSSL_malloc| OPENSSL_EXPORT void OPENSSL_free(void *ptr); +#ifndef _BORINGSSL_PROHIBIT_OPENSSL_MALLOC // OPENSSL_realloc returns a pointer to a buffer of |new_size| bytes that // contains the contents of |ptr|. Unlike |realloc|, a new buffer is always -// allocated and the data at |ptr| is always wiped and freed. +// allocated and the data at |ptr| is always wiped and freed. Memory is +// allocated with |OPENSSL_malloc| and must be freed with |OPENSSL_free|. OPENSSL_EXPORT void *OPENSSL_realloc(void *ptr, size_t new_size); +#endif // !_BORINGSSL_PROHIBIT_OPENSSL_MALLOC // OPENSSL_cleanse zeros out |len| bytes of memory at |ptr|. This is similar to // |memset_s| from C11. @@ -110,13 +119,42 @@ OPENSSL_EXPORT char *OPENSSL_strdup(const char *s); // OPENSSL_strnlen has the same behaviour as strnlen(3). OPENSSL_EXPORT size_t OPENSSL_strnlen(const char *s, size_t len); -// OPENSSL_tolower is a locale-independent version of tolower(3). +// OPENSSL_isalpha is a locale-independent, ASCII-only version of isalpha(3), It +// only recognizes 'a' through 'z' and 'A' through 'Z' as alphabetic. +OPENSSL_EXPORT int OPENSSL_isalpha(int c); + +// OPENSSL_isdigit is a locale-independent, ASCII-only version of isdigit(3), It +// only recognizes '0' through '9' as digits. +OPENSSL_EXPORT int OPENSSL_isdigit(int c); + +// OPENSSL_isxdigit is a locale-independent, ASCII-only version of isxdigit(3), +// It only recognizes '0' through '9', 'a' through 'f', and 'A through 'F' as +// digits. +OPENSSL_EXPORT int OPENSSL_isxdigit(int c); + +// OPENSSL_fromxdigit returns one if |c| is a hexadecimal digit as recognized +// by OPENSSL_isxdigit, and sets |out| to the corresponding value. Otherwise +// zero is returned. +OPENSSL_EXPORT int OPENSSL_fromxdigit(uint8_t *out, int c); + +// OPENSSL_isalnum is a locale-independent, ASCII-only version of isalnum(3), It +// only recognizes what |OPENSSL_isalpha| and |OPENSSL_isdigit| recognize. +OPENSSL_EXPORT int OPENSSL_isalnum(int c); + +// OPENSSL_tolower is a locale-independent, ASCII-only version of tolower(3). It +// only lowercases ASCII values. Other values are returned as-is. OPENSSL_EXPORT int OPENSSL_tolower(int c); -// OPENSSL_strcasecmp is a locale-independent version of strcasecmp(3). +// OPENSSL_isspace is a locale-independent, ASCII-only version of isspace(3). It +// only recognizes '\t', '\n', '\v', '\f', '\r', and ' '. +OPENSSL_EXPORT int OPENSSL_isspace(int c); + +// OPENSSL_strcasecmp is a locale-independent, ASCII-only version of +// strcasecmp(3). OPENSSL_EXPORT int OPENSSL_strcasecmp(const char *a, const char *b); -// OPENSSL_strncasecmp is a locale-independent version of strncasecmp(3). +// OPENSSL_strncasecmp is a locale-independent, ASCII-only version of +// strncasecmp(3). OPENSSL_EXPORT int OPENSSL_strncasecmp(const char *a, const char *b, size_t n); // DECIMAL_SIZE returns an upper bound for the length of the decimal @@ -131,12 +169,25 @@ OPENSSL_EXPORT int BIO_snprintf(char *buf, size_t n, const char *format, ...) OPENSSL_EXPORT int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args) OPENSSL_PRINTF_FORMAT_FUNC(3, 0); +// OPENSSL_vasprintf has the same behavior as vasprintf(3), except that +// memory allocated in a returned string must be freed with |OPENSSL_free|. +OPENSSL_EXPORT int OPENSSL_vasprintf(char **str, const char *format, + va_list args) + OPENSSL_PRINTF_FORMAT_FUNC(2, 0); + +// OPENSSL_asprintf has the same behavior as asprintf(3), except that +// memory allocated in a returned string must be freed with |OPENSSL_free|. +OPENSSL_EXPORT int OPENSSL_asprintf(char **str, const char *format, ...) + OPENSSL_PRINTF_FORMAT_FUNC(2, 3); + // OPENSSL_strndup returns an allocated, duplicate of |str|, which is, at most, -// |size| bytes. The result is always NUL terminated. +// |size| bytes. The result is always NUL terminated. The memory allocated +// must be freed with |OPENSSL_free|. OPENSSL_EXPORT char *OPENSSL_strndup(const char *str, size_t size); // OPENSSL_memdup returns an allocated, duplicate of |size| bytes from |data| or -// NULL on allocation failure. +// NULL on allocation failure. The memory allocated must be freed with +// |OPENSSL_free|. OPENSSL_EXPORT void *OPENSSL_memdup(const void *data, size_t size); // OPENSSL_strlcpy acts like strlcpy(3). diff --git a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_nid.h b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_nid.h index 2ae1baf3..02b9a91f 100644 --- a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_nid.h +++ b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_nid.h @@ -4255,6 +4255,15 @@ extern "C" { #define LN_hkdf "hkdf" #define NID_hkdf 963 +#define SN_X25519Kyber768 "X25519Kyber768" +#define NID_X25519Kyber768 964 + +#define SN_P256Kyber768 "P256Kyber768" +#define NID_P256Kyber768 965 + +#define SN_P384Kyber768 "P384Kyber768" +#define NID_P384Kyber768 966 + #if defined(__cplusplus) } /* extern C */ diff --git a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_obj.h b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_obj.h index 10fbbc9d..b583cbd6 100644 --- a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_obj.h +++ b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_obj.h @@ -183,8 +183,15 @@ OPENSSL_EXPORT int OBJ_obj2txt(char *out, int out_len, const ASN1_OBJECT *obj, // Adding objects at runtime. -// OBJ_create adds a known object and returns the nid of the new object, or +// OBJ_create adds a known object and returns the NID of the new object, or // NID_undef on error. +// +// WARNING: This function modifies global state. The table cannot contain +// duplicate OIDs, short names, or long names. If two callers in the same +// address space add conflicting values, only one registration will take effect. +// Avoid this function if possible. Instead, callers can process OIDs unknown to +// BoringSSL by acting on the byte representation directly. See |OBJ_get0_data| +// and |OBJ_length|. OPENSSL_EXPORT int OBJ_create(const char *oid, const char *short_name, const char *long_name); diff --git a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_pem.h b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_pem.h index ecd2b89b..da30db25 100644 --- a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_pem.h +++ b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_pem.h @@ -372,9 +372,6 @@ OPENSSL_EXPORT STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, // password. OPENSSL_EXPORT int PEM_def_callback(char *buf, int size, int rwflag, void *userdata); -OPENSSL_EXPORT void PEM_proc_type(char *buf, int type); -OPENSSL_EXPORT void PEM_dek_info(char *buf, const char *type, int len, - char *str); DECLARE_PEM_rw(X509, X509) @@ -417,40 +414,40 @@ DECLARE_PEM_rw_cb(PrivateKey, EVP_PKEY) DECLARE_PEM_rw(PUBKEY, EVP_PKEY) -OPENSSL_EXPORT int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, +OPENSSL_EXPORT int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, const EVP_PKEY *x, int nid, char *kstr, int klen, pem_password_cb *cb, void *u); -OPENSSL_EXPORT int PEM_write_bio_PKCS8PrivateKey(BIO *, EVP_PKEY *, +OPENSSL_EXPORT int PEM_write_bio_PKCS8PrivateKey(BIO *, const EVP_PKEY *, const EVP_CIPHER *, char *, int, pem_password_cb *, void *); -OPENSSL_EXPORT int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, +OPENSSL_EXPORT int i2d_PKCS8PrivateKey_bio(BIO *bp, const EVP_PKEY *x, const EVP_CIPHER *enc, char *kstr, int klen, pem_password_cb *cb, void *u); -OPENSSL_EXPORT int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid, - char *kstr, int klen, +OPENSSL_EXPORT int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, const EVP_PKEY *x, + int nid, char *kstr, int klen, pem_password_cb *cb, void *u); OPENSSL_EXPORT EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u); -OPENSSL_EXPORT int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, +OPENSSL_EXPORT int i2d_PKCS8PrivateKey_fp(FILE *fp, const EVP_PKEY *x, const EVP_CIPHER *enc, char *kstr, int klen, pem_password_cb *cb, void *u); -OPENSSL_EXPORT int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid, - char *kstr, int klen, +OPENSSL_EXPORT int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, const EVP_PKEY *x, + int nid, char *kstr, int klen, pem_password_cb *cb, void *u); -OPENSSL_EXPORT int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid, - char *kstr, int klen, +OPENSSL_EXPORT int PEM_write_PKCS8PrivateKey_nid(FILE *fp, const EVP_PKEY *x, + int nid, char *kstr, int klen, pem_password_cb *cb, void *u); OPENSSL_EXPORT EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u); -OPENSSL_EXPORT int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, +OPENSSL_EXPORT int PEM_write_PKCS8PrivateKey(FILE *fp, const EVP_PKEY *x, const EVP_CIPHER *enc, char *kstr, int klen, pem_password_cb *cd, void *u); diff --git a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_rsa.h b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_rsa.h index 2fa076ac..ceb4a9af 100644 --- a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_rsa.h +++ b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_rsa.h @@ -775,7 +775,7 @@ struct rsa_st { // num_blindings contains the size of the |blindings| and |blindings_inuse| // arrays. This member and the |blindings_inuse| array are protected by // |lock|. - unsigned num_blindings; + size_t num_blindings; // blindings is an array of BN_BLINDING structures that can be reserved by a // thread by locking |lock| and changing the corresponding element in // |blindings_inuse| from 0 to 1. diff --git a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ssl.h b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ssl.h index 52359030..4df747a2 100644 --- a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ssl.h +++ b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ssl.h @@ -157,11 +157,6 @@ #include #endif -// NGINX needs this #include. Consider revisiting this after NGINX 1.14.0 has -// been out for a year or so (assuming that they fix it in that release.) See -// https://boringssl-review.googlesource.com/c/boringssl/+/21664. -#include "CNIOBoringSSL_hmac.h" - // Forward-declare struct timeval. On Windows, it is defined in winsock2.h and // Windows headers define too many macros to be included in public headers. // However, only a forward declaration is needed. @@ -2340,6 +2335,8 @@ OPENSSL_EXPORT int SSL_set1_curves_list(SSL *ssl, const char *curves); #define SSL_CURVE_SECP521R1 25 #define SSL_CURVE_X25519 29 #define SSL_CURVE_CECPQ2 16696 +#define SSL_CURVE_X25519KYBER768 0x6399 +#define SSL_CURVE_P256KYBER768 0xfe32 // SSL_get_curve_id returns the ID of the curve used by |ssl|'s most recently // completed handshake or 0 if not applicable. @@ -2832,7 +2829,7 @@ OPENSSL_EXPORT SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx); // WARNING: this function is dangerous because it breaks the usual return value // convention. OPENSSL_EXPORT int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const uint8_t *protos, - unsigned protos_len); + size_t protos_len); // SSL_set_alpn_protos sets the client ALPN protocol list on |ssl| to |protos|. // |protos| must be in wire-format (i.e. a series of non-empty, 8-bit @@ -2843,7 +2840,7 @@ OPENSSL_EXPORT int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const uint8_t *protos, // WARNING: this function is dangerous because it breaks the usual return value // convention. OPENSSL_EXPORT int SSL_set_alpn_protos(SSL *ssl, const uint8_t *protos, - unsigned protos_len); + size_t protos_len); // SSL_CTX_set_alpn_select_cb sets a callback function on |ctx| that is called // during ClientHello processing in order to select an ALPN protocol from the @@ -4327,12 +4324,24 @@ OPENSSL_EXPORT void SSL_CTX_set_dos_protection_cb( // respected on clients. OPENSSL_EXPORT void SSL_CTX_set_reverify_on_resume(SSL_CTX *ctx, int enabled); -// SSL_set_enforce_rsa_key_usage configures whether the keyUsage extension of -// RSA leaf certificates will be checked for consistency with the TLS -// usage. This parameter may be set late; it will not be read until after the +// SSL_set_enforce_rsa_key_usage configures whether, when |ssl| is a client +// negotiating TLS 1.2 or below, the keyUsage extension of RSA leaf server +// certificates will be checked for consistency with the TLS usage. In all other +// cases, this check is always enabled. +// +// This parameter may be set late; it will not be read until after the // certificate verification callback. OPENSSL_EXPORT void SSL_set_enforce_rsa_key_usage(SSL *ssl, int enabled); +// SSL_was_key_usage_invalid returns one if |ssl|'s handshake succeeded despite +// using TLS parameters which were incompatible with the leaf certificate's +// keyUsage extension. Otherwise, it returns zero. +// +// If |SSL_set_enforce_rsa_key_usage| is enabled or not applicable, this +// function will always return zero because key usages will be consistently +// checked. +OPENSSL_EXPORT int SSL_was_key_usage_invalid(const SSL *ssl); + // SSL_ST_* are possible values for |SSL_state|, the bitmasks that make them up, // and some historical values for compatibility. Only |SSL_ST_INIT| and // |SSL_ST_OK| are ever returned. @@ -4519,13 +4528,6 @@ OPENSSL_EXPORT const char *SSL_CIPHER_description(const SSL_CIPHER *cipher, // SSL_CIPHER_get_version returns the string "TLSv1/SSLv3". OPENSSL_EXPORT const char *SSL_CIPHER_get_version(const SSL_CIPHER *cipher); -// SSL_CIPHER_get_rfc_name returns a newly-allocated string containing the -// result of |SSL_CIPHER_standard_name| or NULL on error. The caller is -// responsible for calling |OPENSSL_free| on the result. -// -// Use |SSL_CIPHER_standard_name| instead. -OPENSSL_EXPORT char *SSL_CIPHER_get_rfc_name(const SSL_CIPHER *cipher); - typedef void COMP_METHOD; typedef struct ssl_comp_st SSL_COMP; @@ -5411,6 +5413,18 @@ OPENSSL_EXPORT bool SSL_get_traffic_secrets( const SSL *ssl, Span *out_read_traffic_secret, Span *out_write_traffic_secret); +// SSL_CTX_set_aes_hw_override_for_testing sets |override_value| to +// override checking for aes hardware support for testing. If |override_value| +// is set to true, the library will behave as if aes hardware support is +// present. If it is set to false, the library will behave as if aes hardware +// support is not present. +OPENSSL_EXPORT void SSL_CTX_set_aes_hw_override_for_testing( + SSL_CTX *ctx, bool override_value); + +// SSL_set_aes_hw_override_for_testing acts the same as +// |SSL_CTX_set_aes_override_for_testing| but only configures a single |SSL*|. +OPENSSL_EXPORT void SSL_set_aes_hw_override_for_testing(SSL *ssl, + bool override_value); BSSL_NAMESPACE_END diff --git a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ssl3.h b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ssl3.h index a45da07b..31c7de38 100644 --- a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ssl3.h +++ b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ssl3.h @@ -1,4 +1,3 @@ -/* ssl/ssl3.h */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * diff --git a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_stack.h b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_stack.h index 935e6f48..0f902bd0 100644 --- a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_stack.h +++ b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_stack.h @@ -120,17 +120,15 @@ typedef void (*sk_SAMPLE_free_func)(SAMPLE *); // sk_SAMPLE_copy_func is a callback to copy an element in a stack. It should // return the copy or NULL on error. -typedef SAMPLE *(*sk_SAMPLE_copy_func)(SAMPLE *); +typedef SAMPLE *(*sk_SAMPLE_copy_func)(const SAMPLE *); // sk_SAMPLE_cmp_func is a callback to compare |*a| to |*b|. It should return a // value < 0, 0, or > 0 if |*a| is less than, equal to, or greater than |*b|, // respectively. Note the extra indirection - the function is given a pointer // to a pointer to the element. This is the |qsort|/|bsearch| comparison // function applied to an array of |SAMPLE*|. -// -// TODO(https://crbug.com/boringssl/498): The parameters should be -// |const SAMPLE *const *|. -typedef int (*sk_SAMPLE_cmp_func)(const SAMPLE **a, const SAMPLE **b); +typedef int (*sk_SAMPLE_cmp_func)(const SAMPLE *const *a, + const SAMPLE *const *b); // sk_SAMPLE_new creates a new, empty stack with the given comparison function, // which may be NULL. It returns the new stack or NULL on allocation failure. @@ -178,6 +176,17 @@ SAMPLE *sk_SAMPLE_delete(STACK_OF(SAMPLE) *sk, size_t where); // otherwise it returns NULL. SAMPLE *sk_SAMPLE_delete_ptr(STACK_OF(SAMPLE) *sk, const SAMPLE *p); +// sk_SAMPLE_delete_if_func is the callback function for |sk_SAMPLE_delete_if|. +// It should return one to remove |p| and zero to keep it. +typedef int (*sk_SAMPLE_delete_if_func)(SAMPLE *p, void *data); + +// sk_SAMPLE_delete_if calls |func| with each element of |sk| and removes the +// entries where |func| returned one. This function does not free or return +// removed pointers so, if |sk| owns its contents, |func| should release the +// pointers prior to returning one. +void sk_SAMPLE_delete_if(STACK_OF(SAMPLE) *sk, sk_SAMPLE_delete_if_func func, + void *data); + // sk_SAMPLE_find find the first value in |sk| equal to |p|. |sk|'s comparison // function determines equality, or pointer equality if |sk| has no comparison // function. @@ -244,29 +253,33 @@ STACK_OF(SAMPLE) *sk_SAMPLE_deep_copy(const STACK_OF(SAMPLE) *sk, typedef void (*OPENSSL_sk_free_func)(void *ptr); // OPENSSL_sk_copy_func is a function that copies an element in a stack. Note -// its actual type is T *(*)(T *) for some T. Low-level |sk_*| functions will be -// passed a type-specific wrapper to call it correctly. -typedef void *(*OPENSSL_sk_copy_func)(void *ptr); +// its actual type is T *(*)(const T *) for some T. Low-level |sk_*| functions +// will be passed a type-specific wrapper to call it correctly. +typedef void *(*OPENSSL_sk_copy_func)(const void *ptr); // OPENSSL_sk_cmp_func is a comparison function that returns a value < 0, 0 or > // 0 if |*a| is less than, equal to or greater than |*b|, respectively. Note // the extra indirection - the function is given a pointer to a pointer to the // element. This differs from the usual qsort/bsearch comparison function. // -// Note its actual type is |int (*)(const T **a, const T **b)|. Low-level |sk_*| -// functions will be passed a type-specific wrapper to call it correctly. -// -// TODO(davidben): This type should be |const T *const *|. It is already fixed -// in OpenSSL 1.1.1, so hopefully we can fix this compatibly. -typedef int (*OPENSSL_sk_cmp_func)(const void **a, const void **b); +// Note its actual type is |int (*)(const T *const *a, const T *const *b)|. +// Low-level |sk_*| functions will be passed a type-specific wrapper to call it +// correctly. +typedef int (*OPENSSL_sk_cmp_func)(const void *const *a, const void *const *b); + +// OPENSSL_sk_delete_if_func is the generic version of +// |sk_SAMPLE_delete_if_func|. +typedef int (*OPENSSL_sk_delete_if_func)(void *obj, void *data); // The following function types call the above type-erased signatures with the // true types. typedef void (*OPENSSL_sk_call_free_func)(OPENSSL_sk_free_func, void *); -typedef void *(*OPENSSL_sk_call_copy_func)(OPENSSL_sk_copy_func, void *); +typedef void *(*OPENSSL_sk_call_copy_func)(OPENSSL_sk_copy_func, const void *); typedef int (*OPENSSL_sk_call_cmp_func)(OPENSSL_sk_cmp_func, const void *const *, const void *const *); +typedef int (*OPENSSL_sk_call_delete_if_func)(OPENSSL_sk_delete_if_func, void *, + void *); // stack_st contains an array of pointers. It is not designed to be used // directly, rather the wrapper macros should be used. @@ -300,6 +313,9 @@ OPENSSL_EXPORT void sk_pop_free_ex(_STACK *sk, OPENSSL_EXPORT size_t sk_insert(_STACK *sk, void *p, size_t where); OPENSSL_EXPORT void *sk_delete(_STACK *sk, size_t where); OPENSSL_EXPORT void *sk_delete_ptr(_STACK *sk, const void *p); +OPENSSL_EXPORT void sk_delete_if(_STACK *sk, + OPENSSL_sk_call_delete_if_func call_func, + OPENSSL_sk_delete_if_func func, void *data); OPENSSL_EXPORT int sk_find(const _STACK *sk, size_t *out_index, const void *p, OPENSSL_sk_call_cmp_func call_cmp_func); OPENSSL_EXPORT void *sk_shift(_STACK *sk); @@ -365,8 +381,10 @@ BSSL_NAMESPACE_END DECLARE_STACK_OF(name) \ \ typedef void (*sk_##name##_free_func)(ptrtype); \ - typedef ptrtype (*sk_##name##_copy_func)(ptrtype); \ - typedef int (*sk_##name##_cmp_func)(constptrtype *a, constptrtype *b); \ + typedef ptrtype (*sk_##name##_copy_func)(constptrtype); \ + typedef int (*sk_##name##_cmp_func)(constptrtype const *, \ + constptrtype const *); \ + typedef int (*sk_##name##_delete_if_func)(ptrtype, void *); \ \ OPENSSL_INLINE void sk_##name##_call_free_func( \ OPENSSL_sk_free_func free_func, void *ptr) { \ @@ -374,8 +392,8 @@ BSSL_NAMESPACE_END } \ \ OPENSSL_INLINE void *sk_##name##_call_copy_func( \ - OPENSSL_sk_copy_func copy_func, void *ptr) { \ - return (void *)((sk_##name##_copy_func)copy_func)((ptrtype)ptr); \ + OPENSSL_sk_copy_func copy_func, const void *ptr) { \ + return (void *)((sk_##name##_copy_func)copy_func)((constptrtype)ptr); \ } \ \ OPENSSL_INLINE int sk_##name##_call_cmp_func(OPENSSL_sk_cmp_func cmp_func, \ @@ -389,6 +407,11 @@ BSSL_NAMESPACE_END return ((sk_##name##_cmp_func)cmp_func)(&a_ptr, &b_ptr); \ } \ \ + OPENSSL_INLINE int sk_##name##_call_delete_if_func( \ + OPENSSL_sk_delete_if_func func, void *obj, void *data) { \ + return ((sk_##name##_delete_if_func)func)((ptrtype)obj, data); \ + } \ + \ OPENSSL_INLINE STACK_OF(name) *sk_##name##_new(sk_##name##_cmp_func comp) { \ return (STACK_OF(name) *)sk_new((OPENSSL_sk_cmp_func)comp); \ } \ @@ -440,6 +463,12 @@ BSSL_NAMESPACE_END return (ptrtype)sk_delete_ptr((_STACK *)sk, (const void *)p); \ } \ \ + OPENSSL_INLINE void sk_##name##_delete_if( \ + STACK_OF(name) *sk, sk_##name##_delete_if_func func, void *data) { \ + sk_delete_if((_STACK *)sk, sk_##name##_call_delete_if_func, \ + (OPENSSL_sk_delete_if_func)func, data); \ + } \ + \ OPENSSL_INLINE int sk_##name##_find(const STACK_OF(name) *sk, \ size_t *out_index, constptrtype p) { \ return sk_find((const _STACK *)sk, out_index, (const void *)p, \ diff --git a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_time.h b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_time.h new file mode 100644 index 00000000..4d273948 --- /dev/null +++ b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_time.h @@ -0,0 +1,41 @@ +/* Copyright (c) 2022, 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_TIME_H +#define OPENSSL_HEADER_TIME_H + +#include "CNIOBoringSSL_base.h" + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +// OPENSSL_posix_to_tm converts a int64_t POSIX time value in |time|, which must +// be in the range of year 0000 to 9999, to a broken out time value in |tm|. It +// returns one on success and zero on error. +OPENSSL_EXPORT int OPENSSL_posix_to_tm(int64_t time, struct tm *out_tm); + +// OPENSSL_tm_to_posix converts a time value between the years 0 and 9999 in +// |tm| to a POSIX time value in |out|. One is returned on success, zero is +// returned on failure. It is a failure if |tm| contains out of range values. +OPENSSL_EXPORT int OPENSSL_tm_to_posix(const struct tm *tm, int64_t *out); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_TIME_H diff --git a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_trust_token.h b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_trust_token.h index f9753db9..f342196f 100644 --- a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_trust_token.h +++ b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_trust_token.h @@ -48,6 +48,14 @@ OPENSSL_EXPORT const TRUST_TOKEN_METHOD *TRUST_TOKEN_experiment_v2_voprf(void); // PMBTokens and P-384 with up to 3 keys, without RR verification. OPENSSL_EXPORT const TRUST_TOKEN_METHOD *TRUST_TOKEN_experiment_v2_pmb(void); +// TRUST_TOKEN_pst_v1_voprf is an experimental Trust Tokens protocol +// using VOPRFs and P-384 with up to 6 keys, without RR verification. +OPENSSL_EXPORT const TRUST_TOKEN_METHOD *TRUST_TOKEN_pst_v1_voprf(void); + +// TRUST_TOKEN_pst_v1_pmb is an experimental Trust Tokens protocol using +// PMBTokens and P-384 with up to 3 keys, without RR verification. +OPENSSL_EXPORT const TRUST_TOKEN_METHOD *TRUST_TOKEN_pst_v1_pmb(void); + // trust_token_st represents a single-use token for the Trust Token protocol. // For the client, this is the token and its corresponding signature. For the // issuer, this is the token itself. @@ -143,6 +151,15 @@ OPENSSL_EXPORT int TRUST_TOKEN_CLIENT_begin_issuance(TRUST_TOKEN_CLIENT *ctx, size_t *out_len, size_t count); +// TRUST_TOKEN_CLIENT_begin_issuance_over_message produces a request for a trust +// token derived from |msg| and serializes the request into a newly-allocated +// buffer, setting |*out| to that buffer and |*out_len| to its length. The +// caller takes ownership of the buffer and must call |OPENSSL_free| when done. +// It returns one on success and zero on error. +OPENSSL_EXPORT int TRUST_TOKEN_CLIENT_begin_issuance_over_message( + TRUST_TOKEN_CLIENT *ctx, uint8_t **out, size_t *out_len, size_t count, + const uint8_t *msg, size_t msg_len); + // TRUST_TOKEN_CLIENT_finish_issuance consumes |response| from the issuer and // extracts the tokens, returning a list of tokens and the index of the key used // to sign the tokens in |*out_key_index|. The caller can use this to determine @@ -239,31 +256,32 @@ OPENSSL_EXPORT int TRUST_TOKEN_ISSUER_issue( uint32_t public_metadata, uint8_t private_metadata, size_t max_issuance); // TRUST_TOKEN_ISSUER_redeem ingests a |request| for token redemption and -// verifies the token. If the token is valid, a RR is produced with a lifetime -// of |lifetime| (in seconds), signing over the requested data from the request -// and the value of the token, storing the result into a newly-allocated buffer -// and setting |*out| to that buffer and |*out_len| to its length. The extracted +// verifies the token. The public metadata is stored in |*out_public|. The +// private metadata (if any) is stored in |*out_private|. The extracted // |TRUST_TOKEN| is stored into a newly-allocated buffer and stored in // |*out_token|. The extracted client data is stored into a newly-allocated -// buffer and stored in |*out_client_data|. In TrustTokenV1, the extracted -// redemption time is stored in |*out_redemption_time|. The caller takes -// ownership of each output buffer and must call |OPENSSL_free| when done. It -// returns one on success or zero on error. +// buffer and stored in |*out_client_data|. The caller takes ownership of each +// output buffer and must call |OPENSSL_free| when done. It returns one on +// success or zero on error. // // The caller must keep track of all values of |*out_token| seen globally before -// returning the SRR to the client. If the value has been reused, the caller -// must discard the SRR and report an error to the caller. Returning an SRR with -// replayed values allows an attacker to double-spend tokens. +// returning a response to the client. If the value has been reused, the caller +// must report an error to the client. Returning a response with replayed values +// allows an attacker to double-spend tokens. OPENSSL_EXPORT int TRUST_TOKEN_ISSUER_redeem( - const TRUST_TOKEN_ISSUER *ctx, uint8_t **out, size_t *out_len, + const TRUST_TOKEN_ISSUER *ctx, uint32_t *out_public, uint8_t *out_private, TRUST_TOKEN **out_token, uint8_t **out_client_data, - size_t *out_client_data_len, uint64_t *out_redemption_time, - const uint8_t *request, size_t request_len, uint64_t lifetime); + size_t *out_client_data_len, const uint8_t *request, size_t request_len); -// TRUST_TOKEN_ISSUER_redeem_raw ingests a |request| for token redemption and -// verifies the token. The public metadata is stored in |*out_public|. The -// private metadata (if any) is stored in |*out_private|. The extracted -// |TRUST_TOKEN| is stored into a newly-allocated buffer and stored in +// TRUST_TOKEN_ISSUER_redeem_raw is a legacy alias for +// |TRUST_TOKEN_ISSUER_redeem|. +#define TRUST_TOKEN_ISSUER_redeem_raw TRUST_TOKEN_ISSUER_redeem + +// TRUST_TOKEN_ISSUER_redeem_over_message ingests a |request| for token +// redemption and a message and verifies the token and that it is derived from +// the provided |msg|. The public metadata is stored in +// |*out_public|. The private metadata (if any) is stored in |*out_private|. The +// extracted |TRUST_TOKEN| is stored into a newly-allocated buffer and stored in // |*out_token|. The extracted client data is stored into a newly-allocated // buffer and stored in |*out_client_data|. The caller takes ownership of each // output buffer and must call |OPENSSL_free| when done. It returns one on @@ -273,10 +291,11 @@ OPENSSL_EXPORT int TRUST_TOKEN_ISSUER_redeem( // returning a response to the client. If the value has been reused, the caller // must report an error to the client. Returning a response with replayed values // allows an attacker to double-spend tokens. -OPENSSL_EXPORT int TRUST_TOKEN_ISSUER_redeem_raw( +OPENSSL_EXPORT int TRUST_TOKEN_ISSUER_redeem_over_message( const TRUST_TOKEN_ISSUER *ctx, uint32_t *out_public, uint8_t *out_private, TRUST_TOKEN **out_token, uint8_t **out_client_data, - size_t *out_client_data_len, const uint8_t *request, size_t request_len); + size_t *out_client_data_len, const uint8_t *request, size_t request_len, + const uint8_t *msg, size_t msg_len); // TRUST_TOKEN_decode_private_metadata decodes |encrypted_bit| using the // private metadata key specified by a |key| buffer of length |key_len| and the diff --git a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_x509.h b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_x509.h index 0ae629b0..8eec57a7 100644 --- a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_x509.h +++ b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_x509.h @@ -60,8 +60,8 @@ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. */ -#ifndef HEADER_X509_H -#define HEADER_X509_H +#ifndef OPENSSL_HEADER_X509_H +#define OPENSSL_HEADER_X509_H #include "CNIOBoringSSL_asn1.h" #include "CNIOBoringSSL_base.h" @@ -146,7 +146,7 @@ OPENSSL_EXPORT X509 *X509_dup(X509 *x509); OPENSSL_EXPORT void X509_free(X509 *x509); // d2i_X509 parses up to |len| bytes from |*inp| as a DER-encoded X.509 -// Certificate (RFC 5280), as described in |d2i_SAMPLE_with_reuse|. +// Certificate (RFC 5280), as described in |d2i_SAMPLE|. OPENSSL_EXPORT X509 *d2i_X509(X509 **out, const uint8_t **inp, long len); // X509_parse_from_buffer parses an X.509 structure from |buf| and returns a @@ -398,8 +398,7 @@ OPENSSL_EXPORT int i2d_X509_AUX(X509 *x509, unsigned char **outp); // d2i_X509_AUX parses up to |length| bytes from |*inp| as a DER-encoded X.509 // Certificate (RFC 5280), followed optionally by a separate, OpenSSL-specific -// structure with auxiliary properties. It behaves as described in -// |d2i_SAMPLE_with_reuse|. +// structure with auxiliary properties. It behaves as described in |d2i_SAMPLE|. // // Some auxiliary properties affect trust decisions, so this function should not // be used with untrusted input. @@ -414,13 +413,13 @@ OPENSSL_EXPORT X509 *d2i_X509_AUX(X509 **x509, const unsigned char **inp, // NULL, the alias is cleared instead. Aliases are not part of the certificate // itself and will not be serialized by |i2d_X509|. OPENSSL_EXPORT int X509_alias_set1(X509 *x509, const unsigned char *name, - int len); + ossl_ssize_t len); // X509_keyid_set1 sets |x509|'s key ID to |len| bytes from |id|. If |id| is // NULL, the key ID is cleared instead. Key IDs are not part of the certificate // itself and will not be serialized by |i2d_X509|. OPENSSL_EXPORT int X509_keyid_set1(X509 *x509, const unsigned char *id, - int len); + ossl_ssize_t len); // X509_alias_get0 looks up |x509|'s alias. If found, it sets |*out_len| to the // alias's length and returns a pointer to a buffer containing the contents. If @@ -485,7 +484,7 @@ OPENSSL_EXPORT X509_CRL *X509_CRL_dup(X509_CRL *crl); OPENSSL_EXPORT void X509_CRL_free(X509_CRL *crl); // d2i_X509_CRL parses up to |len| bytes from |*inp| as a DER-encoded X.509 -// CertificateList (RFC 5280), as described in |d2i_SAMPLE_with_reuse|. +// CertificateList (RFC 5280), as described in |d2i_SAMPLE|. OPENSSL_EXPORT X509_CRL *d2i_X509_CRL(X509_CRL **out, const uint8_t **inp, long len); @@ -699,7 +698,7 @@ OPENSSL_EXPORT X509_REQ *X509_REQ_dup(X509_REQ *req); OPENSSL_EXPORT void X509_REQ_free(X509_REQ *req); // d2i_X509_REQ parses up to |len| bytes from |*inp| as a DER-encoded -// CertificateRequest (RFC 2986), as described in |d2i_SAMPLE_with_reuse|. +// CertificateRequest (RFC 2986), as described in |d2i_SAMPLE|. OPENSSL_EXPORT X509_REQ *d2i_X509_REQ(X509_REQ **out, const uint8_t **inp, long len); @@ -850,7 +849,7 @@ OPENSSL_EXPORT X509_NAME *X509_NAME_new(void); OPENSSL_EXPORT void X509_NAME_free(X509_NAME *name); // d2i_X509_NAME parses up to |len| bytes from |*inp| as a DER-encoded X.509 -// Name (RFC 5280), as described in |d2i_SAMPLE_with_reuse|. +// Name (RFC 5280), as described in |d2i_SAMPLE|. OPENSSL_EXPORT X509_NAME *d2i_X509_NAME(X509_NAME **out, const uint8_t **inp, long len); @@ -938,7 +937,7 @@ OPENSSL_EXPORT int X509_NAME_add_entry(X509_NAME *name, // success or zero on error. The entry's attribute type is |obj|. The entry's // attribute value is determined by |type|, |bytes|, and |len|, as in // |X509_NAME_ENTRY_set_data|. The entry's position is determined by |loc| and -// |set| as in |X509_NAME_entry|. +// |set| as in |X509_NAME_add_entry|. OPENSSL_EXPORT int X509_NAME_add_entry_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, int type, const uint8_t *bytes, int len, @@ -970,7 +969,7 @@ OPENSSL_EXPORT X509_NAME_ENTRY *X509_NAME_ENTRY_new(void); OPENSSL_EXPORT void X509_NAME_ENTRY_free(X509_NAME_ENTRY *entry); // d2i_X509_NAME_ENTRY parses up to |len| bytes from |*inp| as a DER-encoded -// AttributeTypeAndValue (RFC 5280), as described in |d2i_SAMPLE_with_reuse|. +// AttributeTypeAndValue (RFC 5280), as described in |d2i_SAMPLE|. OPENSSL_EXPORT X509_NAME_ENTRY *d2i_X509_NAME_ENTRY(X509_NAME_ENTRY **out, const uint8_t **inp, long len); @@ -1073,15 +1072,14 @@ OPENSSL_EXPORT X509_EXTENSION *X509_EXTENSION_new(void); OPENSSL_EXPORT void X509_EXTENSION_free(X509_EXTENSION *ex); // d2i_X509_EXTENSION parses up to |len| bytes from |*inp| as a DER-encoded -// X.509 Extension (RFC 5280), as described in |d2i_SAMPLE_with_reuse|. +// X.509 Extension (RFC 5280), as described in |d2i_SAMPLE|. OPENSSL_EXPORT X509_EXTENSION *d2i_X509_EXTENSION(X509_EXTENSION **out, const uint8_t **inp, long len); -// i2d_X509_EXTENSION marshals |alg| as a DER-encoded X.509 Extension (RFC +// i2d_X509_EXTENSION marshals |ex| as a DER-encoded X.509 Extension (RFC // 5280), as described in |i2d_SAMPLE|. -OPENSSL_EXPORT int i2d_X509_EXTENSION(const X509_EXTENSION *alg, - uint8_t **outp); +OPENSSL_EXPORT int i2d_X509_EXTENSION(const X509_EXTENSION *ex, uint8_t **outp); // X509_EXTENSION_dup returns a newly-allocated copy of |ex|, or NULL on error. // This function works by serializing the structure, so if |ex| is incomplete, @@ -1149,7 +1147,7 @@ typedef STACK_OF(X509_EXTENSION) X509_EXTENSIONS; DECLARE_ASN1_ITEM(X509_EXTENSIONS) // d2i_X509_EXTENSIONS parses up to |len| bytes from |*inp| as a DER-encoded -// SEQUENCE OF Extension (RFC 5280), as described in |d2i_SAMPLE_with_reuse|. +// SEQUENCE OF Extension (RFC 5280), as described in |d2i_SAMPLE|. OPENSSL_EXPORT X509_EXTENSIONS *d2i_X509_EXTENSIONS(X509_EXTENSIONS **out, const uint8_t **inp, long len); @@ -1235,7 +1233,7 @@ OPENSSL_EXPORT X509_ALGOR *X509_ALGOR_dup(const X509_ALGOR *alg); OPENSSL_EXPORT void X509_ALGOR_free(X509_ALGOR *alg); // d2i_X509_ALGOR parses up to |len| bytes from |*inp| as a DER-encoded -// AlgorithmIdentifier, as described in |d2i_SAMPLE_with_reuse|. +// AlgorithmIdentifier, as described in |d2i_SAMPLE|. OPENSSL_EXPORT X509_ALGOR *d2i_X509_ALGOR(X509_ALGOR **out, const uint8_t **inp, long len); @@ -1794,7 +1792,7 @@ OPENSSL_EXPORT int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *spki, EVP_PKEY *pkey); // If |len| is 0 or negative, the length is calculated with |strlen| and |str| // must be a NUL-terminated C string. OPENSSL_EXPORT NETSCAPE_SPKI *NETSCAPE_SPKI_b64_decode(const char *str, - int len); + ossl_ssize_t len); // NETSCAPE_SPKI_b64_encode encodes |spki| as a base64-encoded Netscape signed // public key and challenge (SPKAC) structure. It returns a newly-allocated @@ -1838,6 +1836,14 @@ OPENSSL_EXPORT X509_REVOKED *X509_REVOKED_dup(const X509_REVOKED *rev); // error, not equality. OPENSSL_EXPORT int X509_cmp_time(const ASN1_TIME *s, time_t *t); +// X509_cmp_time_posix compares |s| against |t|. On success, it returns a +// negative number if |s| <= |t| and a positive number if |s| > |t|. On error, +// it returns zero. +// +// WARNING: Unlike most comparison functions, this function returns zero on +// error, not equality. +OPENSSL_EXPORT int X509_cmp_time_posix(const ASN1_TIME *s, int64_t t); + // X509_cmp_current_time behaves like |X509_cmp_time| but compares |s| against // the current time. OPENSSL_EXPORT int X509_cmp_current_time(const ASN1_TIME *s); @@ -2557,9 +2563,9 @@ OPENSSL_EXPORT void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth); #define X509_V_FLAG_IGNORE_CRITICAL 0x10 // Does nothing as its functionality has been enabled by default. #define X509_V_FLAG_X509_STRICT 0x00 -// Enable proxy certificate validation +// This flag does nothing as proxy certificate support has been removed. #define X509_V_FLAG_ALLOW_PROXY_CERTS 0x40 -// Enable policy checking +// Does nothing as its functionality has been enabled by default. #define X509_V_FLAG_POLICY_CHECK 0x80 // Policy variable require-explicit-policy #define X509_V_FLAG_EXPLICIT_POLICY 0x100 @@ -2596,11 +2602,6 @@ OPENSSL_EXPORT void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth); #define X509_VP_FLAG_LOCKED 0x8 #define X509_VP_FLAG_ONCE 0x10 -// Internal use: mask of policy related options -#define X509_V_FLAG_POLICY_MASK \ - (X509_V_FLAG_POLICY_CHECK | X509_V_FLAG_EXPLICIT_POLICY | \ - X509_V_FLAG_INHIBIT_ANY | X509_V_FLAG_INHIBIT_MAP) - OPENSSL_EXPORT int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type, X509_NAME *name); OPENSSL_EXPORT X509_OBJECT *X509_OBJECT_retrieve_by_subject( @@ -2771,6 +2772,9 @@ OPENSSL_EXPORT void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags); OPENSSL_EXPORT void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, time_t t); +OPENSSL_EXPORT void X509_STORE_CTX_set_time_posix(X509_STORE_CTX *ctx, + unsigned long flags, + int64_t t); OPENSSL_EXPORT void X509_STORE_CTX_set_verify_cb( X509_STORE_CTX *ctx, int (*verify_cb)(int, X509_STORE_CTX *)); @@ -2805,10 +2809,12 @@ OPENSSL_EXPORT void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth); OPENSSL_EXPORT void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t); +OPENSSL_EXPORT void X509_VERIFY_PARAM_set_time_posix(X509_VERIFY_PARAM *param, + int64_t t); OPENSSL_EXPORT int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, ASN1_OBJECT *policy); OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_policies( - X509_VERIFY_PARAM *param, STACK_OF(ASN1_OBJECT) *policies); + X509_VERIFY_PARAM *param, const STACK_OF(ASN1_OBJECT) *policies); OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param, const char *name, @@ -2832,12 +2838,8 @@ OPENSSL_EXPORT int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param); OPENSSL_EXPORT const char *X509_VERIFY_PARAM_get0_name( const X509_VERIFY_PARAM *param); -OPENSSL_EXPORT int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param); -OPENSSL_EXPORT int X509_VERIFY_PARAM_get_count(void); -OPENSSL_EXPORT const X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id); OPENSSL_EXPORT const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup( const char *name); -OPENSSL_EXPORT void X509_VERIFY_PARAM_table_cleanup(void); #if defined(__cplusplus) @@ -2921,5 +2923,6 @@ BSSL_NAMESPACE_END #define X509_R_NO_CERTIFICATE_FOUND 141 #define X509_R_NO_CERTIFICATE_OR_CRL_FOUND 142 #define X509_R_NO_CRL_FOUND 143 +#define X509_R_INVALID_POLICY_EXTENSION 144 -#endif +#endif // OPENSSL_HEADER_X509_H diff --git a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_x509v3.h b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_x509v3.h index 7a6c6f14..796af445 100644 --- a/Sources/CNIOBoringSSL/include/CNIOBoringSSL_x509v3.h +++ b/Sources/CNIOBoringSSL/include/CNIOBoringSSL_x509v3.h @@ -52,8 +52,8 @@ * (eay@cryptsoft.com). This product includes software written by Tim * Hudson (tjh@cryptsoft.com). */ -#ifndef HEADER_X509V3_H -#define HEADER_X509V3_H +#ifndef OPENSSL_HEADER_X509V3_H +#define OPENSSL_HEADER_X509V3_H #include "CNIOBoringSSL_bio.h" #include "CNIOBoringSSL_conf.h" @@ -89,14 +89,15 @@ typedef STACK_OF(CONF_VALUE) *(*X509V3_EXT_I2V)(const X509V3_EXT_METHOD *method, void *ext, STACK_OF(CONF_VALUE) *extlist); typedef void *(*X509V3_EXT_V2I)(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values); + const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *values); typedef char *(*X509V3_EXT_I2S)(const X509V3_EXT_METHOD *method, void *ext); typedef void *(*X509V3_EXT_S2I)(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, const char *str); + const X509V3_CTX *ctx, const char *str); typedef int (*X509V3_EXT_I2R)(const X509V3_EXT_METHOD *method, void *ext, BIO *out, int indent); typedef void *(*X509V3_EXT_R2I)(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, const char *str); + const X509V3_CTX *ctx, const char *str); // V3 extension structure @@ -126,26 +127,6 @@ struct v3_ext_method { void *usr_data; // Any extension specific data }; -typedef struct X509V3_CONF_METHOD_st { - char *(*get_string)(void *db, const char *section, const char *value); - STACK_OF(CONF_VALUE) *(*get_section)(void *db, const char *section); - void (*free_string)(void *db, char *string); - void (*free_section)(void *db, STACK_OF(CONF_VALUE) *section); -} X509V3_CONF_METHOD; - -// Context specific info -struct v3_ext_ctx { -#define CTX_TEST 0x1 - int flags; - X509 *issuer_cert; - X509 *subject_cert; - X509_REQ *subject_req; - X509_CRL *crl; - const X509V3_CONF_METHOD *db_meth; - void *db; - // Maybe more here -}; - DEFINE_STACK_OF(X509V3_EXT_METHOD) // ext_flags values @@ -186,7 +167,7 @@ typedef struct GENERAL_NAME_st { OTHERNAME *otherName; // otherName ASN1_IA5STRING *rfc822Name; ASN1_IA5STRING *dNSName; - ASN1_TYPE *x400Address; + ASN1_STRING *x400Address; X509_NAME *directoryName; EDIPARTYNAME *ediPartyName; ASN1_IA5STRING *uniformResourceIdentifier; @@ -198,7 +179,6 @@ typedef struct GENERAL_NAME_st { X509_NAME *dirn; // dirn ASN1_IA5STRING *ia5; // rfc822Name, dNSName, uniformResourceIdentifier ASN1_OBJECT *rid; // registeredID - ASN1_TYPE *other; // x400Address } d; } GENERAL_NAME; @@ -317,20 +297,6 @@ typedef struct POLICY_CONSTRAINTS_st { ASN1_INTEGER *inhibitPolicyMapping; } POLICY_CONSTRAINTS; -// Proxy certificate structures, see RFC 3820 -typedef struct PROXY_POLICY_st { - ASN1_OBJECT *policyLanguage; - ASN1_OCTET_STRING *policy; -} PROXY_POLICY; - -typedef struct PROXY_CERT_INFO_EXTENSION_st { - ASN1_INTEGER *pcPathLengthConstraint; - PROXY_POLICY *proxyPolicy; -} PROXY_CERT_INFO_EXTENSION; - -DECLARE_ASN1_FUNCTIONS_const(PROXY_POLICY) -DECLARE_ASN1_FUNCTIONS_const(PROXY_CERT_INFO_EXTENSION) - struct ISSUING_DIST_POINT_st { DIST_POINT_NAME *distpoint; int onlyuser; @@ -356,13 +322,6 @@ struct ISSUING_DIST_POINT_st { // onlysomereasons present #define IDP_REASONS 0x40 -#define X509V3_conf_err(val) \ - ERR_add_error_data(6, "section:", (val)->section, ",name:", (val)->name, \ - ",value:", (val)->value); - -#define X509V3_set_ctx_test(ctx) \ - X509V3_set_ctx(ctx, NULL, NULL, NULL, NULL, CTX_TEST) -#define X509V3_set_ctx_nodb(ctx) (ctx)->db = NULL; // X509_PURPOSE stuff @@ -379,9 +338,7 @@ struct ISSUING_DIST_POINT_st { #define EXFLAG_INVALID 0x80 #define EXFLAG_SET 0x100 #define EXFLAG_CRITICAL 0x200 -#define EXFLAG_PROXY 0x400 -#define EXFLAG_INVALID_POLICY 0x800 #define EXFLAG_FRESHEST 0x1000 // Self signed #define EXFLAG_SS 0x2000 @@ -454,12 +411,6 @@ DECLARE_ASN1_FUNCTIONS(AUTHORITY_KEYID) DECLARE_ASN1_FUNCTIONS(GENERAL_NAME) OPENSSL_EXPORT GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a); -// GENERAL_NAME_cmp returns zero if |a| and |b| are equal and a non-zero -// value otherwise. Note this function does not provide a comparison suitable -// for sorting. -OPENSSL_EXPORT int GENERAL_NAME_cmp(const GENERAL_NAME *a, - const GENERAL_NAME *b); - // i2v_GENERAL_NAME serializes |gen| as a |CONF_VALUE|. If |ret| is non-NULL, it // appends the value to |ret| and returns |ret| on success or NULL on error. If // it returns NULL, the caller is still responsible for freeing |ret|. If |ret| @@ -470,9 +421,15 @@ OPENSSL_EXPORT int GENERAL_NAME_cmp(const GENERAL_NAME *a, // human-readable print functions. If extracting a SAN list from a certificate, // look at |gen| directly. OPENSSL_EXPORT STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME( - const X509V3_EXT_METHOD *method, GENERAL_NAME *gen, + const X509V3_EXT_METHOD *method, const GENERAL_NAME *gen, STACK_OF(CONF_VALUE) *ret); -OPENSSL_EXPORT int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen); + +// GENERAL_NAME_print prints a human-readable representation of |gen| to |out|. +// It returns one on success and zero on error. +// +// TODO(davidben): Actually, it just returns one and doesn't check for I/O or +// allocation errors. But it should return zero on error. +OPENSSL_EXPORT int GENERAL_NAME_print(BIO *out, const GENERAL_NAME *gen); // TODO(https://crbug.com/boringssl/407): This is not const because it contains // an |X509_NAME|. @@ -488,15 +445,14 @@ DECLARE_ASN1_FUNCTIONS(GENERAL_NAMES) // human-readable print functions. If extracting a SAN list from a certificate, // look at |gen| directly. OPENSSL_EXPORT STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES( - const X509V3_EXT_METHOD *method, GENERAL_NAMES *gen, + const X509V3_EXT_METHOD *method, const GENERAL_NAMES *gen, STACK_OF(CONF_VALUE) *extlist); -OPENSSL_EXPORT GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval); +OPENSSL_EXPORT GENERAL_NAMES *v2i_GENERAL_NAMES( + const X509V3_EXT_METHOD *method, const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *nval); DECLARE_ASN1_FUNCTIONS_const(OTHERNAME) DECLARE_ASN1_FUNCTIONS_const(EDIPARTYNAME) -OPENSSL_EXPORT int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b); OPENSSL_EXPORT void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value); OPENSSL_EXPORT void *GENERAL_NAME_get0_value(const GENERAL_NAME *a, int *ptype); @@ -507,10 +463,14 @@ OPENSSL_EXPORT int GENERAL_NAME_get0_otherName(const GENERAL_NAME *gen, ASN1_OBJECT **poid, ASN1_TYPE **pvalue); +// i2s_ASN1_OCTET_STRING returns a human-readable representation of |oct| as a +// newly-allocated, NUL-terminated string, or NULL on error. |method| is +// ignored. The caller must release the result with |OPENSSL_free| when done. OPENSSL_EXPORT char *i2s_ASN1_OCTET_STRING(const X509V3_EXT_METHOD *method, - const ASN1_OCTET_STRING *ia5); + const ASN1_OCTET_STRING *oct); + OPENSSL_EXPORT ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING( - const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, const char *str); + const X509V3_EXT_METHOD *method, const X509V3_CTX *ctx, const char *str); DECLARE_ASN1_FUNCTIONS_const(EXTENDED_KEY_USAGE) OPENSSL_EXPORT int i2a_ACCESS_DESCRIPTION(BIO *bp, const ACCESS_DESCRIPTION *a); @@ -561,85 +521,141 @@ DECLARE_ASN1_ITEM(POLICY_CONSTRAINTS) OPENSSL_EXPORT GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, int gen_type, + const X509V3_CTX *ctx, int gen_type, const char *value, int is_nc); OPENSSL_EXPORT GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, CONF_VALUE *cnf); + const X509V3_CTX *ctx, + const CONF_VALUE *cnf); OPENSSL_EXPORT GENERAL_NAME *v2i_GENERAL_NAME_ex( - GENERAL_NAME *out, const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, - CONF_VALUE *cnf, int is_nc); + GENERAL_NAME *out, const X509V3_EXT_METHOD *method, const X509V3_CTX *ctx, + const CONF_VALUE *cnf, int is_nc); OPENSSL_EXPORT void X509V3_conf_free(CONF_VALUE *val); -// X509V3_EXT_conf_nid contains the only exposed instance of an LHASH in our -// public headers. The |conf| pointer must be NULL but cryptography.io wraps -// this function so we cannot, yet, replace the type with a dummy struct. -OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, - X509V3_CTX *ctx, int ext_nid, - const char *value); -OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, - int ext_nid, - const char *value); -OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, +// Deprecated config-based extension creation. +// +// The following functions allow specifying X.509 extensions using OpenSSL's +// config file syntax, from the OpenSSL command-line tool. They are retained, +// for now, for compatibility with legacy software but may be removed in the +// future. Construct the extensions using the typed C APIs instead. +// +// Callers should especially avoid these functions if passing in non-constant +// values. They use ad-hoc, string-based formats which are prone to injection +// vulnerabilities. For a CA, this means using them risks misissuance. +// +// These functions are not safe to use with untrusted inputs. The string formats +// may implicitly reference context information and, in OpenSSL (though not +// BoringSSL), one even allows reading arbitrary files. They additionally see +// much less testing and review than most of the library and may have bugs +// including memory leaks or crashes. + +// v3_ext_ctx, aka |X509V3_CTX|, contains additional context information for +// constructing extensions. Some string formats reference additional values in +// these objects. It must be initialized with |X509V3_set_ctx| or +// |X509V3_set_ctx_test| before use. +struct v3_ext_ctx { + int flags; + const X509 *issuer_cert; + const X509 *subject_cert; + const X509_REQ *subject_req; + const X509_CRL *crl; + const CONF *db; +}; + +#define X509V3_CTX_TEST 0x1 + +// X509V3_set_ctx initializes |ctx| with the specified objects. Some string +// formats will reference fields in these objects. Each object may be NULL to +// omit it, in which case those formats cannot be used. |flags| should be zero, +// unless called via |X509V3_set_ctx_test|. +// +// |issuer|, |subject|, |req|, and |crl|, if non-NULL, must outlive |ctx|. +OPENSSL_EXPORT void X509V3_set_ctx(X509V3_CTX *ctx, const X509 *issuer, + const X509 *subject, const X509_REQ *req, + const X509_CRL *crl, int flags); + +// X509V3_set_ctx_test calls |X509V3_set_ctx| without any reference objects and +// mocks out some features that use them. The resulting extensions may be +// incomplete and should be discarded. This can be used to partially validate +// syntax. +// +// TODO(davidben): Can we remove this? +#define X509V3_set_ctx_test(ctx) \ + X509V3_set_ctx(ctx, NULL, NULL, NULL, NULL, X509V3_CTX_TEST) + +// X509V3_set_nconf sets |ctx| to use |conf| as the config database. |ctx| must +// have previously been initialized by |X509V3_set_ctx| or +// |X509V3_set_ctx_test|. Some string formats will reference sections in |conf|. +// |conf| may be NULL, in which case these formats cannot be used. If non-NULL, +// |conf| must outlive |ctx|. +OPENSSL_EXPORT void X509V3_set_nconf(X509V3_CTX *ctx, const CONF *conf); + +// X509V3_set_ctx_nodb calls |X509V3_set_nconf| with no config database. +#define X509V3_set_ctx_nodb(ctx) X509V3_set_nconf(ctx, NULL) + +// X509V3_EXT_nconf constructs an extension of type specified by |name|, and +// value specified by |value|. It returns a newly-allocated |X509_EXTENSION| +// object on success, or NULL on error. |conf| and |ctx| specify additional +// information referenced by some formats. Either |conf| or |ctx| may be NULL, +// in which case features which use it will be disabled. +// +// If non-NULL, |ctx| must be initialized with |X509V3_set_ctx| or +// |X509V3_set_ctx_test|. +// +// Both |conf| and |ctx| provide a |CONF| object. When |ctx| is non-NULL, most +// features use the |ctx| copy, configured with |X509V3_set_ctx|, but some use +// |conf|. Callers should ensure the two match to avoid surprisingly behavior. +OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_nconf(const CONF *conf, + const X509V3_CTX *ctx, const char *name, const char *value); -OPENSSL_EXPORT int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, + +// X509V3_EXT_nconf_nid behaves like |X509V3_EXT_nconf|, except the extension +// type is specified as a NID. +OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_nconf_nid(const CONF *conf, + const X509V3_CTX *ctx, + int ext_nid, + const char *value); + +// X509V3_EXT_conf_nid calls |X509V3_EXT_nconf_nid|. |conf| must be NULL. +// +// TODO(davidben): This is the only exposed instance of an LHASH in our public +// headers. cryptography.io wraps this function so we cannot, yet, replace the +// type with a dummy struct. +OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, + const X509V3_CTX *ctx, + int ext_nid, + const char *value); + +// X509V3_EXT_add_nconf_sk looks up the section named |section| in |conf|. For +// each |CONF_VALUE| in the section, it constructs an extension as in +// |X509V3_EXT_nconf|, taking |name| and |value| from the |CONF_VALUE|. Each new +// extension is appended to |*sk|. If |*sk| is non-NULL, and at least one +// extension is added, it sets |*sk| to a newly-allocated +// |STACK_OF(X509_EXTENSION)|. It returns one on success and zero on error. +OPENSSL_EXPORT int X509V3_EXT_add_nconf_sk(const CONF *conf, + const X509V3_CTX *ctx, const char *section, STACK_OF(X509_EXTENSION) **sk); -OPENSSL_EXPORT int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, + +// X509V3_EXT_add_nconf adds extensions to |cert| as in +// |X509V3_EXT_add_nconf_sk|. It returns one on success and zero on error. +OPENSSL_EXPORT int X509V3_EXT_add_nconf(const CONF *conf, const X509V3_CTX *ctx, const char *section, X509 *cert); -OPENSSL_EXPORT int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, + +// X509V3_EXT_REQ_add_nconf adds extensions to |req| as in +// |X509V3_EXT_add_nconf_sk|. It returns one on success and zero on error. +OPENSSL_EXPORT int X509V3_EXT_REQ_add_nconf(const CONF *conf, + const X509V3_CTX *ctx, const char *section, X509_REQ *req); -OPENSSL_EXPORT int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, + +// X509V3_EXT_CRL_add_nconf adds extensions to |crl| as in +// |X509V3_EXT_add_nconf_sk|. It returns one on success and zero on error. +OPENSSL_EXPORT int X509V3_EXT_CRL_add_nconf(const CONF *conf, + const X509V3_CTX *ctx, const char *section, X509_CRL *crl); -OPENSSL_EXPORT int X509V3_add_value_bool_nf(const char *name, int asn1_bool, - STACK_OF(CONF_VALUE) **extlist); -OPENSSL_EXPORT int X509V3_get_value_bool(const CONF_VALUE *value, - int *asn1_bool); -OPENSSL_EXPORT int X509V3_get_value_int(const CONF_VALUE *value, - ASN1_INTEGER **aint); -OPENSSL_EXPORT void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf); - -OPENSSL_EXPORT char *X509V3_get_string(X509V3_CTX *ctx, const char *name, - const char *section); -OPENSSL_EXPORT STACK_OF(CONF_VALUE) *X509V3_get_section(X509V3_CTX *ctx, - const char *section); -OPENSSL_EXPORT void X509V3_string_free(X509V3_CTX *ctx, char *str); -OPENSSL_EXPORT void X509V3_section_free(X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *section); -OPENSSL_EXPORT void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subject, - X509_REQ *req, X509_CRL *crl, int flags); - -// X509V3_add_value appends a |CONF_VALUE| containing |name| and |value| to -// |*extlist|. It returns one on success and zero on error. If |*extlist| is -// NULL, it sets |*extlist| to a newly-allocated |STACK_OF(CONF_VALUE)| -// containing the result. Either |name| or |value| may be NULL to omit the -// field. -// -// On failure, if |*extlist| was NULL, |*extlist| will remain NULL when the -// function returns. -OPENSSL_EXPORT int X509V3_add_value(const char *name, const char *value, - STACK_OF(CONF_VALUE) **extlist); - -// X509V3_add_value_uchar behaves like |X509V3_add_value| but takes an -// |unsigned char| pointer. -OPENSSL_EXPORT int X509V3_add_value_uchar(const char *name, - const unsigned char *value, - STACK_OF(CONF_VALUE) **extlist); - -// X509V3_add_value_bool behaves like |X509V3_add_value| but stores the value -// "TRUE" if |asn1_bool| is non-zero and "FALSE" otherwise. -OPENSSL_EXPORT int X509V3_add_value_bool(const char *name, int asn1_bool, - STACK_OF(CONF_VALUE) **extlist); - -// X509V3_add_value_bool behaves like |X509V3_add_value| but stores a string -// representation of |aint|. Note this string representation may be decimal or -// hexadecimal, depending on the size of |aint|. -OPENSSL_EXPORT int X509V3_add_value_int(const char *name, - const ASN1_INTEGER *aint, - STACK_OF(CONF_VALUE) **extlist); OPENSSL_EXPORT char *i2s_ASN1_INTEGER(const X509V3_EXT_METHOD *meth, const ASN1_INTEGER *aint); @@ -656,7 +672,6 @@ OPENSSL_EXPORT const X509V3_EXT_METHOD *X509V3_EXT_get( const X509_EXTENSION *ext); OPENSSL_EXPORT const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid); OPENSSL_EXPORT int X509V3_add_standard_extensions(void); -OPENSSL_EXPORT STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line); // X509V3_EXT_d2i decodes |ext| and returns a pointer to a newly-allocated // structure, with type dependent on the type of the extension. It returns NULL @@ -903,9 +918,6 @@ OPENSSL_EXPORT int X509_check_ip_asc(X509 *x, const char *ipasc, OPENSSL_EXPORT ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc); OPENSSL_EXPORT ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc); -OPENSSL_EXPORT int X509V3_NAME_from_section(X509_NAME *nm, - STACK_OF(CONF_VALUE) *dn_sk, - unsigned long chtype); // BEGIN ERROR CODES // The following lines are auto generated by the script mkerr.pl. Any changes @@ -1002,4 +1014,4 @@ BSSL_NAMESPACE_END #define X509V3_R_INVALID_VALUE 163 #define X509V3_R_TRAILING_DATA_IN_EXTENSION 164 -#endif +#endif // OPENSSL_HEADER_X509V3_H diff --git a/Sources/CNIOBoringSSL/include/boringssl_prefix_symbols_nasm.inc b/Sources/CNIOBoringSSL/include/boringssl_prefix_symbols_nasm.inc index 66ea9016..c403513b 100644 --- a/Sources/CNIOBoringSSL/include/boringssl_prefix_symbols_nasm.inc +++ b/Sources/CNIOBoringSSL/include/boringssl_prefix_symbols_nasm.inc @@ -100,7 +100,6 @@ %xdefine _ASN1_PRINTABLE_free _ %+ BORINGSSL_PREFIX %+ _ASN1_PRINTABLE_free %xdefine _ASN1_PRINTABLE_it _ %+ BORINGSSL_PREFIX %+ _ASN1_PRINTABLE_it %xdefine _ASN1_PRINTABLE_new _ %+ BORINGSSL_PREFIX %+ _ASN1_PRINTABLE_new -%xdefine _ASN1_PRINTABLE_type _ %+ BORINGSSL_PREFIX %+ _ASN1_PRINTABLE_type %xdefine _ASN1_SEQUENCE_ANY_it _ %+ BORINGSSL_PREFIX %+ _ASN1_SEQUENCE_ANY_it %xdefine _ASN1_SEQUENCE_it _ %+ BORINGSSL_PREFIX %+ _ASN1_SEQUENCE_it %xdefine _ASN1_SET_ANY_it _ %+ BORINGSSL_PREFIX %+ _ASN1_SET_ANY_it @@ -138,6 +137,7 @@ %xdefine _ASN1_TIME_new _ %+ BORINGSSL_PREFIX %+ _ASN1_TIME_new %xdefine _ASN1_TIME_print _ %+ BORINGSSL_PREFIX %+ _ASN1_TIME_print %xdefine _ASN1_TIME_set _ %+ BORINGSSL_PREFIX %+ _ASN1_TIME_set +%xdefine _ASN1_TIME_set_posix _ %+ BORINGSSL_PREFIX %+ _ASN1_TIME_set_posix %xdefine _ASN1_TIME_set_string _ %+ BORINGSSL_PREFIX %+ _ASN1_TIME_set_string %xdefine _ASN1_TIME_to_generalizedtime _ %+ BORINGSSL_PREFIX %+ _ASN1_TIME_to_generalizedtime %xdefine _ASN1_TIME_to_posix _ %+ BORINGSSL_PREFIX %+ _ASN1_TIME_to_posix @@ -450,6 +450,9 @@ %xdefine _BN_usub _ %+ BORINGSSL_PREFIX %+ _BN_usub %xdefine _BN_value_one _ %+ BORINGSSL_PREFIX %+ _BN_value_one %xdefine _BN_zero _ %+ BORINGSSL_PREFIX %+ _BN_zero +%xdefine _BORINGSSL_keccak _ %+ BORINGSSL_PREFIX %+ _BORINGSSL_keccak +%xdefine _BORINGSSL_keccak_init _ %+ BORINGSSL_PREFIX %+ _BORINGSSL_keccak_init +%xdefine _BORINGSSL_keccak_squeeze _ %+ BORINGSSL_PREFIX %+ _BORINGSSL_keccak_squeeze %xdefine _BORINGSSL_self_test _ %+ BORINGSSL_PREFIX %+ _BORINGSSL_self_test %xdefine _BUF_MEM_append _ %+ BORINGSSL_PREFIX %+ _BUF_MEM_append %xdefine _BUF_MEM_free _ %+ BORINGSSL_PREFIX %+ _BUF_MEM_free @@ -527,6 +530,7 @@ %xdefine _CBS_get_u32 _ %+ BORINGSSL_PREFIX %+ _CBS_get_u32 %xdefine _CBS_get_u32le _ %+ BORINGSSL_PREFIX %+ _CBS_get_u32le %xdefine _CBS_get_u64 _ %+ BORINGSSL_PREFIX %+ _CBS_get_u64 +%xdefine _CBS_get_u64_decimal _ %+ BORINGSSL_PREFIX %+ _CBS_get_u64_decimal %xdefine _CBS_get_u64le _ %+ BORINGSSL_PREFIX %+ _CBS_get_u64le %xdefine _CBS_get_u8 _ %+ BORINGSSL_PREFIX %+ _CBS_get_u8 %xdefine _CBS_get_u8_length_prefixed _ %+ BORINGSSL_PREFIX %+ _CBS_get_u8_length_prefixed @@ -535,6 +539,7 @@ %xdefine _CBS_is_unsigned_asn1_integer _ %+ BORINGSSL_PREFIX %+ _CBS_is_unsigned_asn1_integer %xdefine _CBS_is_valid_asn1_bitstring _ %+ BORINGSSL_PREFIX %+ _CBS_is_valid_asn1_bitstring %xdefine _CBS_is_valid_asn1_integer _ %+ BORINGSSL_PREFIX %+ _CBS_is_valid_asn1_integer +%xdefine _CBS_is_valid_asn1_oid _ %+ BORINGSSL_PREFIX %+ _CBS_is_valid_asn1_oid %xdefine _CBS_len _ %+ BORINGSSL_PREFIX %+ _CBS_len %xdefine _CBS_mem_equal _ %+ BORINGSSL_PREFIX %+ _CBS_mem_equal %xdefine _CBS_parse_generalized_time _ %+ BORINGSSL_PREFIX %+ _CBS_parse_generalized_time @@ -597,7 +602,7 @@ %xdefine _CRYPTO_cleanup_all_ex_data _ %+ BORINGSSL_PREFIX %+ _CRYPTO_cleanup_all_ex_data %xdefine _CRYPTO_ctr128_encrypt _ %+ BORINGSSL_PREFIX %+ _CRYPTO_ctr128_encrypt %xdefine _CRYPTO_ctr128_encrypt_ctr32 _ %+ BORINGSSL_PREFIX %+ _CRYPTO_ctr128_encrypt_ctr32 -%xdefine _CRYPTO_fork_detect_ignore_madv_wipeonfork_for_testing _ %+ BORINGSSL_PREFIX %+ _CRYPTO_fork_detect_ignore_madv_wipeonfork_for_testing +%xdefine _CRYPTO_fork_detect_force_madv_wipeonfork_for_testing _ %+ BORINGSSL_PREFIX %+ _CRYPTO_fork_detect_force_madv_wipeonfork_for_testing %xdefine _CRYPTO_free _ %+ BORINGSSL_PREFIX %+ _CRYPTO_free %xdefine _CRYPTO_free_ex_data _ %+ BORINGSSL_PREFIX %+ _CRYPTO_free_ex_data %xdefine _CRYPTO_gcm128_aad _ %+ BORINGSSL_PREFIX %+ _CRYPTO_gcm128_aad @@ -830,9 +835,13 @@ %xdefine _EC_KEY_new _ %+ BORINGSSL_PREFIX %+ _EC_KEY_new %xdefine _EC_KEY_new_by_curve_name _ %+ BORINGSSL_PREFIX %+ _EC_KEY_new_by_curve_name %xdefine _EC_KEY_new_method _ %+ BORINGSSL_PREFIX %+ _EC_KEY_new_method +%xdefine _EC_KEY_oct2key _ %+ BORINGSSL_PREFIX %+ _EC_KEY_oct2key +%xdefine _EC_KEY_oct2priv _ %+ BORINGSSL_PREFIX %+ _EC_KEY_oct2priv %xdefine _EC_KEY_parse_curve_name _ %+ BORINGSSL_PREFIX %+ _EC_KEY_parse_curve_name %xdefine _EC_KEY_parse_parameters _ %+ BORINGSSL_PREFIX %+ _EC_KEY_parse_parameters %xdefine _EC_KEY_parse_private_key _ %+ BORINGSSL_PREFIX %+ _EC_KEY_parse_private_key +%xdefine _EC_KEY_priv2buf _ %+ BORINGSSL_PREFIX %+ _EC_KEY_priv2buf +%xdefine _EC_KEY_priv2oct _ %+ BORINGSSL_PREFIX %+ _EC_KEY_priv2oct %xdefine _EC_KEY_set_asn1_flag _ %+ BORINGSSL_PREFIX %+ _EC_KEY_set_asn1_flag %xdefine _EC_KEY_set_conv_form _ %+ BORINGSSL_PREFIX %+ _EC_KEY_set_conv_form %xdefine _EC_KEY_set_enc_flags _ %+ BORINGSSL_PREFIX %+ _EC_KEY_set_enc_flags @@ -858,6 +867,7 @@ %xdefine _EC_POINT_mul _ %+ BORINGSSL_PREFIX %+ _EC_POINT_mul %xdefine _EC_POINT_new _ %+ BORINGSSL_PREFIX %+ _EC_POINT_new %xdefine _EC_POINT_oct2point _ %+ BORINGSSL_PREFIX %+ _EC_POINT_oct2point +%xdefine _EC_POINT_point2buf _ %+ BORINGSSL_PREFIX %+ _EC_POINT_point2buf %xdefine _EC_POINT_point2cbb _ %+ BORINGSSL_PREFIX %+ _EC_POINT_point2cbb %xdefine _EC_POINT_point2oct _ %+ BORINGSSL_PREFIX %+ _EC_POINT_point2oct %xdefine _EC_POINT_set_affine_coordinates _ %+ BORINGSSL_PREFIX %+ _EC_POINT_set_affine_coordinates @@ -867,6 +877,8 @@ %xdefine _EC_curve_nid2nist _ %+ BORINGSSL_PREFIX %+ _EC_curve_nid2nist %xdefine _EC_curve_nist2nid _ %+ BORINGSSL_PREFIX %+ _EC_curve_nist2nid %xdefine _EC_get_builtin_curves _ %+ BORINGSSL_PREFIX %+ _EC_get_builtin_curves +%xdefine _EC_hash_to_curve_p256_xmd_sha256_sswu _ %+ BORINGSSL_PREFIX %+ _EC_hash_to_curve_p256_xmd_sha256_sswu +%xdefine _EC_hash_to_curve_p384_xmd_sha384_sswu _ %+ BORINGSSL_PREFIX %+ _EC_hash_to_curve_p384_xmd_sha384_sswu %xdefine _ED25519_keypair _ %+ BORINGSSL_PREFIX %+ _ED25519_keypair %xdefine _ED25519_keypair_from_seed _ %+ BORINGSSL_PREFIX %+ _ED25519_keypair_from_seed %xdefine _ED25519_sign _ %+ BORINGSSL_PREFIX %+ _ED25519_sign @@ -882,6 +894,8 @@ %xdefine _ENGINE_register_all_complete _ %+ BORINGSSL_PREFIX %+ _ENGINE_register_all_complete %xdefine _ENGINE_set_ECDSA_method _ %+ BORINGSSL_PREFIX %+ _ENGINE_set_ECDSA_method %xdefine _ENGINE_set_RSA_method _ %+ BORINGSSL_PREFIX %+ _ENGINE_set_RSA_method +%xdefine _ERR_GET_LIB _ %+ BORINGSSL_PREFIX %+ _ERR_GET_LIB +%xdefine _ERR_GET_REASON _ %+ BORINGSSL_PREFIX %+ _ERR_GET_REASON %xdefine _ERR_SAVE_STATE_free _ %+ BORINGSSL_PREFIX %+ _ERR_SAVE_STATE_free %xdefine _ERR_add_error_data _ %+ BORINGSSL_PREFIX %+ _ERR_add_error_data %xdefine _ERR_add_error_dataf _ %+ BORINGSSL_PREFIX %+ _ERR_add_error_dataf @@ -1301,6 +1315,16 @@ %xdefine _ISSUING_DIST_POINT_free _ %+ BORINGSSL_PREFIX %+ _ISSUING_DIST_POINT_free %xdefine _ISSUING_DIST_POINT_it _ %+ BORINGSSL_PREFIX %+ _ISSUING_DIST_POINT_it %xdefine _ISSUING_DIST_POINT_new _ %+ BORINGSSL_PREFIX %+ _ISSUING_DIST_POINT_new +%xdefine _KYBER_decap _ %+ BORINGSSL_PREFIX %+ _KYBER_decap +%xdefine _KYBER_encap _ %+ BORINGSSL_PREFIX %+ _KYBER_encap +%xdefine _KYBER_encap_external_entropy _ %+ BORINGSSL_PREFIX %+ _KYBER_encap_external_entropy +%xdefine _KYBER_generate_key _ %+ BORINGSSL_PREFIX %+ _KYBER_generate_key +%xdefine _KYBER_generate_key_external_entropy _ %+ BORINGSSL_PREFIX %+ _KYBER_generate_key_external_entropy +%xdefine _KYBER_marshal_private_key _ %+ BORINGSSL_PREFIX %+ _KYBER_marshal_private_key +%xdefine _KYBER_marshal_public_key _ %+ BORINGSSL_PREFIX %+ _KYBER_marshal_public_key +%xdefine _KYBER_parse_private_key _ %+ BORINGSSL_PREFIX %+ _KYBER_parse_private_key +%xdefine _KYBER_parse_public_key _ %+ BORINGSSL_PREFIX %+ _KYBER_parse_public_key +%xdefine _KYBER_public_from_private _ %+ BORINGSSL_PREFIX %+ _KYBER_public_from_private %xdefine _MD4 _ %+ BORINGSSL_PREFIX %+ _MD4 %xdefine _MD4_Final _ %+ BORINGSSL_PREFIX %+ _MD4_Final %xdefine _MD4_Init _ %+ BORINGSSL_PREFIX %+ _MD4_Init @@ -1359,6 +1383,7 @@ %xdefine _OBJ_txt2obj _ %+ BORINGSSL_PREFIX %+ _OBJ_txt2obj %xdefine _OPENSSL_add_all_algorithms_conf _ %+ BORINGSSL_PREFIX %+ _OPENSSL_add_all_algorithms_conf %xdefine _OPENSSL_armcap_P _ %+ BORINGSSL_PREFIX %+ _OPENSSL_armcap_P +%xdefine _OPENSSL_asprintf _ %+ BORINGSSL_PREFIX %+ _OPENSSL_asprintf %xdefine _OPENSSL_built_in_curves _ %+ BORINGSSL_PREFIX %+ _OPENSSL_built_in_curves %xdefine _OPENSSL_cleanse _ %+ BORINGSSL_PREFIX %+ _OPENSSL_cleanse %xdefine _OPENSSL_cleanup _ %+ BORINGSSL_PREFIX %+ _OPENSSL_cleanup @@ -1366,6 +1391,7 @@ %xdefine _OPENSSL_config _ %+ BORINGSSL_PREFIX %+ _OPENSSL_config %xdefine _OPENSSL_cpuid_setup _ %+ BORINGSSL_PREFIX %+ _OPENSSL_cpuid_setup %xdefine _OPENSSL_free _ %+ BORINGSSL_PREFIX %+ _OPENSSL_free +%xdefine _OPENSSL_fromxdigit _ %+ BORINGSSL_PREFIX %+ _OPENSSL_fromxdigit %xdefine _OPENSSL_get_armcap_pointer_for_test _ %+ BORINGSSL_PREFIX %+ _OPENSSL_get_armcap_pointer_for_test %xdefine _OPENSSL_gmtime _ %+ BORINGSSL_PREFIX %+ _OPENSSL_gmtime %xdefine _OPENSSL_gmtime_adj _ %+ BORINGSSL_PREFIX %+ _OPENSSL_gmtime_adj @@ -1374,6 +1400,11 @@ %xdefine _OPENSSL_ia32cap_P _ %+ BORINGSSL_PREFIX %+ _OPENSSL_ia32cap_P %xdefine _OPENSSL_init_crypto _ %+ BORINGSSL_PREFIX %+ _OPENSSL_init_crypto %xdefine _OPENSSL_init_ssl _ %+ BORINGSSL_PREFIX %+ _OPENSSL_init_ssl +%xdefine _OPENSSL_isalnum _ %+ BORINGSSL_PREFIX %+ _OPENSSL_isalnum +%xdefine _OPENSSL_isalpha _ %+ BORINGSSL_PREFIX %+ _OPENSSL_isalpha +%xdefine _OPENSSL_isdigit _ %+ BORINGSSL_PREFIX %+ _OPENSSL_isdigit +%xdefine _OPENSSL_isspace _ %+ BORINGSSL_PREFIX %+ _OPENSSL_isspace +%xdefine _OPENSSL_isxdigit _ %+ BORINGSSL_PREFIX %+ _OPENSSL_isxdigit %xdefine _OPENSSL_lh_delete _ %+ BORINGSSL_PREFIX %+ _OPENSSL_lh_delete %xdefine _OPENSSL_lh_doall_arg _ %+ BORINGSSL_PREFIX %+ _OPENSSL_lh_doall_arg %xdefine _OPENSSL_lh_free _ %+ BORINGSSL_PREFIX %+ _OPENSSL_lh_free @@ -1402,7 +1433,8 @@ %xdefine _OPENSSL_timegm _ %+ BORINGSSL_PREFIX %+ _OPENSSL_timegm %xdefine _OPENSSL_tm_to_posix _ %+ BORINGSSL_PREFIX %+ _OPENSSL_tm_to_posix %xdefine _OPENSSL_tolower _ %+ BORINGSSL_PREFIX %+ _OPENSSL_tolower -%xdefine _OTHERNAME_cmp _ %+ BORINGSSL_PREFIX %+ _OTHERNAME_cmp +%xdefine _OPENSSL_vasprintf _ %+ BORINGSSL_PREFIX %+ _OPENSSL_vasprintf +%xdefine _OPENSSL_vasprintf_internal _ %+ BORINGSSL_PREFIX %+ _OPENSSL_vasprintf_internal %xdefine _OTHERNAME_free _ %+ BORINGSSL_PREFIX %+ _OTHERNAME_free %xdefine _OTHERNAME_it _ %+ BORINGSSL_PREFIX %+ _OTHERNAME_it %xdefine _OTHERNAME_new _ %+ BORINGSSL_PREFIX %+ _OTHERNAME_new @@ -1419,10 +1451,8 @@ %xdefine _PEM_X509_INFO_read_bio _ %+ BORINGSSL_PREFIX %+ _PEM_X509_INFO_read_bio %xdefine _PEM_bytes_read_bio _ %+ BORINGSSL_PREFIX %+ _PEM_bytes_read_bio %xdefine _PEM_def_callback _ %+ BORINGSSL_PREFIX %+ _PEM_def_callback -%xdefine _PEM_dek_info _ %+ BORINGSSL_PREFIX %+ _PEM_dek_info %xdefine _PEM_do_header _ %+ BORINGSSL_PREFIX %+ _PEM_do_header %xdefine _PEM_get_EVP_CIPHER_INFO _ %+ BORINGSSL_PREFIX %+ _PEM_get_EVP_CIPHER_INFO -%xdefine _PEM_proc_type _ %+ BORINGSSL_PREFIX %+ _PEM_proc_type %xdefine _PEM_read _ %+ BORINGSSL_PREFIX %+ _PEM_read %xdefine _PEM_read_DHparams _ %+ BORINGSSL_PREFIX %+ _PEM_read_DHparams %xdefine _PEM_read_DSAPrivateKey _ %+ BORINGSSL_PREFIX %+ _PEM_read_DSAPrivateKey @@ -1515,6 +1545,7 @@ %xdefine _PKCS12_get_key_and_certs _ %+ BORINGSSL_PREFIX %+ _PKCS12_get_key_and_certs %xdefine _PKCS12_parse _ %+ BORINGSSL_PREFIX %+ _PKCS12_parse %xdefine _PKCS12_verify_mac _ %+ BORINGSSL_PREFIX %+ _PKCS12_verify_mac +%xdefine _PKCS1_MGF1 _ %+ BORINGSSL_PREFIX %+ _PKCS1_MGF1 %xdefine _PKCS5_PBKDF2_HMAC _ %+ BORINGSSL_PREFIX %+ _PKCS5_PBKDF2_HMAC %xdefine _PKCS5_PBKDF2_HMAC_SHA1 _ %+ BORINGSSL_PREFIX %+ _PKCS5_PBKDF2_HMAC_SHA1 %xdefine _PKCS5_pbe2_decrypt_init _ %+ BORINGSSL_PREFIX %+ _PKCS5_pbe2_decrypt_init @@ -1555,12 +1586,6 @@ %xdefine _POLICY_MAPPING_free _ %+ BORINGSSL_PREFIX %+ _POLICY_MAPPING_free %xdefine _POLICY_MAPPING_it _ %+ BORINGSSL_PREFIX %+ _POLICY_MAPPING_it %xdefine _POLICY_MAPPING_new _ %+ BORINGSSL_PREFIX %+ _POLICY_MAPPING_new -%xdefine _PROXY_CERT_INFO_EXTENSION_free _ %+ BORINGSSL_PREFIX %+ _PROXY_CERT_INFO_EXTENSION_free -%xdefine _PROXY_CERT_INFO_EXTENSION_it _ %+ BORINGSSL_PREFIX %+ _PROXY_CERT_INFO_EXTENSION_it -%xdefine _PROXY_CERT_INFO_EXTENSION_new _ %+ BORINGSSL_PREFIX %+ _PROXY_CERT_INFO_EXTENSION_new -%xdefine _PROXY_POLICY_free _ %+ BORINGSSL_PREFIX %+ _PROXY_POLICY_free -%xdefine _PROXY_POLICY_it _ %+ BORINGSSL_PREFIX %+ _PROXY_POLICY_it -%xdefine _PROXY_POLICY_new _ %+ BORINGSSL_PREFIX %+ _PROXY_POLICY_new %xdefine _RAND_OpenSSL _ %+ BORINGSSL_PREFIX %+ _RAND_OpenSSL %xdefine _RAND_SSLeay _ %+ BORINGSSL_PREFIX %+ _RAND_SSLeay %xdefine _RAND_add _ %+ BORINGSSL_PREFIX %+ _RAND_add @@ -1620,11 +1645,9 @@ %xdefine _RSA_padding_add_PKCS1_OAEP_mgf1 _ %+ BORINGSSL_PREFIX %+ _RSA_padding_add_PKCS1_OAEP_mgf1 %xdefine _RSA_padding_add_PKCS1_PSS_mgf1 _ %+ BORINGSSL_PREFIX %+ _RSA_padding_add_PKCS1_PSS_mgf1 %xdefine _RSA_padding_add_PKCS1_type_1 _ %+ BORINGSSL_PREFIX %+ _RSA_padding_add_PKCS1_type_1 -%xdefine _RSA_padding_add_PKCS1_type_2 _ %+ BORINGSSL_PREFIX %+ _RSA_padding_add_PKCS1_type_2 %xdefine _RSA_padding_add_none _ %+ BORINGSSL_PREFIX %+ _RSA_padding_add_none %xdefine _RSA_padding_check_PKCS1_OAEP_mgf1 _ %+ BORINGSSL_PREFIX %+ _RSA_padding_check_PKCS1_OAEP_mgf1 %xdefine _RSA_padding_check_PKCS1_type_1 _ %+ BORINGSSL_PREFIX %+ _RSA_padding_check_PKCS1_type_1 -%xdefine _RSA_padding_check_PKCS1_type_2 _ %+ BORINGSSL_PREFIX %+ _RSA_padding_check_PKCS1_type_2 %xdefine _RSA_parse_private_key _ %+ BORINGSSL_PREFIX %+ _RSA_parse_private_key %xdefine _RSA_parse_public_key _ %+ BORINGSSL_PREFIX %+ _RSA_parse_public_key %xdefine _RSA_print _ %+ BORINGSSL_PREFIX %+ _RSA_print @@ -1632,7 +1655,6 @@ %xdefine _RSA_private_encrypt _ %+ BORINGSSL_PREFIX %+ _RSA_private_encrypt %xdefine _RSA_private_key_from_bytes _ %+ BORINGSSL_PREFIX %+ _RSA_private_key_from_bytes %xdefine _RSA_private_key_to_bytes _ %+ BORINGSSL_PREFIX %+ _RSA_private_key_to_bytes -%xdefine _RSA_private_transform _ %+ BORINGSSL_PREFIX %+ _RSA_private_transform %xdefine _RSA_public_decrypt _ %+ BORINGSSL_PREFIX %+ _RSA_public_decrypt %xdefine _RSA_public_encrypt _ %+ BORINGSSL_PREFIX %+ _RSA_public_encrypt %xdefine _RSA_public_key_from_bytes _ %+ BORINGSSL_PREFIX %+ _RSA_public_key_from_bytes @@ -1697,7 +1719,6 @@ %xdefine _SSL_CIPHER_get_name _ %+ BORINGSSL_PREFIX %+ _SSL_CIPHER_get_name %xdefine _SSL_CIPHER_get_prf_nid _ %+ BORINGSSL_PREFIX %+ _SSL_CIPHER_get_prf_nid %xdefine _SSL_CIPHER_get_protocol_id _ %+ BORINGSSL_PREFIX %+ _SSL_CIPHER_get_protocol_id -%xdefine _SSL_CIPHER_get_rfc_name _ %+ BORINGSSL_PREFIX %+ _SSL_CIPHER_get_rfc_name %xdefine _SSL_CIPHER_get_value _ %+ BORINGSSL_PREFIX %+ _SSL_CIPHER_get_value %xdefine _SSL_CIPHER_get_version _ %+ BORINGSSL_PREFIX %+ _SSL_CIPHER_get_version %xdefine _SSL_CIPHER_is_aead _ %+ BORINGSSL_PREFIX %+ _SSL_CIPHER_is_aead @@ -2185,6 +2206,7 @@ %xdefine _SSL_used_hello_retry_request _ %+ BORINGSSL_PREFIX %+ _SSL_used_hello_retry_request %xdefine _SSL_version _ %+ BORINGSSL_PREFIX %+ _SSL_version %xdefine _SSL_want _ %+ BORINGSSL_PREFIX %+ _SSL_want +%xdefine _SSL_was_key_usage_invalid _ %+ BORINGSSL_PREFIX %+ _SSL_was_key_usage_invalid %xdefine _SSL_write _ %+ BORINGSSL_PREFIX %+ _SSL_write %xdefine _SSLeay _ %+ BORINGSSL_PREFIX %+ _SSLeay %xdefine _SSLeay_version _ %+ BORINGSSL_PREFIX %+ _SSLeay_version @@ -2206,6 +2228,7 @@ %xdefine _TLSv1_server_method _ %+ BORINGSSL_PREFIX %+ _TLSv1_server_method %xdefine _TRUST_TOKEN_CLIENT_add_key _ %+ BORINGSSL_PREFIX %+ _TRUST_TOKEN_CLIENT_add_key %xdefine _TRUST_TOKEN_CLIENT_begin_issuance _ %+ BORINGSSL_PREFIX %+ _TRUST_TOKEN_CLIENT_begin_issuance +%xdefine _TRUST_TOKEN_CLIENT_begin_issuance_over_message _ %+ BORINGSSL_PREFIX %+ _TRUST_TOKEN_CLIENT_begin_issuance_over_message %xdefine _TRUST_TOKEN_CLIENT_begin_redemption _ %+ BORINGSSL_PREFIX %+ _TRUST_TOKEN_CLIENT_begin_redemption %xdefine _TRUST_TOKEN_CLIENT_finish_issuance _ %+ BORINGSSL_PREFIX %+ _TRUST_TOKEN_CLIENT_finish_issuance %xdefine _TRUST_TOKEN_CLIENT_finish_redemption _ %+ BORINGSSL_PREFIX %+ _TRUST_TOKEN_CLIENT_finish_redemption @@ -2217,7 +2240,7 @@ %xdefine _TRUST_TOKEN_ISSUER_issue _ %+ BORINGSSL_PREFIX %+ _TRUST_TOKEN_ISSUER_issue %xdefine _TRUST_TOKEN_ISSUER_new _ %+ BORINGSSL_PREFIX %+ _TRUST_TOKEN_ISSUER_new %xdefine _TRUST_TOKEN_ISSUER_redeem _ %+ BORINGSSL_PREFIX %+ _TRUST_TOKEN_ISSUER_redeem -%xdefine _TRUST_TOKEN_ISSUER_redeem_raw _ %+ BORINGSSL_PREFIX %+ _TRUST_TOKEN_ISSUER_redeem_raw +%xdefine _TRUST_TOKEN_ISSUER_redeem_over_message _ %+ BORINGSSL_PREFIX %+ _TRUST_TOKEN_ISSUER_redeem_over_message %xdefine _TRUST_TOKEN_ISSUER_set_metadata_key _ %+ BORINGSSL_PREFIX %+ _TRUST_TOKEN_ISSUER_set_metadata_key %xdefine _TRUST_TOKEN_ISSUER_set_srr_key _ %+ BORINGSSL_PREFIX %+ _TRUST_TOKEN_ISSUER_set_srr_key %xdefine _TRUST_TOKEN_PRETOKEN_free _ %+ BORINGSSL_PREFIX %+ _TRUST_TOKEN_PRETOKEN_free @@ -2229,6 +2252,8 @@ %xdefine _TRUST_TOKEN_free _ %+ BORINGSSL_PREFIX %+ _TRUST_TOKEN_free %xdefine _TRUST_TOKEN_generate_key _ %+ BORINGSSL_PREFIX %+ _TRUST_TOKEN_generate_key %xdefine _TRUST_TOKEN_new _ %+ BORINGSSL_PREFIX %+ _TRUST_TOKEN_new +%xdefine _TRUST_TOKEN_pst_v1_pmb _ %+ BORINGSSL_PREFIX %+ _TRUST_TOKEN_pst_v1_pmb +%xdefine _TRUST_TOKEN_pst_v1_voprf _ %+ BORINGSSL_PREFIX %+ _TRUST_TOKEN_pst_v1_voprf %xdefine _USERNOTICE_free _ %+ BORINGSSL_PREFIX %+ _USERNOTICE_free %xdefine _USERNOTICE_it _ %+ BORINGSSL_PREFIX %+ _USERNOTICE_it %xdefine _USERNOTICE_new _ %+ BORINGSSL_PREFIX %+ _USERNOTICE_new @@ -2258,21 +2283,17 @@ %xdefine _X509V3_add_standard_extensions _ %+ BORINGSSL_PREFIX %+ _X509V3_add_standard_extensions %xdefine _X509V3_add_value _ %+ BORINGSSL_PREFIX %+ _X509V3_add_value %xdefine _X509V3_add_value_bool _ %+ BORINGSSL_PREFIX %+ _X509V3_add_value_bool -%xdefine _X509V3_add_value_bool_nf _ %+ BORINGSSL_PREFIX %+ _X509V3_add_value_bool_nf %xdefine _X509V3_add_value_int _ %+ BORINGSSL_PREFIX %+ _X509V3_add_value_int -%xdefine _X509V3_add_value_uchar _ %+ BORINGSSL_PREFIX %+ _X509V3_add_value_uchar +%xdefine _X509V3_bool_from_string _ %+ BORINGSSL_PREFIX %+ _X509V3_bool_from_string %xdefine _X509V3_conf_free _ %+ BORINGSSL_PREFIX %+ _X509V3_conf_free %xdefine _X509V3_extensions_print _ %+ BORINGSSL_PREFIX %+ _X509V3_extensions_print %xdefine _X509V3_get_d2i _ %+ BORINGSSL_PREFIX %+ _X509V3_get_d2i %xdefine _X509V3_get_section _ %+ BORINGSSL_PREFIX %+ _X509V3_get_section -%xdefine _X509V3_get_string _ %+ BORINGSSL_PREFIX %+ _X509V3_get_string %xdefine _X509V3_get_value_bool _ %+ BORINGSSL_PREFIX %+ _X509V3_get_value_bool %xdefine _X509V3_get_value_int _ %+ BORINGSSL_PREFIX %+ _X509V3_get_value_int %xdefine _X509V3_parse_list _ %+ BORINGSSL_PREFIX %+ _X509V3_parse_list -%xdefine _X509V3_section_free _ %+ BORINGSSL_PREFIX %+ _X509V3_section_free %xdefine _X509V3_set_ctx _ %+ BORINGSSL_PREFIX %+ _X509V3_set_ctx %xdefine _X509V3_set_nconf _ %+ BORINGSSL_PREFIX %+ _X509V3_set_nconf -%xdefine _X509V3_string_free _ %+ BORINGSSL_PREFIX %+ _X509V3_string_free %xdefine _X509_ALGOR_cmp _ %+ BORINGSSL_PREFIX %+ _X509_ALGOR_cmp %xdefine _X509_ALGOR_dup _ %+ BORINGSSL_PREFIX %+ _X509_ALGOR_dup %xdefine _X509_ALGOR_free _ %+ BORINGSSL_PREFIX %+ _X509_ALGOR_free @@ -2419,7 +2440,6 @@ %xdefine _X509_OBJECT_up_ref_count _ %+ BORINGSSL_PREFIX %+ _X509_OBJECT_up_ref_count %xdefine _X509_PKEY_free _ %+ BORINGSSL_PREFIX %+ _X509_PKEY_free %xdefine _X509_PKEY_new _ %+ BORINGSSL_PREFIX %+ _X509_PKEY_new -%xdefine _X509_POLICY_NODE_print _ %+ BORINGSSL_PREFIX %+ _X509_POLICY_NODE_print %xdefine _X509_PUBKEY_free _ %+ BORINGSSL_PREFIX %+ _X509_PUBKEY_free %xdefine _X509_PUBKEY_get _ %+ BORINGSSL_PREFIX %+ _X509_PUBKEY_get %xdefine _X509_PUBKEY_get0_param _ %+ BORINGSSL_PREFIX %+ _X509_PUBKEY_get0_param @@ -2534,6 +2554,7 @@ %xdefine _X509_STORE_CTX_set_flags _ %+ BORINGSSL_PREFIX %+ _X509_STORE_CTX_set_flags %xdefine _X509_STORE_CTX_set_purpose _ %+ BORINGSSL_PREFIX %+ _X509_STORE_CTX_set_purpose %xdefine _X509_STORE_CTX_set_time _ %+ BORINGSSL_PREFIX %+ _X509_STORE_CTX_set_time +%xdefine _X509_STORE_CTX_set_time_posix _ %+ BORINGSSL_PREFIX %+ _X509_STORE_CTX_set_time_posix %xdefine _X509_STORE_CTX_set_trust _ %+ BORINGSSL_PREFIX %+ _X509_STORE_CTX_set_trust %xdefine _X509_STORE_CTX_set_verify_cb _ %+ BORINGSSL_PREFIX %+ _X509_STORE_CTX_set_verify_cb %xdefine _X509_STORE_CTX_trusted_stack _ %+ BORINGSSL_PREFIX %+ _X509_STORE_CTX_trusted_stack @@ -2591,14 +2612,11 @@ %xdefine _X509_VAL_it _ %+ BORINGSSL_PREFIX %+ _X509_VAL_it %xdefine _X509_VAL_new _ %+ BORINGSSL_PREFIX %+ _X509_VAL_new %xdefine _X509_VERIFY_PARAM_add0_policy _ %+ BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_add0_policy -%xdefine _X509_VERIFY_PARAM_add0_table _ %+ BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_add0_table %xdefine _X509_VERIFY_PARAM_add1_host _ %+ BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_add1_host %xdefine _X509_VERIFY_PARAM_clear_flags _ %+ BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_clear_flags %xdefine _X509_VERIFY_PARAM_free _ %+ BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_free -%xdefine _X509_VERIFY_PARAM_get0 _ %+ BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_get0 %xdefine _X509_VERIFY_PARAM_get0_name _ %+ BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_get0_name %xdefine _X509_VERIFY_PARAM_get0_peername _ %+ BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_get0_peername -%xdefine _X509_VERIFY_PARAM_get_count _ %+ BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_get_count %xdefine _X509_VERIFY_PARAM_get_depth _ %+ BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_get_depth %xdefine _X509_VERIFY_PARAM_get_flags _ %+ BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_get_flags %xdefine _X509_VERIFY_PARAM_inherit _ %+ BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_inherit @@ -2616,8 +2634,8 @@ %xdefine _X509_VERIFY_PARAM_set_hostflags _ %+ BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_set_hostflags %xdefine _X509_VERIFY_PARAM_set_purpose _ %+ BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_set_purpose %xdefine _X509_VERIFY_PARAM_set_time _ %+ BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_set_time +%xdefine _X509_VERIFY_PARAM_set_time_posix _ %+ BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_set_time_posix %xdefine _X509_VERIFY_PARAM_set_trust _ %+ BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_set_trust -%xdefine _X509_VERIFY_PARAM_table_cleanup _ %+ BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_table_cleanup %xdefine _X509_add1_ext_i2d _ %+ BORINGSSL_PREFIX %+ _X509_add1_ext_i2d %xdefine _X509_add1_reject_object _ %+ BORINGSSL_PREFIX %+ _X509_add1_reject_object %xdefine _X509_add1_trust_object _ %+ BORINGSSL_PREFIX %+ _X509_add1_trust_object @@ -2638,6 +2656,7 @@ %xdefine _X509_cmp _ %+ BORINGSSL_PREFIX %+ _X509_cmp %xdefine _X509_cmp_current_time _ %+ BORINGSSL_PREFIX %+ _X509_cmp_current_time %xdefine _X509_cmp_time _ %+ BORINGSSL_PREFIX %+ _X509_cmp_time +%xdefine _X509_cmp_time_posix _ %+ BORINGSSL_PREFIX %+ _X509_cmp_time_posix %xdefine _X509_delete_ext _ %+ BORINGSSL_PREFIX %+ _X509_delete_ext %xdefine _X509_digest _ %+ BORINGSSL_PREFIX %+ _X509_digest %xdefine _X509_dup _ %+ BORINGSSL_PREFIX %+ _X509_dup @@ -2701,7 +2720,6 @@ %xdefine _X509_new _ %+ BORINGSSL_PREFIX %+ _X509_new %xdefine _X509_parse_from_buffer _ %+ BORINGSSL_PREFIX %+ _X509_parse_from_buffer %xdefine _X509_policy_check _ %+ BORINGSSL_PREFIX %+ _X509_policy_check -%xdefine _X509_policy_tree_free _ %+ BORINGSSL_PREFIX %+ _X509_policy_tree_free %xdefine _X509_print _ %+ BORINGSSL_PREFIX %+ _X509_print %xdefine _X509_print_ex _ %+ BORINGSSL_PREFIX %+ _X509_print_ex %xdefine _X509_print_ex_fp _ %+ BORINGSSL_PREFIX %+ _X509_print_ex_fp @@ -2770,6 +2788,8 @@ %xdefine _aes256gcmsiv_enc_msg_x8 _ %+ BORINGSSL_PREFIX %+ _aes256gcmsiv_enc_msg_x8 %xdefine _aes256gcmsiv_kdf _ %+ BORINGSSL_PREFIX %+ _aes256gcmsiv_kdf %xdefine _aes_ctr_set_key _ %+ BORINGSSL_PREFIX %+ _aes_ctr_set_key +%xdefine _aes_gcm_dec_kernel _ %+ BORINGSSL_PREFIX %+ _aes_gcm_dec_kernel +%xdefine _aes_gcm_enc_kernel _ %+ BORINGSSL_PREFIX %+ _aes_gcm_enc_kernel %xdefine _aes_hw_cbc_encrypt _ %+ BORINGSSL_PREFIX %+ _aes_hw_cbc_encrypt %xdefine _aes_hw_ctr32_encrypt_blocks _ %+ BORINGSSL_PREFIX %+ _aes_hw_ctr32_encrypt_blocks %xdefine _aes_hw_decrypt _ %+ BORINGSSL_PREFIX %+ _aes_hw_decrypt @@ -2795,15 +2815,16 @@ %xdefine _asn1_enc_init _ %+ BORINGSSL_PREFIX %+ _asn1_enc_init %xdefine _asn1_enc_restore _ %+ BORINGSSL_PREFIX %+ _asn1_enc_restore %xdefine _asn1_enc_save _ %+ BORINGSSL_PREFIX %+ _asn1_enc_save +%xdefine _asn1_encoding_clear _ %+ BORINGSSL_PREFIX %+ _asn1_encoding_clear %xdefine _asn1_generalizedtime_to_tm _ %+ BORINGSSL_PREFIX %+ _asn1_generalizedtime_to_tm %xdefine _asn1_get_choice_selector _ %+ BORINGSSL_PREFIX %+ _asn1_get_choice_selector %xdefine _asn1_get_field_ptr _ %+ BORINGSSL_PREFIX %+ _asn1_get_field_ptr %xdefine _asn1_get_string_table_for_testing _ %+ BORINGSSL_PREFIX %+ _asn1_get_string_table_for_testing %xdefine _asn1_is_printable _ %+ BORINGSSL_PREFIX %+ _asn1_is_printable -%xdefine _asn1_item_combine_free _ %+ BORINGSSL_PREFIX %+ _asn1_item_combine_free %xdefine _asn1_refcount_dec_and_test_zero _ %+ BORINGSSL_PREFIX %+ _asn1_refcount_dec_and_test_zero %xdefine _asn1_refcount_set_one _ %+ BORINGSSL_PREFIX %+ _asn1_refcount_set_one %xdefine _asn1_set_choice_selector _ %+ BORINGSSL_PREFIX %+ _asn1_set_choice_selector +%xdefine _asn1_type_cleanup _ %+ BORINGSSL_PREFIX %+ _asn1_type_cleanup %xdefine _asn1_type_value_as_pointer _ %+ BORINGSSL_PREFIX %+ _asn1_type_value_as_pointer %xdefine _asn1_utctime_to_tm _ %+ BORINGSSL_PREFIX %+ _asn1_utctime_to_tm %xdefine _beeu_mod_inverse_vartime _ %+ BORINGSSL_PREFIX %+ _beeu_mod_inverse_vartime @@ -2814,6 +2835,7 @@ %xdefine _bio_socket_nbio _ %+ BORINGSSL_PREFIX %+ _bio_socket_nbio %xdefine _bn_abs_sub_consttime _ %+ BORINGSSL_PREFIX %+ _bn_abs_sub_consttime %xdefine _bn_add_words _ %+ BORINGSSL_PREFIX %+ _bn_add_words +%xdefine _bn_assert_fits_in_bytes _ %+ BORINGSSL_PREFIX %+ _bn_assert_fits_in_bytes %xdefine _bn_big_endian_to_words _ %+ BORINGSSL_PREFIX %+ _bn_big_endian_to_words %xdefine _bn_copy_words _ %+ BORINGSSL_PREFIX %+ _bn_copy_words %xdefine _bn_div_consttime _ %+ BORINGSSL_PREFIX %+ _bn_div_consttime @@ -2976,8 +2998,6 @@ %xdefine _d2i_PKCS8_fp _ %+ BORINGSSL_PREFIX %+ _d2i_PKCS8_fp %xdefine _d2i_POLICYINFO _ %+ BORINGSSL_PREFIX %+ _d2i_POLICYINFO %xdefine _d2i_POLICYQUALINFO _ %+ BORINGSSL_PREFIX %+ _d2i_POLICYQUALINFO -%xdefine _d2i_PROXY_CERT_INFO_EXTENSION _ %+ BORINGSSL_PREFIX %+ _d2i_PROXY_CERT_INFO_EXTENSION -%xdefine _d2i_PROXY_POLICY _ %+ BORINGSSL_PREFIX %+ _d2i_PROXY_POLICY %xdefine _d2i_PUBKEY _ %+ BORINGSSL_PREFIX %+ _d2i_PUBKEY %xdefine _d2i_PUBKEY_bio _ %+ BORINGSSL_PREFIX %+ _d2i_PUBKEY_bio %xdefine _d2i_PUBKEY_fp _ %+ BORINGSSL_PREFIX %+ _d2i_PUBKEY_fp @@ -3024,11 +3044,13 @@ %xdefine _d2i_X509_fp _ %+ BORINGSSL_PREFIX %+ _d2i_X509_fp %xdefine _dh_compute_key_padded_no_self_test _ %+ BORINGSSL_PREFIX %+ _dh_compute_key_padded_no_self_test %xdefine _dsa_asn1_meth _ %+ BORINGSSL_PREFIX %+ _dsa_asn1_meth -%xdefine _dsa_check_parameters _ %+ BORINGSSL_PREFIX %+ _dsa_check_parameters +%xdefine _dsa_check_key _ %+ BORINGSSL_PREFIX %+ _dsa_check_key %xdefine _ec_GFp_mont_add _ %+ BORINGSSL_PREFIX %+ _ec_GFp_mont_add %xdefine _ec_GFp_mont_dbl _ %+ BORINGSSL_PREFIX %+ _ec_GFp_mont_dbl +%xdefine _ec_GFp_mont_felem_exp _ %+ BORINGSSL_PREFIX %+ _ec_GFp_mont_felem_exp %xdefine _ec_GFp_mont_felem_from_bytes _ %+ BORINGSSL_PREFIX %+ _ec_GFp_mont_felem_from_bytes %xdefine _ec_GFp_mont_felem_mul _ %+ BORINGSSL_PREFIX %+ _ec_GFp_mont_felem_mul +%xdefine _ec_GFp_mont_felem_reduce _ %+ BORINGSSL_PREFIX %+ _ec_GFp_mont_felem_reduce %xdefine _ec_GFp_mont_felem_sqr _ %+ BORINGSSL_PREFIX %+ _ec_GFp_mont_felem_sqr %xdefine _ec_GFp_mont_felem_to_bytes _ %+ BORINGSSL_PREFIX %+ _ec_GFp_mont_felem_to_bytes %xdefine _ec_GFp_mont_group_finish _ %+ BORINGSSL_PREFIX %+ _ec_GFp_mont_group_finish @@ -3075,12 +3097,16 @@ %xdefine _ec_get_x_coordinate_as_bytes _ %+ BORINGSSL_PREFIX %+ _ec_get_x_coordinate_as_bytes %xdefine _ec_get_x_coordinate_as_scalar _ %+ BORINGSSL_PREFIX %+ _ec_get_x_coordinate_as_scalar %xdefine _ec_group_new _ %+ BORINGSSL_PREFIX %+ _ec_group_new +%xdefine _ec_hash_to_curve_p256_xmd_sha256_sswu _ %+ BORINGSSL_PREFIX %+ _ec_hash_to_curve_p256_xmd_sha256_sswu +%xdefine _ec_hash_to_curve_p384_xmd_sha384_sswu _ %+ BORINGSSL_PREFIX %+ _ec_hash_to_curve_p384_xmd_sha384_sswu %xdefine _ec_hash_to_curve_p384_xmd_sha512_sswu_draft07 _ %+ BORINGSSL_PREFIX %+ _ec_hash_to_curve_p384_xmd_sha512_sswu_draft07 +%xdefine _ec_hash_to_scalar_p384_xmd_sha384 _ %+ BORINGSSL_PREFIX %+ _ec_hash_to_scalar_p384_xmd_sha384 %xdefine _ec_hash_to_scalar_p384_xmd_sha512_draft07 _ %+ BORINGSSL_PREFIX %+ _ec_hash_to_scalar_p384_xmd_sha512_draft07 %xdefine _ec_init_precomp _ %+ BORINGSSL_PREFIX %+ _ec_init_precomp %xdefine _ec_jacobian_to_affine _ %+ BORINGSSL_PREFIX %+ _ec_jacobian_to_affine %xdefine _ec_jacobian_to_affine_batch _ %+ BORINGSSL_PREFIX %+ _ec_jacobian_to_affine_batch %xdefine _ec_pkey_meth _ %+ BORINGSSL_PREFIX %+ _ec_pkey_meth +%xdefine _ec_point_byte_len _ %+ BORINGSSL_PREFIX %+ _ec_point_byte_len %xdefine _ec_point_from_uncompressed _ %+ BORINGSSL_PREFIX %+ _ec_point_from_uncompressed %xdefine _ec_point_mul_no_self_test _ %+ BORINGSSL_PREFIX %+ _ec_point_mul_no_self_test %xdefine _ec_point_mul_scalar _ %+ BORINGSSL_PREFIX %+ _ec_point_mul_scalar @@ -3234,8 +3260,6 @@ %xdefine _i2d_PKCS8_fp _ %+ BORINGSSL_PREFIX %+ _i2d_PKCS8_fp %xdefine _i2d_POLICYINFO _ %+ BORINGSSL_PREFIX %+ _i2d_POLICYINFO %xdefine _i2d_POLICYQUALINFO _ %+ BORINGSSL_PREFIX %+ _i2d_POLICYQUALINFO -%xdefine _i2d_PROXY_CERT_INFO_EXTENSION _ %+ BORINGSSL_PREFIX %+ _i2d_PROXY_CERT_INFO_EXTENSION -%xdefine _i2d_PROXY_POLICY _ %+ BORINGSSL_PREFIX %+ _i2d_PROXY_POLICY %xdefine _i2d_PUBKEY _ %+ BORINGSSL_PREFIX %+ _i2d_PUBKEY %xdefine _i2d_PUBKEY_bio _ %+ BORINGSSL_PREFIX %+ _i2d_PUBKEY_bio %xdefine _i2d_PUBKEY_fp _ %+ BORINGSSL_PREFIX %+ _i2d_PUBKEY_fp @@ -3297,8 +3321,6 @@ %xdefine _kOpenSSLReasonStringData _ %+ BORINGSSL_PREFIX %+ _kOpenSSLReasonStringData %xdefine _kOpenSSLReasonValues _ %+ BORINGSSL_PREFIX %+ _kOpenSSLReasonValues %xdefine _kOpenSSLReasonValuesLen _ %+ BORINGSSL_PREFIX %+ _kOpenSSLReasonValuesLen -%xdefine _level_add_node _ %+ BORINGSSL_PREFIX %+ _level_add_node -%xdefine _level_find_node _ %+ BORINGSSL_PREFIX %+ _level_find_node %xdefine _md4_block_data_order _ %+ BORINGSSL_PREFIX %+ _md4_block_data_order %xdefine _md5_block_asm_data_order _ %+ BORINGSSL_PREFIX %+ _md5_block_asm_data_order %xdefine _o2i_ECPublicKey _ %+ BORINGSSL_PREFIX %+ _o2i_ECPublicKey @@ -3326,24 +3348,25 @@ %xdefine _pmbtoken_exp2_read _ %+ BORINGSSL_PREFIX %+ _pmbtoken_exp2_read %xdefine _pmbtoken_exp2_sign _ %+ BORINGSSL_PREFIX %+ _pmbtoken_exp2_sign %xdefine _pmbtoken_exp2_unblind _ %+ BORINGSSL_PREFIX %+ _pmbtoken_exp2_unblind -%xdefine _policy_cache_find_data _ %+ BORINGSSL_PREFIX %+ _policy_cache_find_data -%xdefine _policy_cache_free _ %+ BORINGSSL_PREFIX %+ _policy_cache_free -%xdefine _policy_cache_set _ %+ BORINGSSL_PREFIX %+ _policy_cache_set -%xdefine _policy_cache_set_mapping _ %+ BORINGSSL_PREFIX %+ _policy_cache_set_mapping -%xdefine _policy_data_free _ %+ BORINGSSL_PREFIX %+ _policy_data_free -%xdefine _policy_data_new _ %+ BORINGSSL_PREFIX %+ _policy_data_new -%xdefine _policy_node_cmp_new _ %+ BORINGSSL_PREFIX %+ _policy_node_cmp_new -%xdefine _policy_node_free _ %+ BORINGSSL_PREFIX %+ _policy_node_free -%xdefine _policy_node_match _ %+ BORINGSSL_PREFIX %+ _policy_node_match +%xdefine _pmbtoken_pst1_blind _ %+ BORINGSSL_PREFIX %+ _pmbtoken_pst1_blind +%xdefine _pmbtoken_pst1_client_key_from_bytes _ %+ BORINGSSL_PREFIX %+ _pmbtoken_pst1_client_key_from_bytes +%xdefine _pmbtoken_pst1_derive_key_from_secret _ %+ BORINGSSL_PREFIX %+ _pmbtoken_pst1_derive_key_from_secret +%xdefine _pmbtoken_pst1_generate_key _ %+ BORINGSSL_PREFIX %+ _pmbtoken_pst1_generate_key +%xdefine _pmbtoken_pst1_get_h_for_testing _ %+ BORINGSSL_PREFIX %+ _pmbtoken_pst1_get_h_for_testing +%xdefine _pmbtoken_pst1_issuer_key_from_bytes _ %+ BORINGSSL_PREFIX %+ _pmbtoken_pst1_issuer_key_from_bytes +%xdefine _pmbtoken_pst1_read _ %+ BORINGSSL_PREFIX %+ _pmbtoken_pst1_read +%xdefine _pmbtoken_pst1_sign _ %+ BORINGSSL_PREFIX %+ _pmbtoken_pst1_sign +%xdefine _pmbtoken_pst1_unblind _ %+ BORINGSSL_PREFIX %+ _pmbtoken_pst1_unblind %xdefine _poly_Rq_mul _ %+ BORINGSSL_PREFIX %+ _poly_Rq_mul %xdefine _rand_fork_unsafe_buffering_enabled _ %+ BORINGSSL_PREFIX %+ _rand_fork_unsafe_buffering_enabled %xdefine _rsa_asn1_meth _ %+ BORINGSSL_PREFIX %+ _rsa_asn1_meth %xdefine _rsa_check_public_key _ %+ BORINGSSL_PREFIX %+ _rsa_check_public_key -%xdefine _rsa_default_decrypt _ %+ BORINGSSL_PREFIX %+ _rsa_default_decrypt %xdefine _rsa_default_private_transform _ %+ BORINGSSL_PREFIX %+ _rsa_default_private_transform %xdefine _rsa_default_sign_raw _ %+ BORINGSSL_PREFIX %+ _rsa_default_sign_raw %xdefine _rsa_default_size _ %+ BORINGSSL_PREFIX %+ _rsa_default_size %xdefine _rsa_pkey_meth _ %+ BORINGSSL_PREFIX %+ _rsa_pkey_meth +%xdefine _rsa_private_transform _ %+ BORINGSSL_PREFIX %+ _rsa_private_transform +%xdefine _rsa_private_transform_no_self_test _ %+ BORINGSSL_PREFIX %+ _rsa_private_transform_no_self_test %xdefine _rsa_sign_no_self_test _ %+ BORINGSSL_PREFIX %+ _rsa_sign_no_self_test %xdefine _rsa_verify_no_self_test _ %+ BORINGSSL_PREFIX %+ _rsa_verify_no_self_test %xdefine _rsa_verify_raw_no_self_test _ %+ BORINGSSL_PREFIX %+ _rsa_verify_raw_no_self_test @@ -3398,6 +3421,7 @@ %xdefine _sk_X509_value _ %+ BORINGSSL_PREFIX %+ _sk_X509_value %xdefine _sk_deep_copy _ %+ BORINGSSL_PREFIX %+ _sk_deep_copy %xdefine _sk_delete _ %+ BORINGSSL_PREFIX %+ _sk_delete +%xdefine _sk_delete_if _ %+ BORINGSSL_PREFIX %+ _sk_delete_if %xdefine _sk_delete_ptr _ %+ BORINGSSL_PREFIX %+ _sk_delete_ptr %xdefine _sk_dup _ %+ BORINGSSL_PREFIX %+ _sk_dup %xdefine _sk_find _ %+ BORINGSSL_PREFIX %+ _sk_find @@ -3417,7 +3441,6 @@ %xdefine _sk_sort _ %+ BORINGSSL_PREFIX %+ _sk_sort %xdefine _sk_value _ %+ BORINGSSL_PREFIX %+ _sk_value %xdefine _sk_zero _ %+ BORINGSSL_PREFIX %+ _sk_zero -%xdefine _tree_find_sk _ %+ BORINGSSL_PREFIX %+ _tree_find_sk %xdefine _v2i_GENERAL_NAME _ %+ BORINGSSL_PREFIX %+ _v2i_GENERAL_NAME %xdefine _v2i_GENERAL_NAMES _ %+ BORINGSSL_PREFIX %+ _v2i_GENERAL_NAMES %xdefine _v2i_GENERAL_NAME_ex _ %+ BORINGSSL_PREFIX %+ _v2i_GENERAL_NAME_ex @@ -3441,7 +3464,6 @@ %xdefine _v3_nscert _ %+ BORINGSSL_PREFIX %+ _v3_nscert %xdefine _v3_ocsp_accresp _ %+ BORINGSSL_PREFIX %+ _v3_ocsp_accresp %xdefine _v3_ocsp_nocheck _ %+ BORINGSSL_PREFIX %+ _v3_ocsp_nocheck -%xdefine _v3_pci _ %+ BORINGSSL_PREFIX %+ _v3_pci %xdefine _v3_policy_constraints _ %+ BORINGSSL_PREFIX %+ _v3_policy_constraints %xdefine _v3_policy_mappings _ %+ BORINGSSL_PREFIX %+ _v3_policy_mappings %xdefine _v3_sinfo _ %+ BORINGSSL_PREFIX %+ _v3_sinfo @@ -3454,6 +3476,14 @@ %xdefine _voprf_exp2_read _ %+ BORINGSSL_PREFIX %+ _voprf_exp2_read %xdefine _voprf_exp2_sign _ %+ BORINGSSL_PREFIX %+ _voprf_exp2_sign %xdefine _voprf_exp2_unblind _ %+ BORINGSSL_PREFIX %+ _voprf_exp2_unblind +%xdefine _voprf_pst1_blind _ %+ BORINGSSL_PREFIX %+ _voprf_pst1_blind +%xdefine _voprf_pst1_client_key_from_bytes _ %+ BORINGSSL_PREFIX %+ _voprf_pst1_client_key_from_bytes +%xdefine _voprf_pst1_derive_key_from_secret _ %+ BORINGSSL_PREFIX %+ _voprf_pst1_derive_key_from_secret +%xdefine _voprf_pst1_generate_key _ %+ BORINGSSL_PREFIX %+ _voprf_pst1_generate_key +%xdefine _voprf_pst1_issuer_key_from_bytes _ %+ BORINGSSL_PREFIX %+ _voprf_pst1_issuer_key_from_bytes +%xdefine _voprf_pst1_read _ %+ BORINGSSL_PREFIX %+ _voprf_pst1_read +%xdefine _voprf_pst1_sign _ %+ BORINGSSL_PREFIX %+ _voprf_pst1_sign +%xdefine _voprf_pst1_unblind _ %+ BORINGSSL_PREFIX %+ _voprf_pst1_unblind %xdefine _vpaes_cbc_encrypt _ %+ BORINGSSL_PREFIX %+ _vpaes_cbc_encrypt %xdefine _vpaes_ctr32_encrypt_blocks _ %+ BORINGSSL_PREFIX %+ _vpaes_ctr32_encrypt_blocks %xdefine _vpaes_decrypt _ %+ BORINGSSL_PREFIX %+ _vpaes_decrypt @@ -3482,9 +3512,9 @@ %xdefine _x509v3_a2i_ipadd _ %+ BORINGSSL_PREFIX %+ _x509v3_a2i_ipadd %xdefine _x509v3_bytes_to_hex _ %+ BORINGSSL_PREFIX %+ _x509v3_bytes_to_hex %xdefine _x509v3_cache_extensions _ %+ BORINGSSL_PREFIX %+ _x509v3_cache_extensions +%xdefine _x509v3_conf_name_matches _ %+ BORINGSSL_PREFIX %+ _x509v3_conf_name_matches %xdefine _x509v3_hex_to_bytes _ %+ BORINGSSL_PREFIX %+ _x509v3_hex_to_bytes %xdefine _x509v3_looks_like_dns_name _ %+ BORINGSSL_PREFIX %+ _x509v3_looks_like_dns_name -%xdefine _x509v3_name_cmp _ %+ BORINGSSL_PREFIX %+ _x509v3_name_cmp %else %xdefine ACCESS_DESCRIPTION_free BORINGSSL_PREFIX %+ _ACCESS_DESCRIPTION_free %xdefine ACCESS_DESCRIPTION_it BORINGSSL_PREFIX %+ _ACCESS_DESCRIPTION_it @@ -3572,7 +3602,6 @@ %xdefine ASN1_PRINTABLE_free BORINGSSL_PREFIX %+ _ASN1_PRINTABLE_free %xdefine ASN1_PRINTABLE_it BORINGSSL_PREFIX %+ _ASN1_PRINTABLE_it %xdefine ASN1_PRINTABLE_new BORINGSSL_PREFIX %+ _ASN1_PRINTABLE_new -%xdefine ASN1_PRINTABLE_type BORINGSSL_PREFIX %+ _ASN1_PRINTABLE_type %xdefine ASN1_SEQUENCE_ANY_it BORINGSSL_PREFIX %+ _ASN1_SEQUENCE_ANY_it %xdefine ASN1_SEQUENCE_it BORINGSSL_PREFIX %+ _ASN1_SEQUENCE_it %xdefine ASN1_SET_ANY_it BORINGSSL_PREFIX %+ _ASN1_SET_ANY_it @@ -3610,6 +3639,7 @@ %xdefine ASN1_TIME_new BORINGSSL_PREFIX %+ _ASN1_TIME_new %xdefine ASN1_TIME_print BORINGSSL_PREFIX %+ _ASN1_TIME_print %xdefine ASN1_TIME_set BORINGSSL_PREFIX %+ _ASN1_TIME_set +%xdefine ASN1_TIME_set_posix BORINGSSL_PREFIX %+ _ASN1_TIME_set_posix %xdefine ASN1_TIME_set_string BORINGSSL_PREFIX %+ _ASN1_TIME_set_string %xdefine ASN1_TIME_to_generalizedtime BORINGSSL_PREFIX %+ _ASN1_TIME_to_generalizedtime %xdefine ASN1_TIME_to_posix BORINGSSL_PREFIX %+ _ASN1_TIME_to_posix @@ -3922,6 +3952,9 @@ %xdefine BN_usub BORINGSSL_PREFIX %+ _BN_usub %xdefine BN_value_one BORINGSSL_PREFIX %+ _BN_value_one %xdefine BN_zero BORINGSSL_PREFIX %+ _BN_zero +%xdefine BORINGSSL_keccak BORINGSSL_PREFIX %+ _BORINGSSL_keccak +%xdefine BORINGSSL_keccak_init BORINGSSL_PREFIX %+ _BORINGSSL_keccak_init +%xdefine BORINGSSL_keccak_squeeze BORINGSSL_PREFIX %+ _BORINGSSL_keccak_squeeze %xdefine BORINGSSL_self_test BORINGSSL_PREFIX %+ _BORINGSSL_self_test %xdefine BUF_MEM_append BORINGSSL_PREFIX %+ _BUF_MEM_append %xdefine BUF_MEM_free BORINGSSL_PREFIX %+ _BUF_MEM_free @@ -3999,6 +4032,7 @@ %xdefine CBS_get_u32 BORINGSSL_PREFIX %+ _CBS_get_u32 %xdefine CBS_get_u32le BORINGSSL_PREFIX %+ _CBS_get_u32le %xdefine CBS_get_u64 BORINGSSL_PREFIX %+ _CBS_get_u64 +%xdefine CBS_get_u64_decimal BORINGSSL_PREFIX %+ _CBS_get_u64_decimal %xdefine CBS_get_u64le BORINGSSL_PREFIX %+ _CBS_get_u64le %xdefine CBS_get_u8 BORINGSSL_PREFIX %+ _CBS_get_u8 %xdefine CBS_get_u8_length_prefixed BORINGSSL_PREFIX %+ _CBS_get_u8_length_prefixed @@ -4007,6 +4041,7 @@ %xdefine CBS_is_unsigned_asn1_integer BORINGSSL_PREFIX %+ _CBS_is_unsigned_asn1_integer %xdefine CBS_is_valid_asn1_bitstring BORINGSSL_PREFIX %+ _CBS_is_valid_asn1_bitstring %xdefine CBS_is_valid_asn1_integer BORINGSSL_PREFIX %+ _CBS_is_valid_asn1_integer +%xdefine CBS_is_valid_asn1_oid BORINGSSL_PREFIX %+ _CBS_is_valid_asn1_oid %xdefine CBS_len BORINGSSL_PREFIX %+ _CBS_len %xdefine CBS_mem_equal BORINGSSL_PREFIX %+ _CBS_mem_equal %xdefine CBS_parse_generalized_time BORINGSSL_PREFIX %+ _CBS_parse_generalized_time @@ -4069,7 +4104,7 @@ %xdefine CRYPTO_cleanup_all_ex_data BORINGSSL_PREFIX %+ _CRYPTO_cleanup_all_ex_data %xdefine CRYPTO_ctr128_encrypt BORINGSSL_PREFIX %+ _CRYPTO_ctr128_encrypt %xdefine CRYPTO_ctr128_encrypt_ctr32 BORINGSSL_PREFIX %+ _CRYPTO_ctr128_encrypt_ctr32 -%xdefine CRYPTO_fork_detect_ignore_madv_wipeonfork_for_testing BORINGSSL_PREFIX %+ _CRYPTO_fork_detect_ignore_madv_wipeonfork_for_testing +%xdefine CRYPTO_fork_detect_force_madv_wipeonfork_for_testing BORINGSSL_PREFIX %+ _CRYPTO_fork_detect_force_madv_wipeonfork_for_testing %xdefine CRYPTO_free BORINGSSL_PREFIX %+ _CRYPTO_free %xdefine CRYPTO_free_ex_data BORINGSSL_PREFIX %+ _CRYPTO_free_ex_data %xdefine CRYPTO_gcm128_aad BORINGSSL_PREFIX %+ _CRYPTO_gcm128_aad @@ -4302,9 +4337,13 @@ %xdefine EC_KEY_new BORINGSSL_PREFIX %+ _EC_KEY_new %xdefine EC_KEY_new_by_curve_name BORINGSSL_PREFIX %+ _EC_KEY_new_by_curve_name %xdefine EC_KEY_new_method BORINGSSL_PREFIX %+ _EC_KEY_new_method +%xdefine EC_KEY_oct2key BORINGSSL_PREFIX %+ _EC_KEY_oct2key +%xdefine EC_KEY_oct2priv BORINGSSL_PREFIX %+ _EC_KEY_oct2priv %xdefine EC_KEY_parse_curve_name BORINGSSL_PREFIX %+ _EC_KEY_parse_curve_name %xdefine EC_KEY_parse_parameters BORINGSSL_PREFIX %+ _EC_KEY_parse_parameters %xdefine EC_KEY_parse_private_key BORINGSSL_PREFIX %+ _EC_KEY_parse_private_key +%xdefine EC_KEY_priv2buf BORINGSSL_PREFIX %+ _EC_KEY_priv2buf +%xdefine EC_KEY_priv2oct BORINGSSL_PREFIX %+ _EC_KEY_priv2oct %xdefine EC_KEY_set_asn1_flag BORINGSSL_PREFIX %+ _EC_KEY_set_asn1_flag %xdefine EC_KEY_set_conv_form BORINGSSL_PREFIX %+ _EC_KEY_set_conv_form %xdefine EC_KEY_set_enc_flags BORINGSSL_PREFIX %+ _EC_KEY_set_enc_flags @@ -4330,6 +4369,7 @@ %xdefine EC_POINT_mul BORINGSSL_PREFIX %+ _EC_POINT_mul %xdefine EC_POINT_new BORINGSSL_PREFIX %+ _EC_POINT_new %xdefine EC_POINT_oct2point BORINGSSL_PREFIX %+ _EC_POINT_oct2point +%xdefine EC_POINT_point2buf BORINGSSL_PREFIX %+ _EC_POINT_point2buf %xdefine EC_POINT_point2cbb BORINGSSL_PREFIX %+ _EC_POINT_point2cbb %xdefine EC_POINT_point2oct BORINGSSL_PREFIX %+ _EC_POINT_point2oct %xdefine EC_POINT_set_affine_coordinates BORINGSSL_PREFIX %+ _EC_POINT_set_affine_coordinates @@ -4339,6 +4379,8 @@ %xdefine EC_curve_nid2nist BORINGSSL_PREFIX %+ _EC_curve_nid2nist %xdefine EC_curve_nist2nid BORINGSSL_PREFIX %+ _EC_curve_nist2nid %xdefine EC_get_builtin_curves BORINGSSL_PREFIX %+ _EC_get_builtin_curves +%xdefine EC_hash_to_curve_p256_xmd_sha256_sswu BORINGSSL_PREFIX %+ _EC_hash_to_curve_p256_xmd_sha256_sswu +%xdefine EC_hash_to_curve_p384_xmd_sha384_sswu BORINGSSL_PREFIX %+ _EC_hash_to_curve_p384_xmd_sha384_sswu %xdefine ED25519_keypair BORINGSSL_PREFIX %+ _ED25519_keypair %xdefine ED25519_keypair_from_seed BORINGSSL_PREFIX %+ _ED25519_keypair_from_seed %xdefine ED25519_sign BORINGSSL_PREFIX %+ _ED25519_sign @@ -4354,6 +4396,8 @@ %xdefine ENGINE_register_all_complete BORINGSSL_PREFIX %+ _ENGINE_register_all_complete %xdefine ENGINE_set_ECDSA_method BORINGSSL_PREFIX %+ _ENGINE_set_ECDSA_method %xdefine ENGINE_set_RSA_method BORINGSSL_PREFIX %+ _ENGINE_set_RSA_method +%xdefine ERR_GET_LIB BORINGSSL_PREFIX %+ _ERR_GET_LIB +%xdefine ERR_GET_REASON BORINGSSL_PREFIX %+ _ERR_GET_REASON %xdefine ERR_SAVE_STATE_free BORINGSSL_PREFIX %+ _ERR_SAVE_STATE_free %xdefine ERR_add_error_data BORINGSSL_PREFIX %+ _ERR_add_error_data %xdefine ERR_add_error_dataf BORINGSSL_PREFIX %+ _ERR_add_error_dataf @@ -4773,6 +4817,16 @@ %xdefine ISSUING_DIST_POINT_free BORINGSSL_PREFIX %+ _ISSUING_DIST_POINT_free %xdefine ISSUING_DIST_POINT_it BORINGSSL_PREFIX %+ _ISSUING_DIST_POINT_it %xdefine ISSUING_DIST_POINT_new BORINGSSL_PREFIX %+ _ISSUING_DIST_POINT_new +%xdefine KYBER_decap BORINGSSL_PREFIX %+ _KYBER_decap +%xdefine KYBER_encap BORINGSSL_PREFIX %+ _KYBER_encap +%xdefine KYBER_encap_external_entropy BORINGSSL_PREFIX %+ _KYBER_encap_external_entropy +%xdefine KYBER_generate_key BORINGSSL_PREFIX %+ _KYBER_generate_key +%xdefine KYBER_generate_key_external_entropy BORINGSSL_PREFIX %+ _KYBER_generate_key_external_entropy +%xdefine KYBER_marshal_private_key BORINGSSL_PREFIX %+ _KYBER_marshal_private_key +%xdefine KYBER_marshal_public_key BORINGSSL_PREFIX %+ _KYBER_marshal_public_key +%xdefine KYBER_parse_private_key BORINGSSL_PREFIX %+ _KYBER_parse_private_key +%xdefine KYBER_parse_public_key BORINGSSL_PREFIX %+ _KYBER_parse_public_key +%xdefine KYBER_public_from_private BORINGSSL_PREFIX %+ _KYBER_public_from_private %xdefine MD4 BORINGSSL_PREFIX %+ _MD4 %xdefine MD4_Final BORINGSSL_PREFIX %+ _MD4_Final %xdefine MD4_Init BORINGSSL_PREFIX %+ _MD4_Init @@ -4831,6 +4885,7 @@ %xdefine OBJ_txt2obj BORINGSSL_PREFIX %+ _OBJ_txt2obj %xdefine OPENSSL_add_all_algorithms_conf BORINGSSL_PREFIX %+ _OPENSSL_add_all_algorithms_conf %xdefine OPENSSL_armcap_P BORINGSSL_PREFIX %+ _OPENSSL_armcap_P +%xdefine OPENSSL_asprintf BORINGSSL_PREFIX %+ _OPENSSL_asprintf %xdefine OPENSSL_built_in_curves BORINGSSL_PREFIX %+ _OPENSSL_built_in_curves %xdefine OPENSSL_cleanse BORINGSSL_PREFIX %+ _OPENSSL_cleanse %xdefine OPENSSL_cleanup BORINGSSL_PREFIX %+ _OPENSSL_cleanup @@ -4838,6 +4893,7 @@ %xdefine OPENSSL_config BORINGSSL_PREFIX %+ _OPENSSL_config %xdefine OPENSSL_cpuid_setup BORINGSSL_PREFIX %+ _OPENSSL_cpuid_setup %xdefine OPENSSL_free BORINGSSL_PREFIX %+ _OPENSSL_free +%xdefine OPENSSL_fromxdigit BORINGSSL_PREFIX %+ _OPENSSL_fromxdigit %xdefine OPENSSL_get_armcap_pointer_for_test BORINGSSL_PREFIX %+ _OPENSSL_get_armcap_pointer_for_test %xdefine OPENSSL_gmtime BORINGSSL_PREFIX %+ _OPENSSL_gmtime %xdefine OPENSSL_gmtime_adj BORINGSSL_PREFIX %+ _OPENSSL_gmtime_adj @@ -4846,6 +4902,11 @@ %xdefine OPENSSL_ia32cap_P BORINGSSL_PREFIX %+ _OPENSSL_ia32cap_P %xdefine OPENSSL_init_crypto BORINGSSL_PREFIX %+ _OPENSSL_init_crypto %xdefine OPENSSL_init_ssl BORINGSSL_PREFIX %+ _OPENSSL_init_ssl +%xdefine OPENSSL_isalnum BORINGSSL_PREFIX %+ _OPENSSL_isalnum +%xdefine OPENSSL_isalpha BORINGSSL_PREFIX %+ _OPENSSL_isalpha +%xdefine OPENSSL_isdigit BORINGSSL_PREFIX %+ _OPENSSL_isdigit +%xdefine OPENSSL_isspace BORINGSSL_PREFIX %+ _OPENSSL_isspace +%xdefine OPENSSL_isxdigit BORINGSSL_PREFIX %+ _OPENSSL_isxdigit %xdefine OPENSSL_lh_delete BORINGSSL_PREFIX %+ _OPENSSL_lh_delete %xdefine OPENSSL_lh_doall_arg BORINGSSL_PREFIX %+ _OPENSSL_lh_doall_arg %xdefine OPENSSL_lh_free BORINGSSL_PREFIX %+ _OPENSSL_lh_free @@ -4874,7 +4935,8 @@ %xdefine OPENSSL_timegm BORINGSSL_PREFIX %+ _OPENSSL_timegm %xdefine OPENSSL_tm_to_posix BORINGSSL_PREFIX %+ _OPENSSL_tm_to_posix %xdefine OPENSSL_tolower BORINGSSL_PREFIX %+ _OPENSSL_tolower -%xdefine OTHERNAME_cmp BORINGSSL_PREFIX %+ _OTHERNAME_cmp +%xdefine OPENSSL_vasprintf BORINGSSL_PREFIX %+ _OPENSSL_vasprintf +%xdefine OPENSSL_vasprintf_internal BORINGSSL_PREFIX %+ _OPENSSL_vasprintf_internal %xdefine OTHERNAME_free BORINGSSL_PREFIX %+ _OTHERNAME_free %xdefine OTHERNAME_it BORINGSSL_PREFIX %+ _OTHERNAME_it %xdefine OTHERNAME_new BORINGSSL_PREFIX %+ _OTHERNAME_new @@ -4891,10 +4953,8 @@ %xdefine PEM_X509_INFO_read_bio BORINGSSL_PREFIX %+ _PEM_X509_INFO_read_bio %xdefine PEM_bytes_read_bio BORINGSSL_PREFIX %+ _PEM_bytes_read_bio %xdefine PEM_def_callback BORINGSSL_PREFIX %+ _PEM_def_callback -%xdefine PEM_dek_info BORINGSSL_PREFIX %+ _PEM_dek_info %xdefine PEM_do_header BORINGSSL_PREFIX %+ _PEM_do_header %xdefine PEM_get_EVP_CIPHER_INFO BORINGSSL_PREFIX %+ _PEM_get_EVP_CIPHER_INFO -%xdefine PEM_proc_type BORINGSSL_PREFIX %+ _PEM_proc_type %xdefine PEM_read BORINGSSL_PREFIX %+ _PEM_read %xdefine PEM_read_DHparams BORINGSSL_PREFIX %+ _PEM_read_DHparams %xdefine PEM_read_DSAPrivateKey BORINGSSL_PREFIX %+ _PEM_read_DSAPrivateKey @@ -4987,6 +5047,7 @@ %xdefine PKCS12_get_key_and_certs BORINGSSL_PREFIX %+ _PKCS12_get_key_and_certs %xdefine PKCS12_parse BORINGSSL_PREFIX %+ _PKCS12_parse %xdefine PKCS12_verify_mac BORINGSSL_PREFIX %+ _PKCS12_verify_mac +%xdefine PKCS1_MGF1 BORINGSSL_PREFIX %+ _PKCS1_MGF1 %xdefine PKCS5_PBKDF2_HMAC BORINGSSL_PREFIX %+ _PKCS5_PBKDF2_HMAC %xdefine PKCS5_PBKDF2_HMAC_SHA1 BORINGSSL_PREFIX %+ _PKCS5_PBKDF2_HMAC_SHA1 %xdefine PKCS5_pbe2_decrypt_init BORINGSSL_PREFIX %+ _PKCS5_pbe2_decrypt_init @@ -5027,12 +5088,6 @@ %xdefine POLICY_MAPPING_free BORINGSSL_PREFIX %+ _POLICY_MAPPING_free %xdefine POLICY_MAPPING_it BORINGSSL_PREFIX %+ _POLICY_MAPPING_it %xdefine POLICY_MAPPING_new BORINGSSL_PREFIX %+ _POLICY_MAPPING_new -%xdefine PROXY_CERT_INFO_EXTENSION_free BORINGSSL_PREFIX %+ _PROXY_CERT_INFO_EXTENSION_free -%xdefine PROXY_CERT_INFO_EXTENSION_it BORINGSSL_PREFIX %+ _PROXY_CERT_INFO_EXTENSION_it -%xdefine PROXY_CERT_INFO_EXTENSION_new BORINGSSL_PREFIX %+ _PROXY_CERT_INFO_EXTENSION_new -%xdefine PROXY_POLICY_free BORINGSSL_PREFIX %+ _PROXY_POLICY_free -%xdefine PROXY_POLICY_it BORINGSSL_PREFIX %+ _PROXY_POLICY_it -%xdefine PROXY_POLICY_new BORINGSSL_PREFIX %+ _PROXY_POLICY_new %xdefine RAND_OpenSSL BORINGSSL_PREFIX %+ _RAND_OpenSSL %xdefine RAND_SSLeay BORINGSSL_PREFIX %+ _RAND_SSLeay %xdefine RAND_add BORINGSSL_PREFIX %+ _RAND_add @@ -5092,11 +5147,9 @@ %xdefine RSA_padding_add_PKCS1_OAEP_mgf1 BORINGSSL_PREFIX %+ _RSA_padding_add_PKCS1_OAEP_mgf1 %xdefine RSA_padding_add_PKCS1_PSS_mgf1 BORINGSSL_PREFIX %+ _RSA_padding_add_PKCS1_PSS_mgf1 %xdefine RSA_padding_add_PKCS1_type_1 BORINGSSL_PREFIX %+ _RSA_padding_add_PKCS1_type_1 -%xdefine RSA_padding_add_PKCS1_type_2 BORINGSSL_PREFIX %+ _RSA_padding_add_PKCS1_type_2 %xdefine RSA_padding_add_none BORINGSSL_PREFIX %+ _RSA_padding_add_none %xdefine RSA_padding_check_PKCS1_OAEP_mgf1 BORINGSSL_PREFIX %+ _RSA_padding_check_PKCS1_OAEP_mgf1 %xdefine RSA_padding_check_PKCS1_type_1 BORINGSSL_PREFIX %+ _RSA_padding_check_PKCS1_type_1 -%xdefine RSA_padding_check_PKCS1_type_2 BORINGSSL_PREFIX %+ _RSA_padding_check_PKCS1_type_2 %xdefine RSA_parse_private_key BORINGSSL_PREFIX %+ _RSA_parse_private_key %xdefine RSA_parse_public_key BORINGSSL_PREFIX %+ _RSA_parse_public_key %xdefine RSA_print BORINGSSL_PREFIX %+ _RSA_print @@ -5104,7 +5157,6 @@ %xdefine RSA_private_encrypt BORINGSSL_PREFIX %+ _RSA_private_encrypt %xdefine RSA_private_key_from_bytes BORINGSSL_PREFIX %+ _RSA_private_key_from_bytes %xdefine RSA_private_key_to_bytes BORINGSSL_PREFIX %+ _RSA_private_key_to_bytes -%xdefine RSA_private_transform BORINGSSL_PREFIX %+ _RSA_private_transform %xdefine RSA_public_decrypt BORINGSSL_PREFIX %+ _RSA_public_decrypt %xdefine RSA_public_encrypt BORINGSSL_PREFIX %+ _RSA_public_encrypt %xdefine RSA_public_key_from_bytes BORINGSSL_PREFIX %+ _RSA_public_key_from_bytes @@ -5169,7 +5221,6 @@ %xdefine SSL_CIPHER_get_name BORINGSSL_PREFIX %+ _SSL_CIPHER_get_name %xdefine SSL_CIPHER_get_prf_nid BORINGSSL_PREFIX %+ _SSL_CIPHER_get_prf_nid %xdefine SSL_CIPHER_get_protocol_id BORINGSSL_PREFIX %+ _SSL_CIPHER_get_protocol_id -%xdefine SSL_CIPHER_get_rfc_name BORINGSSL_PREFIX %+ _SSL_CIPHER_get_rfc_name %xdefine SSL_CIPHER_get_value BORINGSSL_PREFIX %+ _SSL_CIPHER_get_value %xdefine SSL_CIPHER_get_version BORINGSSL_PREFIX %+ _SSL_CIPHER_get_version %xdefine SSL_CIPHER_is_aead BORINGSSL_PREFIX %+ _SSL_CIPHER_is_aead @@ -5657,6 +5708,7 @@ %xdefine SSL_used_hello_retry_request BORINGSSL_PREFIX %+ _SSL_used_hello_retry_request %xdefine SSL_version BORINGSSL_PREFIX %+ _SSL_version %xdefine SSL_want BORINGSSL_PREFIX %+ _SSL_want +%xdefine SSL_was_key_usage_invalid BORINGSSL_PREFIX %+ _SSL_was_key_usage_invalid %xdefine SSL_write BORINGSSL_PREFIX %+ _SSL_write %xdefine SSLeay BORINGSSL_PREFIX %+ _SSLeay %xdefine SSLeay_version BORINGSSL_PREFIX %+ _SSLeay_version @@ -5678,6 +5730,7 @@ %xdefine TLSv1_server_method BORINGSSL_PREFIX %+ _TLSv1_server_method %xdefine TRUST_TOKEN_CLIENT_add_key BORINGSSL_PREFIX %+ _TRUST_TOKEN_CLIENT_add_key %xdefine TRUST_TOKEN_CLIENT_begin_issuance BORINGSSL_PREFIX %+ _TRUST_TOKEN_CLIENT_begin_issuance +%xdefine TRUST_TOKEN_CLIENT_begin_issuance_over_message BORINGSSL_PREFIX %+ _TRUST_TOKEN_CLIENT_begin_issuance_over_message %xdefine TRUST_TOKEN_CLIENT_begin_redemption BORINGSSL_PREFIX %+ _TRUST_TOKEN_CLIENT_begin_redemption %xdefine TRUST_TOKEN_CLIENT_finish_issuance BORINGSSL_PREFIX %+ _TRUST_TOKEN_CLIENT_finish_issuance %xdefine TRUST_TOKEN_CLIENT_finish_redemption BORINGSSL_PREFIX %+ _TRUST_TOKEN_CLIENT_finish_redemption @@ -5689,7 +5742,7 @@ %xdefine TRUST_TOKEN_ISSUER_issue BORINGSSL_PREFIX %+ _TRUST_TOKEN_ISSUER_issue %xdefine TRUST_TOKEN_ISSUER_new BORINGSSL_PREFIX %+ _TRUST_TOKEN_ISSUER_new %xdefine TRUST_TOKEN_ISSUER_redeem BORINGSSL_PREFIX %+ _TRUST_TOKEN_ISSUER_redeem -%xdefine TRUST_TOKEN_ISSUER_redeem_raw BORINGSSL_PREFIX %+ _TRUST_TOKEN_ISSUER_redeem_raw +%xdefine TRUST_TOKEN_ISSUER_redeem_over_message BORINGSSL_PREFIX %+ _TRUST_TOKEN_ISSUER_redeem_over_message %xdefine TRUST_TOKEN_ISSUER_set_metadata_key BORINGSSL_PREFIX %+ _TRUST_TOKEN_ISSUER_set_metadata_key %xdefine TRUST_TOKEN_ISSUER_set_srr_key BORINGSSL_PREFIX %+ _TRUST_TOKEN_ISSUER_set_srr_key %xdefine TRUST_TOKEN_PRETOKEN_free BORINGSSL_PREFIX %+ _TRUST_TOKEN_PRETOKEN_free @@ -5701,6 +5754,8 @@ %xdefine TRUST_TOKEN_free BORINGSSL_PREFIX %+ _TRUST_TOKEN_free %xdefine TRUST_TOKEN_generate_key BORINGSSL_PREFIX %+ _TRUST_TOKEN_generate_key %xdefine TRUST_TOKEN_new BORINGSSL_PREFIX %+ _TRUST_TOKEN_new +%xdefine TRUST_TOKEN_pst_v1_pmb BORINGSSL_PREFIX %+ _TRUST_TOKEN_pst_v1_pmb +%xdefine TRUST_TOKEN_pst_v1_voprf BORINGSSL_PREFIX %+ _TRUST_TOKEN_pst_v1_voprf %xdefine USERNOTICE_free BORINGSSL_PREFIX %+ _USERNOTICE_free %xdefine USERNOTICE_it BORINGSSL_PREFIX %+ _USERNOTICE_it %xdefine USERNOTICE_new BORINGSSL_PREFIX %+ _USERNOTICE_new @@ -5730,21 +5785,17 @@ %xdefine X509V3_add_standard_extensions BORINGSSL_PREFIX %+ _X509V3_add_standard_extensions %xdefine X509V3_add_value BORINGSSL_PREFIX %+ _X509V3_add_value %xdefine X509V3_add_value_bool BORINGSSL_PREFIX %+ _X509V3_add_value_bool -%xdefine X509V3_add_value_bool_nf BORINGSSL_PREFIX %+ _X509V3_add_value_bool_nf %xdefine X509V3_add_value_int BORINGSSL_PREFIX %+ _X509V3_add_value_int -%xdefine X509V3_add_value_uchar BORINGSSL_PREFIX %+ _X509V3_add_value_uchar +%xdefine X509V3_bool_from_string BORINGSSL_PREFIX %+ _X509V3_bool_from_string %xdefine X509V3_conf_free BORINGSSL_PREFIX %+ _X509V3_conf_free %xdefine X509V3_extensions_print BORINGSSL_PREFIX %+ _X509V3_extensions_print %xdefine X509V3_get_d2i BORINGSSL_PREFIX %+ _X509V3_get_d2i %xdefine X509V3_get_section BORINGSSL_PREFIX %+ _X509V3_get_section -%xdefine X509V3_get_string BORINGSSL_PREFIX %+ _X509V3_get_string %xdefine X509V3_get_value_bool BORINGSSL_PREFIX %+ _X509V3_get_value_bool %xdefine X509V3_get_value_int BORINGSSL_PREFIX %+ _X509V3_get_value_int %xdefine X509V3_parse_list BORINGSSL_PREFIX %+ _X509V3_parse_list -%xdefine X509V3_section_free BORINGSSL_PREFIX %+ _X509V3_section_free %xdefine X509V3_set_ctx BORINGSSL_PREFIX %+ _X509V3_set_ctx %xdefine X509V3_set_nconf BORINGSSL_PREFIX %+ _X509V3_set_nconf -%xdefine X509V3_string_free BORINGSSL_PREFIX %+ _X509V3_string_free %xdefine X509_ALGOR_cmp BORINGSSL_PREFIX %+ _X509_ALGOR_cmp %xdefine X509_ALGOR_dup BORINGSSL_PREFIX %+ _X509_ALGOR_dup %xdefine X509_ALGOR_free BORINGSSL_PREFIX %+ _X509_ALGOR_free @@ -5891,7 +5942,6 @@ %xdefine X509_OBJECT_up_ref_count BORINGSSL_PREFIX %+ _X509_OBJECT_up_ref_count %xdefine X509_PKEY_free BORINGSSL_PREFIX %+ _X509_PKEY_free %xdefine X509_PKEY_new BORINGSSL_PREFIX %+ _X509_PKEY_new -%xdefine X509_POLICY_NODE_print BORINGSSL_PREFIX %+ _X509_POLICY_NODE_print %xdefine X509_PUBKEY_free BORINGSSL_PREFIX %+ _X509_PUBKEY_free %xdefine X509_PUBKEY_get BORINGSSL_PREFIX %+ _X509_PUBKEY_get %xdefine X509_PUBKEY_get0_param BORINGSSL_PREFIX %+ _X509_PUBKEY_get0_param @@ -6006,6 +6056,7 @@ %xdefine X509_STORE_CTX_set_flags BORINGSSL_PREFIX %+ _X509_STORE_CTX_set_flags %xdefine X509_STORE_CTX_set_purpose BORINGSSL_PREFIX %+ _X509_STORE_CTX_set_purpose %xdefine X509_STORE_CTX_set_time BORINGSSL_PREFIX %+ _X509_STORE_CTX_set_time +%xdefine X509_STORE_CTX_set_time_posix BORINGSSL_PREFIX %+ _X509_STORE_CTX_set_time_posix %xdefine X509_STORE_CTX_set_trust BORINGSSL_PREFIX %+ _X509_STORE_CTX_set_trust %xdefine X509_STORE_CTX_set_verify_cb BORINGSSL_PREFIX %+ _X509_STORE_CTX_set_verify_cb %xdefine X509_STORE_CTX_trusted_stack BORINGSSL_PREFIX %+ _X509_STORE_CTX_trusted_stack @@ -6063,14 +6114,11 @@ %xdefine X509_VAL_it BORINGSSL_PREFIX %+ _X509_VAL_it %xdefine X509_VAL_new BORINGSSL_PREFIX %+ _X509_VAL_new %xdefine X509_VERIFY_PARAM_add0_policy BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_add0_policy -%xdefine X509_VERIFY_PARAM_add0_table BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_add0_table %xdefine X509_VERIFY_PARAM_add1_host BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_add1_host %xdefine X509_VERIFY_PARAM_clear_flags BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_clear_flags %xdefine X509_VERIFY_PARAM_free BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_free -%xdefine X509_VERIFY_PARAM_get0 BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_get0 %xdefine X509_VERIFY_PARAM_get0_name BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_get0_name %xdefine X509_VERIFY_PARAM_get0_peername BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_get0_peername -%xdefine X509_VERIFY_PARAM_get_count BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_get_count %xdefine X509_VERIFY_PARAM_get_depth BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_get_depth %xdefine X509_VERIFY_PARAM_get_flags BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_get_flags %xdefine X509_VERIFY_PARAM_inherit BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_inherit @@ -6088,8 +6136,8 @@ %xdefine X509_VERIFY_PARAM_set_hostflags BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_set_hostflags %xdefine X509_VERIFY_PARAM_set_purpose BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_set_purpose %xdefine X509_VERIFY_PARAM_set_time BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_set_time +%xdefine X509_VERIFY_PARAM_set_time_posix BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_set_time_posix %xdefine X509_VERIFY_PARAM_set_trust BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_set_trust -%xdefine X509_VERIFY_PARAM_table_cleanup BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_table_cleanup %xdefine X509_add1_ext_i2d BORINGSSL_PREFIX %+ _X509_add1_ext_i2d %xdefine X509_add1_reject_object BORINGSSL_PREFIX %+ _X509_add1_reject_object %xdefine X509_add1_trust_object BORINGSSL_PREFIX %+ _X509_add1_trust_object @@ -6110,6 +6158,7 @@ %xdefine X509_cmp BORINGSSL_PREFIX %+ _X509_cmp %xdefine X509_cmp_current_time BORINGSSL_PREFIX %+ _X509_cmp_current_time %xdefine X509_cmp_time BORINGSSL_PREFIX %+ _X509_cmp_time +%xdefine X509_cmp_time_posix BORINGSSL_PREFIX %+ _X509_cmp_time_posix %xdefine X509_delete_ext BORINGSSL_PREFIX %+ _X509_delete_ext %xdefine X509_digest BORINGSSL_PREFIX %+ _X509_digest %xdefine X509_dup BORINGSSL_PREFIX %+ _X509_dup @@ -6173,7 +6222,6 @@ %xdefine X509_new BORINGSSL_PREFIX %+ _X509_new %xdefine X509_parse_from_buffer BORINGSSL_PREFIX %+ _X509_parse_from_buffer %xdefine X509_policy_check BORINGSSL_PREFIX %+ _X509_policy_check -%xdefine X509_policy_tree_free BORINGSSL_PREFIX %+ _X509_policy_tree_free %xdefine X509_print BORINGSSL_PREFIX %+ _X509_print %xdefine X509_print_ex BORINGSSL_PREFIX %+ _X509_print_ex %xdefine X509_print_ex_fp BORINGSSL_PREFIX %+ _X509_print_ex_fp @@ -6242,6 +6290,8 @@ %xdefine aes256gcmsiv_enc_msg_x8 BORINGSSL_PREFIX %+ _aes256gcmsiv_enc_msg_x8 %xdefine aes256gcmsiv_kdf BORINGSSL_PREFIX %+ _aes256gcmsiv_kdf %xdefine aes_ctr_set_key BORINGSSL_PREFIX %+ _aes_ctr_set_key +%xdefine aes_gcm_dec_kernel BORINGSSL_PREFIX %+ _aes_gcm_dec_kernel +%xdefine aes_gcm_enc_kernel BORINGSSL_PREFIX %+ _aes_gcm_enc_kernel %xdefine aes_hw_cbc_encrypt BORINGSSL_PREFIX %+ _aes_hw_cbc_encrypt %xdefine aes_hw_ctr32_encrypt_blocks BORINGSSL_PREFIX %+ _aes_hw_ctr32_encrypt_blocks %xdefine aes_hw_decrypt BORINGSSL_PREFIX %+ _aes_hw_decrypt @@ -6267,15 +6317,16 @@ %xdefine asn1_enc_init BORINGSSL_PREFIX %+ _asn1_enc_init %xdefine asn1_enc_restore BORINGSSL_PREFIX %+ _asn1_enc_restore %xdefine asn1_enc_save BORINGSSL_PREFIX %+ _asn1_enc_save +%xdefine asn1_encoding_clear BORINGSSL_PREFIX %+ _asn1_encoding_clear %xdefine asn1_generalizedtime_to_tm BORINGSSL_PREFIX %+ _asn1_generalizedtime_to_tm %xdefine asn1_get_choice_selector BORINGSSL_PREFIX %+ _asn1_get_choice_selector %xdefine asn1_get_field_ptr BORINGSSL_PREFIX %+ _asn1_get_field_ptr %xdefine asn1_get_string_table_for_testing BORINGSSL_PREFIX %+ _asn1_get_string_table_for_testing %xdefine asn1_is_printable BORINGSSL_PREFIX %+ _asn1_is_printable -%xdefine asn1_item_combine_free BORINGSSL_PREFIX %+ _asn1_item_combine_free %xdefine asn1_refcount_dec_and_test_zero BORINGSSL_PREFIX %+ _asn1_refcount_dec_and_test_zero %xdefine asn1_refcount_set_one BORINGSSL_PREFIX %+ _asn1_refcount_set_one %xdefine asn1_set_choice_selector BORINGSSL_PREFIX %+ _asn1_set_choice_selector +%xdefine asn1_type_cleanup BORINGSSL_PREFIX %+ _asn1_type_cleanup %xdefine asn1_type_value_as_pointer BORINGSSL_PREFIX %+ _asn1_type_value_as_pointer %xdefine asn1_utctime_to_tm BORINGSSL_PREFIX %+ _asn1_utctime_to_tm %xdefine beeu_mod_inverse_vartime BORINGSSL_PREFIX %+ _beeu_mod_inverse_vartime @@ -6286,6 +6337,7 @@ %xdefine bio_socket_nbio BORINGSSL_PREFIX %+ _bio_socket_nbio %xdefine bn_abs_sub_consttime BORINGSSL_PREFIX %+ _bn_abs_sub_consttime %xdefine bn_add_words BORINGSSL_PREFIX %+ _bn_add_words +%xdefine bn_assert_fits_in_bytes BORINGSSL_PREFIX %+ _bn_assert_fits_in_bytes %xdefine bn_big_endian_to_words BORINGSSL_PREFIX %+ _bn_big_endian_to_words %xdefine bn_copy_words BORINGSSL_PREFIX %+ _bn_copy_words %xdefine bn_div_consttime BORINGSSL_PREFIX %+ _bn_div_consttime @@ -6448,8 +6500,6 @@ %xdefine d2i_PKCS8_fp BORINGSSL_PREFIX %+ _d2i_PKCS8_fp %xdefine d2i_POLICYINFO BORINGSSL_PREFIX %+ _d2i_POLICYINFO %xdefine d2i_POLICYQUALINFO BORINGSSL_PREFIX %+ _d2i_POLICYQUALINFO -%xdefine d2i_PROXY_CERT_INFO_EXTENSION BORINGSSL_PREFIX %+ _d2i_PROXY_CERT_INFO_EXTENSION -%xdefine d2i_PROXY_POLICY BORINGSSL_PREFIX %+ _d2i_PROXY_POLICY %xdefine d2i_PUBKEY BORINGSSL_PREFIX %+ _d2i_PUBKEY %xdefine d2i_PUBKEY_bio BORINGSSL_PREFIX %+ _d2i_PUBKEY_bio %xdefine d2i_PUBKEY_fp BORINGSSL_PREFIX %+ _d2i_PUBKEY_fp @@ -6496,11 +6546,13 @@ %xdefine d2i_X509_fp BORINGSSL_PREFIX %+ _d2i_X509_fp %xdefine dh_compute_key_padded_no_self_test BORINGSSL_PREFIX %+ _dh_compute_key_padded_no_self_test %xdefine dsa_asn1_meth BORINGSSL_PREFIX %+ _dsa_asn1_meth -%xdefine dsa_check_parameters BORINGSSL_PREFIX %+ _dsa_check_parameters +%xdefine dsa_check_key BORINGSSL_PREFIX %+ _dsa_check_key %xdefine ec_GFp_mont_add BORINGSSL_PREFIX %+ _ec_GFp_mont_add %xdefine ec_GFp_mont_dbl BORINGSSL_PREFIX %+ _ec_GFp_mont_dbl +%xdefine ec_GFp_mont_felem_exp BORINGSSL_PREFIX %+ _ec_GFp_mont_felem_exp %xdefine ec_GFp_mont_felem_from_bytes BORINGSSL_PREFIX %+ _ec_GFp_mont_felem_from_bytes %xdefine ec_GFp_mont_felem_mul BORINGSSL_PREFIX %+ _ec_GFp_mont_felem_mul +%xdefine ec_GFp_mont_felem_reduce BORINGSSL_PREFIX %+ _ec_GFp_mont_felem_reduce %xdefine ec_GFp_mont_felem_sqr BORINGSSL_PREFIX %+ _ec_GFp_mont_felem_sqr %xdefine ec_GFp_mont_felem_to_bytes BORINGSSL_PREFIX %+ _ec_GFp_mont_felem_to_bytes %xdefine ec_GFp_mont_group_finish BORINGSSL_PREFIX %+ _ec_GFp_mont_group_finish @@ -6547,12 +6599,16 @@ %xdefine ec_get_x_coordinate_as_bytes BORINGSSL_PREFIX %+ _ec_get_x_coordinate_as_bytes %xdefine ec_get_x_coordinate_as_scalar BORINGSSL_PREFIX %+ _ec_get_x_coordinate_as_scalar %xdefine ec_group_new BORINGSSL_PREFIX %+ _ec_group_new +%xdefine ec_hash_to_curve_p256_xmd_sha256_sswu BORINGSSL_PREFIX %+ _ec_hash_to_curve_p256_xmd_sha256_sswu +%xdefine ec_hash_to_curve_p384_xmd_sha384_sswu BORINGSSL_PREFIX %+ _ec_hash_to_curve_p384_xmd_sha384_sswu %xdefine ec_hash_to_curve_p384_xmd_sha512_sswu_draft07 BORINGSSL_PREFIX %+ _ec_hash_to_curve_p384_xmd_sha512_sswu_draft07 +%xdefine ec_hash_to_scalar_p384_xmd_sha384 BORINGSSL_PREFIX %+ _ec_hash_to_scalar_p384_xmd_sha384 %xdefine ec_hash_to_scalar_p384_xmd_sha512_draft07 BORINGSSL_PREFIX %+ _ec_hash_to_scalar_p384_xmd_sha512_draft07 %xdefine ec_init_precomp BORINGSSL_PREFIX %+ _ec_init_precomp %xdefine ec_jacobian_to_affine BORINGSSL_PREFIX %+ _ec_jacobian_to_affine %xdefine ec_jacobian_to_affine_batch BORINGSSL_PREFIX %+ _ec_jacobian_to_affine_batch %xdefine ec_pkey_meth BORINGSSL_PREFIX %+ _ec_pkey_meth +%xdefine ec_point_byte_len BORINGSSL_PREFIX %+ _ec_point_byte_len %xdefine ec_point_from_uncompressed BORINGSSL_PREFIX %+ _ec_point_from_uncompressed %xdefine ec_point_mul_no_self_test BORINGSSL_PREFIX %+ _ec_point_mul_no_self_test %xdefine ec_point_mul_scalar BORINGSSL_PREFIX %+ _ec_point_mul_scalar @@ -6706,8 +6762,6 @@ %xdefine i2d_PKCS8_fp BORINGSSL_PREFIX %+ _i2d_PKCS8_fp %xdefine i2d_POLICYINFO BORINGSSL_PREFIX %+ _i2d_POLICYINFO %xdefine i2d_POLICYQUALINFO BORINGSSL_PREFIX %+ _i2d_POLICYQUALINFO -%xdefine i2d_PROXY_CERT_INFO_EXTENSION BORINGSSL_PREFIX %+ _i2d_PROXY_CERT_INFO_EXTENSION -%xdefine i2d_PROXY_POLICY BORINGSSL_PREFIX %+ _i2d_PROXY_POLICY %xdefine i2d_PUBKEY BORINGSSL_PREFIX %+ _i2d_PUBKEY %xdefine i2d_PUBKEY_bio BORINGSSL_PREFIX %+ _i2d_PUBKEY_bio %xdefine i2d_PUBKEY_fp BORINGSSL_PREFIX %+ _i2d_PUBKEY_fp @@ -6769,8 +6823,6 @@ %xdefine kOpenSSLReasonStringData BORINGSSL_PREFIX %+ _kOpenSSLReasonStringData %xdefine kOpenSSLReasonValues BORINGSSL_PREFIX %+ _kOpenSSLReasonValues %xdefine kOpenSSLReasonValuesLen BORINGSSL_PREFIX %+ _kOpenSSLReasonValuesLen -%xdefine level_add_node BORINGSSL_PREFIX %+ _level_add_node -%xdefine level_find_node BORINGSSL_PREFIX %+ _level_find_node %xdefine md4_block_data_order BORINGSSL_PREFIX %+ _md4_block_data_order %xdefine md5_block_asm_data_order BORINGSSL_PREFIX %+ _md5_block_asm_data_order %xdefine o2i_ECPublicKey BORINGSSL_PREFIX %+ _o2i_ECPublicKey @@ -6798,24 +6850,25 @@ %xdefine pmbtoken_exp2_read BORINGSSL_PREFIX %+ _pmbtoken_exp2_read %xdefine pmbtoken_exp2_sign BORINGSSL_PREFIX %+ _pmbtoken_exp2_sign %xdefine pmbtoken_exp2_unblind BORINGSSL_PREFIX %+ _pmbtoken_exp2_unblind -%xdefine policy_cache_find_data BORINGSSL_PREFIX %+ _policy_cache_find_data -%xdefine policy_cache_free BORINGSSL_PREFIX %+ _policy_cache_free -%xdefine policy_cache_set BORINGSSL_PREFIX %+ _policy_cache_set -%xdefine policy_cache_set_mapping BORINGSSL_PREFIX %+ _policy_cache_set_mapping -%xdefine policy_data_free BORINGSSL_PREFIX %+ _policy_data_free -%xdefine policy_data_new BORINGSSL_PREFIX %+ _policy_data_new -%xdefine policy_node_cmp_new BORINGSSL_PREFIX %+ _policy_node_cmp_new -%xdefine policy_node_free BORINGSSL_PREFIX %+ _policy_node_free -%xdefine policy_node_match BORINGSSL_PREFIX %+ _policy_node_match +%xdefine pmbtoken_pst1_blind BORINGSSL_PREFIX %+ _pmbtoken_pst1_blind +%xdefine pmbtoken_pst1_client_key_from_bytes BORINGSSL_PREFIX %+ _pmbtoken_pst1_client_key_from_bytes +%xdefine pmbtoken_pst1_derive_key_from_secret BORINGSSL_PREFIX %+ _pmbtoken_pst1_derive_key_from_secret +%xdefine pmbtoken_pst1_generate_key BORINGSSL_PREFIX %+ _pmbtoken_pst1_generate_key +%xdefine pmbtoken_pst1_get_h_for_testing BORINGSSL_PREFIX %+ _pmbtoken_pst1_get_h_for_testing +%xdefine pmbtoken_pst1_issuer_key_from_bytes BORINGSSL_PREFIX %+ _pmbtoken_pst1_issuer_key_from_bytes +%xdefine pmbtoken_pst1_read BORINGSSL_PREFIX %+ _pmbtoken_pst1_read +%xdefine pmbtoken_pst1_sign BORINGSSL_PREFIX %+ _pmbtoken_pst1_sign +%xdefine pmbtoken_pst1_unblind BORINGSSL_PREFIX %+ _pmbtoken_pst1_unblind %xdefine poly_Rq_mul BORINGSSL_PREFIX %+ _poly_Rq_mul %xdefine rand_fork_unsafe_buffering_enabled BORINGSSL_PREFIX %+ _rand_fork_unsafe_buffering_enabled %xdefine rsa_asn1_meth BORINGSSL_PREFIX %+ _rsa_asn1_meth %xdefine rsa_check_public_key BORINGSSL_PREFIX %+ _rsa_check_public_key -%xdefine rsa_default_decrypt BORINGSSL_PREFIX %+ _rsa_default_decrypt %xdefine rsa_default_private_transform BORINGSSL_PREFIX %+ _rsa_default_private_transform %xdefine rsa_default_sign_raw BORINGSSL_PREFIX %+ _rsa_default_sign_raw %xdefine rsa_default_size BORINGSSL_PREFIX %+ _rsa_default_size %xdefine rsa_pkey_meth BORINGSSL_PREFIX %+ _rsa_pkey_meth +%xdefine rsa_private_transform BORINGSSL_PREFIX %+ _rsa_private_transform +%xdefine rsa_private_transform_no_self_test BORINGSSL_PREFIX %+ _rsa_private_transform_no_self_test %xdefine rsa_sign_no_self_test BORINGSSL_PREFIX %+ _rsa_sign_no_self_test %xdefine rsa_verify_no_self_test BORINGSSL_PREFIX %+ _rsa_verify_no_self_test %xdefine rsa_verify_raw_no_self_test BORINGSSL_PREFIX %+ _rsa_verify_raw_no_self_test @@ -6870,6 +6923,7 @@ %xdefine sk_X509_value BORINGSSL_PREFIX %+ _sk_X509_value %xdefine sk_deep_copy BORINGSSL_PREFIX %+ _sk_deep_copy %xdefine sk_delete BORINGSSL_PREFIX %+ _sk_delete +%xdefine sk_delete_if BORINGSSL_PREFIX %+ _sk_delete_if %xdefine sk_delete_ptr BORINGSSL_PREFIX %+ _sk_delete_ptr %xdefine sk_dup BORINGSSL_PREFIX %+ _sk_dup %xdefine sk_find BORINGSSL_PREFIX %+ _sk_find @@ -6889,7 +6943,6 @@ %xdefine sk_sort BORINGSSL_PREFIX %+ _sk_sort %xdefine sk_value BORINGSSL_PREFIX %+ _sk_value %xdefine sk_zero BORINGSSL_PREFIX %+ _sk_zero -%xdefine tree_find_sk BORINGSSL_PREFIX %+ _tree_find_sk %xdefine v2i_GENERAL_NAME BORINGSSL_PREFIX %+ _v2i_GENERAL_NAME %xdefine v2i_GENERAL_NAMES BORINGSSL_PREFIX %+ _v2i_GENERAL_NAMES %xdefine v2i_GENERAL_NAME_ex BORINGSSL_PREFIX %+ _v2i_GENERAL_NAME_ex @@ -6913,7 +6966,6 @@ %xdefine v3_nscert BORINGSSL_PREFIX %+ _v3_nscert %xdefine v3_ocsp_accresp BORINGSSL_PREFIX %+ _v3_ocsp_accresp %xdefine v3_ocsp_nocheck BORINGSSL_PREFIX %+ _v3_ocsp_nocheck -%xdefine v3_pci BORINGSSL_PREFIX %+ _v3_pci %xdefine v3_policy_constraints BORINGSSL_PREFIX %+ _v3_policy_constraints %xdefine v3_policy_mappings BORINGSSL_PREFIX %+ _v3_policy_mappings %xdefine v3_sinfo BORINGSSL_PREFIX %+ _v3_sinfo @@ -6926,6 +6978,14 @@ %xdefine voprf_exp2_read BORINGSSL_PREFIX %+ _voprf_exp2_read %xdefine voprf_exp2_sign BORINGSSL_PREFIX %+ _voprf_exp2_sign %xdefine voprf_exp2_unblind BORINGSSL_PREFIX %+ _voprf_exp2_unblind +%xdefine voprf_pst1_blind BORINGSSL_PREFIX %+ _voprf_pst1_blind +%xdefine voprf_pst1_client_key_from_bytes BORINGSSL_PREFIX %+ _voprf_pst1_client_key_from_bytes +%xdefine voprf_pst1_derive_key_from_secret BORINGSSL_PREFIX %+ _voprf_pst1_derive_key_from_secret +%xdefine voprf_pst1_generate_key BORINGSSL_PREFIX %+ _voprf_pst1_generate_key +%xdefine voprf_pst1_issuer_key_from_bytes BORINGSSL_PREFIX %+ _voprf_pst1_issuer_key_from_bytes +%xdefine voprf_pst1_read BORINGSSL_PREFIX %+ _voprf_pst1_read +%xdefine voprf_pst1_sign BORINGSSL_PREFIX %+ _voprf_pst1_sign +%xdefine voprf_pst1_unblind BORINGSSL_PREFIX %+ _voprf_pst1_unblind %xdefine vpaes_cbc_encrypt BORINGSSL_PREFIX %+ _vpaes_cbc_encrypt %xdefine vpaes_ctr32_encrypt_blocks BORINGSSL_PREFIX %+ _vpaes_ctr32_encrypt_blocks %xdefine vpaes_decrypt BORINGSSL_PREFIX %+ _vpaes_decrypt @@ -6954,7 +7014,7 @@ %xdefine x509v3_a2i_ipadd BORINGSSL_PREFIX %+ _x509v3_a2i_ipadd %xdefine x509v3_bytes_to_hex BORINGSSL_PREFIX %+ _x509v3_bytes_to_hex %xdefine x509v3_cache_extensions BORINGSSL_PREFIX %+ _x509v3_cache_extensions +%xdefine x509v3_conf_name_matches BORINGSSL_PREFIX %+ _x509v3_conf_name_matches %xdefine x509v3_hex_to_bytes BORINGSSL_PREFIX %+ _x509v3_hex_to_bytes %xdefine x509v3_looks_like_dns_name BORINGSSL_PREFIX %+ _x509v3_looks_like_dns_name -%xdefine x509v3_name_cmp BORINGSSL_PREFIX %+ _x509v3_name_cmp %endif diff --git a/Sources/CNIOBoringSSL/ssl/bio_ssl.cc b/Sources/CNIOBoringSSL/ssl/bio_ssl.cc index 9c26b15c..a7fe5bac 100644 --- a/Sources/CNIOBoringSSL/ssl/bio_ssl.cc +++ b/Sources/CNIOBoringSSL/ssl/bio_ssl.cc @@ -109,7 +109,7 @@ static long ssl_ctrl(BIO *bio, int cmd, long num, void *ptr) { // |bio->next_bio| with |ssl|'s rbio here, and on |BIO_CTRL_PUSH|. We call // into the corresponding |BIO| directly. (We can implement the upstream // behavior if it ends up necessary.) - bio->shutdown = num; + bio->shutdown = static_cast(num); bio->ptr = ptr; bio->init = 1; return 1; @@ -118,7 +118,7 @@ static long ssl_ctrl(BIO *bio, int cmd, long num, void *ptr) { return bio->shutdown; case BIO_CTRL_SET_CLOSE: - bio->shutdown = num; + bio->shutdown = static_cast(num); return 1; case BIO_CTRL_WPENDING: diff --git a/Sources/CNIOBoringSSL/ssl/d1_both.cc b/Sources/CNIOBoringSSL/ssl/d1_both.cc index 01581fa1..fe1b68a1 100644 --- a/Sources/CNIOBoringSSL/ssl/d1_both.cc +++ b/Sources/CNIOBoringSSL/ssl/d1_both.cc @@ -163,7 +163,6 @@ static UniquePtr dtls1_hm_fragment_new( frag->data = (uint8_t *)OPENSSL_malloc(DTLS1_HM_HEADER_LENGTH + msg_hdr->msg_len); if (frag->data == NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return nullptr; } @@ -174,7 +173,6 @@ static UniquePtr dtls1_hm_fragment_new( !CBB_add_u24(cbb.get(), 0 /* frag_off */) || !CBB_add_u24(cbb.get(), msg_hdr->msg_len) || !CBB_finish(cbb.get(), NULL, NULL)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return nullptr; } @@ -188,7 +186,6 @@ static UniquePtr dtls1_hm_fragment_new( size_t bitmask_len = (msg_hdr->msg_len + 7) / 8; frag->reassembly = (uint8_t *)OPENSSL_malloc(bitmask_len); if (frag->reassembly == NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return nullptr; } OPENSSL_memset(frag->reassembly, 0, bitmask_len); @@ -682,6 +679,7 @@ static enum seal_result_t seal_next_message(SSL *ssl, uint8_t *out, // Assemble a fragment, to be sealed in-place. ScopedCBB cbb; + CBB child; uint8_t *frag = out + prefix; size_t max_frag = max_out - prefix, frag_len; if (!CBB_init_fixed(cbb.get(), frag, max_frag) || @@ -689,8 +687,8 @@ static enum seal_result_t seal_next_message(SSL *ssl, uint8_t *out, !CBB_add_u24(cbb.get(), hdr.msg_len) || !CBB_add_u16(cbb.get(), hdr.seq) || !CBB_add_u24(cbb.get(), ssl->d1->outgoing_offset) || - !CBB_add_u24(cbb.get(), todo) || - !CBB_add_bytes(cbb.get(), CBS_data(&body), todo) || + !CBB_add_u24_length_prefixed(cbb.get(), &child) || + !CBB_add_bytes(&child, CBS_data(&body), todo) || !CBB_finish(cbb.get(), NULL, &frag_len)) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); return seal_error; diff --git a/Sources/CNIOBoringSSL/ssl/encrypted_client_hello.cc b/Sources/CNIOBoringSSL/ssl/encrypted_client_hello.cc index 62a2f66f..e20566c7 100644 --- a/Sources/CNIOBoringSSL/ssl/encrypted_client_hello.cc +++ b/Sources/CNIOBoringSSL/ssl/encrypted_client_hello.cc @@ -334,8 +334,7 @@ static bool is_hex_component(Span in) { return false; } for (uint8_t b : in.subspan(2)) { - if (!('0' <= b && b <= '9') && !('a' <= b && b <= 'f') && - !('A' <= b && b <= 'F')) { + if (!OPENSSL_isxdigit(b)) { return false; } } @@ -387,8 +386,7 @@ bool ssl_is_valid_ech_public_name(Span public_name) { return false; } for (uint8_t c : component) { - if (!('a' <= c && c <= 'z') && !('A' <= c && c <= 'Z') && - !('0' <= c && c <= '9') && c != '-') { + if (!OPENSSL_isalnum(c) && c != '-') { return false; } } @@ -573,7 +571,6 @@ bool ECHServerConfig::SetupContext(EVP_HPKE_CTX *ctx, uint16_t kdf_id, sizeof(kInfoLabel) /* includes trailing NUL */) || !CBB_add_bytes(info_cbb.get(), ech_config_.raw.data(), ech_config_.raw.size())) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return false; } @@ -604,8 +601,8 @@ bool ssl_is_valid_ech_config_list(Span ech_config_list) { static bool select_ech_cipher_suite(const EVP_HPKE_KDF **out_kdf, const EVP_HPKE_AEAD **out_aead, - Span cipher_suites) { - const bool has_aes_hardware = EVP_has_aes_hardware(); + Span cipher_suites, + const bool has_aes_hardware) { const EVP_HPKE_AEAD *aead = nullptr; CBS cbs = cipher_suites; while (CBS_len(&cbs) != 0) { @@ -663,14 +660,16 @@ bool ssl_select_ech_config(SSL_HANDSHAKE *hs, Span out_enc, const EVP_HPKE_AEAD *aead; if (supported && // ech_config.kem_id == EVP_HPKE_DHKEM_X25519_HKDF_SHA256 && - select_ech_cipher_suite(&kdf, &aead, ech_config.cipher_suites)) { + select_ech_cipher_suite(&kdf, &aead, ech_config.cipher_suites, + hs->ssl->config->aes_hw_override + ? hs->ssl->config->aes_hw_override_value + : EVP_has_aes_hardware())) { ScopedCBB info; static const uint8_t kInfoLabel[] = "tls ech"; // includes trailing NUL if (!CBB_init(info.get(), sizeof(kInfoLabel) + ech_config.raw.size()) || !CBB_add_bytes(info.get(), kInfoLabel, sizeof(kInfoLabel)) || !CBB_add_bytes(info.get(), ech_config.raw.data(), ech_config.raw.size())) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return false; } @@ -718,9 +717,11 @@ static bool setup_ech_grease(SSL_HANDSHAKE *hs) { } const uint16_t kdf_id = EVP_HPKE_HKDF_SHA256; - const EVP_HPKE_AEAD *aead = EVP_has_aes_hardware() - ? EVP_hpke_aes_128_gcm() - : EVP_hpke_chacha20_poly1305(); + const bool has_aes_hw = hs->ssl->config->aes_hw_override + ? hs->ssl->config->aes_hw_override_value + : EVP_has_aes_hardware(); + const EVP_HPKE_AEAD *aead = + has_aes_hw ? EVP_hpke_aes_128_gcm() : EVP_hpke_chacha20_poly1305(); static_assert(ssl_grease_ech_config_id < sizeof(hs->grease_seed), "hs->grease_seed is too small"); uint8_t config_id = hs->grease_seed[ssl_grease_ech_config_id]; @@ -1038,7 +1039,6 @@ int SSL_ECH_KEYS_add(SSL_ECH_KEYS *configs, int is_retry_config, return 0; } if (!configs->configs.Push(std::move(parsed_config))) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } return 1; @@ -1061,14 +1061,12 @@ int SSL_ECH_KEYS_marshal_retry_configs(const SSL_ECH_KEYS *keys, uint8_t **out, CBB child; if (!CBB_init(cbb.get(), 128) || !CBB_add_u16_length_prefixed(cbb.get(), &child)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return false; } for (const auto &config : keys->configs) { if (config->is_retry_config() && !CBB_add_bytes(&child, config->ech_config().raw.data(), config->ech_config().raw.size())) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return false; } } diff --git a/Sources/CNIOBoringSSL/ssl/extensions.cc b/Sources/CNIOBoringSSL/ssl/extensions.cc index c41e02c7..1e647ee9 100644 --- a/Sources/CNIOBoringSSL/ssl/extensions.cc +++ b/Sources/CNIOBoringSSL/ssl/extensions.cc @@ -205,7 +205,14 @@ static bool tls1_check_duplicate_extensions(const CBS *cbs) { } static bool is_post_quantum_group(uint16_t id) { - return id == SSL_CURVE_CECPQ2; + switch (id) { + case SSL_CURVE_CECPQ2: + case SSL_CURVE_X25519KYBER768: + case SSL_CURVE_P256KYBER768: + return true; + default: + return false; + } } bool ssl_client_hello_init(const SSL *ssl, SSL_CLIENT_HELLO *out, @@ -340,8 +347,8 @@ bool tls1_get_shared_group(SSL_HANDSHAKE *hs, uint16_t *out_group_id) { for (uint16_t pref_group : pref) { for (uint16_t supp_group : supp) { if (pref_group == supp_group && - // CECPQ2(b) doesn't fit in the u8-length-prefixed ECPoint field in - // TLS 1.2 and below. + // Post-quantum key agreements don't fit in the u8-length-prefixed + // ECPoint field in TLS 1.2 and below. (ssl_protocol_version(ssl) >= TLS1_3_VERSION || !is_post_quantum_group(pref_group))) { *out_group_id = pref_group; @@ -1248,10 +1255,12 @@ static bool ext_npn_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, } } + // |orig_len| fits in |unsigned| because TLS extensions use 16-bit lengths. uint8_t *selected; uint8_t selected_len; if (ssl->ctx->next_proto_select_cb( - ssl, &selected, &selected_len, orig_contents, orig_len, + ssl, &selected, &selected_len, orig_contents, + static_cast(orig_len), ssl->ctx->next_proto_select_cb_arg) != SSL_TLSEXT_ERR_OK || !ssl->s3->next_proto_negotiated.CopyFrom( MakeConstSpan(selected, selected_len))) { @@ -1564,11 +1573,14 @@ bool ssl_negotiate_alpn(SSL_HANDSHAKE *hs, uint8_t *out_alert, return false; } + // |protocol_name_list| fits in |unsigned| because TLS extensions use 16-bit + // lengths. const uint8_t *selected; uint8_t selected_len; int ret = ssl->ctx->alpn_select_cb( ssl, &selected, &selected_len, CBS_data(&protocol_name_list), - CBS_len(&protocol_name_list), ssl->ctx->alpn_select_cb_arg); + static_cast(CBS_len(&protocol_name_list)), + ssl->ctx->alpn_select_cb_arg); // ALPN is required when QUIC is used. if (ssl->quic_method && (ret == SSL_TLSEXT_ERR_NOACK || ret == SSL_TLSEXT_ERR_ALERT_WARNING)) { @@ -2295,11 +2307,13 @@ bool ssl_setup_key_shares(SSL_HANDSHAKE *hs, uint16_t override_group_id) { group_id = groups[0]; - if (is_post_quantum_group(group_id) && groups.size() >= 2) { - // CECPQ2(b) is not sent as the only initial key share. We'll include the - // 2nd preference group too to avoid round-trips. - second_group_id = groups[1]; - assert(second_group_id != group_id); + // We'll try to include one post-quantum and one classical initial key + // share. + for (size_t i = 1; i < groups.size() && second_group_id == 0; i++) { + if (is_post_quantum_group(group_id) != is_post_quantum_group(groups[i])) { + second_group_id = groups[i]; + assert(second_group_id != group_id); + } } } @@ -2308,7 +2322,7 @@ bool ssl_setup_key_shares(SSL_HANDSHAKE *hs, uint16_t override_group_id) { if (!hs->key_shares[0] || // !CBB_add_u16(cbb.get(), group_id) || !CBB_add_u16_length_prefixed(cbb.get(), &key_exchange) || - !hs->key_shares[0]->Offer(&key_exchange)) { + !hs->key_shares[0]->Generate(&key_exchange)) { return false; } @@ -2317,7 +2331,7 @@ bool ssl_setup_key_shares(SSL_HANDSHAKE *hs, uint16_t override_group_id) { if (!hs->key_shares[1] || // !CBB_add_u16(cbb.get(), second_group_id) || !CBB_add_u16_length_prefixed(cbb.get(), &key_exchange) || - !hs->key_shares[1]->Offer(&key_exchange)) { + !hs->key_shares[1]->Generate(&key_exchange)) { return false; } } @@ -2349,10 +2363,10 @@ static bool ext_key_share_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out, bool ssl_ext_key_share_parse_serverhello(SSL_HANDSHAKE *hs, Array *out_secret, uint8_t *out_alert, CBS *contents) { - CBS peer_key; + CBS ciphertext; uint16_t group_id; if (!CBS_get_u16(contents, &group_id) || - !CBS_get_u16_length_prefixed(contents, &peer_key) || + !CBS_get_u16_length_prefixed(contents, &ciphertext) || CBS_len(contents) != 0) { OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); *out_alert = SSL_AD_DECODE_ERROR; @@ -2369,7 +2383,7 @@ bool ssl_ext_key_share_parse_serverhello(SSL_HANDSHAKE *hs, key_share = hs->key_shares[1].get(); } - if (!key_share->Finish(out_secret, out_alert, peer_key)) { + if (!key_share->Decap(out_secret, out_alert, ciphertext)) { *out_alert = SSL_AD_INTERNAL_ERROR; return false; } @@ -2434,13 +2448,13 @@ bool ssl_ext_key_share_parse_clienthello(SSL_HANDSHAKE *hs, bool *out_found, } bool ssl_ext_key_share_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { - CBB kse_bytes, public_key; + CBB entry, ciphertext; if (!CBB_add_u16(out, TLSEXT_TYPE_key_share) || - !CBB_add_u16_length_prefixed(out, &kse_bytes) || - !CBB_add_u16(&kse_bytes, hs->new_session->group_id) || - !CBB_add_u16_length_prefixed(&kse_bytes, &public_key) || - !CBB_add_bytes(&public_key, hs->ecdh_public_key.data(), - hs->ecdh_public_key.size()) || + !CBB_add_u16_length_prefixed(out, &entry) || + !CBB_add_u16(&entry, hs->new_session->group_id) || + !CBB_add_u16_length_prefixed(&entry, &ciphertext) || + !CBB_add_bytes(&ciphertext, hs->key_share_ciphertext.data(), + hs->key_share_ciphertext.size()) || !CBB_flush(out)) { return false; } @@ -3930,7 +3944,6 @@ static enum ssl_ticket_aead_result_t ssl_decrypt_ticket_with_method( Span ticket) { Array plaintext; if (!plaintext.Init(ticket.size())) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return ssl_ticket_aead_error; } @@ -4097,10 +4110,7 @@ bool tls1_choose_signature_algorithm(SSL_HANDSHAKE *hs, uint16_t *out) { Span peer_sigalgs = tls1_get_peer_verify_algorithms(hs); for (uint16_t sigalg : sigalgs) { - // SSL_SIGN_RSA_PKCS1_MD5_SHA1 is an internal value and should never be - // negotiated. - if (sigalg == SSL_SIGN_RSA_PKCS1_MD5_SHA1 || - !ssl_private_key_supports_signature_algorithm(hs, sigalg)) { + if (!ssl_private_key_supports_signature_algorithm(hs, sigalg)) { continue; } diff --git a/Sources/CNIOBoringSSL/ssl/handoff.cc b/Sources/CNIOBoringSSL/ssl/handoff.cc index 6656b77c..7c427e54 100644 --- a/Sources/CNIOBoringSSL/ssl/handoff.cc +++ b/Sources/CNIOBoringSSL/ssl/handoff.cc @@ -26,7 +26,7 @@ BSSL_NAMESPACE_BEGIN constexpr int kHandoffVersion = 0; constexpr int kHandbackVersion = 0; -static const unsigned kHandoffTagALPS = CBS_ASN1_CONTEXT_SPECIFIC | 0; +static const CBS_ASN1_TAG kHandoffTagALPS = CBS_ASN1_CONTEXT_SPECIFIC | 0; // early_data_t represents the state of early data in a more compact way than // the 3 bits used by the implementation. @@ -124,6 +124,9 @@ static bool apply_remote_features(SSL *ssl, CBS *in) { return false; } bssl::UniquePtr supported(sk_SSL_CIPHER_new_null()); + if (!supported) { + return false; + } while (CBS_len(&ciphers)) { uint16_t id; if (!CBS_get_u16(&ciphers, &id)) { @@ -141,6 +144,9 @@ static bool apply_remote_features(SSL *ssl, CBS *in) { ssl->config->cipher_list ? ssl->config->cipher_list->ciphers.get() : ssl->ctx->cipher_list->ciphers.get(); bssl::UniquePtr unsupported(sk_SSL_CIPHER_new_null()); + if (!unsupported) { + return false; + } for (const SSL_CIPHER *configured_cipher : configured) { if (sk_SSL_CIPHER_find(supported.get(), nullptr, configured_cipher)) { continue; @@ -151,7 +157,8 @@ static bool apply_remote_features(SSL *ssl, CBS *in) { } if (sk_SSL_CIPHER_num(unsupported.get()) && !ssl->config->cipher_list) { ssl->config->cipher_list = bssl::MakeUnique(); - if (!ssl->config->cipher_list->Init(*ssl->ctx->cipher_list)) { + if (!ssl->config->cipher_list || + !ssl->config->cipher_list->Init(*ssl->ctx->cipher_list)) { return false; } } @@ -380,9 +387,14 @@ bool SSL_serialize_handback(const SSL *ssl, CBB *out) { !CBB_add_asn1(&seq, &key_share, CBS_ASN1_SEQUENCE)) { return false; } - if (type == handback_after_ecdhe && - !s3->hs->key_shares[0]->Serialize(&key_share)) { - return false; + if (type == handback_after_ecdhe) { + CBB private_key; + if (!CBB_add_asn1_uint64(&key_share, s3->hs->key_shares[0]->GroupID()) || + !CBB_add_asn1(&key_share, &private_key, CBS_ASN1_OCTETSTRING) || + !s3->hs->key_shares[0]->SerializePrivateKey(&private_key) || + !CBB_flush(&key_share)) { + return false; + } } if (type == handback_tls13) { early_data_t early_data; @@ -488,6 +500,9 @@ bool SSL_apply_handback(SSL *ssl, Span handback) { } s3->hs = ssl_handshake_new(ssl); + if (!s3->hs) { + return false; + } SSL_HANDSHAKE *const hs = s3->hs.get(); if (!session_reused || type == handback_tls13) { hs->new_session = @@ -704,9 +719,19 @@ bool SSL_apply_handback(SSL *ssl, Span handback) { } s3->read_sequence = CRYPTO_load_u64_be(read_sequence); s3->write_sequence = CRYPTO_load_u64_be(write_sequence); - if (type == handback_after_ecdhe && - (hs->key_shares[0] = SSLKeyShare::Create(&key_share)) == nullptr) { - return false; + if (type == handback_after_ecdhe) { + uint64_t group_id; + CBS private_key; + if (!CBS_get_asn1_uint64(&key_share, &group_id) || // + group_id > 0xffff || + !CBS_get_asn1(&key_share, &private_key, CBS_ASN1_OCTETSTRING)) { + return false; + } + hs->key_shares[0] = SSLKeyShare::Create(group_id); + if (!hs->key_shares[0] || + !hs->key_shares[0]->DeserializePrivateKey(&private_key)) { + return false; + } } return true; // Trailing data allowed for extensibility. } @@ -799,7 +824,7 @@ int SSL_request_handshake_hints(SSL *ssl, const uint8_t *client_hello, // // KeyShareHint ::= SEQUENCE { // groupId INTEGER, -// publicKey OCTET STRING, +// ciphertext OCTET STRING, // secret OCTET STRING, // } // @@ -823,19 +848,22 @@ int SSL_request_handshake_hints(SSL *ssl, const uint8_t *client_hello, // } // HandshakeHints tags. -static const unsigned kServerRandomTLS13Tag = CBS_ASN1_CONTEXT_SPECIFIC | 0; -static const unsigned kKeyShareHintTag = +static const CBS_ASN1_TAG kServerRandomTLS13Tag = + CBS_ASN1_CONTEXT_SPECIFIC | 0; +static const CBS_ASN1_TAG kKeyShareHintTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 1; -static const unsigned kSignatureHintTag = +static const CBS_ASN1_TAG kSignatureHintTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 2; -static const unsigned kDecryptedPSKTag = CBS_ASN1_CONTEXT_SPECIFIC | 3; -static const unsigned kIgnorePSKTag = CBS_ASN1_CONTEXT_SPECIFIC | 4; -static const unsigned kCompressCertificateTag = CBS_ASN1_CONTEXT_SPECIFIC | 5; -static const unsigned kServerRandomTLS12Tag = CBS_ASN1_CONTEXT_SPECIFIC | 6; -static const unsigned kECDHEHintTag = CBS_ASN1_CONSTRUCTED | 7; -static const unsigned kDecryptedTicketTag = CBS_ASN1_CONTEXT_SPECIFIC | 8; -static const unsigned kRenewTicketTag = CBS_ASN1_CONTEXT_SPECIFIC | 9; -static const unsigned kIgnoreTicketTag = CBS_ASN1_CONTEXT_SPECIFIC | 10; +static const CBS_ASN1_TAG kDecryptedPSKTag = CBS_ASN1_CONTEXT_SPECIFIC | 3; +static const CBS_ASN1_TAG kIgnorePSKTag = CBS_ASN1_CONTEXT_SPECIFIC | 4; +static const CBS_ASN1_TAG kCompressCertificateTag = + CBS_ASN1_CONTEXT_SPECIFIC | 5; +static const CBS_ASN1_TAG kServerRandomTLS12Tag = + CBS_ASN1_CONTEXT_SPECIFIC | 6; +static const CBS_ASN1_TAG kECDHEHintTag = CBS_ASN1_CONSTRUCTED | 7; +static const CBS_ASN1_TAG kDecryptedTicketTag = CBS_ASN1_CONTEXT_SPECIFIC | 8; +static const CBS_ASN1_TAG kRenewTicketTag = CBS_ASN1_CONTEXT_SPECIFIC | 9; +static const CBS_ASN1_TAG kIgnoreTicketTag = CBS_ASN1_CONTEXT_SPECIFIC | 10; int SSL_serialize_handshake_hints(const SSL *ssl, CBB *out) { const SSL_HANDSHAKE *hs = ssl->s3->hs.get(); @@ -858,12 +886,12 @@ int SSL_serialize_handshake_hints(const SSL *ssl, CBB *out) { } } - if (hints->key_share_group_id != 0 && !hints->key_share_public_key.empty() && + if (hints->key_share_group_id != 0 && !hints->key_share_ciphertext.empty() && !hints->key_share_secret.empty()) { if (!CBB_add_asn1(&seq, &child, kKeyShareHintTag) || !CBB_add_asn1_uint64(&child, hints->key_share_group_id) || - !CBB_add_asn1_octet_string(&child, hints->key_share_public_key.data(), - hints->key_share_public_key.size()) || + !CBB_add_asn1_octet_string(&child, hints->key_share_ciphertext.data(), + hints->key_share_ciphertext.size()) || !CBB_add_asn1_octet_string(&child, hints->key_share_secret.data(), hints->key_share_secret.size())) { return 0; @@ -954,7 +982,7 @@ int SSL_serialize_handshake_hints(const SSL *ssl, CBB *out) { } static bool get_optional_implicit_null(CBS *cbs, bool *out_present, - unsigned tag) { + CBS_ASN1_TAG tag) { CBS value; int present; if (!CBS_get_optional_asn1(cbs, &value, &present, tag) || @@ -1012,11 +1040,11 @@ int SSL_set_handshake_hints(SSL *ssl, const uint8_t *hints, size_t hints_len) { if (has_key_share) { uint64_t group_id; - CBS public_key, secret; + CBS ciphertext, secret; if (!CBS_get_asn1_uint64(&key_share, &group_id) || // group_id == 0 || group_id > 0xffff || - !CBS_get_asn1(&key_share, &public_key, CBS_ASN1_OCTETSTRING) || - !hints_obj->key_share_public_key.CopyFrom(public_key) || + !CBS_get_asn1(&key_share, &ciphertext, CBS_ASN1_OCTETSTRING) || + !hints_obj->key_share_ciphertext.CopyFrom(ciphertext) || !CBS_get_asn1(&key_share, &secret, CBS_ASN1_OCTETSTRING) || !hints_obj->key_share_secret.CopyFrom(secret)) { OPENSSL_PUT_ERROR(SSL, SSL_R_COULD_NOT_PARSE_HINTS); diff --git a/Sources/CNIOBoringSSL/ssl/handshake_client.cc b/Sources/CNIOBoringSSL/ssl/handshake_client.cc index 80acbce0..26bce5f3 100644 --- a/Sources/CNIOBoringSSL/ssl/handshake_client.cc +++ b/Sources/CNIOBoringSSL/ssl/handshake_client.cc @@ -239,8 +239,12 @@ static bool ssl_write_client_cipher_list(const SSL_HANDSHAKE *hs, CBB *out, TLS1_3_CK_CHACHA20_POLY1305_SHA256 & 0xffff, ssl->config->only_fips_cipher_suites_in_tls13); - if (!EVP_has_aes_hardware() && // - include_chacha20 && // + const bool has_aes_hw = ssl->config->aes_hw_override + ? ssl->config->aes_hw_override_value + : EVP_has_aes_hardware(); + + if (!has_aes_hw && // + include_chacha20 && // !CBB_add_u16(&child, TLS1_3_CK_CHACHA20_POLY1305_SHA256 & 0xffff)) { return false; } @@ -248,8 +252,8 @@ static bool ssl_write_client_cipher_list(const SSL_HANDSHAKE *hs, CBB *out, !CBB_add_u16(&child, TLS1_3_CK_AES_256_GCM_SHA384 & 0xffff)) { return false; } - if (EVP_has_aes_hardware() && // - include_chacha20 && // + if (has_aes_hw && // + include_chacha20 && // !CBB_add_u16(&child, TLS1_3_CK_CHACHA20_POLY1305_SHA256 & 0xffff)) { return false; } @@ -833,11 +837,18 @@ static enum ssl_hs_wait_t do_read_server_hello(SSL_HANDSHAKE *hs) { ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); return ssl_hs_error; } - // Note: session_id could be empty. - hs->new_session->session_id_length = CBS_len(&server_hello.session_id); + + // Save the session ID from the server. This may be empty if the session + // isn't resumable, or if we'll receive a session ticket later. + assert(CBS_len(&server_hello.session_id) <= SSL3_SESSION_ID_SIZE); + static_assert(SSL3_SESSION_ID_SIZE <= UINT8_MAX, + "max session ID is too large"); + hs->new_session->session_id_length = + static_cast(CBS_len(&server_hello.session_id)); OPENSSL_memcpy(hs->new_session->session_id, CBS_data(&server_hello.session_id), CBS_len(&server_hello.session_id)); + hs->new_session->cipher = hs->new_cipher; } @@ -1098,7 +1109,6 @@ static enum ssl_hs_wait_t do_read_server_key_exchange(SSL_HANDSHAKE *hs) { char *raw = nullptr; if (CBS_len(&psk_identity_hint) != 0 && !CBS_strdup(&psk_identity_hint, &raw)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); return ssl_hs_error; } @@ -1118,7 +1128,6 @@ static enum ssl_hs_wait_t do_read_server_key_exchange(SSL_HANDSHAKE *hs) { ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); return ssl_hs_error; } - hs->new_session->group_id = group_id; // Ensure the group is consistent with preferences. if (!tls1_check_group_id(hs, group_id)) { @@ -1127,10 +1136,9 @@ static enum ssl_hs_wait_t do_read_server_key_exchange(SSL_HANDSHAKE *hs) { return ssl_hs_error; } - // Initialize ECDH and save the peer public key for later. - hs->key_shares[0] = SSLKeyShare::Create(group_id); - if (!hs->key_shares[0] || - !hs->peer_key.CopyFrom(point)) { + // Save the group and peer public key for later. + hs->new_session->group_id = group_id; + if (!hs->peer_key.CopyFrom(point)) { return ssl_hs_error; } } else if (!(alg_k & SSL_kPSK)) { @@ -1390,11 +1398,13 @@ static enum ssl_hs_wait_t do_send_client_key_exchange(SSL_HANDSHAKE *hs) { ssl_key_usage_t intended_use = (alg_k & SSL_kRSA) ? key_usage_encipherment : key_usage_digital_signature; - if (hs->config->enforce_rsa_key_usage || - EVP_PKEY_id(hs->peer_pubkey.get()) != EVP_PKEY_RSA) { - if (!ssl_cert_check_key_usage(&leaf_cbs, intended_use)) { + if (!ssl_cert_check_key_usage(&leaf_cbs, intended_use)) { + if (hs->config->enforce_rsa_key_usage || + EVP_PKEY_id(hs->peer_pubkey.get()) != EVP_PKEY_RSA) { return ssl_hs_error; } + ERR_clear_error(); + ssl->s3->was_key_usage_invalid = true; } } @@ -1421,7 +1431,6 @@ static enum ssl_hs_wait_t do_send_client_key_exchange(SSL_HANDSHAKE *hs) { hs->new_session->psk_identity.reset(OPENSSL_strdup(identity)); if (hs->new_session->psk_identity == nullptr) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return ssl_hs_error; } @@ -1465,15 +1474,16 @@ static enum ssl_hs_wait_t do_send_client_key_exchange(SSL_HANDSHAKE *hs) { return ssl_hs_error; } } else if (alg_k & SSL_kECDHE) { - // Generate a keypair and serialize the public half. CBB child; if (!CBB_add_u8_length_prefixed(&body, &child)) { return ssl_hs_error; } - // Compute the premaster. + // Generate a premaster secret and encapsulate it. + bssl::UniquePtr kem = + SSLKeyShare::Create(hs->new_session->group_id); uint8_t alert = SSL_AD_DECODE_ERROR; - if (!hs->key_shares[0]->Accept(&child, &pms, &alert, hs->peer_key)) { + if (!kem || !kem->Encap(&child, &pms, &alert, hs->peer_key)) { ssl_send_alert(ssl, SSL3_AL_FATAL, alert); return ssl_hs_error; } @@ -1481,9 +1491,7 @@ static enum ssl_hs_wait_t do_send_client_key_exchange(SSL_HANDSHAKE *hs) { return ssl_hs_error; } - // The key exchange state may now be discarded. - hs->key_shares[0].reset(); - hs->key_shares[1].reset(); + // The peer key can now be discarded. hs->peer_key.Reset(); } else if (alg_k & SSL_kPSK) { // For plain PSK, other_secret is a block of 0s with the same length as @@ -1509,7 +1517,6 @@ static enum ssl_hs_wait_t do_send_client_key_exchange(SSL_HANDSHAKE *hs) { !CBB_add_u16_length_prefixed(pms_cbb.get(), &child) || !CBB_add_bytes(&child, psk, psk_len) || !CBBFinishArray(pms_cbb.get(), &pms)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return ssl_hs_error; } } diff --git a/Sources/CNIOBoringSSL/ssl/handshake_server.cc b/Sources/CNIOBoringSSL/ssl/handshake_server.cc index 3eb65916..a3392465 100644 --- a/Sources/CNIOBoringSSL/ssl/handshake_server.cc +++ b/Sources/CNIOBoringSSL/ssl/handshake_server.cc @@ -272,7 +272,6 @@ static UniquePtr ssl_parse_client_cipher_list( UniquePtr sk(sk_SSL_CIPHER_new_null()); if (!sk) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return nullptr; } @@ -286,7 +285,6 @@ static UniquePtr ssl_parse_client_cipher_list( const SSL_CIPHER *c = SSL_get_cipher_by_value(cipher_suite); if (c != NULL && !sk_SSL_CIPHER_push(sk.get(), c)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return nullptr; } } @@ -1148,7 +1146,7 @@ static enum ssl_hs_wait_t do_send_server_certificate(SSL_HANDSHAKE *hs) { } } else { // Generate a key, and emit the public half. - if (!hs->key_shares[0]->Offer(&child)) { + if (!hs->key_shares[0]->Generate(&child)) { return ssl_hs_error; } // If generating hints, save the ECDHE key. @@ -1407,7 +1405,6 @@ static enum ssl_hs_wait_t do_read_client_key_exchange(SSL_HANDSHAKE *hs) { } char *raw = nullptr; if (!CBS_strdup(&psk_identity, &raw)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); return ssl_hs_error; } @@ -1493,17 +1490,17 @@ static enum ssl_hs_wait_t do_read_client_key_exchange(SSL_HANDSHAKE *hs) { } } else if (alg_k & SSL_kECDHE) { // Parse the ClientKeyExchange. - CBS peer_key; - if (!CBS_get_u8_length_prefixed(&client_key_exchange, &peer_key) || + CBS ciphertext; + if (!CBS_get_u8_length_prefixed(&client_key_exchange, &ciphertext) || CBS_len(&client_key_exchange) != 0) { OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); return ssl_hs_error; } - // Compute the premaster. + // Decapsulate the premaster secret. uint8_t alert = SSL_AD_DECODE_ERROR; - if (!hs->key_shares[0]->Finish(&premaster_secret, &alert, peer_key)) { + if (!hs->key_shares[0]->Decap(&premaster_secret, &alert, ciphertext)) { ssl_send_alert(ssl, SSL3_AL_FATAL, alert); return ssl_hs_error; } @@ -1560,7 +1557,6 @@ static enum ssl_hs_wait_t do_read_client_key_exchange(SSL_HANDSHAKE *hs) { !CBB_add_u16_length_prefixed(new_premaster.get(), &child) || !CBB_add_bytes(&child, psk, psk_len) || !CBBFinishArray(new_premaster.get(), &premaster_secret)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return ssl_hs_error; } } diff --git a/Sources/CNIOBoringSSL/ssl/internal.h b/Sources/CNIOBoringSSL/ssl/internal.h index 54c9e0f8..7cd4dc33 100644 --- a/Sources/CNIOBoringSSL/ssl/internal.h +++ b/Sources/CNIOBoringSSL/ssl/internal.h @@ -195,7 +195,6 @@ template T *New(Args &&... args) { void *t = OPENSSL_malloc(sizeof(T)); if (t == nullptr) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return nullptr; } return new (t) T(std::forward(args)...); @@ -315,7 +314,6 @@ class Array { } data_ = reinterpret_cast(OPENSSL_malloc(new_size * sizeof(T))); if (data_ == nullptr) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return false; } size_ = new_size; @@ -635,9 +633,11 @@ const EVP_MD *ssl_get_handshake_digest(uint16_t version, // newly-allocated |SSLCipherPreferenceList| containing the result. It returns // true on success and false on failure. If |strict| is true, nonsense will be // rejected. If false, nonsense will be silently ignored. An empty result is -// considered an error regardless of |strict|. +// considered an error regardless of |strict|. |has_aes_hw| indicates if the +// list should be ordered based on having support for AES in hardware or not. bool ssl_create_cipher_list(UniquePtr *out_cipher_list, - const char *rule_str, bool strict); + const bool has_aes_hw, const char *rule_str, + bool strict); // ssl_cipher_auth_mask_for_key returns the mask of cipher |algorithm_auth| // values suitable for use with |key| in TLS 1.2 and below. @@ -661,9 +661,12 @@ size_t ssl_cipher_get_record_split_len(const SSL_CIPHER *cipher); // ssl_choose_tls13_cipher returns an |SSL_CIPHER| corresponding with the best // available from |cipher_suites| compatible with |version|, |group_id|, and -// |only_fips|. It returns NULL if there isn't a compatible cipher. -const SSL_CIPHER *ssl_choose_tls13_cipher(CBS cipher_suites, uint16_t version, - uint16_t group_id, bool only_fips); +// |only_fips|. It returns NULL if there isn't a compatible cipher. |has_aes_hw| +// indicates if the choice should be made as if support for AES in hardware +// is available. +const SSL_CIPHER *ssl_choose_tls13_cipher(CBS cipher_suites, bool has_aes_hw, + uint16_t version, uint16_t group_id, + bool only_fips); // ssl_tls13_cipher_meets_policy returns true if |cipher_id| is acceptable given // |only_fips|. (For now there's only a single policy and so the policy argument @@ -1053,7 +1056,15 @@ bool ssl_public_key_verify(SSL *ssl, Span signature, // Key shares. -// SSLKeyShare abstracts over Diffie-Hellman-like key exchanges. +// SSLKeyShare abstracts over KEM-like constructions, for use with TLS 1.2 ECDHE +// cipher suites and the TLS 1.3 key_share extension. +// +// TODO(davidben): This class is named SSLKeyShare after the TLS 1.3 key_share +// extension, but it really implements a KEM abstraction. Additionally, we use +// the same type for Encap, which is a one-off, stateless operation, as Generate +// and Decap. Slightly tidier would be for Generate to return a new SSLKEMKey +// (or we introduce EVP_KEM and EVP_KEM_KEY), with a Decap method, and for Encap +// to be static function. class SSLKeyShare { public: virtual ~SSLKeyShare() {} @@ -1064,40 +1075,29 @@ class SSLKeyShare { // nullptr on error. static UniquePtr Create(uint16_t group_id); - // Create deserializes an SSLKeyShare instance previously serialized by - // |Serialize|. - static UniquePtr Create(CBS *in); - - // Serializes writes the group ID and private key, in a format that can be - // read by |Create|. - bool Serialize(CBB *out); - // GroupID returns the group ID. virtual uint16_t GroupID() const PURE_VIRTUAL; - // Offer generates a keypair and writes the public value to - // |out_public_key|. It returns true on success and false on error. - virtual bool Offer(CBB *out_public_key) PURE_VIRTUAL; - - // Accept performs a key exchange against the |peer_key| generated by |Offer|. - // On success, it returns true, writes the public value to |out_public_key|, - // and sets |*out_secret| to the shared secret. On failure, it returns false - // and sets |*out_alert| to an alert to send to the peer. - // - // The default implementation calls |Offer| and then |Finish|, assuming a key - // exchange protocol where the peers are symmetric. - virtual bool Accept(CBB *out_public_key, Array *out_secret, - uint8_t *out_alert, Span peer_key); - - // Finish performs a key exchange against the |peer_key| generated by - // |Accept|. On success, it returns true and sets |*out_secret| to the shared - // secret. On failure, it returns false and sets |*out_alert| to an alert to - // send to the peer. - virtual bool Finish(Array *out_secret, uint8_t *out_alert, - Span peer_key) PURE_VIRTUAL; + // Generate generates a keypair and writes the public key to |out_public_key|. + // It returns true on success and false on error. + virtual bool Generate(CBB *out_public_key) PURE_VIRTUAL; + + // Encap generates an ephemeral, symmetric secret and encapsulates it with + // |peer_key|. On success, it returns true, writes the encapsulated secret to + // |out_ciphertext|, and sets |*out_secret| to the shared secret. On failure, + // it returns false and sets |*out_alert| to an alert to send to the peer. + virtual bool Encap(CBB *out_ciphertext, Array *out_secret, + uint8_t *out_alert, + Span peer_key) PURE_VIRTUAL; + + // Decap decapsulates the symmetric secret in |ciphertext|. On success, it + // returns true and sets |*out_secret| to the shared secret. On failure, it + // returns false and sets |*out_alert| to an alert to send to the peer. + virtual bool Decap(Array *out_secret, uint8_t *out_alert, + Span ciphertext) PURE_VIRTUAL; // SerializePrivateKey writes the private key to |out|, returning true if - // successful and false otherwise. It should be called after |Offer|. + // successful and false otherwise. It should be called after |Generate|. virtual bool SerializePrivateKey(CBB *out) { return false; } // DeserializePrivateKey initializes the state of the key exchange from |in|, @@ -1108,7 +1108,7 @@ class SSLKeyShare { struct NamedGroup { int nid; uint16_t group_id; - const char name[8], alias[11]; + const char name[12], alias[12]; }; // NamedGroups returns all supported groups. @@ -1313,7 +1313,8 @@ enum ssl_key_usage_t { // ssl_cert_check_key_usage parses the DER-encoded, X.509 certificate in |in| // and returns true if doesn't specify a key usage or, if it does, if it // includes |bit|. Otherwise it pushes to the error queue and returns false. -bool ssl_cert_check_key_usage(const CBS *in, enum ssl_key_usage_t bit); +OPENSSL_EXPORT bool ssl_cert_check_key_usage(const CBS *in, + enum ssl_key_usage_t bit); // ssl_cert_parse_pubkey extracts the public key from the DER-encoded, X.509 // certificate in |in|. It returns an allocated |EVP_PKEY| or else returns @@ -1692,7 +1693,7 @@ struct SSL_HANDSHAKE_HINTS { Array server_random_tls13; uint16_t key_share_group_id = 0; - Array key_share_public_key; + Array key_share_ciphertext; Array key_share_secret; uint16_t signature_algorithm = 0; @@ -1852,9 +1853,9 @@ struct SSL_HANDSHAKE { // key_share_bytes is the key_share extension that the client should send. Array key_share_bytes; - // ecdh_public_key, for servers, is the key share to be sent to the client in - // TLS 1.3. - Array ecdh_public_key; + // key_share_ciphertext, for servers, is encapsulated shared secret to be sent + // to the client in the TLS 1.3 key_share extension. + Array key_share_ciphertext; // peer_sigalgs are the signature algorithms that the peer supports. These are // taken from the contents of the signature algorithms extension for a server @@ -2762,6 +2763,11 @@ struct SSL3_STATE { // HelloRetryRequest message. bool used_hello_retry_request : 1; + // was_key_usage_invalid is whether the handshake succeeded despite using a + // TLS mode which was incompatible with the leaf certificate's keyUsage + // extension. + bool was_key_usage_invalid : 1; + // hs_buf is the buffer of handshake data to process. UniquePtr hs_buf; @@ -3110,6 +3116,15 @@ struct SSL_CONFIG { // only_fips_cipher_suites_in_tls13 constrains the selection of cipher suites // in TLS 1.3 such that only FIPS approved ones will be selected. bool only_fips_cipher_suites_in_tls13 : 1; + + // aes_hw_override if set indicates we should override checking for aes + // hardware support, and use the value in aes_hw_override_value instead. + bool aes_hw_override : 1; + + // aes_hw_override_value is used for testing to indicate the support or lack + // of support for AES hw. The value is only considered if |aes_hw_override| is + // true. + bool aes_hw_override_value : 1; }; // From RFC 8446, used in determining PSK modes. @@ -3131,8 +3146,9 @@ bool ssl_compare_public_and_private_key(const EVP_PKEY *pubkey, const EVP_PKEY *privkey); bool ssl_cert_check_private_key(const CERT *cert, const EVP_PKEY *privkey); bool ssl_get_new_session(SSL_HANDSHAKE *hs); -int ssl_encrypt_ticket(SSL_HANDSHAKE *hs, CBB *out, const SSL_SESSION *session); -int ssl_ctx_rotate_ticket_encryption_key(SSL_CTX *ctx); +bool ssl_encrypt_ticket(SSL_HANDSHAKE *hs, CBB *out, + const SSL_SESSION *session); +bool ssl_ctx_rotate_ticket_encryption_key(SSL_CTX *ctx); // ssl_session_new returns a newly-allocated blank |SSL_SESSION| or nullptr on // error. @@ -3148,23 +3164,22 @@ OPENSSL_EXPORT UniquePtr SSL_SESSION_parse( CBS *cbs, const SSL_X509_METHOD *x509_method, CRYPTO_BUFFER_POOL *pool); // ssl_session_serialize writes |in| to |cbb| as if it were serialising a -// session for Session-ID resumption. It returns one on success and zero on +// session for Session-ID resumption. It returns true on success and false on // error. -OPENSSL_EXPORT int ssl_session_serialize(const SSL_SESSION *in, CBB *cbb); +OPENSSL_EXPORT bool ssl_session_serialize(const SSL_SESSION *in, CBB *cbb); -// ssl_session_is_context_valid returns one if |session|'s session ID context -// matches the one set on |hs| and zero otherwise. -int ssl_session_is_context_valid(const SSL_HANDSHAKE *hs, - const SSL_SESSION *session); +// ssl_session_is_context_valid returns whether |session|'s session ID context +// matches the one set on |hs|. +bool ssl_session_is_context_valid(const SSL_HANDSHAKE *hs, + const SSL_SESSION *session); -// ssl_session_is_time_valid returns one if |session| is still valid and zero if -// it has expired. -int ssl_session_is_time_valid(const SSL *ssl, const SSL_SESSION *session); +// ssl_session_is_time_valid returns true if |session| is still valid and false +// if it has expired. +bool ssl_session_is_time_valid(const SSL *ssl, const SSL_SESSION *session); -// ssl_session_is_resumable returns one if |session| is resumable for |hs| and -// zero otherwise. -int ssl_session_is_resumable(const SSL_HANDSHAKE *hs, - const SSL_SESSION *session); +// ssl_session_is_resumable returns whether |session| is resumable for |hs|. +bool ssl_session_is_resumable(const SSL_HANDSHAKE *hs, + const SSL_SESSION *session); // ssl_session_protocol_version returns the protocol version associated with // |session|. Note that despite the name, this is not the same as @@ -3721,6 +3736,15 @@ struct ssl_ctx_st { // in TLS 1.3 such that only FIPS approved ones will be selected. bool only_fips_cipher_suites_in_tls13 : 1; + // aes_hw_override if set indicates we should override checking for AES + // hardware support, and use the value in aes_hw_override_value instead. + bool aes_hw_override : 1; + + // aes_hw_override_value is used for testing to indicate the support or lack + // of support for AES hardware. The value is only considered if + // |aes_hw_override| is true. + bool aes_hw_override_value : 1; + private: ~ssl_ctx_st(); friend OPENSSL_EXPORT void SSL_CTX_free(SSL_CTX *); @@ -3837,11 +3861,11 @@ struct ssl_session_st { // session. In TLS 1.3 and up, it is the resumption PSK for sessions handed to // the caller, but it stores the resumption secret when stored on |SSL| // objects. - int secret_length = 0; + uint8_t secret_length = 0; uint8_t secret[SSL_MAX_MASTER_KEY_LENGTH] = {0}; // session_id - valid? - unsigned session_id_length = 0; + uint8_t session_id_length = 0; uint8_t session_id[SSL_MAX_SSL_SESSION_ID_LENGTH] = {0}; // this is used to determine whether the session is being reused in // the appropriate context. It is up to the application to set this, diff --git a/Sources/CNIOBoringSSL/ssl/s3_both.cc b/Sources/CNIOBoringSSL/ssl/s3_both.cc index 2afb09bd..7a31d223 100644 --- a/Sources/CNIOBoringSSL/ssl/s3_both.cc +++ b/Sources/CNIOBoringSSL/ssl/s3_both.cc @@ -439,7 +439,6 @@ static ssl_open_record_t read_v2_client_hello(SSL *ssl, size_t *out_consumed, // No session id. !CBB_add_u8(&hello_body, 0) || !CBB_add_u16_length_prefixed(&hello_body, &cipher_suites)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return ssl_open_record_error; } @@ -664,31 +663,26 @@ void tls_next_message(SSL *ssl) { // the client. class CipherScorer { public: - CipherScorer(uint16_t group_id) - : aes_is_fine_(EVP_has_aes_hardware()), - security_128_is_fine_(group_id != SSL_CURVE_CECPQ2) {} + CipherScorer(bool has_aes_hw) : aes_is_fine_(has_aes_hw) {} - typedef std::tuple Score; + typedef std::tuple Score; // MinScore returns a |Score| that will compare less than the score of all // cipher suites. Score MinScore() const { - return Score(false, false, false); + return Score(false, false); } Score Evaluate(const SSL_CIPHER *a) const { return Score( // Something is always preferable to nothing. true, - // Either 128-bit is fine, or 256-bit is preferred. - security_128_is_fine_ || a->algorithm_enc != SSL_AES128GCM, // Either AES is fine, or else ChaCha20 is preferred. aes_is_fine_ || a->algorithm_enc == SSL_CHACHA20POLY1305); } private: const bool aes_is_fine_; - const bool security_128_is_fine_; }; bool ssl_tls13_cipher_meets_policy(uint16_t cipher_id, bool only_fips) { @@ -708,14 +702,15 @@ bool ssl_tls13_cipher_meets_policy(uint16_t cipher_id, bool only_fips) { } } -const SSL_CIPHER *ssl_choose_tls13_cipher(CBS cipher_suites, uint16_t version, - uint16_t group_id, bool only_fips) { +const SSL_CIPHER *ssl_choose_tls13_cipher(CBS cipher_suites, bool has_aes_hw, + uint16_t version, uint16_t group_id, + bool only_fips) { if (CBS_len(&cipher_suites) % 2 != 0) { return nullptr; } const SSL_CIPHER *best = nullptr; - CipherScorer scorer(group_id); + CipherScorer scorer(has_aes_hw); CipherScorer::Score best_score = scorer.MinScore(); while (CBS_len(&cipher_suites) > 0) { diff --git a/Sources/CNIOBoringSSL/ssl/s3_lib.cc b/Sources/CNIOBoringSSL/ssl/s3_lib.cc index 9ef0b38f..54170076 100644 --- a/Sources/CNIOBoringSSL/ssl/s3_lib.cc +++ b/Sources/CNIOBoringSSL/ssl/s3_lib.cc @@ -178,7 +178,8 @@ SSL3_STATE::SSL3_STATE() early_data_accepted(false), alert_dispatch(false), renegotiate_pending(false), - used_hello_retry_request(false) {} + used_hello_retry_request(false), + was_key_usage_invalid(false) {} SSL3_STATE::~SSL3_STATE() {} diff --git a/Sources/CNIOBoringSSL/ssl/ssl_aead_ctx.cc b/Sources/CNIOBoringSSL/ssl/ssl_aead_ctx.cc index bc4f89e8..005c2c34 100644 --- a/Sources/CNIOBoringSSL/ssl/ssl_aead_ctx.cc +++ b/Sources/CNIOBoringSSL/ssl/ssl_aead_ctx.cc @@ -91,7 +91,6 @@ UniquePtr SSLAEADContext::Create( UniquePtr aead_ctx = MakeUnique(version, is_dtls, cipher); if (!aead_ctx) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return nullptr; } diff --git a/Sources/CNIOBoringSSL/ssl/ssl_asn1.cc b/Sources/CNIOBoringSSL/ssl/ssl_asn1.cc index 3effb376..f43530f2 100644 --- a/Sources/CNIOBoringSSL/ssl/ssl_asn1.cc +++ b/Sources/CNIOBoringSSL/ssl/ssl_asn1.cc @@ -150,57 +150,57 @@ BSSL_NAMESPACE_BEGIN static const unsigned kVersion = 1; -static const unsigned kTimeTag = +static const CBS_ASN1_TAG kTimeTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 1; -static const unsigned kTimeoutTag = +static const CBS_ASN1_TAG kTimeoutTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 2; -static const unsigned kPeerTag = +static const CBS_ASN1_TAG kPeerTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 3; -static const unsigned kSessionIDContextTag = +static const CBS_ASN1_TAG kSessionIDContextTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 4; -static const unsigned kVerifyResultTag = +static const CBS_ASN1_TAG kVerifyResultTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 5; -static const unsigned kHostNameTag = +static const CBS_ASN1_TAG kHostNameTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 6; -static const unsigned kPSKIdentityTag = +static const CBS_ASN1_TAG kPSKIdentityTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 8; -static const unsigned kTicketLifetimeHintTag = +static const CBS_ASN1_TAG kTicketLifetimeHintTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 9; -static const unsigned kTicketTag = +static const CBS_ASN1_TAG kTicketTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 10; -static const unsigned kPeerSHA256Tag = +static const CBS_ASN1_TAG kPeerSHA256Tag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 13; -static const unsigned kOriginalHandshakeHashTag = +static const CBS_ASN1_TAG kOriginalHandshakeHashTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 14; -static const unsigned kSignedCertTimestampListTag = +static const CBS_ASN1_TAG kSignedCertTimestampListTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 15; -static const unsigned kOCSPResponseTag = +static const CBS_ASN1_TAG kOCSPResponseTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 16; -static const unsigned kExtendedMasterSecretTag = +static const CBS_ASN1_TAG kExtendedMasterSecretTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 17; -static const unsigned kGroupIDTag = +static const CBS_ASN1_TAG kGroupIDTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 18; -static const unsigned kCertChainTag = +static const CBS_ASN1_TAG kCertChainTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 19; -static const unsigned kTicketAgeAddTag = +static const CBS_ASN1_TAG kTicketAgeAddTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 21; -static const unsigned kIsServerTag = +static const CBS_ASN1_TAG kIsServerTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 22; -static const unsigned kPeerSignatureAlgorithmTag = +static const CBS_ASN1_TAG kPeerSignatureAlgorithmTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 23; -static const unsigned kTicketMaxEarlyDataTag = +static const CBS_ASN1_TAG kTicketMaxEarlyDataTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 24; -static const unsigned kAuthTimeoutTag = +static const CBS_ASN1_TAG kAuthTimeoutTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 25; -static const unsigned kEarlyALPNTag = +static const CBS_ASN1_TAG kEarlyALPNTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 26; -static const unsigned kIsQuicTag = +static const CBS_ASN1_TAG kIsQuicTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 27; -static const unsigned kQuicEarlyDataContextTag = +static const CBS_ASN1_TAG kQuicEarlyDataContextTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 28; -static const unsigned kLocalALPSTag = +static const CBS_ASN1_TAG kLocalALPSTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 29; -static const unsigned kPeerALPSTag = +static const CBS_ASN1_TAG kPeerALPSTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 30; static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, @@ -223,7 +223,6 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, !CBB_add_asn1_uint64(&child, in->time) || !CBB_add_asn1(&session, &child, kTimeoutTag) || !CBB_add_asn1_uint64(&child, in->timeout)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } @@ -234,7 +233,6 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, if (!CBB_add_asn1(&session, &child, kPeerTag) || !CBB_add_bytes(&child, CRYPTO_BUFFER_data(buffer), CRYPTO_BUFFER_len(buffer))) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } } @@ -243,14 +241,12 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, // historically always encoded the sid_ctx. if (!CBB_add_asn1(&session, &child, kSessionIDContextTag) || !CBB_add_asn1_octet_string(&child, in->sid_ctx, in->sid_ctx_length)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } if (in->verify_result != X509_V_OK) { if (!CBB_add_asn1(&session, &child, kVerifyResultTag) || !CBB_add_asn1_uint64(&child, in->verify_result)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } } @@ -260,7 +256,6 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, !CBB_add_asn1_octet_string(&child, (const uint8_t *)in->psk_identity.get(), strlen(in->psk_identity.get()))) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } } @@ -268,7 +263,6 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, if (in->ticket_lifetime_hint > 0) { if (!CBB_add_asn1(&session, &child, kTicketLifetimeHintTag) || !CBB_add_asn1_uint64(&child, in->ticket_lifetime_hint)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } } @@ -277,7 +271,6 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, if (!CBB_add_asn1(&session, &child, kTicketTag) || !CBB_add_asn1_octet_string(&child, in->ticket.data(), in->ticket.size())) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } } @@ -286,7 +279,6 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, if (!CBB_add_asn1(&session, &child, kPeerSHA256Tag) || !CBB_add_asn1_octet_string(&child, in->peer_sha256, sizeof(in->peer_sha256))) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } } @@ -295,7 +287,6 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, if (!CBB_add_asn1(&session, &child, kOriginalHandshakeHashTag) || !CBB_add_asn1_octet_string(&child, in->original_handshake_hash, in->original_handshake_hash_len)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } } @@ -305,7 +296,6 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, !CBB_add_asn1_octet_string( &child, CRYPTO_BUFFER_data(in->signed_cert_timestamp_list.get()), CRYPTO_BUFFER_len(in->signed_cert_timestamp_list.get()))) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } } @@ -315,7 +305,6 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, !CBB_add_asn1_octet_string( &child, CRYPTO_BUFFER_data(in->ocsp_response.get()), CRYPTO_BUFFER_len(in->ocsp_response.get()))) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } } @@ -323,7 +312,6 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, if (in->extended_master_secret) { if (!CBB_add_asn1(&session, &child, kExtendedMasterSecretTag) || !CBB_add_asn1_bool(&child, true)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } } @@ -331,7 +319,6 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, if (in->group_id > 0 && (!CBB_add_asn1(&session, &child, kGroupIDTag) || !CBB_add_asn1_uint64(&child, in->group_id))) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } @@ -341,14 +328,12 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, !in->peer_sha256_valid && sk_CRYPTO_BUFFER_num(in->certs.get()) >= 2) { if (!CBB_add_asn1(&session, &child, kCertChainTag)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } for (size_t i = 1; i < sk_CRYPTO_BUFFER_num(in->certs.get()); i++) { const CRYPTO_BUFFER *buffer = sk_CRYPTO_BUFFER_value(in->certs.get(), i); if (!CBB_add_bytes(&child, CRYPTO_BUFFER_data(buffer), CRYPTO_BUFFER_len(buffer))) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } } @@ -358,7 +343,6 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, if (!CBB_add_asn1(&session, &child, kTicketAgeAddTag) || !CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) || !CBB_add_u32(&child2, in->ticket_age_add)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } } @@ -366,7 +350,6 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, if (!in->is_server) { if (!CBB_add_asn1(&session, &child, kIsServerTag) || !CBB_add_asn1_bool(&child, false)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } } @@ -374,21 +357,18 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, if (in->peer_signature_algorithm != 0 && (!CBB_add_asn1(&session, &child, kPeerSignatureAlgorithmTag) || !CBB_add_asn1_uint64(&child, in->peer_signature_algorithm))) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } if (in->ticket_max_early_data != 0 && (!CBB_add_asn1(&session, &child, kTicketMaxEarlyDataTag) || !CBB_add_asn1_uint64(&child, in->ticket_max_early_data))) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } if (in->timeout != in->auth_timeout && (!CBB_add_asn1(&session, &child, kAuthTimeoutTag) || !CBB_add_asn1_uint64(&child, in->auth_timeout))) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } @@ -396,7 +376,6 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, if (!CBB_add_asn1(&session, &child, kEarlyALPNTag) || !CBB_add_asn1_octet_string(&child, in->early_alpn.data(), in->early_alpn.size())) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } } @@ -404,7 +383,6 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, if (in->is_quic) { if (!CBB_add_asn1(&session, &child, kIsQuicTag) || !CBB_add_asn1_bool(&child, true)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } } @@ -413,7 +391,6 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, if (!CBB_add_asn1(&session, &child, kQuicEarlyDataContextTag) || !CBB_add_asn1_octet_string(&child, in->quic_early_data_context.data(), in->quic_early_data_context.size())) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } } @@ -426,7 +403,6 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, !CBB_add_asn1(&session, &child, kPeerALPSTag) || !CBB_add_asn1_octet_string(&child, in->peer_application_settings.data(), in->peer_application_settings.size())) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } } @@ -438,7 +414,8 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, // tagged with |tag| from |cbs| and saves it in |*out|. If the element was not // found, it sets |*out| to NULL. It returns one on success, whether or not the // element was found, and zero on decode error. -static int SSL_SESSION_parse_string(CBS *cbs, UniquePtr *out, unsigned tag) { +static int SSL_SESSION_parse_string(CBS *cbs, UniquePtr *out, + CBS_ASN1_TAG tag) { CBS value; int present; if (!CBS_get_optional_asn1_octet_string(cbs, &value, &present, tag)) { @@ -452,7 +429,6 @@ static int SSL_SESSION_parse_string(CBS *cbs, UniquePtr *out, unsigned tag } char *raw = nullptr; if (!CBS_strdup(&value, &raw)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } out->reset(raw); @@ -466,7 +442,7 @@ static int SSL_SESSION_parse_string(CBS *cbs, UniquePtr *out, unsigned tag // tagged with |tag| from |cbs| and stows it in |*out|. It returns one on // success, whether or not the element was found, and zero on decode error. static bool SSL_SESSION_parse_octet_string(CBS *cbs, Array *out, - unsigned tag) { + CBS_ASN1_TAG tag) { CBS value; if (!CBS_get_optional_asn1_octet_string(cbs, &value, NULL, tag)) { OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); @@ -477,7 +453,7 @@ static bool SSL_SESSION_parse_octet_string(CBS *cbs, Array *out, static int SSL_SESSION_parse_crypto_buffer(CBS *cbs, UniquePtr *out, - unsigned tag, + CBS_ASN1_TAG tag, CRYPTO_BUFFER_POOL *pool) { if (!CBS_peek_asn1_tag(cbs, tag)) { return 1; @@ -492,7 +468,6 @@ static int SSL_SESSION_parse_crypto_buffer(CBS *cbs, } out->reset(CRYPTO_BUFFER_new_from_CBS(&value, pool)); if (*out == nullptr) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } return 1; @@ -500,8 +475,10 @@ static int SSL_SESSION_parse_crypto_buffer(CBS *cbs, // SSL_SESSION_parse_bounded_octet_string parses an optional ASN.1 OCTET STRING // explicitly tagged with |tag| of size at most |max_out|. -static int SSL_SESSION_parse_bounded_octet_string( - CBS *cbs, uint8_t *out, uint8_t *out_len, uint8_t max_out, unsigned tag) { +static int SSL_SESSION_parse_bounded_octet_string(CBS *cbs, uint8_t *out, + uint8_t *out_len, + uint8_t max_out, + CBS_ASN1_TAG tag) { CBS value; if (!CBS_get_optional_asn1_octet_string(cbs, &value, NULL, tag) || CBS_len(&value) > max_out) { @@ -509,11 +486,11 @@ static int SSL_SESSION_parse_bounded_octet_string( return 0; } OPENSSL_memcpy(out, CBS_data(&value), CBS_len(&value)); - *out_len = (uint8_t)CBS_len(&value); + *out_len = static_cast(CBS_len(&value)); return 1; } -static int SSL_SESSION_parse_long(CBS *cbs, long *out, unsigned tag, +static int SSL_SESSION_parse_long(CBS *cbs, long *out, CBS_ASN1_TAG tag, long default_value) { uint64_t value; if (!CBS_get_optional_asn1_uint64(cbs, &value, tag, @@ -526,7 +503,7 @@ static int SSL_SESSION_parse_long(CBS *cbs, long *out, unsigned tag, return 1; } -static int SSL_SESSION_parse_u32(CBS *cbs, uint32_t *out, unsigned tag, +static int SSL_SESSION_parse_u32(CBS *cbs, uint32_t *out, CBS_ASN1_TAG tag, uint32_t default_value) { uint64_t value; if (!CBS_get_optional_asn1_uint64(cbs, &value, tag, @@ -539,7 +516,7 @@ static int SSL_SESSION_parse_u32(CBS *cbs, uint32_t *out, unsigned tag, return 1; } -static int SSL_SESSION_parse_u16(CBS *cbs, uint16_t *out, unsigned tag, +static int SSL_SESSION_parse_u16(CBS *cbs, uint16_t *out, CBS_ASN1_TAG tag, uint16_t default_value) { uint64_t value; if (!CBS_get_optional_asn1_uint64(cbs, &value, tag, @@ -601,9 +578,13 @@ UniquePtr SSL_SESSION_parse(CBS *cbs, return nullptr; } OPENSSL_memcpy(ret->session_id, CBS_data(&session_id), CBS_len(&session_id)); - ret->session_id_length = CBS_len(&session_id); + static_assert(SSL3_MAX_SSL_SESSION_ID_LENGTH <= UINT8_MAX, + "max session ID is too large"); + ret->session_id_length = static_cast(CBS_len(&session_id)); OPENSSL_memcpy(ret->secret, CBS_data(&secret), CBS_len(&secret)); - ret->secret_length = CBS_len(&secret); + static_assert(SSL_MAX_MASTER_KEY_LENGTH <= UINT8_MAX, + "max secret is too large"); + ret->secret_length = static_cast(CBS_len(&secret)); CBS child; uint64_t timeout; @@ -709,7 +690,6 @@ UniquePtr SSL_SESSION_parse(CBS *cbs, if (has_peer || has_cert_chain) { ret->certs.reset(sk_CRYPTO_BUFFER_new_null()); if (ret->certs == nullptr) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return nullptr; } @@ -717,7 +697,6 @@ UniquePtr SSL_SESSION_parse(CBS *cbs, UniquePtr buffer(CRYPTO_BUFFER_new_from_CBS(&peer, pool)); if (!buffer || !PushToStack(ret->certs.get(), std::move(buffer))) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return nullptr; } } @@ -733,7 +712,6 @@ UniquePtr SSL_SESSION_parse(CBS *cbs, UniquePtr buffer(CRYPTO_BUFFER_new_from_CBS(&cert, pool)); if (buffer == nullptr || !PushToStack(ret->certs.get(), std::move(buffer))) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return nullptr; } } @@ -808,7 +786,7 @@ UniquePtr SSL_SESSION_parse(CBS *cbs, return ret; } -int ssl_session_serialize(const SSL_SESSION *in, CBB *cbb) { +bool ssl_session_serialize(const SSL_SESSION *in, CBB *cbb) { return SSL_SESSION_to_bytes_full(in, cbb, 0); } diff --git a/Sources/CNIOBoringSSL/ssl/ssl_cert.cc b/Sources/CNIOBoringSSL/ssl/ssl_cert.cc index db5477dc..969731f9 100644 --- a/Sources/CNIOBoringSSL/ssl/ssl_cert.cc +++ b/Sources/CNIOBoringSSL/ssl/ssl_cert.cc @@ -142,9 +142,9 @@ CERT::~CERT() { x509_method->cert_free(this); } -static CRYPTO_BUFFER *buffer_up_ref(CRYPTO_BUFFER *buffer) { - CRYPTO_BUFFER_up_ref(buffer); - return buffer; +static CRYPTO_BUFFER *buffer_up_ref(const CRYPTO_BUFFER *buffer) { + CRYPTO_BUFFER_up_ref(const_cast(buffer)); + return const_cast(buffer); } UniquePtr ssl_cert_dup(CERT *cert) { @@ -237,14 +237,14 @@ static enum leaf_cert_and_privkey_result_t check_leaf_cert_and_privkey( return leaf_cert_and_privkey_error; } - if (!ssl_is_key_type_supported(pubkey->type)) { + if (!ssl_is_key_type_supported(EVP_PKEY_id(pubkey.get()))) { OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE); return leaf_cert_and_privkey_error; } // An ECC certificate may be usable for ECDH or ECDSA. We only support ECDSA // certificates, so sanity-check the key usage extension. - if (pubkey->type == EVP_PKEY_EC && + if (EVP_PKEY_id(pubkey.get()) == EVP_PKEY_EC && !ssl_cert_check_key_usage(&cert_cbs, key_usage_digital_signature)) { OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE); return leaf_cert_and_privkey_error; @@ -365,7 +365,6 @@ bool ssl_parse_cert_chain(uint8_t *out_alert, UniquePtr chain(sk_CRYPTO_BUFFER_new_null()); if (!chain) { *out_alert = SSL_AD_INTERNAL_ERROR; - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return false; } @@ -397,7 +396,6 @@ bool ssl_parse_cert_chain(uint8_t *out_alert, if (!buf || !PushToStack(chain.get(), std::move(buf))) { *out_alert = SSL_AD_INTERNAL_ERROR; - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return false; } } @@ -623,7 +621,6 @@ UniquePtr ssl_parse_client_CA_list(SSL *ssl, UniquePtr ret(sk_CRYPTO_BUFFER_new_null()); if (!ret) { *out_alert = SSL_AD_INTERNAL_ERROR; - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return nullptr; } @@ -647,7 +644,6 @@ UniquePtr ssl_parse_client_CA_list(SSL *ssl, if (!buffer || !PushToStack(ret.get(), std::move(buffer))) { *out_alert = SSL_AD_INTERNAL_ERROR; - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return nullptr; } } diff --git a/Sources/CNIOBoringSSL/ssl/ssl_cipher.cc b/Sources/CNIOBoringSSL/ssl/ssl_cipher.cc index a8dd7f57..6f0a233b 100644 --- a/Sources/CNIOBoringSSL/ssl/ssl_cipher.cc +++ b/Sources/CNIOBoringSSL/ssl/ssl_cipher.cc @@ -1002,8 +1002,7 @@ static bool ssl_cipher_process_rulestr(const char *rule_str, rule = CIPHER_ADD; l++; continue; - } else if (!(ch >= 'a' && ch <= 'z') && !(ch >= 'A' && ch <= 'Z') && - !(ch >= '0' && ch <= '9')) { + } else if (!OPENSSL_isalnum(ch)) { OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_OPERATOR_IN_GROUP); return false; } else { @@ -1056,8 +1055,7 @@ static bool ssl_cipher_process_rulestr(const char *rule_str, ch = *l; buf = l; buf_len = 0; - while ((ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') || - (ch >= 'a' && ch <= 'z') || ch == '-' || ch == '.' || ch == '_') { + while (OPENSSL_isalnum(ch) || ch == '-' || ch == '.' || ch == '_') { ch = *(++l); buf_len++; } @@ -1150,7 +1148,8 @@ static bool ssl_cipher_process_rulestr(const char *rule_str, } bool ssl_create_cipher_list(UniquePtr *out_cipher_list, - const char *rule_str, bool strict) { + const bool has_aes_hw, const char *rule_str, + bool strict) { // Return with error if nothing to do. if (rule_str == NULL || out_cipher_list == NULL) { return false; @@ -1181,7 +1180,7 @@ bool ssl_create_cipher_list(UniquePtr *out_cipher_list, // CHACHA20 unless there is hardware support for fast and constant-time // AES_GCM. Of the two CHACHA20 variants, the new one is preferred over the // old one. - if (EVP_has_aes_hardware()) { + if (has_aes_hw) { ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128GCM, ~0u, 0, CIPHER_ADD, -1, false, &head, &tail); ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256GCM, ~0u, 0, CIPHER_ADD, -1, @@ -1533,14 +1532,6 @@ const char *SSL_CIPHER_get_kx_name(const SSL_CIPHER *cipher) { } } -char *SSL_CIPHER_get_rfc_name(const SSL_CIPHER *cipher) { - if (cipher == NULL) { - return NULL; - } - - return OPENSSL_strdup(SSL_CIPHER_standard_name(cipher)); -} - int SSL_CIPHER_get_bits(const SSL_CIPHER *cipher, int *out_alg_bits) { if (cipher == NULL) { return 0; diff --git a/Sources/CNIOBoringSSL/ssl/ssl_file.cc b/Sources/CNIOBoringSSL/ssl/ssl_file.cc index 5b2448f1..53c0b379 100644 --- a/Sources/CNIOBoringSSL/ssl/ssl_file.cc +++ b/Sources/CNIOBoringSSL/ssl/ssl_file.cc @@ -124,7 +124,7 @@ #include "internal.h" -static int xname_cmp(const X509_NAME **a, const X509_NAME **b) { +static int xname_cmp(const X509_NAME *const *a, const X509_NAME *const *b) { return X509_NAME_cmp(*a, *b); } @@ -143,7 +143,7 @@ static int add_bio_cert_subjects_to_stack(STACK_OF(X509_NAME) *out, BIO *bio, struct RestoreCmpFunc { ~RestoreCmpFunc() { sk_X509_NAME_set_cmp_func(stack, old_cmp); } STACK_OF(X509_NAME) *stack; - int (*old_cmp)(const X509_NAME **, const X509_NAME **); + int (*old_cmp)(const X509_NAME *const *, const X509_NAME *const *); }; RestoreCmpFunc restore = {out, sk_X509_NAME_set_cmp_func(out, xname_cmp)}; diff --git a/Sources/CNIOBoringSSL/ssl/ssl_key_share.cc b/Sources/CNIOBoringSSL/ssl/ssl_key_share.cc index c4d76538..9f74afa8 100644 --- a/Sources/CNIOBoringSSL/ssl/ssl_key_share.cc +++ b/Sources/CNIOBoringSSL/ssl/ssl_key_share.cc @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -38,85 +39,76 @@ namespace { class ECKeyShare : public SSLKeyShare { public: - ECKeyShare(int nid, uint16_t group_id) : nid_(nid), group_id_(group_id) {} + ECKeyShare(int nid, uint16_t group_id) + : group_(EC_GROUP_new_by_curve_name(nid)), group_id_(group_id) {} uint16_t GroupID() const override { return group_id_; } - bool Offer(CBB *out) override { + bool Generate(CBB *out) override { assert(!private_key_); - // Set up a shared |BN_CTX| for all operations. - UniquePtr bn_ctx(BN_CTX_new()); - if (!bn_ctx) { - return false; - } - BN_CTXScope scope(bn_ctx.get()); - // Generate a private key. - UniquePtr group(EC_GROUP_new_by_curve_name(nid_)); private_key_.reset(BN_new()); - if (!group || !private_key_ || + if (!group_ || !private_key_ || !BN_rand_range_ex(private_key_.get(), 1, - EC_GROUP_get0_order(group.get()))) { + EC_GROUP_get0_order(group_))) { return false; } // Compute the corresponding public key and serialize it. - UniquePtr public_key(EC_POINT_new(group.get())); + UniquePtr public_key(EC_POINT_new(group_)); if (!public_key || - !EC_POINT_mul(group.get(), public_key.get(), private_key_.get(), NULL, - NULL, bn_ctx.get()) || - !EC_POINT_point2cbb(out, group.get(), public_key.get(), - POINT_CONVERSION_UNCOMPRESSED, bn_ctx.get())) { + !EC_POINT_mul(group_, public_key.get(), private_key_.get(), + nullptr, nullptr, /*ctx=*/nullptr) || + !EC_POINT_point2cbb(out, group_, public_key.get(), + POINT_CONVERSION_UNCOMPRESSED, /*ctx=*/nullptr)) { return false; } return true; } - bool Finish(Array *out_secret, uint8_t *out_alert, - Span peer_key) override { - assert(private_key_); + bool Encap(CBB *out_ciphertext, Array *out_secret, + uint8_t *out_alert, Span peer_key) override { + // ECDH may be fit into a KEM-like abstraction by using a second keypair's + // public key as the ciphertext. *out_alert = SSL_AD_INTERNAL_ERROR; + return Generate(out_ciphertext) && Decap(out_secret, out_alert, peer_key); + } - // Set up a shared |BN_CTX| for all operations. - UniquePtr bn_ctx(BN_CTX_new()); - if (!bn_ctx) { - return false; - } - BN_CTXScope scope(bn_ctx.get()); - - UniquePtr group(EC_GROUP_new_by_curve_name(nid_)); - if (!group) { - return false; - } + bool Decap(Array *out_secret, uint8_t *out_alert, + Span ciphertext) override { + assert(group_); + assert(private_key_); + *out_alert = SSL_AD_INTERNAL_ERROR; - UniquePtr peer_point(EC_POINT_new(group.get())); - UniquePtr result(EC_POINT_new(group.get())); - BIGNUM *x = BN_CTX_get(bn_ctx.get()); + UniquePtr peer_point(EC_POINT_new(group_)); + UniquePtr result(EC_POINT_new(group_)); + UniquePtr x(BN_new()); if (!peer_point || !result || !x) { return false; } - if (peer_key.empty() || peer_key[0] != POINT_CONVERSION_UNCOMPRESSED || - !EC_POINT_oct2point(group.get(), peer_point.get(), peer_key.data(), - peer_key.size(), bn_ctx.get())) { + if (ciphertext.empty() || ciphertext[0] != POINT_CONVERSION_UNCOMPRESSED || + !EC_POINT_oct2point(group_, peer_point.get(), ciphertext.data(), + ciphertext.size(), /*ctx=*/nullptr)) { OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECPOINT); *out_alert = SSL_AD_DECODE_ERROR; return false; } // Compute the x-coordinate of |peer_key| * |private_key_|. - if (!EC_POINT_mul(group.get(), result.get(), NULL, peer_point.get(), - private_key_.get(), bn_ctx.get()) || - !EC_POINT_get_affine_coordinates_GFp(group.get(), result.get(), x, NULL, - bn_ctx.get())) { + if (!EC_POINT_mul(group_, result.get(), NULL, peer_point.get(), + private_key_.get(), /*ctx=*/nullptr) || + !EC_POINT_get_affine_coordinates_GFp(group_, result.get(), x.get(), + NULL, + /*ctx=*/nullptr)) { return false; } // Encode the x-coordinate left-padded with zeros. Array secret; - if (!secret.Init((EC_GROUP_get_degree(group.get()) + 7) / 8) || - !BN_bn2bin_padded(secret.data(), secret.size(), x)) { + if (!secret.Init((EC_GROUP_get_degree(group_) + 7) / 8) || + !BN_bn2bin_padded(secret.data(), secret.size(), x.get())) { return false; } @@ -125,10 +117,10 @@ class ECKeyShare : public SSLKeyShare { } bool SerializePrivateKey(CBB *out) override { + assert(group_); assert(private_key_); - UniquePtr group(EC_GROUP_new_by_curve_name(nid_)); // Padding is added to avoid leaking the length. - size_t len = BN_num_bytes(EC_GROUP_get0_order(group.get())); + size_t len = BN_num_bytes(EC_GROUP_get0_order(group_)); return BN_bn2cbb_padded(out, len, private_key_.get()); } @@ -140,7 +132,7 @@ class ECKeyShare : public SSLKeyShare { private: UniquePtr private_key_; - int nid_; + const EC_GROUP *const group_ = nullptr; uint16_t group_id_; }; @@ -150,24 +142,31 @@ class X25519KeyShare : public SSLKeyShare { uint16_t GroupID() const override { return SSL_CURVE_X25519; } - bool Offer(CBB *out) override { + bool Generate(CBB *out) override { uint8_t public_key[32]; X25519_keypair(public_key, private_key_); return !!CBB_add_bytes(out, public_key, sizeof(public_key)); } - bool Finish(Array *out_secret, uint8_t *out_alert, - Span peer_key) override { + bool Encap(CBB *out_ciphertext, Array *out_secret, + uint8_t *out_alert, Span peer_key) override { + // X25519 may be fit into a KEM-like abstraction by using a second keypair's + // public key as the ciphertext. + *out_alert = SSL_AD_INTERNAL_ERROR; + return Generate(out_ciphertext) && Decap(out_secret, out_alert, peer_key); + } + + bool Decap(Array *out_secret, uint8_t *out_alert, + Span ciphertext) override { *out_alert = SSL_AD_INTERNAL_ERROR; Array secret; if (!secret.Init(32)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return false; } - if (peer_key.size() != 32 || - !X25519(secret.data(), private_key_, peer_key.data())) { + if (ciphertext.size() != 32 || // + !X25519(secret.data(), private_key_, ciphertext.data())) { *out_alert = SSL_AD_DECODE_ERROR; OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECPOINT); return false; @@ -199,7 +198,7 @@ class CECPQ2KeyShare : public SSLKeyShare { uint16_t GroupID() const override { return SSL_CURVE_CECPQ2; } - bool Offer(CBB *out) override { + bool Generate(CBB *out) override { uint8_t x25519_public_key[32]; X25519_keypair(x25519_public_key, x25519_private_key_); @@ -223,11 +222,10 @@ class CECPQ2KeyShare : public SSLKeyShare { return true; } - bool Accept(CBB *out_public_key, Array *out_secret, - uint8_t *out_alert, Span peer_key) override { + bool Encap(CBB *out_ciphertext, Array *out_secret, + uint8_t *out_alert, Span peer_key) override { Array secret; if (!secret.Init(32 + HRSS_KEY_BYTES)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return false; } @@ -249,9 +247,9 @@ class CECPQ2KeyShare : public SSLKeyShare { if (!HRSS_encap(ciphertext, secret.data() + 32, &peer_public_key, entropy) || - !CBB_add_bytes(out_public_key, x25519_public_key, + !CBB_add_bytes(out_ciphertext, x25519_public_key, sizeof(x25519_public_key)) || - !CBB_add_bytes(out_public_key, ciphertext, sizeof(ciphertext))) { + !CBB_add_bytes(out_ciphertext, ciphertext, sizeof(ciphertext))) { return false; } @@ -259,25 +257,24 @@ class CECPQ2KeyShare : public SSLKeyShare { return true; } - bool Finish(Array *out_secret, uint8_t *out_alert, - Span peer_key) override { + bool Decap(Array *out_secret, uint8_t *out_alert, + Span ciphertext) override { *out_alert = SSL_AD_INTERNAL_ERROR; Array secret; if (!secret.Init(32 + HRSS_KEY_BYTES)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return false; } - if (peer_key.size() != 32 + HRSS_CIPHERTEXT_BYTES || - !X25519(secret.data(), x25519_private_key_, peer_key.data())) { + if (ciphertext.size() != 32 + HRSS_CIPHERTEXT_BYTES || + !X25519(secret.data(), x25519_private_key_, ciphertext.data())) { *out_alert = SSL_AD_DECODE_ERROR; OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECPOINT); return false; } if (!HRSS_decap(secret.data() + 32, &hrss_private_key_, - peer_key.data() + 32, peer_key.size() - 32)) { + ciphertext.data() + 32, ciphertext.size() - 32)) { return false; } @@ -290,6 +287,118 @@ class CECPQ2KeyShare : public SSLKeyShare { HRSS_private_key hrss_private_key_; }; +class X25519Kyber768KeyShare : public SSLKeyShare { + public: + X25519Kyber768KeyShare() {} + + uint16_t GroupID() const override { return SSL_CURVE_X25519KYBER768; } + + bool Generate(CBB *out) override { + uint8_t x25519_public_key[32]; + X25519_keypair(x25519_public_key, x25519_private_key_); + + uint8_t kyber_public_key[KYBER_PUBLIC_KEY_BYTES]; + KYBER_generate_key(kyber_public_key, &kyber_private_key_); + + if (!CBB_add_bytes(out, x25519_public_key, sizeof(x25519_public_key)) || + !CBB_add_bytes(out, kyber_public_key, sizeof(kyber_public_key))) { + return false; + } + + return true; + } + + bool Encap(CBB *out_ciphertext, Array *out_secret, + uint8_t *out_alert, Span peer_key) override { + Array secret; + if (!secret.Init(32 + 32)) { + return false; + } + + uint8_t x25519_public_key[32]; + X25519_keypair(x25519_public_key, x25519_private_key_); + KYBER_public_key peer_kyber_pub; + CBS peer_key_cbs; + CBS peer_x25519_cbs; + CBS peer_kyber_cbs; + CBS_init(&peer_key_cbs, peer_key.data(), peer_key.size()); + if (!CBS_get_bytes(&peer_key_cbs, &peer_x25519_cbs, 32) || + !CBS_get_bytes(&peer_key_cbs, &peer_kyber_cbs, + KYBER_PUBLIC_KEY_BYTES) || + CBS_len(&peer_key_cbs) != 0 || + !X25519(secret.data(), x25519_private_key_, + CBS_data(&peer_x25519_cbs)) || + !KYBER_parse_public_key(&peer_kyber_pub, &peer_kyber_cbs)) { + *out_alert = SSL_AD_DECODE_ERROR; + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECPOINT); + return false; + } + + uint8_t kyber_ciphertext[KYBER_CIPHERTEXT_BYTES]; + KYBER_encap(kyber_ciphertext, secret.data() + 32, secret.size() - 32, + &peer_kyber_pub); + + if (!CBB_add_bytes(out_ciphertext, x25519_public_key, + sizeof(x25519_public_key)) || + !CBB_add_bytes(out_ciphertext, kyber_ciphertext, + sizeof(kyber_ciphertext))) { + return false; + } + + *out_secret = std::move(secret); + return true; + } + + bool Decap(Array *out_secret, uint8_t *out_alert, + Span ciphertext) override { + *out_alert = SSL_AD_INTERNAL_ERROR; + + Array secret; + if (!secret.Init(32 + 32)) { + return false; + } + + if (ciphertext.size() != 32 + KYBER_CIPHERTEXT_BYTES || + !X25519(secret.data(), x25519_private_key_, ciphertext.data())) { + *out_alert = SSL_AD_DECODE_ERROR; + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECPOINT); + return false; + } + + KYBER_decap(secret.data() + 32, secret.size() - 32, ciphertext.data() + 32, + &kyber_private_key_); + *out_secret = std::move(secret); + return true; + } + + private: + uint8_t x25519_private_key_[32]; + KYBER_private_key kyber_private_key_; +}; + +class P256Kyber768KeyShare : public SSLKeyShare { + public: + P256Kyber768KeyShare() {} + + uint16_t GroupID() const override { return SSL_CURVE_P256KYBER768; } + + bool Generate(CBB *out) override { + // There is no implementation on Kyber in BoringSSL. BoringSSL must be + // patched for this KEM to be workable. It is not enabled by default. + return false; + } + + bool Encap(CBB *out_ciphertext, Array *out_secret, + uint8_t *out_alert, Span peer_key) override { + return false; + } + + bool Decap(Array *out_secret, uint8_t *out_alert, + Span ciphertext) override { + return false; + } +}; + constexpr NamedGroup kNamedGroups[] = { {NID_secp224r1, SSL_CURVE_SECP224R1, "P-224", "secp224r1"}, {NID_X9_62_prime256v1, SSL_CURVE_SECP256R1, "P-256", "prime256v1"}, @@ -297,6 +406,9 @@ constexpr NamedGroup kNamedGroups[] = { {NID_secp521r1, SSL_CURVE_SECP521R1, "P-521", "secp521r1"}, {NID_X25519, SSL_CURVE_X25519, "X25519", "x25519"}, {NID_CECPQ2, SSL_CURVE_CECPQ2, "CECPQ2", "CECPQ2"}, + {NID_X25519Kyber768, SSL_CURVE_X25519KYBER768, "X25519KYBER", + "X25519Kyber"}, + {NID_P256Kyber768, SSL_CURVE_P256KYBER768, "P256KYBER", "P256Kyber"}, }; } // namespace @@ -308,58 +420,26 @@ Span NamedGroups() { UniquePtr SSLKeyShare::Create(uint16_t group_id) { switch (group_id) { case SSL_CURVE_SECP224R1: - return UniquePtr( - New(NID_secp224r1, SSL_CURVE_SECP224R1)); + return MakeUnique(NID_secp224r1, SSL_CURVE_SECP224R1); case SSL_CURVE_SECP256R1: - return UniquePtr( - New(NID_X9_62_prime256v1, SSL_CURVE_SECP256R1)); + return MakeUnique(NID_X9_62_prime256v1, SSL_CURVE_SECP256R1); case SSL_CURVE_SECP384R1: - return UniquePtr( - New(NID_secp384r1, SSL_CURVE_SECP384R1)); + return MakeUnique(NID_secp384r1, SSL_CURVE_SECP384R1); case SSL_CURVE_SECP521R1: - return UniquePtr( - New(NID_secp521r1, SSL_CURVE_SECP521R1)); + return MakeUnique(NID_secp521r1, SSL_CURVE_SECP521R1); case SSL_CURVE_X25519: - return UniquePtr(New()); + return MakeUnique(); case SSL_CURVE_CECPQ2: - return UniquePtr(New()); + return MakeUnique(); + case SSL_CURVE_X25519KYBER768: + return MakeUnique(); + case SSL_CURVE_P256KYBER768: + return MakeUnique(); default: return nullptr; } } -UniquePtr SSLKeyShare::Create(CBS *in) { - uint64_t group; - CBS private_key; - if (!CBS_get_asn1_uint64(in, &group) || group > 0xffff || - !CBS_get_asn1(in, &private_key, CBS_ASN1_OCTETSTRING)) { - return nullptr; - } - UniquePtr key_share = Create(static_cast(group)); - if (!key_share || !key_share->DeserializePrivateKey(&private_key)) { - return nullptr; - } - return key_share; -} - -bool SSLKeyShare::Serialize(CBB *out) { - CBB private_key; - if (!CBB_add_asn1_uint64(out, GroupID()) || - !CBB_add_asn1(out, &private_key, CBS_ASN1_OCTETSTRING) || - !SerializePrivateKey(&private_key) || // - !CBB_flush(out)) { - return false; - } - return true; -} - -bool SSLKeyShare::Accept(CBB *out_public_key, Array *out_secret, - uint8_t *out_alert, Span peer_key) { - *out_alert = SSL_AD_INTERNAL_ERROR; - return Offer(out_public_key) && - Finish(out_secret, out_alert, peer_key); -} - bool ssl_nid_to_group_id(uint16_t *out_group_id, int nid) { for (const auto &group : kNamedGroups) { if (group.nid == nid) { diff --git a/Sources/CNIOBoringSSL/ssl/ssl_lib.cc b/Sources/CNIOBoringSSL/ssl/ssl_lib.cc index 83a2b2ce..93746a0e 100644 --- a/Sources/CNIOBoringSSL/ssl/ssl_lib.cc +++ b/Sources/CNIOBoringSSL/ssl/ssl_lib.cc @@ -143,6 +143,7 @@ #include #include +#include #include #include @@ -483,6 +484,17 @@ bool SSL_get_traffic_secrets(const SSL *ssl, return true; } +void SSL_CTX_set_aes_hw_override_for_testing(SSL_CTX *ctx, + bool override_value) { + ctx->aes_hw_override = true; + ctx->aes_hw_override_value = override_value; +} + +void SSL_set_aes_hw_override_for_testing(SSL *ssl, bool override_value) { + ssl->config->aes_hw_override = true; + ssl->config->aes_hw_override_value = override_value; +} + BSSL_NAMESPACE_END using namespace bssl; @@ -524,7 +536,9 @@ ssl_ctx_st::ssl_ctx_st(const SSL_METHOD *ssl_method) false_start_allowed_without_alpn(false), handoff(false), enable_early_data(false), - only_fips_cipher_suites_in_tls13(false) { + only_fips_cipher_suites_in_tls13(false), + aes_hw_override(false), + aes_hw_override_value(false) { CRYPTO_MUTEX_init(&lock); CRYPTO_new_ex_data(&ex_data); } @@ -646,6 +660,8 @@ SSL *SSL_new(SSL_CTX *ctx) { ssl->config->permute_extensions = ctx->permute_extensions; ssl->config->only_fips_cipher_suites_in_tls13 = ctx->only_fips_cipher_suites_in_tls13; + ssl->config->aes_hw_override = ctx->aes_hw_override; + ssl->config->aes_hw_override_value = ctx->aes_hw_override_value; if (!ssl->config->supported_group_list.CopyFrom(ctx->supported_group_list) || !ssl->config->alpn_client_proto_list.CopyFrom( @@ -687,7 +703,7 @@ SSL_CONFIG::SSL_CONFIG(SSL *ssl_arg) signed_cert_timestamps_enabled(false), ocsp_stapling_enabled(false), channel_id_enabled(false), - enforce_rsa_key_usage(true), + enforce_rsa_key_usage(false), retain_only_sha256_of_client_certs(false), handoff(false), shed_handshake_config(false), @@ -2025,18 +2041,27 @@ const char *SSL_get_cipher_list(const SSL *ssl, int n) { } int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str) { - return ssl_create_cipher_list(&ctx->cipher_list, str, false /* not strict */); + const bool has_aes_hw = ctx->aes_hw_override ? ctx->aes_hw_override_value + : EVP_has_aes_hardware(); + return ssl_create_cipher_list(&ctx->cipher_list, has_aes_hw, str, + false /* not strict */); } int SSL_CTX_set_strict_cipher_list(SSL_CTX *ctx, const char *str) { - return ssl_create_cipher_list(&ctx->cipher_list, str, true /* strict */); + const bool has_aes_hw = ctx->aes_hw_override ? ctx->aes_hw_override_value + : EVP_has_aes_hardware(); + return ssl_create_cipher_list(&ctx->cipher_list, has_aes_hw, str, + true /* strict */); } int SSL_set_cipher_list(SSL *ssl, const char *str) { if (!ssl->config) { return 0; } - return ssl_create_cipher_list(&ssl->config->cipher_list, str, + const bool has_aes_hw = ssl->config->aes_hw_override + ? ssl->config->aes_hw_override_value + : EVP_has_aes_hardware(); + return ssl_create_cipher_list(&ssl->config->cipher_list, has_aes_hw, str, false /* not strict */); } @@ -2044,7 +2069,10 @@ int SSL_set_strict_cipher_list(SSL *ssl, const char *str) { if (!ssl->config) { return 0; } - return ssl_create_cipher_list(&ssl->config->cipher_list, str, + const bool has_aes_hw = ssl->config->aes_hw_override + ? ssl->config->aes_hw_override_value + : EVP_has_aes_hardware(); + return ssl_create_cipher_list(&ssl->config->cipher_list, has_aes_hw, str, true /* strict */); } @@ -2147,7 +2175,6 @@ int SSL_set_tlsext_host_name(SSL *ssl, const char *name) { } ssl->hostname.reset(OPENSSL_strdup(name)); if (ssl->hostname == nullptr) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } return 1; @@ -2199,8 +2226,10 @@ int SSL_select_next_proto(uint8_t **out, uint8_t *out_len, const uint8_t *peer, void SSL_get0_next_proto_negotiated(const SSL *ssl, const uint8_t **out_data, unsigned *out_len) { + // NPN protocols have one-byte lengths, so they must fit in |unsigned|. + assert(ssl->s3->next_proto_negotiated.size() <= UINT_MAX); *out_data = ssl->s3->next_proto_negotiated.data(); - *out_len = ssl->s3->next_proto_negotiated.size(); + *out_len = static_cast(ssl->s3->next_proto_negotiated.size()); } void SSL_CTX_set_next_protos_advertised_cb( @@ -2220,7 +2249,7 @@ void SSL_CTX_set_next_proto_select_cb( } int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const uint8_t *protos, - unsigned protos_len) { + size_t protos_len) { // Note this function's return value is backwards. auto span = MakeConstSpan(protos, protos_len); if (!span.empty() && !ssl_is_valid_alpn_list(span)) { @@ -2230,7 +2259,7 @@ int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const uint8_t *protos, return ctx->alpn_client_proto_list.CopyFrom(span) ? 0 : 1; } -int SSL_set_alpn_protos(SSL *ssl, const uint8_t *protos, unsigned protos_len) { +int SSL_set_alpn_protos(SSL *ssl, const uint8_t *protos, size_t protos_len) { // Note this function's return value is backwards. if (!ssl->config) { return 1; @@ -2254,13 +2283,16 @@ void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx, void SSL_get0_alpn_selected(const SSL *ssl, const uint8_t **out_data, unsigned *out_len) { + Span protocol; if (SSL_in_early_data(ssl) && !ssl->server) { - *out_data = ssl->s3->hs->early_session->early_alpn.data(); - *out_len = ssl->s3->hs->early_session->early_alpn.size(); + protocol = ssl->s3->hs->early_session->early_alpn; } else { - *out_data = ssl->s3->alpn_selected.data(); - *out_len = ssl->s3->alpn_selected.size(); + protocol = ssl->s3->alpn_selected; } + // ALPN protocols have one-byte lengths, so they must fit in |unsigned|. + assert(protocol.size() < UINT_MAX); + *out_data = protocol.data(); + *out_len = static_cast(protocol.size()); } void SSL_CTX_set_allow_unknown_alpn_protos(SSL_CTX *ctx, int enabled) { @@ -2801,6 +2833,10 @@ void SSL_set_enforce_rsa_key_usage(SSL *ssl, int enabled) { ssl->config->enforce_rsa_key_usage = !!enabled; } +int SSL_was_key_usage_invalid(const SSL *ssl) { + return ssl->s3->was_key_usage_invalid; +} + void SSL_set_renegotiate_mode(SSL *ssl, enum ssl_renegotiate_mode_t mode) { ssl->renegotiate_mode = mode; diff --git a/Sources/CNIOBoringSSL/ssl/ssl_privkey.cc b/Sources/CNIOBoringSSL/ssl/ssl_privkey.cc index 516e768d..57c96a5c 100644 --- a/Sources/CNIOBoringSSL/ssl/ssl_privkey.cc +++ b/Sources/CNIOBoringSSL/ssl/ssl_privkey.cc @@ -77,7 +77,7 @@ bool ssl_is_key_type_supported(int key_type) { } static bool ssl_set_pkey(CERT *cert, EVP_PKEY *pkey) { - if (!ssl_is_key_type_supported(pkey->type)) { + if (!ssl_is_key_type_supported(EVP_PKEY_id(pkey))) { OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE); return false; } @@ -151,6 +151,20 @@ static bool pkey_supports_algorithm(const SSL *ssl, EVP_PKEY *pkey, return false; } + if (ssl_protocol_version(ssl) < TLS1_2_VERSION) { + // TLS 1.0 and 1.1 do not negotiate algorithms and always sign one of two + // hardcoded algorithms. + return sigalg == SSL_SIGN_RSA_PKCS1_MD5_SHA1 || + sigalg == SSL_SIGN_ECDSA_SHA1; + } + + // |SSL_SIGN_RSA_PKCS1_MD5_SHA1| is not a real SignatureScheme for TLS 1.2 and + // higher. It is an internal value we use to represent TLS 1.0/1.1's MD5/SHA1 + // concatenation. + if (sigalg == SSL_SIGN_RSA_PKCS1_MD5_SHA1) { + return false; + } + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { // RSA keys may only be used with RSA-PSS. if (alg->pkey_type == EVP_PKEY_RSA && !alg->is_rsa_pss) { @@ -531,9 +545,83 @@ int SSL_is_signature_algorithm_rsa_pss(uint16_t sigalg) { return alg != nullptr && alg->is_rsa_pss; } +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); + if (u1 < u2) { + return -1; + } else if (u1 > u2) { + return 1; + } else { + return 0; + } +} + +static bool sigalgs_unique(Span in_sigalgs) { + if (in_sigalgs.size() < 2) { + return true; + } + + Array sigalgs; + if (!sigalgs.CopyFrom(in_sigalgs)) { + return false; + } + + qsort(sigalgs.data(), sigalgs.size(), sizeof(uint16_t), compare_uint16_t); + + for (size_t i = 1; i < sigalgs.size(); i++) { + if (sigalgs[i - 1] == sigalgs[i]) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DUPLICATE_SIGNATURE_ALGORITHM); + return false; + } + } + + return true; +} + +static bool set_sigalg_prefs(Array *out, Span prefs) { + if (!sigalgs_unique(prefs)) { + return false; + } + + // Check for invalid algorithms, and filter out |SSL_SIGN_RSA_PKCS1_MD5_SHA1|. + Array filtered; + if (!filtered.Init(prefs.size())) { + return false; + } + size_t added = 0; + for (uint16_t pref : prefs) { + if (pref == SSL_SIGN_RSA_PKCS1_MD5_SHA1) { + // Though not intended to be used with this API, we treat + // |SSL_SIGN_RSA_PKCS1_MD5_SHA1| as a real signature algorithm in + // |SSL_PRIVATE_KEY_METHOD|. Not accepting it here makes for a confusing + // abstraction. + continue; + } + if (get_signature_algorithm(pref) == nullptr) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SIGNATURE_ALGORITHM); + return false; + } + filtered[added] = pref; + added++; + } + filtered.Shrink(added); + + // This can happen if |prefs| contained only |SSL_SIGN_RSA_PKCS1_MD5_SHA1|. + // Leaving it empty would revert to the default, so treat this as an error + // condition. + if (!prefs.empty() && filtered.empty()) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SIGNATURE_ALGORITHM); + return false; + } + + *out = std::move(filtered); + return true; +} + int SSL_CTX_set_signing_algorithm_prefs(SSL_CTX *ctx, const uint16_t *prefs, size_t num_prefs) { - return ctx->cert->sigalgs.CopyFrom(MakeConstSpan(prefs, num_prefs)); + return set_sigalg_prefs(&ctx->cert->sigalgs, MakeConstSpan(prefs, num_prefs)); } int SSL_set_signing_algorithm_prefs(SSL *ssl, const uint16_t *prefs, @@ -541,7 +629,8 @@ int SSL_set_signing_algorithm_prefs(SSL *ssl, const uint16_t *prefs, if (!ssl->config) { return 0; } - return ssl->config->cert->sigalgs.CopyFrom(MakeConstSpan(prefs, num_prefs)); + return set_sigalg_prefs(&ssl->config->cert->sigalgs, + MakeConstSpan(prefs, num_prefs)); } static constexpr struct { @@ -597,50 +686,16 @@ static bool parse_sigalg_pairs(Array *out, const int *values, return true; } -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); - if (u1 < u2) { - return -1; - } else if (u1 > u2) { - return 1; - } else { - return 0; - } -} - -static bool sigalgs_unique(Span in_sigalgs) { - if (in_sigalgs.size() < 2) { - return true; - } - - Array sigalgs; - if (!sigalgs.CopyFrom(in_sigalgs)) { - return false; - } - - qsort(sigalgs.data(), sigalgs.size(), sizeof(uint16_t), compare_uint16_t); - - for (size_t i = 1; i < sigalgs.size(); i++) { - if (sigalgs[i - 1] == sigalgs[i]) { - OPENSSL_PUT_ERROR(SSL, SSL_R_DUPLICATE_SIGNATURE_ALGORITHM); - return false; - } - } - - return true; -} - int SSL_CTX_set1_sigalgs(SSL_CTX *ctx, const int *values, size_t num_values) { Array sigalgs; - if (!parse_sigalg_pairs(&sigalgs, values, num_values) || - !sigalgs_unique(sigalgs)) { + if (!parse_sigalg_pairs(&sigalgs, values, num_values)) { return 0; } if (!SSL_CTX_set_signing_algorithm_prefs(ctx, sigalgs.data(), sigalgs.size()) || - !ctx->verify_sigalgs.CopyFrom(sigalgs)) { + !SSL_CTX_set_verify_algorithm_prefs(ctx, sigalgs.data(), + sigalgs.size())) { return 0; } @@ -654,13 +709,12 @@ int SSL_set1_sigalgs(SSL *ssl, const int *values, size_t num_values) { } Array sigalgs; - if (!parse_sigalg_pairs(&sigalgs, values, num_values) || - !sigalgs_unique(sigalgs)) { + if (!parse_sigalg_pairs(&sigalgs, values, num_values)) { return 0; } if (!SSL_set_signing_algorithm_prefs(ssl, sigalgs.data(), sigalgs.size()) || - !ssl->config->verify_sigalgs.CopyFrom(sigalgs)) { + !SSL_set_verify_algorithm_prefs(ssl, sigalgs.data(), sigalgs.size())) { return 0; } @@ -805,8 +859,7 @@ static bool parse_sigalgs_list(Array *out, const char *str) { return false; } - if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || - (c >= 'A' && c <= 'Z') || c == '-' || c == '_') { + if (OPENSSL_isalnum(c) || c == '-' || c == '_') { buf[buf_used++] = c; } else { OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SIGNATURE_ALGORITHM); @@ -823,8 +876,7 @@ static bool parse_sigalgs_list(Array *out, const char *str) { int SSL_CTX_set1_sigalgs_list(SSL_CTX *ctx, const char *str) { Array sigalgs; - if (!parse_sigalgs_list(&sigalgs, str) || - !sigalgs_unique(sigalgs)) { + if (!parse_sigalgs_list(&sigalgs, str)) { return 0; } @@ -845,8 +897,7 @@ int SSL_set1_sigalgs_list(SSL *ssl, const char *str) { } Array sigalgs; - if (!parse_sigalgs_list(&sigalgs, str) || - !sigalgs_unique(sigalgs)) { + if (!parse_sigalgs_list(&sigalgs, str)) { return 0; } @@ -860,7 +911,8 @@ int SSL_set1_sigalgs_list(SSL *ssl, const char *str) { int SSL_CTX_set_verify_algorithm_prefs(SSL_CTX *ctx, const uint16_t *prefs, size_t num_prefs) { - return ctx->verify_sigalgs.CopyFrom(MakeConstSpan(prefs, num_prefs)); + return set_sigalg_prefs(&ctx->verify_sigalgs, + MakeConstSpan(prefs, num_prefs)); } int SSL_set_verify_algorithm_prefs(SSL *ssl, const uint16_t *prefs, @@ -870,5 +922,6 @@ int SSL_set_verify_algorithm_prefs(SSL *ssl, const uint16_t *prefs, return 0; } - return ssl->config->verify_sigalgs.CopyFrom(MakeConstSpan(prefs, num_prefs)); + return set_sigalg_prefs(&ssl->config->verify_sigalgs, + MakeConstSpan(prefs, num_prefs)); } diff --git a/Sources/CNIOBoringSSL/ssl/ssl_session.cc b/Sources/CNIOBoringSSL/ssl/ssl_session.cc index 9c73441a..b5acb451 100644 --- a/Sources/CNIOBoringSSL/ssl/ssl_session.cc +++ b/Sources/CNIOBoringSSL/ssl/ssl_session.cc @@ -214,9 +214,9 @@ UniquePtr SSL_SESSION_dup(SSL_SESSION *session, int dup_flags) { } } if (session->certs != nullptr) { - auto buf_up_ref = [](CRYPTO_BUFFER *buf) { - CRYPTO_BUFFER_up_ref(buf); - return buf; + auto buf_up_ref = [](const CRYPTO_BUFFER *buf) { + CRYPTO_BUFFER_up_ref(const_cast(buf)); + return const_cast(buf); }; new_session->certs.reset(sk_CRYPTO_BUFFER_deep_copy( session->certs.get(), buf_up_ref, CRYPTO_BUFFER_free)); @@ -400,7 +400,7 @@ bool ssl_get_new_session(SSL_HANDSHAKE *hs) { return true; } -int ssl_ctx_rotate_ticket_encryption_key(SSL_CTX *ctx) { +bool ssl_ctx_rotate_ticket_encryption_key(SSL_CTX *ctx) { OPENSSL_timeval now; ssl_ctx_get_current_time(ctx, &now); { @@ -412,7 +412,7 @@ int ssl_ctx_rotate_ticket_encryption_key(SSL_CTX *ctx) { ctx->ticket_key_current->next_rotation_tv_sec > now.tv_sec) && (!ctx->ticket_key_prev || ctx->ticket_key_prev->next_rotation_tv_sec > now.tv_sec)) { - return 1; + return true; } } @@ -423,7 +423,7 @@ int ssl_ctx_rotate_ticket_encryption_key(SSL_CTX *ctx) { // The current key has not been initialized or it is expired. auto new_key = bssl::MakeUnique(); if (!new_key) { - return 0; + return false; } RAND_bytes(new_key->name, 16); RAND_bytes(new_key->hmac_key, 16); @@ -447,7 +447,7 @@ int ssl_ctx_rotate_ticket_encryption_key(SSL_CTX *ctx) { ctx->ticket_key_prev.reset(); } - return 1; + return true; } static int ssl_encrypt_ticket_with_cipher_ctx(SSL_HANDSHAKE *hs, CBB *out, @@ -560,30 +560,28 @@ static int ssl_encrypt_ticket_with_method(SSL_HANDSHAKE *hs, CBB *out, return 1; } -int ssl_encrypt_ticket(SSL_HANDSHAKE *hs, CBB *out, +bool ssl_encrypt_ticket(SSL_HANDSHAKE *hs, CBB *out, const SSL_SESSION *session) { // Serialize the SSL_SESSION to be encoded into the ticket. - uint8_t *session_buf = NULL; + uint8_t *session_buf = nullptr; size_t session_len; if (!SSL_SESSION_to_bytes_for_ticket(session, &session_buf, &session_len)) { - return -1; + return false; } + bssl::UniquePtr free_session_buf(session_buf); - int ret = 0; if (hs->ssl->session_ctx->ticket_aead_method) { - ret = ssl_encrypt_ticket_with_method(hs, out, session_buf, session_len); + return ssl_encrypt_ticket_with_method(hs, out, session_buf, session_len); } else { - ret = ssl_encrypt_ticket_with_cipher_ctx(hs, out, session_buf, session_len); + return ssl_encrypt_ticket_with_cipher_ctx(hs, out, session_buf, + session_len); } - - OPENSSL_free(session_buf); - return ret; } -int ssl_session_is_context_valid(const SSL_HANDSHAKE *hs, - const SSL_SESSION *session) { +bool ssl_session_is_context_valid(const SSL_HANDSHAKE *hs, + const SSL_SESSION *session) { if (session == NULL) { - return 0; + return false; } return session->sid_ctx_length == hs->config->cert->sid_ctx_length && @@ -591,9 +589,9 @@ int ssl_session_is_context_valid(const SSL_HANDSHAKE *hs, hs->config->cert->sid_ctx_length) == 0; } -int ssl_session_is_time_valid(const SSL *ssl, const SSL_SESSION *session) { +bool ssl_session_is_time_valid(const SSL *ssl, const SSL_SESSION *session) { if (session == NULL) { - return 0; + return false; } struct OPENSSL_timeval now; @@ -601,14 +599,14 @@ int ssl_session_is_time_valid(const SSL *ssl, const SSL_SESSION *session) { // Reject tickets from the future to avoid underflow. if (now.tv_sec < session->time) { - return 0; + return false; } return session->timeout > now.tv_sec - session->time; } -int ssl_session_is_resumable(const SSL_HANDSHAKE *hs, - const SSL_SESSION *session) { +bool ssl_session_is_resumable(const SSL_HANDSHAKE *hs, + const SSL_SESSION *session) { const SSL *const ssl = hs->ssl; return ssl_session_is_context_valid(hs, session) && // The session must have been created by the same type of end point as diff --git a/Sources/CNIOBoringSSL/ssl/ssl_x509.cc b/Sources/CNIOBoringSSL/ssl/ssl_x509.cc index 0ed6fc71..36847350 100644 --- a/Sources/CNIOBoringSSL/ssl/ssl_x509.cc +++ b/Sources/CNIOBoringSSL/ssl/ssl_x509.cc @@ -284,7 +284,6 @@ static bool ssl_crypto_x509_session_cache_objects(SSL_SESSION *sess) { if (sk_CRYPTO_BUFFER_num(sess->certs.get()) > 0) { chain.reset(sk_X509_new_null()); if (!chain) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return false; } if (sess->is_server) { @@ -292,7 +291,6 @@ static bool ssl_crypto_x509_session_cache_objects(SSL_SESSION *sess) { // |SSL_get_peer_cert_chain|. chain_without_leaf.reset(sk_X509_new_null()); if (!chain_without_leaf) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return false; } } @@ -309,11 +307,9 @@ static bool ssl_crypto_x509_session_cache_objects(SSL_SESSION *sess) { leaf = UpRef(x509); } else if (chain_without_leaf && !PushToStack(chain_without_leaf.get(), UpRef(x509))) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return false; } if (!PushToStack(chain.get(), std::move(x509))) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return false; } } @@ -1041,7 +1037,11 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const uint8_t **pp, long length) { } STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *list) { - return sk_X509_NAME_deep_copy(list, X509_NAME_dup, X509_NAME_free); + // TODO(https://crbug.com/boringssl/407): |X509_NAME_dup| should be const. + auto name_dup = [](const X509_NAME *name) { + return X509_NAME_dup(const_cast(name)); + }; + return sk_X509_NAME_deep_copy(list, name_dup, X509_NAME_free); } static void set_client_CA_list(UniquePtr *ca_list, @@ -1100,7 +1100,6 @@ static STACK_OF(X509_NAME) * UniquePtr new_cache(sk_X509_NAME_new_null()); if (!new_cache) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return NULL; } diff --git a/Sources/CNIOBoringSSL/ssl/t1_enc.cc b/Sources/CNIOBoringSSL/ssl/t1_enc.cc index 5c1b8c64..dab57645 100644 --- a/Sources/CNIOBoringSSL/ssl/t1_enc.cc +++ b/Sources/CNIOBoringSSL/ssl/t1_enc.cc @@ -333,16 +333,12 @@ 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) { - // Exporters may be used in False Start and server 0-RTT, where the handshake - // has progressed enough. Otherwise, they may not be used during a handshake. - if (SSL_in_init(ssl) && - !SSL_in_false_start(ssl) && - !(SSL_is_server(ssl) && SSL_in_early_data(ssl))) { - OPENSSL_PUT_ERROR(SSL, SSL_R_HANDSHAKE_NOT_COMPLETE); - return 0; - } - - if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + // In TLS 1.3, the exporter may be used whenever the secret has been derived. + if (ssl->s3->have_version && ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + if (ssl->s3->exporter_secret_len == 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_HANDSHAKE_NOT_COMPLETE); + return 0; + } if (!use_context) { context = nullptr; context_len = 0; @@ -353,6 +349,13 @@ int SSL_export_keying_material(SSL *ssl, uint8_t *out, size_t out_len, MakeConstSpan(label, label_len), MakeConstSpan(context, context_len)); } + // Exporters may be used in False Start, where the handshake has progressed + // enough. Otherwise, they may not be used during a handshake. + if (SSL_in_init(ssl) && !SSL_in_false_start(ssl)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_HANDSHAKE_NOT_COMPLETE); + return 0; + } + size_t seed_len = 2 * SSL3_RANDOM_SIZE; if (use_context) { if (context_len >= 1u << 16) { @@ -363,7 +366,6 @@ int SSL_export_keying_material(SSL *ssl, uint8_t *out, size_t out_len, } Array seed; if (!seed.Init(seed_len)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } diff --git a/Sources/CNIOBoringSSL/ssl/tls13_both.cc b/Sources/CNIOBoringSSL/ssl/tls13_both.cc index cfffae39..dcaa5047 100644 --- a/Sources/CNIOBoringSSL/ssl/tls13_both.cc +++ b/Sources/CNIOBoringSSL/ssl/tls13_both.cc @@ -58,13 +58,11 @@ bool tls13_get_cert_verify_signature_input( enum ssl_cert_verify_context_t cert_verify_context) { ScopedCBB cbb; if (!CBB_init(cbb.get(), 64 + 33 + 1 + 2 * EVP_MAX_MD_SIZE)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return false; } for (size_t i = 0; i < 64; i++) { if (!CBB_add_u8(cbb.get(), 0x20)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return false; } } @@ -80,7 +78,6 @@ bool tls13_get_cert_verify_signature_input( static const char kContext[] = "TLS 1.3, Channel ID"; context = kContext; } else { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return false; } @@ -88,7 +85,6 @@ bool tls13_get_cert_verify_signature_input( if (!CBB_add_bytes(cbb.get(), reinterpret_cast(context.data()), context.size())) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return false; } @@ -97,7 +93,6 @@ bool tls13_get_cert_verify_signature_input( if (!hs->transcript.GetHash(context_hash, &context_hash_len) || !CBB_add_bytes(cbb.get(), context_hash, context_hash_len) || !CBBFinishArray(cbb.get(), out)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return false; } @@ -186,7 +181,6 @@ bool tls13_process_certificate(SSL_HANDSHAKE *hs, const SSLMessage &msg, UniquePtr certs(sk_CRYPTO_BUFFER_new_null()); if (!certs) { ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return false; } @@ -230,7 +224,6 @@ bool tls13_process_certificate(SSL_HANDSHAKE *hs, const SSLMessage &msg, if (!buf || !PushToStack(certs.get(), std::move(buf))) { ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return false; } @@ -520,7 +513,8 @@ bool tls13_add_certificate(SSL_HANDSHAKE *hs) { if (!ssl->method->init_message(ssl, cbb.get(), body, SSL3_MT_COMPRESSED_CERTIFICATE) || !CBB_add_u16(body, hs->cert_compression_alg_id) || - !CBB_add_u24(body, msg.size()) || + msg.size() > (1u << 24) - 1 || // + !CBB_add_u24(body, static_cast(msg.size())) || !CBB_add_u24_length_prefixed(body, &compressed)) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); return false; diff --git a/Sources/CNIOBoringSSL/ssl/tls13_client.cc b/Sources/CNIOBoringSSL/ssl/tls13_client.cc index dd13358e..7f5b47a2 100644 --- a/Sources/CNIOBoringSSL/ssl/tls13_client.cc +++ b/Sources/CNIOBoringSSL/ssl/tls13_client.cc @@ -671,7 +671,6 @@ static enum ssl_hs_wait_t do_read_certificate_request(SSL_HANDSHAKE *hs) { } else { hs->ca_names.reset(sk_CRYPTO_BUFFER_new_null()); if (!hs->ca_names) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); return ssl_hs_error; } diff --git a/Sources/CNIOBoringSSL/ssl/tls13_server.cc b/Sources/CNIOBoringSSL/ssl/tls13_server.cc index ad955dc0..982974fb 100644 --- a/Sources/CNIOBoringSSL/ssl/tls13_server.cc +++ b/Sources/CNIOBoringSSL/ssl/tls13_server.cc @@ -66,25 +66,25 @@ static bool resolve_ecdhe_secret(SSL_HANDSHAKE *hs, SSL_HANDSHAKE_HINTS *const hints = hs->hints.get(); if (hints && !hs->hints_requested && hints->key_share_group_id == group_id && !hints->key_share_secret.empty()) { - // Copy DH secret from hints. - if (!hs->ecdh_public_key.CopyFrom(hints->key_share_public_key) || + // Copy the key_share secret from hints. + if (!hs->key_share_ciphertext.CopyFrom(hints->key_share_ciphertext) || !secret.CopyFrom(hints->key_share_secret)) { ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); return false; } } else { - ScopedCBB public_key; + ScopedCBB ciphertext; UniquePtr key_share = SSLKeyShare::Create(group_id); if (!key_share || // - !CBB_init(public_key.get(), 32) || - !key_share->Accept(public_key.get(), &secret, &alert, peer_key) || - !CBBFinishArray(public_key.get(), &hs->ecdh_public_key)) { + !CBB_init(ciphertext.get(), 32) || + !key_share->Encap(ciphertext.get(), &secret, &alert, peer_key) || + !CBBFinishArray(ciphertext.get(), &hs->key_share_ciphertext)) { ssl_send_alert(ssl, SSL3_AL_FATAL, alert); return false; } if (hints && hs->hints_requested) { hints->key_share_group_id = group_id; - if (!hints->key_share_public_key.CopyFrom(hs->ecdh_public_key) || + if (!hints->key_share_ciphertext.CopyFrom(hs->key_share_ciphertext) || !hints->key_share_secret.CopyFrom(secret)) { ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); return false; @@ -116,8 +116,11 @@ static const SSL_CIPHER *choose_tls13_cipher( const uint16_t version = ssl_protocol_version(ssl); - return ssl_choose_tls13_cipher(cipher_suites, version, group_id, - ssl->config->only_fips_cipher_suites_in_tls13); + return ssl_choose_tls13_cipher( + cipher_suites, + ssl->config->aes_hw_override ? ssl->config->aes_hw_override_value + : EVP_has_aes_hardware(), + version, group_id, ssl->config->only_fips_cipher_suites_in_tls13); } static bool add_new_session_tickets(SSL_HANDSHAKE *hs, bool *out_sent_tickets) { @@ -790,7 +793,7 @@ static enum ssl_hs_wait_t do_send_server_hello(SSL_HANDSHAKE *hs) { return ssl_hs_error; } - hs->ecdh_public_key.Reset(); // No longer needed. + hs->key_share_ciphertext.Reset(); // No longer needed. if (!ssl->s3->used_hello_retry_request && !ssl->method->add_change_cipher_spec(ssl)) { return ssl_hs_error; diff --git a/Sources/NIOSSL/SSLCertificate.swift b/Sources/NIOSSL/SSLCertificate.swift index c3c51bd1..64804a3e 100644 --- a/Sources/NIOSSL/SSLCertificate.swift +++ b/Sources/NIOSSL/SSLCertificate.swift @@ -109,7 +109,7 @@ public final class NIOSSLCertificate { /// - format: The format to use to parse the file. public convenience init(bytes: [UInt8], format: NIOSSLSerializationFormats) throws { let ref = bytes.withUnsafeBytes { (ptr) -> OpaquePointer? in - let bio = CNIOBoringSSL_BIO_new_mem_buf(ptr.baseAddress, CInt(ptr.count))! + let bio = CNIOBoringSSL_BIO_new_mem_buf(ptr.baseAddress, ptr.count)! defer { CNIOBoringSSL_BIO_free(bio) @@ -137,7 +137,7 @@ public final class NIOSSLCertificate { // ContiguousBytes would have been the lowest effort way to reduce this duplication, but we can't use it without // bringing Foundation in. Probably we should use Sequence where Element == UInt8 and the withUnsafeContiguousBytesIfAvailable // method, but that's a much more substantial refactor. Let's do it later. - let bio = CNIOBoringSSL_BIO_new_mem_buf(ptr.baseAddress, CInt(ptr.count))! + let bio = CNIOBoringSSL_BIO_new_mem_buf(ptr.baseAddress, ptr.count)! defer { CNIOBoringSSL_BIO_free(bio) @@ -286,7 +286,7 @@ extension NIOSSLCertificate { } return try bytes.withUnsafeBytes { (ptr) -> [NIOSSLCertificate] in - let bio = CNIOBoringSSL_BIO_new_mem_buf(ptr.baseAddress, CInt(ptr.count))! + let bio = CNIOBoringSSL_BIO_new_mem_buf(ptr.baseAddress, ptr.count)! defer { CNIOBoringSSL_BIO_free(bio) } diff --git a/Sources/NIOSSL/SSLContext.swift b/Sources/NIOSSL/SSLContext.swift index 55995dc6..0b28e675 100644 --- a/Sources/NIOSSL/SSLContext.swift +++ b/Sources/NIOSSL/SSLContext.swift @@ -545,7 +545,7 @@ extension NIOSSLContext { // This copy should be done infrequently, so we don't worry too much about it. let protoBuf = protocols.reduce([UInt8](), +) let rc = protoBuf.withUnsafeBufferPointer { - CNIOBoringSSL_SSL_CTX_set_alpn_protos(context, $0.baseAddress!, CUnsignedInt($0.count)) + CNIOBoringSSL_SSL_CTX_set_alpn_protos(context, $0.baseAddress!, $0.count) } // Annoyingly this function reverses the error convention: 0 is success, non-zero is failure. diff --git a/Sources/NIOSSL/SSLPKCS12Bundle.swift b/Sources/NIOSSL/SSLPKCS12Bundle.swift index c64d703e..e038881e 100644 --- a/Sources/NIOSSL/SSLPKCS12Bundle.swift +++ b/Sources/NIOSSL/SSLPKCS12Bundle.swift @@ -46,7 +46,7 @@ public struct NIOSSLPKCS12Bundle: Hashable { public let privateKey: NIOSSLPrivateKey private init(ref: OpaquePointer, passphrase: Bytes?) throws where Bytes.Element == UInt8 { - var pkey: UnsafeMutablePointer? = nil + var pkey: OpaquePointer?/**/ = nil var cert: OpaquePointer?/**/ = nil var caCerts: OpaquePointer? = nil @@ -90,7 +90,7 @@ public struct NIOSSLPKCS12Bundle: Hashable { guard boringSSLIsInitialized else { fatalError("Failed to initialize BoringSSL") } let p12 = buffer.withUnsafeBytes { pointer -> OpaquePointer? in - let bio = CNIOBoringSSL_BIO_new_mem_buf(pointer.baseAddress, CInt(pointer.count))! + let bio = CNIOBoringSSL_BIO_new_mem_buf(pointer.baseAddress, pointer.count)! defer { CNIOBoringSSL_BIO_free(bio) } diff --git a/Sources/NIOSSL/SSLPrivateKey.swift b/Sources/NIOSSL/SSLPrivateKey.swift index 08318749..03b575c3 100644 --- a/Sources/NIOSSL/SSLPrivateKey.swift +++ b/Sources/NIOSSL/SSLPrivateKey.swift @@ -114,23 +114,23 @@ func globalBoringSSLPassphraseCallback(buf: UnsafeMutablePointer?, public final class NIOSSLPrivateKey { @usableFromInline internal enum Representation { - case native(UnsafeMutableRawPointer /*(_ body: (UnsafeMutablePointer) throws -> ReturnType) rethrows -> ReturnType { + internal func withUnsafeMutableEVPPKEYPointer(_ body: (OpaquePointer) throws -> ReturnType) rethrows -> ReturnType { guard case .native(let pointer) = self.representation else { preconditionFailure() } - return try body(pointer.assumingMemoryBound(to: EVP_PKEY.self)) + return try body(pointer) } - private init(withReference ref: UnsafeMutablePointer) { - self.representation = .native(UnsafeMutableRawPointer(ref)) // erasing the type for @_implementationOnly import CNIOBoringSSL + private init(withReference ref: OpaquePointer) { + self.representation = .native(ref) } /// A delegating initializer for `init(file:format:passphraseCallback)` and `init(file:format:)`. @@ -141,7 +141,7 @@ public final class NIOSSLPrivateKey { _ = try? Posix.fclose(file: fileObject) } - let key = withExtendedLifetime(callbackManager) { callbackManager -> UnsafeMutablePointer? in + let key = withExtendedLifetime(callbackManager) { callbackManager -> OpaquePointer? in guard let bio = CNIOBoringSSL_BIO_new_fp(fileObject, BIO_NOCLOSE) else { return nil } @@ -172,13 +172,13 @@ public final class NIOSSLPrivateKey { /// A delegating initializer for `init(buffer:format:passphraseCallback)` and `init(buffer:format:)`. private convenience init(bytes: [UInt8], format: NIOSSLSerializationFormats, callbackManager: CallbackManagerProtocol?) throws { - let ref = bytes.withUnsafeBytes { (ptr) -> UnsafeMutablePointer? in - let bio = CNIOBoringSSL_BIO_new_mem_buf(ptr.baseAddress!, CInt(ptr.count))! + let ref = bytes.withUnsafeBytes { (ptr) -> OpaquePointer? in + let bio = CNIOBoringSSL_BIO_new_mem_buf(ptr.baseAddress!, ptr.count)! defer { CNIOBoringSSL_BIO_free(bio) } - return withExtendedLifetime(callbackManager) { callbackManager -> UnsafeMutablePointer? in + return withExtendedLifetime(callbackManager) { callbackManager -> OpaquePointer? in switch format { case .pem: if let callbackManager = callbackManager { @@ -299,14 +299,14 @@ public final class NIOSSLPrivateKey { /// /// In general, however, this function should be avoided in favour of one of the convenience /// initializers, which ensure that the lifetime of the EVP_PKEY object is better-managed. - static internal func fromUnsafePointer(takingOwnership pointer: UnsafeMutablePointer) -> NIOSSLPrivateKey { + static internal func fromUnsafePointer(takingOwnership pointer: OpaquePointer) -> NIOSSLPrivateKey { return NIOSSLPrivateKey(withReference: pointer) } deinit { switch self.representation { case .native(let ref): - CNIOBoringSSL_EVP_PKEY_free(ref.assumingMemoryBound(to: EVP_PKEY.self)) + CNIOBoringSSL_EVP_PKEY_free(ref) case .custom: // Merely dropping the ref is enough. () @@ -330,7 +330,7 @@ extension NIOSSLPrivateKey { /// The pointer provided to the closure is not valid beyond the lifetime of this method call. /// /// This method is only safe to call on native private keys. - private static func withUnsafeDERBuffer(of ref: UnsafeMutablePointer, _ body: (UnsafeRawBufferPointer) throws -> T) throws -> T { + private static func withUnsafeDERBuffer(of ref: OpaquePointer, _ body: (UnsafeRawBufferPointer) throws -> T) throws -> T { guard let bio = CNIOBoringSSL_BIO_new(CNIOBoringSSL_BIO_s_mem()) else { fatalError("Failed to malloc for a BIO handler") } @@ -401,7 +401,7 @@ extension NIOSSLPrivateKey: Hashable { // We could attempt the latter, but frankly it causes a lot of pain for minimal gain, so we don't bother. This incurs an allocation, // but that's ok. We crash if we hit an error here, as there is no way to recover. hasher.combine(0) - try! NIOSSLPrivateKey.withUnsafeDERBuffer(of: ref.assumingMemoryBound(to: EVP_PKEY.self)) { hasher.combine(bytes: $0) } + try! NIOSSLPrivateKey.withUnsafeDERBuffer(of: ref) { hasher.combine(bytes: $0) } case .custom(let custom): hasher.combine(1) custom.hash(into: &hasher) diff --git a/Sources/NIOSSL/SSLPublicKey.swift b/Sources/NIOSSL/SSLPublicKey.swift index 924776bc..289b5e8e 100644 --- a/Sources/NIOSSL/SSLPublicKey.swift +++ b/Sources/NIOSSL/SSLPublicKey.swift @@ -21,14 +21,10 @@ /// ``NIOSSLCertificate`` objects to be serialized, so that they can be passed to /// general-purpose cryptography libraries. public final class NIOSSLPublicKey { - private let _ref: UnsafeMutableRawPointer /**/ + private let ref: OpaquePointer /**/ - private var ref: UnsafeMutablePointer { - return self._ref.assumingMemoryBound(to: EVP_PKEY.self) - } - - fileprivate init(withOwnedReference ref: UnsafeMutablePointer) { - self._ref = UnsafeMutableRawPointer(ref) // erasing the type for @_implementationOnly import CNIOBoringSSL + fileprivate init(withOwnedReference ref: OpaquePointer) { + self.ref = ref } deinit { @@ -51,7 +47,7 @@ extension NIOSSLPublicKey { /// - parameters: /// - pointer: A pointer to an `EVP_PKEY` structure containing the public key. /// - returns: An `NIOSSLPublicKey` wrapping the pointer. - internal static func fromInternalPointer(takingOwnership pointer: UnsafeMutablePointer) -> NIOSSLPublicKey { + internal static func fromInternalPointer(takingOwnership pointer: OpaquePointer) -> NIOSSLPublicKey { return NIOSSLPublicKey(withOwnedReference: pointer) } } diff --git a/Tests/NIOSSLTests/CustomPrivateKeyTests.swift b/Tests/NIOSSLTests/CustomPrivateKeyTests.swift index 6c95bae7..8f70fbbf 100644 --- a/Tests/NIOSSLTests/CustomPrivateKeyTests.swift +++ b/Tests/NIOSSLTests/CustomPrivateKeyTests.swift @@ -25,7 +25,7 @@ import NIOConcurrencyHelpers // This is a helper that lets us work with an EVP_PKEY. fileprivate final class CustomPKEY { - private let ref: UnsafeMutablePointer + private let ref: OpaquePointer init(from key: NIOSSLPrivateKey) { // Extract a copy of the key reference here. @@ -35,7 +35,7 @@ fileprivate final class CustomPKEY { } } - init(from generator: () -> UnsafeMutablePointer) { + init(from generator: () -> OpaquePointer) { self.ref = generator() } diff --git a/Tests/NIOSSLTests/NIOSSLTestHelpers.swift b/Tests/NIOSSLTests/NIOSSLTestHelpers.swift index 3bee7ae8..03118f50 100644 --- a/Tests/NIOSSLTests/NIOSSLTestHelpers.swift +++ b/Tests/NIOSSLTests/NIOSSLTestHelpers.swift @@ -556,7 +556,7 @@ func randomSerialNumber() -> ASN1_INTEGER { return asn1int } -func generateRSAPrivateKey() -> UnsafeMutablePointer { +func generateRSAPrivateKey() -> OpaquePointer { let exponent = CNIOBoringSSL_BN_new() defer { CNIOBoringSSL_BN_free(exponent) @@ -575,7 +575,7 @@ func generateRSAPrivateKey() -> UnsafeMutablePointer { return pkey } -func generateECPrivateKey(curveNID: CInt = NID_X9_62_prime256v1) -> UnsafeMutablePointer { +func generateECPrivateKey(curveNID: CInt = NID_X9_62_prime256v1) -> OpaquePointer { let ctx = CNIOBoringSSL_EVP_PKEY_CTX_new_id(EVP_PKEY_EC, nil)! defer { CNIOBoringSSL_EVP_PKEY_CTX_free(ctx) @@ -584,7 +584,7 @@ func generateECPrivateKey(curveNID: CInt = NID_X9_62_prime256v1) -> UnsafeMutabl precondition(CNIOBoringSSL_EVP_PKEY_keygen_init(ctx) == 1) precondition(CNIOBoringSSL_EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, curveNID) == 1) - var pkey: UnsafeMutablePointer? = nil + var pkey: OpaquePointer? = nil precondition(CNIOBoringSSL_EVP_PKEY_keygen(ctx, &pkey) == 1) return pkey! @@ -601,7 +601,7 @@ func addExtension(x509: OpaquePointer, nid: CInt, value: String) { CNIOBoringSSL_X509_EXTENSION_free(ext) } -func generateSelfSignedCert(keygenFunction: () -> UnsafeMutablePointer = generateRSAPrivateKey) -> (NIOSSLCertificate, NIOSSLPrivateKey) { +func generateSelfSignedCert(keygenFunction: () -> OpaquePointer = generateRSAPrivateKey) -> (NIOSSLCertificate, NIOSSLPrivateKey) { let pkey = keygenFunction() let x = CNIOBoringSSL_X509_new()! CNIOBoringSSL_X509_set_version(x, 2) diff --git a/scripts/build-asm.py b/scripts/build-asm.py index f5a0603a..64e5c98e 100755 --- a/scripts/build-asm.py +++ b/scripts/build-asm.py @@ -69,12 +69,12 @@ def ExtractPerlAsmFromCMakeFile(cmakefile): raise ValueError('Bad perlasm line in %s' % cmakefile) # Remove "perlasm(" from start and ")" from end params = line[8:-1].split() - if len(params) < 2: + if len(params) != 4: raise ValueError('Bad perlasm line in %s' % cmakefile) perlasms.append({ - 'extra_args': params[2:], - 'input': os.path.join(os.path.dirname(cmakefile), params[1]), - 'output': os.path.join(os.path.dirname(cmakefile), params[0]), + 'arch': params[1], + 'output': os.path.join(os.path.dirname(cmakefile), params[2]), + 'input': os.path.join(os.path.dirname(cmakefile), params[3]), }) return perlasms @@ -100,53 +100,26 @@ def PerlAsm(output_filename, input_filename, perlasm_style, extra_args): subprocess.check_call( ['perl', input_filename, perlasm_style] + extra_args + [output_filename]) - -def ArchForAsmFilename(filename): - """Returns the architectures that a given asm file should be compiled for - based on substrings in the filename.""" - - if 'x86_64' in filename or 'avx2' in filename: - return ['x86_64'] - elif ('x86' in filename and 'x86_64' not in filename) or '586' in filename: - return ['x86'] - elif 'armx' in filename: - return ['arm', 'aarch64'] - elif 'armv8' in filename: - return ['aarch64'] - elif 'arm' in filename: - return ['arm'] - elif 'ppc' in filename: - # We aren't supporting ppc here. - return [] - else: - raise ValueError('Unknown arch for asm filename: ' + filename) - - def WriteAsmFiles(perlasms): """Generates asm files from perlasm directives for each supported OS x platform combination.""" asmfiles = {} - for osarch in OS_ARCH_COMBOS: - (osname, arch, perlasm_style, extra_args, asm_ext) = osarch - key = (osname, arch) - outDir = '%s-%s' % key + for perlasm in perlasms: + for (osname, arch, perlasm_style, extra_args, asm_ext) in OS_ARCH_COMBOS: + if arch != perlasm['arch']: + continue + key = (osname, arch) + outDir = '%s-%s' % key - for perlasm in perlasms: filename = os.path.basename(perlasm['input']) output = perlasm['output'] if not output.startswith('boringssl/crypto'): raise ValueError('output missing crypto: %s' % output) output = os.path.join(outDir, output[17:]) - if output.endswith('-armx.${ASM_EXT}'): - output = output.replace('-armx', - '-armx64' if arch == 'aarch64' else '-armx32') - output = output.replace('${ASM_EXT}', asm_ext) - - if arch in ArchForAsmFilename(filename): - PerlAsm(output, perlasm['input'], perlasm_style, - perlasm['extra_args'] + extra_args) - asmfiles.setdefault(key, []).append(output) + output = '%s-%s.%s' % (output, osname, asm_ext) + PerlAsm(output, perlasm['input'], perlasm_style, extra_args) + asmfiles.setdefault(key, []).append(output) return asmfiles diff --git a/scripts/patch-3-more-inttypes.patch b/scripts/patch-3-more-inttypes.patch new file mode 100644 index 00000000..81baa244 --- /dev/null +++ b/scripts/patch-3-more-inttypes.patch @@ -0,0 +1,13 @@ +diff --git a/Sources/CNIOBoringSSL/crypto/evp/print.c b/Sources/CNIOBoringSSL/crypto/evp/print.c +index 89ceb32..5e6fb2f 100644 +--- a/Sources/CNIOBoringSSL/crypto/evp/print.c ++++ b/Sources/CNIOBoringSSL/crypto/evp/print.c +@@ -50,6 +50,8 @@ + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + ++#include ++ + #include + + #include diff --git a/scripts/vendor-boringssl.sh b/scripts/vendor-boringssl.sh index a60f3aba..30813951 100755 --- a/scripts/vendor-boringssl.sh +++ b/scripts/vendor-boringssl.sh @@ -88,6 +88,7 @@ function mangle_symbols { swift build --triple "arm64-apple-macosx" --product CNIOBoringSSL ( cd "${SRCROOT}" + go mod tidy -modcacherw go run "util/read_symbols.go" -out "${TMPDIR}/symbols-macOS-intel.txt" "${HERE}/.build/x86_64-apple-macosx/debug/libCNIOBoringSSL.a" go run "util/read_symbols.go" -out "${TMPDIR}/symbols-macOS-as.txt" "${HERE}/.build/arm64-apple-macosx/debug/libCNIOBoringSSL.a" ) @@ -273,6 +274,7 @@ done echo "GENERATING err_data.c" ( cd "$SRCROOT/crypto/err" + go mod tidy -modcacherw go run err_data_generate.go > "${HERE}/${DSTROOT}/crypto/err/err_data.c" ) @@ -315,6 +317,7 @@ echo "RENAMING header files" echo "PATCHING BoringSSL" git apply "${HERE}/scripts/patch-1-inttypes.patch" git apply "${HERE}/scripts/patch-2-inttypes.patch" +git apply "${HERE}/scripts/patch-3-more-inttypes.patch" # We need to avoid having the stack be executable. BoringSSL does this in its build system, but we can't. echo "PROTECTING against executable stacks"